summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/evdev.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 456c7aa..b97b841 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -53,6 +53,9 @@
#include <X11/Xatom.h>
#include <evdev-properties.h>
#include <xserver-properties.h>
+#ifdef MULTITOUCH
+#include <mtdev-plumbing.h>
+#endif
#ifndef XI_PROP_PRODUCT_ID
#define XI_PROP_PRODUCT_ID "Device Product ID"
@@ -780,7 +783,7 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
EvdevPtr pEvdev = pInfo->private;
int map;
- if (!pEvdev->mtdev)
+ if (!pEvdev->mtdev && !EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_SLOT))
return;
if (ev->code == ABS_MT_SLOT) {
@@ -1096,6 +1099,35 @@ EvdevFreeMasks(EvdevPtr pEvdev)
#endif
}
+static void
+EvdevProcessAllEvents(InputInfoPtr pInfo, struct input_event *ev, int nevents, size_t max_events)
+{
+ EvdevPtr pEvdev = pInfo->private;
+ int i, more_events_left = 0;
+
+ do {
+#ifdef MULTITOUCH
+ if (pEvdev->mtdev) {
+ int nmtevents = 0;
+ for (i = 0; i < nevents; i++)
+ mtdev_put_event(pEvdev->mtdev, &ev[i]);
+
+ while (!mtdev_empty(pEvdev->mtdev) && nmtevents < max_events)
+ mtdev_get_event(pEvdev->mtdev, &ev[nmtevents++]);
+
+ /* mtdev may have converted to more events than we have space for */
+ more_events_left = nmtevents >= max_events && !mtdev_empty(pEvdev->mtdev);
+ nevents = nmtevents;
+ }
+#endif
+
+ for (i = 0; i < nevents; i++)
+ EvdevProcessEvent(pInfo, &ev[i]);
+
+ nevents = 0;
+ } while(more_events_left);
+}
+
/* just a magic number to reduce the number of reads */
#define NUM_EVENTS 16
@@ -1103,19 +1135,11 @@ static void
EvdevReadInput(InputInfoPtr pInfo)
{
struct input_event ev[NUM_EVENTS];
- int i, len = sizeof(ev);
+ int len = sizeof(ev);
while (len == sizeof(ev))
{
-#ifdef MULTITOUCH
- EvdevPtr pEvdev = pInfo->private;
-
- if (pEvdev->mtdev)
- len = mtdev_get(pEvdev->mtdev, pInfo->fd, ev, NUM_EVENTS) *
- sizeof(struct input_event);
- else
-#endif
- len = read(pInfo->fd, &ev, sizeof(ev));
+ len = read(pInfo->fd, &ev, sizeof(ev));
if (len <= 0)
{
@@ -1134,8 +1158,8 @@ EvdevReadInput(InputInfoPtr pInfo)
break;
}
- for (i = 0; i < len/sizeof(ev[0]); i++)
- EvdevProcessEvent(pInfo, &ev[i]);
+ EvdevProcessAllEvents(pInfo, ev, len/sizeof(ev[0]), NUM_EVENTS);
+
}
}
@@ -1421,15 +1445,19 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
}
#ifdef MULTITOUCH
- if (pEvdev->mtdev && num_mt_axes_total > 0)
+ if (num_mt_axes_total > 0)
{
int num_touches = 0;
int mode = pEvdev->flags & EVDEV_TOUCHPAD ?
XIDependentTouch : XIDirectTouch;
- if (pEvdev->mtdev->caps.slot.maximum > 0)
- num_touches = pEvdev->mtdev->caps.slot.maximum -
- pEvdev->mtdev->caps.slot.minimum + 1;
+ if (pEvdev->mtdev) {
+ if (pEvdev->mtdev->caps.slot.maximum > 0)
+ num_touches = pEvdev->mtdev->caps.slot.maximum -
+ pEvdev->mtdev->caps.slot.minimum + 1;
+ } else
+ num_touches = pEvdev->absinfo[ABS_MT_SLOT].maximum -
+ pEvdev->absinfo[ABS_MT_SLOT].minimum + 1;
if (!InitTouchClassDeviceStruct(device, num_touches, mode,
num_mt_axes_total)) {
@@ -1441,10 +1469,11 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
for (i = 0; i < num_slots(pEvdev); i++) {
for (axis = ABS_MT_TOUCH_MAJOR; axis < ABS_MAX; axis++) {
if (pEvdev->abs_axis_map[axis] >= 0) {
+ int val = pEvdev->mtdev ? 0 : pEvdev->absinfo[axis].value;
/* XXX: read initial values from mtdev when it adds support
* for doing so. */
valuator_mask_set(pEvdev->last_mt_vals[i],
- pEvdev->abs_axis_map[axis], 0);
+ pEvdev->abs_axis_map[axis], val);
}
}
}
@@ -2404,7 +2433,7 @@ EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
#ifdef MULTITOUCH
/**
* Open an mtdev device for this device. mtdev is a bit too generous with
- * memory usage, so only do so for devices with multitouch bits set.
+ * memory usage, so only do so for multitouch protocol A devices.
*
* @return FALSE on error, TRUE if mtdev was initiated or the device doesn't
* need it
@@ -2420,6 +2449,12 @@ EvdevOpenMTDev(InputInfoPtr pInfo)
if (pEvdev->mtdev) {
pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
return TRUE;
+ } else if (EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_SLOT)) {
+ struct input_absinfo abs;
+ len = ioctl(pInfo->fd, EVIOCGABS(ABS_MT_SLOT), &abs);
+ if (len != -1)
+ pEvdev->cur_slot = abs.value;
+ return TRUE;
}
if (pInfo->fd < 0) {
@@ -2445,6 +2480,10 @@ EvdevOpenMTDev(InputInfoPtr pInfo)
return FALSE;
}
+ /* don't need mtdev for protocol B devices */
+ if (EvdevBitIsSet(abs_bitmask, ABS_MT_SLOT))
+ return TRUE;
+
if (!EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_X) ||
!EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_Y))
return TRUE;