The following patch is necessary to make input/aiptek module function correctly on my system (the described changes also apply to previous versions, this diff was created against module version 1.0.0.5 ) The main bug here is that the driver attempts to use a bitwise OR to turn the tablet buttons both on and off (OR can only result in 1 if one side is set), resulting in immediately stuck buttons. One or two other changes are required to make the event list process correctly through the driver (otherwise no events get passed to X - the tablet effectively doesn't work, although including the module and setting its parameters doesn't kill X.) ### This is an edited diff created from a *fixed* older version of xf86Aiptek.c - so some hunks include lines that will mangle your whitespace a bit. ### --- ./xf86Aiptek.c 2004-04-23 15:54:02.000000000 -0400 +++ /root/xf86Aiptek.c 2004-09-30 17:47:27.000000000 -0400 @@ -309,7 +309,7 @@ int bCorePointer, bAbsolute; int x, y, z, xTilt, yTilt; - + if ((DEVICE_ID(device->flags) != common->currentValues.eventType)) { DBG(7,ErrorF("xf86AiptekSendEvents: not the same device type (%u,%u)\n", @@ -422,13 +422,11 @@ } /* As the coordinates are ready, we can send events to X */ - if (common->currentValues.proximity) - { if (!common->previousValues.proximity) { if (!bCorePointer) { - xf86PostProximityEvent(local->dev, 1, 0, 5, + xf86PostProximityEvent(local->dev, 1, 0, 5, x, y, z, xTilt, yTilt); } } @@ -442,7 +440,7 @@ { if (bAbsolute || common->previousValues.proximity) { - xf86PostMotionEvent(local->dev, bAbsolute, 0, 5, + xf86PostMotionEvent(local->dev, bAbsolute, 0, 5, x, y, z, xTilt, yTilt); } } @@ -456,24 +454,11 @@ int id; id = ffs(delta); delta &= ~(1 << (id-1)); - xf86PostButtonEvent(local->dev, bAbsolute, id, + xf86PostButtonEvent(local->dev, bAbsolute, id, (common->currentValues.button & (1<<(id-1))), 0, 5, x, y, z, xTilt, yTilt); } } - } - else - { - if (!bCorePointer) - { - if (common->previousValues.proximity) - { - xf86PostProximityEvent(local->dev, 0, 0, 5, x, y, z, - xTilt, yTilt); - } - } - common->previousValues.proximity = 0; - } } /* @@ -496,7 +481,7 @@ double d_zCapacity; SYSCALL(len = read(local->fd, eventbuf, sizeof(eventbuf))); - + if (len <= 0) { ErrorF("Error reading Aiptek tablet: %s\n", strerror(errno)); @@ -524,7 +509,7 @@ { case EV_ABS: { - switch (event->code) + switch (event->code) { case ABS_X: { @@ -704,27 +689,48 @@ * as normal buttons. */ case BTN_TOUCH: - { + { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_TOUCH; - } + if (common->currentValues.eventType != STYLUS_ID) + common->currentValues.eventType = STYLUS_ID; + if ((event->value > 0) * BUTTONS_EVENT_TOUCH) + { + common->currentValues.button |= BUTTONS_EVENT_TOUCH; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_TOUCH; + } + } break; + case BTN_STYLUS: { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_STYLUS; - } + if ((event->value > 0) * BUTTONS_EVENT_STYLUS) + { + common->currentValues.button |= BUTTONS_EVENT_STYLUS; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_STYLUS; + } + } break; case BTN_STYLUS2: { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_STYLUS2; - } + if ((event->value > 0) * BUTTONS_EVENT_STYLUS2) + { + common->currentValues.button |= BUTTONS_EVENT_STYLUS2; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_STYLUS2; + } + } break; /* @@ -737,41 +743,71 @@ case BTN_LEFT: { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_MOUSE_LEFT; - } + if ((event->value > 0) * BUTTONS_EVENT_MOUSE_LEFT) + { + common->currentValues.button |= BUTTONS_EVENT_MOUSE_LEFT; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_MOUSE_LEFT; + } + } break; case BTN_MIDDLE: { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_MOUSE_MIDDLE; - } + if ((event->value > 0) * BUTTONS_EVENT_MOUSE_MIDDLE) + { + common->currentValues.button |= BUTTONS_EVENT_MOUSE_MIDDLE; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_MOUSE_MIDDLE; + } + } break; case BTN_RIGHT: { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_MOUSE_RIGHT; - } + if ((event->value > 0) * BUTTONS_EVENT_MOUSE_RIGHT) + { + common->currentValues.button |= BUTTONS_EVENT_MOUSE_RIGHT; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_MOUSE_RIGHT; + } + } break; case BTN_SIDE: { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_SIDE_BTN; - } + if ((event->value > 0) * BUTTONS_EVENT_SIDE_BTN) + { + common->currentValues.button |= BUTTONS_EVENT_SIDE_BTN; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_SIDE_BTN; + } + } break; case BTN_EXTRA: { ++eventsInMessage; - common->currentValues.button |= - (event->value > 0 ? 1 : 0) * BUTTONS_EVENT_EXTRA_BTN; - } + if ((event->value > 0) * BUTTONS_EVENT_EXTRA_BTN) + { + common->currentValues.button |= BUTTONS_EVENT_EXTRA_BTN; + } + else + { + common->currentValues.button &= ~BUTTONS_EVENT_EXTRA_BTN; + } + } break; /* @@ -812,7 +848,6 @@ { continue; } - /* * We've seen EV_MSCs in the incoming data trail with no * other message types in-between. We use 'eventsInMessage' @@ -825,8 +860,6 @@ { continue; } - eventsInMessage = 0; - /* * This filter throws out reports that do not meet minimum threshold * requirements for movement along that axis. @@ -1851,10 +1884,10 @@ xf86AiptekAllocateStylus(void) { LocalDevicePtr local = xf86AiptekAllocate(XI_STYLUS, STYLUS_ID); - + if (local) { - local->type_name = "Stylus"; + local->type_name = "Stylus"; } return local; } @@ -1982,15 +2015,16 @@ s = xf86FindOptionValue(fakeLocal->options, "Type"); if (s && (xf86NameCmp(s, "stylus") == 0)) { - local = xf86AiptekAllocateStylus(); + local = xf86AiptekAllocate(XI_STYLUS, STYLUS_ID); } else if (s && (xf86NameCmp(s, "cursor") == 0)) { - local = xf86AiptekAllocateCursor(); + local = xf86AiptekAllocate(XI_CURSOR, CURSOR_ID); } else if (s && (xf86NameCmp(s, "eraser") == 0)) { - local = xf86AiptekAllocateEraser(); + local = xf86AiptekAllocate(XI_ERASER, + ABSOLUTE_FLAG|ERASER_ID); } else { @@ -2004,7 +2038,6 @@ xfree(fakeLocal); return NULL; } - device = (AiptekDevicePtr) local->private; common = device->common;
Sorry about the phenomenal bug spam, guys. Adding xorg-team@ to the QA contact so bugs don't get lost in future.
Created attachment 13625 [details] [review] Patch with load of fixes, backported from aiptektablet.sourceforge.net Tested with re-branded aiptek 12000U
Wow. This has been reported over a year ago (well, a year and 20 minutes). I am running Fedora 8 now, which is fitted with Xorg 7.2 . Let me introduce myself. I am the guy who fixed the aiptek kernel and X drivers, several years ago. In those times, for optimal tablet pleasure, one needed to download and compile at least the Linux kernel driver. The aiptek driver that was in older Xfree/Xorg releases worked, mostly. By now, an updated kernel driver is in the linux kernel, so that part progressed. However, the fixes/cleanups for this driver in Xorg 7 onwards introduced considerable bitrot in the xorg driver, so much that it is unusable now, and everyone on the aiptek forums/lists is complaining. I don't want to bitch, but this makes me somewhat unhappy. Please, in the future when you plan to fix things, contact me to check that you are not hurting functionality. I produced a patch for the 1.0.1 version of the driver. I stuck as much as possible to your formatting and structure, to get a clean patch. I used the source from the fixed aiptek X driver as reference (aiptektablet.sourceforge.net). Please apply this patch ASAP. If you have a reason not to apply this patch (and it better be a good one), clarify. I tested this on my Medion (re-branded aiptek 12000U) tablet, and it works like a charm. BTW Thanks Adrian, for reporting this and trying to fix the driver. I hope this can be fixed soon. Regards, Rene
(In reply to comment #3) > By now, an updated kernel driver is in the linux kernel, so that part > progressed. However, the fixes/cleanups for this driver in Xorg 7 > onwards introduced considerable bitrot in the xorg driver, so much > that it is unusable now, and everyone on the aiptek forums/lists is > complaining. I don't want to bitch, but this makes me somewhat > unhappy. Please, in the future when you plan to fix things, contact me > to check that you are not hurting functionality. git://anongit.freedesktop.org/git/xorg/doc/xorg-docs, the MAINTAINERS file lists aiptek as unmaintained. AFAIK, there's exactly two ppl working on general input. so if stuff goes amiss, keep poking. > I produced a patch for the 1.0.1 version of the driver. I stuck as > much as possible to your formatting and structure, to get a clean > patch. I used the source from the fixed aiptek X driver as reference > (aiptektablet.sourceforge.net). > > Please apply this patch ASAP. If you have a reason not to apply this > patch (and it better be a good one), clarify. I tested this on my > Medion (re-branded aiptek 12000U) tablet, and it works like a charm. I took the liberty of removing the diff for the xf86Aiptek.c~ file from the diff :) aside from that I fixed three things to make it work with git master, one compiler warning, one call to a deprecated function and - most importantly - one call to an unresolved function. so the current git head should work with 7.3 and beyond. changing to fixed now, please reopen if problems occur. do you want to take over maintainership and cut releases for 7.2 and 7.3?
I forgot: patch was pushed as 3cb825cb4a633132de10df77e792fcbadf082385 Subsequent fixes for server 1.4 as 66e0fbb24377ac14b9cf8a80a55253cff13d7913 a88dafb63b0e0f3e4557ae75a3ee9a377ea4ef68 e34bc8e774d92bd81dcefbcd341ab3f040a7f144
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.