Re: fpit - fixes and passive-pen support
"David M. Clay" <[email protected]>
| Newsgroups | gmane.comp.xfree86.devel |
|---|---|
| Message-ID | <[email protected]> |
David Dawes wrote:
> On Mon, Jan 31, 2005 at 03:41:05PM -0500, David M. Clay wrote:
>
>>Hello all.
>>
>>I am new at this, so please gently guide me through this wonderful
>>process of open-source coding.
>>
>>I just recently purchased a Stylistic 3400 and found the current fpit
>>driver did not support the passive pen of the 3400. So I modified the
>>current driver to support the passive pen.
>>
>>I am looking to have my changes added to the latest source tree. What is
>>the best was to have others test my changes on other systems with
>>different hardware, especially the active-pen models? I am pretty sure
>>that I have fixed several bugs that had to have affected the active-pen
>>systems as well, and I hope that I haven't broken anything. I don't have
>>access to any other Stylistic tablets so I am unable to test it myself.
>>The driver does work beautifully on my Stylistic 3400 though. Are there
>>any testers out there? Whats the best way for me to post the changes? Is
>>there a preferred style for diff patches? Is there a FAQ for this?
>
>
> I don't recall seeing any feedback regarding this driver in the
> past, and from your decsription it sounds like you've fixed some
> real bugs and improved the driver. I'd suggest submitting your
> patches ('diff -u' format preferred), and we can look at getting
> them in for the coming release. You can either post them here, or
> submit them via bugs.xfree86.org.
>
> If anyone here is using the fpit driver, particularly with an active pen
> system, they should speak up now, and test your patches.
>
> David
> _______________________________________________
> Devel mailing list
> [email protected]
> http://XFree86.Org/mailman/listinfo/devel
>
>
Okay, here is my patch for the whole fpit directory. I edited the man
page and readme file to reflect the changes. You will need to apply the
patch in the xc/programs/Xserver/hw/xfree86/input/fpit directory and
specify -p1 option. Forgive me if everyone already knows how to figure
that out (I didn't).
diff -u fpit-1.6/fpit.man fpit/fpit.man
--- fpit-1.6/fpit.man 2002-11-21 22:35:12.000000000 -0500
+++ fpit/fpit.man 2005-01-31 20:31:06.000000000 -0500
@@ -33,6 +33,15 @@
.B setserial /dev/ttyS3 autoconfig
.TP 4
.B setserial /dev/ttyS3 IRQ 15 baud_base 115200 port 0xfce8
+.PP
+This driver now supports Stylistic 3400 (and possibly other passive-pen
+systems) with a special \fI"Passive"\fP paramter. Try this serial
+configuration for the 3400:
+
+.TP 4
+.B setserial /dev/ttyS3 autoconfig
+.TP 4
+.B setserial /dev/ttyS3 uart 16450 irq 5 port 0xfd68
.SH CONFIGURATION DETAILS
Please refer to XF86Config(5x) for general configuration
@@ -85,6 +94,9 @@
.TP 4
.B Option \fI"BaudRate"\fP \fI"38400"\fP, \fI"19200"\fP or \fI"9600"\fP (default)
changes the serial link speed.
+.TP 4
+.B Option \fI"Passive"\fP
+decodes the passive pen.
.RE
Example, for Stylistic LT setup is:
@@ -111,6 +123,21 @@
.B EndSection
.fi
+For Stylistic 3400:
+.nf
+.B "Section \*qInputDevice\*q"
+.BI " Identifier \*q" mouse0 \*q
+.B " Driver \*qfpit\*q"
+.BI " Option \*qDevice\*q \*q"/dev/ttyS3 \*q
+.BI " Option \*qBaudRate\*q \*q"9600 \*q
+.BI " Option \*qMaximumXPosition\*q \*q"4070 \*q
+.BI " Option \*qMaximumYPosition\*q \*q"4020 \*q
+.BI " Option \*qMinimumXPosition\*q \*q"0 \*q
+.BI " Option \*qMinimumYPosition\*q \*q"0 \*q
+.BI " Option \*qPassive\*q"
+.BI " Option \*qSendCoreEvents\*q"
+.B EndSection
+.fi
.SH "SEE ALSO"
XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__).
diff -u fpit-1.6/readme.txt fpit/readme.txt
--- fpit-1.6/readme.txt 2002-11-21 22:37:36.000000000 -0500
+++ fpit/readme.txt 2005-01-31 20:32:40.000000000 -0500
@@ -30,7 +30,7 @@
project into the XFree86 4.0.2 Elographics driver by Patrick Lecoanet.
- John Apfelbaum continuted the work to produce a working XFree86 4.0.x driver for the
Stylistic 1200.
-
+- David Clay added support for Stylistic 3400 passive pen.
Please visit http://linuxslate.com for the latest information.
@@ -93,6 +93,34 @@
tracks the pen correctly.
+New for Ver 4.5.0
+
+ * supports Stylistic 3400 (and possibly other passive-pen systems)
+ * Fixed processing of all packets
+ * Fixed hover-mode pointer movement
+ * Added Passive parameter for passive displays
+ * Added switch 3 for "right" mouse button
+
+Try this serial configuration for the 3400:
+
+setserial /dev/ttyS3 autoconfig
+setserial /dev/ttyS3 uart 16450 irq 5 port 0xfd68
+
+Try this config for the 3400:
+Section "InputDevice"
+ Identifier "mouse0"
+ Driver "fpit"
+ Option "Device" "/dev/ttyS3"
+ Option "BaudRate" "9600"
+ Option "Passive"
+ Option "MaximumXPosition" "4070"
+ Option "MaximumYPosition" "4020"
+ Option "MinimumXPosition" "0"
+ Option "MinimumYPosition" "0"
+ Option "SendCoreEvents"
+EndSection
+
+
Hints if you are having problems (Thanks to Aron Hsiao):
Problem 1: Side switch being reported as wild button numbers
diff -u fpit-1.6/xf86Fpit.c fpit/xf86Fpit.c
--- fpit-1.6/xf86Fpit.c 2004-04-27 06:01:50.000000000 -0400
+++ fpit/xf86Fpit.c 2005-01-31 20:24:08.000000000 -0500
@@ -5,6 +5,15 @@
* This driver is a merge of the Elographics driver (from Patrick Lecoanet) and
* the driver for Fujitsu Pen Computers from Rob Tsuk and John Apfelbaum.
*
+ * Modified for Stylistic 3400 passive pen support by David Clay
+ * Fixed processing of all packets
+ * Detangled and simplified if-statement logic
+ * Fixed hover-mode pointer movement
+ * Added Passive parameter for passive displays
+ * Added switch 3 for "right" mouse button
+ * I might have broken active pen support. I can't test it.
+ * January 2005 <dave at claysrus.com>
+ *
* Stylistic 500, 1000, 1200, 2300 Support fixed by John Apfelbaum
* June 2001 <[email protected]>
*
@@ -61,7 +70,6 @@
# include <xf86Module.h>
-
/*
***************************************************************************
*
@@ -78,13 +86,19 @@
#define FPIT_MIN_Y 0
#define PHASING_BIT 0x80
-#define PROXIMITY_BIT 0x40
+#define PROXIMITY_BIT 0x20 /* DMC: This was 0x40 but the chart says its bit 5 which is 0x20 */
/*#define TABID_BIT 0x20 */
#define XSIGN_BIT 0x10
#define YSIGN_BIT 0x08
#define BUTTON_BITS 0x07
#define COORD_BITS 0x7f
+/* DMC: Added these */
+#define SW1 0x01
+#define SW2 0x02
+#define SW3 0x04
+
+
/*
***************************************************************************
*
@@ -125,6 +139,7 @@
int fpitBaud; /* Baud rate of device */
unsigned char fpitData[BUFFER_SIZE]; /* data read on the device */
int fpitSwapXY; /* swap X and Y values */
+ int fpitPassive; /* translate passive buttons */
} FpitPrivateRec, *FpitPrivatePtr;
@@ -164,13 +179,16 @@
static void xf86FpitReadInput(LocalDevicePtr local)
{
FpitPrivatePtr priv = (FpitPrivatePtr) local->private;
- int len, loop, found;
+ int len, loop;
int is_core_pointer;
int x, y, buttons, prox;
DeviceIntPtr device;
int conv_x, conv_y;
+
+ do { /* keep reading blocks until there are no more */
+
/* Read data into buffer */
- len = xf86ReadSerial(local->fd, priv->fpitData, BUFFER_SIZE);
+ len = xf86ReadSerial(local->fd, priv->fpitData+priv->fpitIndex, BUFFER_SIZE-priv->fpitIndex);
if (len <= 0) {
Error("error reading FPIT device");
priv->fpitIndex = 0;
@@ -182,28 +200,16 @@
can look through the data backwards to find the last full and valid
position. (This may make cursor movement a bit faster) */
- priv->fpitIndex += len;
- found = 0;
- for (loop = priv->fpitIndex - 5; loop >= 0; loop--) {
- if (priv->fpitData[loop] & 0x80) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- /* Wait for our next call when we should have some more data */
+ /* DMC: We want to process ALL packets! This way, all points will come
+ through and drawing curves are smoother. Also we won't miss any
+ button events.
+ */
- /* Check to see if the buffer is filling up - if so do something
- about it */
- /* if (priv->fpitIndex > BUFFER_SIZE - 5) {
- memmove(priv->fpitData, priv->fpitData+priv->fpitIndex-5, 5) ;
- priv->fpitIndex = 5 ;
- }
- */
- return;
- }
+ priv->fpitIndex += len;
+ /* process each packet in this block */
+ for (loop=0;loop+FPIT_PACKET_SIZE<=priv->fpitIndex;loop++) {
+ if (!(priv->fpitData[loop] & 0x80)) continue; /* we don't have a start bit yet */
/* Format of 5 bytes data packet for Fpit Tablets
Byte 1
@@ -233,56 +239,82 @@
bits 6-0 = Y13 - Y7
*/
- x = (int) (priv->fpitData[loop + 1] & 0x7f) + ((int) (priv->fpitData[loop + 2] & 0x7f) << 7);
- y = (int) (priv->fpitData[loop + 3] & 0x7f) + ((int) (priv->fpitData[loop + 4] & 0x7f) << 7);
- /* Add in any offsets */
- if (priv->fpitInvX)
- x = priv->fpitMaxX - x + priv->fpitMinX;
- if (priv->fpitInvY)
- y = priv->fpitMaxY - y + priv->fpitMinY;
- prox = (priv->fpitData[loop] & PROXIMITY_BIT) ? 0 : 1;
- buttons = (priv->fpitData[loop] & BUTTON_BITS);
- priv->fpitIndex = 0;
- device = local->dev;
- is_core_pointer = xf86IsCorePointer(device);
+ x = (int) (priv->fpitData[loop + 1] & 0x7f) + ((int) (priv->fpitData[loop + 2] & 0x7f) << 7);
+ y = (int) (priv->fpitData[loop + 3] & 0x7f) + ((int) (priv->fpitData[loop + 4] & 0x7f) << 7);
+ /* Add in any offsets */
+ if (priv->fpitInvX)
+ x = priv->fpitMaxX - x + priv->fpitMinX;
+ if (priv->fpitInvY)
+ y = priv->fpitMaxY - y + priv->fpitMinY;
+ prox = (priv->fpitData[loop] & PROXIMITY_BIT) ? 0 : 1;
+ buttons = (priv->fpitData[loop] & BUTTON_BITS);
+ device = local->dev;
+ is_core_pointer = xf86IsCorePointer(device);
+
+ xf86FpitConvert(local, 0, 2, x, y, 0, 0, 0, 0, &conv_x, &conv_y);
+ xf86XInputSetScreen(local, priv->screen_no, conv_x, conv_y);
+
+ /* coordonates are ready we can send events */
- xf86FpitConvert(local, 0, 2, x, y, 0, 0, 0, 0, &conv_x, &conv_y);
- xf86XInputSetScreen(local, priv->screen_no, conv_x, conv_y);
+ if (prox!=priv->fpitOldProximity) /* proximity changed */
+ if (!is_core_pointer) xf86PostProximityEvent(device, prox, 0, 2, x, y);
- /* coordinates are ready we can send events */
- if (prox) {
- if (!(priv->fpitOldProximity))
- if (!is_core_pointer)
- xf86PostProximityEvent(device, 1, 0, 2, x, y);
- if ((priv->fpitOldX != x) || (priv->fpitOldY != y)) {
- if (priv->fpitOldProximity) {
- xf86PostMotionEvent(device, 1, 0, 2, x, y);
- }
+ if (priv->fpitOldX != x || priv->fpitOldY != y) /* position changed */
+ xf86PostMotionEvent(device, 1, 0, 2, x, y);
+
+ if (priv->fpitPassive) {
+ /*
+ For passive pen (Stylistic 3400, et al.):
+ sw1 = 1 if pen is moving
+ sw1 = 0 if pen is not moving
+ sw2 = 0 if pen is contacting the pad
+ sw2 = 1 if pen was lifted from the pad
+ sw3 = 1 if right mouse-button icon was chosen
+ */
+ /* convert the pen button bits to actual mouse buttons */
+ if (buttons & SW2) buttons=0; /* the pen was lifted, so no buttons are pressed */
+ else if (buttons & SW3) buttons=SW3; /* the "right mouse" button was pressed, so send down event */
+ else if (prox) buttons=SW1; /* the "left mouse" button was pressed and we are not hovering, so send down event */
+ else buttons=0; /* We are in hover mode, so no buttons */
+ }
+ else { /* the active pen's buttons map directly to the mouse buttons */
+ if (!prox) buttons=0; /* We are in hover mode, so no buttons */
}
+
+ /* DBG(2, ErrorF("%02d/%02d Prox=%d SW:%x Buttons:%x->%x (%d, %d)\n",
+ loop,priv->fpitIndex,prox,priv->fpitData[loop]&BUTTON_BITS,priv->fpitOldButtons,buttons,x,y));*/
if (priv->fpitOldButtons != buttons) {
int delta;
- delta = buttons - priv->fpitOldButtons;
+ delta = buttons ^ priv->fpitOldButtons; /* set delta to the bits that have changed */
while (delta) {
int id;
id = ffs(delta);
delta &= ~(1 << (id - 1));
xf86PostButtonEvent(device, 1, id, (buttons & (1 << (id - 1))), 0, 2, x, y);
+ /* DBG(1, ErrorF("Button %d %s\n",id,(buttons & (1 << (id - 1)))?"DOWN":"UP"));*/
}
+ priv->fpitOldButtons = buttons;
}
-
- priv->fpitOldButtons = buttons;
priv->fpitOldX = x;
priv->fpitOldY = y;
priv->fpitOldProximity = prox;
- } else { /* !PROXIMITY */
- /* Any changes in buttons are ignored when !proximity */
- if (!is_core_pointer)
- if (priv->fpitOldProximity)
- xf86PostProximityEvent(device, 0, 0, 2, x, y);
- priv->fpitOldProximity = 0;
- }
+ loop+=FPIT_PACKET_SIZE-1; /* advance to the next packet */
+ } /* for each packet */
+
+ /* remove from the data buffer all that we have processed */
+ if (loop<priv->fpitIndex) memmove(priv->fpitData, priv->fpitData+loop,priv->fpitIndex-loop);
+ priv->fpitIndex-=loop;
+
+ /* DMC: My system did not read the pen-up event until another event was
+ posted, the result was the button sticking down even though
+ I had lifted the pen. So I am checking the device for more data
+ and then retrieving it. This fixed it for me. I don't know if this is just my system. */
+
+ } while (xf86WaitForInput(local->fd,0)>0); /* go back and check for more data (we don't want to block for I/O!) */
+
+ return;
}
static void xf86FpitPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
@@ -306,7 +338,7 @@
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
FpitPrivatePtr priv = (FpitPrivatePtr) (local->private);
unsigned char map[] = {
- 0, 1, 2
+ 0, 1, 2, 3 /* DMC: changed this so we can use all three buttons */
};
@@ -443,6 +475,7 @@
priv->fpitOldProximity = 0;
priv->fpitIndex = 0;
priv->fpitSwapXY = 0;
+ priv->fpitPassive = 0;
local->name = XI_TOUCHSCREEN;
local->flags = 0 /* XI86_NO_OPEN_ON_INIT */ ;
local->device_control = xf86FpitControl;
@@ -518,6 +551,7 @@
priv->fpitInvX = xf86SetBoolOption(local->options, "InvertX", 0);
priv->fpitInvY = xf86SetBoolOption(local->options, "InvertY", 0);
priv->fpitSwapXY = xf86SetBoolOption(local->options, "SwapXY", 0);
+ priv->fpitPassive = xf86SetBoolOption(local->options, "Passive", 0);
str = xf86SetStrOption(local->options, "Rotate", 0);
if (!xf86NameCmp(str, "CW")) {
priv->fpitInvX = 1;
@@ -531,6 +565,7 @@
xf86Msg(X_CONFIG, "FPIT invert X axis: %s\n", priv->fpitInvX ? "Yes" : "No");
xf86Msg(X_CONFIG, "FPIT invert Y axis: %s\n", priv->fpitInvY ? "Yes" : "No");
xf86Msg(X_CONFIG, "FPIT swap X and Y axis: %s\n", priv->fpitSwapXY ? "Yes" : "No");
+ xf86Msg(X_CONFIG, "FPIT Passive button mode: %s\n", priv->fpitPassive ? "Yes" : "No");
/* mark the device configured */
local->flags |= XI86_CONFIGURED;
return local;