diff options
Diffstat (limited to 'src/evdev.c')
-rw-r--r-- | src/evdev.c | 77 |
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; |