--- 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 + * * Stylistic 500, 1000, 1200, 2300 Support fixed by John Apfelbaum * June 2001 * @@ -61,7 +70,6 @@ # include - /* *************************************************************************** * @@ -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 (loopfpitIndex) 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;