Subject: Mir considered about Multi-display && Multi-touch devices?

From: Leslie Zhai <[email-masked]>
Date: Sat, 19 Oct 2013 12:54:32 +0800

Hi Mir developers,

I use Projected Capacitive touch screen device
http://en.wikipedia.org/wiki/Touchscreen#Projected_capacitance
It can be pasted on the normal monitor, then it is able to touch, the
cursor will move to the position where touched. It experienced like
iphone and other single touch screen device.

But when I put multiple Projected Capacitive touch screen devices on
several monitors, then touch some of them simultaneously, the cursor of
X Window was only moving in the first monitor, even though it was able
to move to other monitors` display, it still failed to show the correct
position. Did Mir consider about Multi-display && Multi-touch devices?

Why the cursor of X Window wired? Some people might argue that it is
Linux kernel Multi-touch Protocol issue
https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt

Nope!

For Protocol Example B

Here is what a minimal event sequence for a two-contact touch would look
like for a type B device:

ABS_MT_SLOT 0
ABS_MT_TRACKING_ID 45
ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
ABS_MT_SLOT 1
ABS_MT_TRACKING_ID 46
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_REPORT

Here is the sequence after moving contact 45 in the x direction:

ABS_MT_SLOT 0
ABS_MT_POSITION_X x[0]
SYN_REPORT

Here is the sequence after lifting the contact in slot 0:

ABS_MT_TRACKING_ID -1
SYN_REPORT

The slot being modified is already 0, so the ABS_MT_SLOT is omitted. The
message removes the association of slot 0 with contact 45, thereby
destroying contact 45 and freeing slot 0 to be reused for another contact.

Finally, here is the sequence after lifting the second contact:

ABS_MT_SLOT 1
ABS_MT_TRACKING_ID -1
SYN_REPORT

Here ABS_MT_SLOT distinguished which finger touch the screen,
ABS_MT_POSITION_X and ABS_MT_POSITION_Y shown the position where the
finger touched.
In case ABS_MT_XXX martix like below:

(0, 0)-------------------------(4075, 0)
| |
| |
| |
| (X, Y) |
| |
| |
| |
| |
| |
| |
| |
(0, 4095)-------------------(4075, 4095)

For single touch screen device situation, the X axis range of the
position is [0, 4075], the Y`s is [0, 4095]; then for multi-devices, the
matrix could not be transformed, the range might never be changed, it
will not increased by multiply the number of monitors. It means if I
could touch several monitors in the same or about position
simultaneously, I am so lucky :) the (X, Y) position values might be the
same, then the cursor of X Window wired.

Then someone might be doubt about it is X evdev input driver issue
http://cgit.freedesktop.org/xorg/driver/xf86-input-evdev/

In the function EvdevAddAbsValuatorClass(DeviceIntPtr device, int
want_scroll_axes)
http://cgit.freedesktop.org/xorg/driver/xf86-input-evdev/tree/src/evdev.c#n1249

It only consider about one single device, a Projected Capacitive touch
screen device connected to Linux box via USB, but what about multi-touch
devices, how to handle several file descriptors? It might be fixed by
Leslie MultiTouch way!

Leslie MultiTouch

I hacked the get devices function via reading /proc/bus/input/devices

void getDevices(std::string DeviceName, std::vector<std::string>* Devices)
{
std::string strLine;
std::string strDevPath;
std::ifstream DevFile("/proc/bus/input/devices");
int nPos;

while (std::getline(DevFile, strLine))
{
if (strLine.size() == 0)
continue;

if (strLine[0] == 'N')
{
if (ToLower(strLine).find(ToLower(DeviceName)) != std::string::npos)
{
while (std::getline(DevFile, strLine))
{
if (strLine[0] == 'H')
break;
}
nPos = strLine.find("event");
if (nPos != std::string::npos) {
strDevPath = "/dev/input/" + strLine.substr(nPos, strLine.size() - nPos
- 1);
#if DEBUG
// such as /dev/input/event13
std::cout << "DEBUG: " << strDevPath << std::endl;
#endif
Devices->push_back(strDevPath);
}
}
}
}
}

Then it need to create a thread pool to handle several DeviceIntPtr
objects simultaneously.

And it need to identify each touch screen device like Xorg Xinerama conf
style:

Section "MultiTouchLayout"
Identifier "MultiTouch Device"
Device 0 "Device0" 0 0
Device 1 "Device1" RightOf "Device0" # LeftOf, BelowOf, AboveOf
Option "MultiTouch" "true"
EndSection

Section "Device"
Identifier "Device0"
Device "/dev/input/event13"
Monitor "Monitor0"
DefaultDepth 24
SubSection "Display"
Viewport 0 0
Depth 24
Modes "1680x1050"
EndSubSection
EndSection

Section "Device"
Identifier "Device1"
Device "/dev/input/event16"
Monitor "Monitor1"
DefaultDepth 24
SubSection "Display"
Viewport 0 0
Depth 24
Modes "1680x1050"
EndSubSection
EndSection

When it send a (X, Y) position event from the touch screen devices`
thread pool, it is able to know which device generate it, and it need to
transform the old (X, Y) position to monitor_N`s new (X`, Y`), the
cursor of X Window might never wired any more.

Best Regards,

Leslie

---

From: Daniel van Vugt <[email-masked]>
Date: Mon, 21 Oct 2013 09:48:58 +0800

Leslie,

XMir does not use Mir's input system at the moment. It lets X use the 
existing evdev interface instead. Also, XMir does not use Mir's hardware 
cursor either. So it is X rendering the mouse pointer(s) in software.

So in theory your issue has nothing to do with Mir and would still 
happen in plain X too. I think you should direct the problem to an X 
mailing list.

- Daniel