From: Chase Douglas <[email protected]> MTDev translates all multitouch devices to the slotted evdev protocol. This provides a clean and uniform interface and reduces message handling inside the input module and X.
Signed-off-by: Chase Douglas <[email protected]> --- configure.ac | 3 +++ src/Makefile.am | 2 +- src/evdev.c | 44 ++++++++++++++++++++++++++++++++++++++++---- src/evdev.h | 7 +++++++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index cc9e721..ed87352 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,9 @@ AC_ARG_ENABLE(multitouch, if test "x$MULTITOUCH" = xyes; then AC_DEFINE(MULTITOUCH, 1, [Enable experimental multitouch code]) + + # Obtain compiler/linker options for mtdev + PKG_CHECK_MODULES(MTDEV, mtdev) fi # Define a configure option for an alternate input module directory diff --git a/src/Makefile.am b/src/Makefile.am index a5c89ac..89137bc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,7 +29,7 @@ AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS) AM_CPPFLAGS =-I$(top_srcdir)/include @driver_n...@_drv_la_ltlibraries = @driver_n...@_drv.la -...@driver_name@_drv_la_LDFLAGS = -module -avoid-version +...@driver_name@_drv_la_LDFLAGS = -module -avoid-version $(MTDEV_LIBS) @driver_n...@_drv_ladir = @inputdir@ @driver_n...@_drv_la_sources = @[email protected] \ diff --git a/src/evdev.c b/src/evdev.c index 8b13e9f..a83d4e4 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1065,7 +1065,17 @@ EvdevReadInput(InputInfoPtr pInfo) while (len == sizeof(ev)) { - len = read(pInfo->fd, &ev, 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 + len = read(pInfo->fd, &ev, sizeof(ev)); +#else + len = read(pInfo->fd, &ev, sizeof(ev)); +#endif if (len <= 0) { if (errno == ENODEV) /* May happen after resume */ @@ -1496,6 +1506,9 @@ EvdevAddAbsClass(DeviceIntPtr device) #ifdef HAVE_MASKED_VALUATORS num_axes = CountBits((uint8_t *)pEvdev->abs_bitmask, ABS_MT_SLOT); num_mt_axes = CountBits((uint8_t *)pEvdev->abs_bitmask, ABS_MAX) - num_axes; + + if (num_mt_axes > 0 && !TestBit(ABS_MT_TRACKING_ID, pEvdev->abs_bitmask)) + num_mt_axes++; #else num_axes = EvdevCountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX)); num_mt_axes = 0; @@ -1540,7 +1553,8 @@ EvdevAddAbsClass(DeviceIntPtr device) for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) { pEvdev->axis_map[axis] = -1; - if (!TestBit(axis, pEvdev->abs_bitmask) || axis == ABS_MT_SLOT) + if ((!TestBit(axis, pEvdev->abs_bitmask) || axis == ABS_MT_SLOT) && + axis != ABS_MT_TRACKING_ID) continue; pEvdev->axis_map[axis] = i; i++; @@ -1565,8 +1579,8 @@ EvdevAddAbsClass(DeviceIntPtr device) int mode = pEvdev->flags & EVDEV_TOUCHPAD ? XIDependentTouch : XIDirectTouch; - if (pEvdev->absinfo[ABS_MT_SLOT].maximum > 0) - num_touches = pEvdev->absinfo[ABS_MT_SLOT].maximum; + if (pEvdev->mtdev->caps.slot.maximum > 0) + num_touches = pEvdev->mtdev->caps.slot.maximum; pEvdev->mt_slot_map = malloc(num_touches * sizeof(int)); if (!pEvdev->mt_slot_map) @@ -2061,6 +2075,8 @@ EvdevProc(DeviceIntPtr device, int what) #ifdef MULTITOUCH free(pEvdev->mt_slot_map); free(pEvdev->mtMask); + if (pEvdev->mtdev) + mtdev_close(pEvdev->mtdev); #endif EvdevRemoveDevice(pInfo); pEvdev->min_maj = 0; @@ -2489,6 +2505,16 @@ EvdevOpenDevice(InputInfoPtr pInfo) pEvdev->device = device; xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device); + +#ifdef MULTITOUCH + pEvdev->mtdev = malloc(sizeof(struct mtdev)); + if (!pEvdev->mtdev) + { + xf86Msg(X_ERROR, "%s: Couldn't allocate mtdev structure\n", + pInfo->name); + return BadAlloc; + } +#endif } if (pInfo->fd < 0) @@ -2503,6 +2529,16 @@ EvdevOpenDevice(InputInfoPtr pInfo) } } +#ifdef MULTITOUCH + if (mtdev_open(pEvdev->mtdev, pInfo->fd) == 0) + pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value; + else { + free(pEvdev->mtdev); + pEvdev->mtdev = NULL; + xf86Msg(X_INFO, "%s: Couldn't open mtdev device\n", pInfo->name); + } +#endif + /* Check major/minor of device node to avoid adding duplicate devices. */ pEvdev->min_maj = EvdevGetMajorMinor(pInfo); if (EvdevIsDuplicate(pInfo)) diff --git a/src/evdev.h b/src/evdev.h index 63c75a3..6bd8fe3 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -39,6 +39,10 @@ #include <xf86_OSproc.h> #include <xkbstr.h> +#ifdef MULTITOUCH +#include <mtdev.h> +#endif + #ifndef EV_CNT /* linux 2.6.23 kernels and earlier lack _CNT defines */ #define EV_CNT (EV_MAX+1) #endif @@ -210,6 +214,9 @@ typedef struct { /* Event queue used to defer keyboard/button events until EV_SYN time. */ int num_queue; EventQueueRec queue[EVDEV_MAXQUEUE]; +#ifdef MULTITOUCH + struct mtdev *mtdev; +#endif } EvdevRec, *EvdevPtr; /* Event posting functions */ -- 1.7.1 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
