[PATCH] fpit. Stylistic 3400 supported. Looking for testers.
David M. Clay
daveclay at wowway.com
Wed Feb 2 10:02:15 PST 2005
I have already posted this patch to the xfree86 devl list. I thought I would post it here to see if I could get someone to test it. I especially need it tested on the active-pen systems to make sure I didn't break anything.
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 -p7 option.
Please report any successes or failures.
Thanks,
David Clay
diff -u xorg_xc/programs/Xserver/hw/xfree86/input/fpit/Imakefile xc/programs/Xserver/hw/xfree86/input/fpit/Imakefile
--- xorg_xc/programs/Xserver/hw/xfree86/input/fpit/Imakefile 2004-04-23 15:54:03.000000000 -0400
+++ xc/programs/Xserver/hw/xfree86/input/fpit/Imakefile 2005-02-02 11:32:08.000000000 -0500
@@ -1,4 +1,4 @@
-XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/fpit/Imakefile,v 1.3 2000/05/23 04:47:47 dawes Exp $
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/fpit/Imakefile,v 1.2 2004/03/18 07:07:02 dawes Exp $
#define IHaveModules
#include <Server.tmpl>
@@ -17,7 +17,7 @@
ModuleObjectRule()
-ObjectModuleTarget($(DRIVER),$(OBJS))
+ObjectModuleTarget($(DRIVER),$(OBJS),input)
InstallObjectModule($(DRIVER),$(MODULEDIR),input)
diff -u xorg_xc/programs/Xserver/hw/xfree86/input/fpit/fpit.man xc/programs/Xserver/hw/xfree86/input/fpit/fpit.man
--- xorg_xc/programs/Xserver/hw/xfree86/input/fpit/fpit.man 2004-04-23 15:54:03.000000000 -0400
+++ xc/programs/Xserver/hw/xfree86/input/fpit/fpit.man 2005-02-02 11:32:25.000000000 -0500
@@ -1,4 +1,4 @@
-.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/wacom/wacom.cpp,v 1.9 2000/12/18 00:17:18 dawes Exp $
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/fpit/fpit.man,v 1.1 2002/11/22 03:35:12 dawes Exp $
.\" shorthand for double quote that works everywhere.
.ds q \N'34'
.TH FPIT __drivermansuffix__ __vendorversion__
@@ -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 __xconfigfile__(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"
__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__).
diff -u xorg_xc/programs/Xserver/hw/xfree86/input/fpit/readme.txt xc/programs/Xserver/hw/xfree86/input/fpit/readme.txt
--- xorg_xc/programs/Xserver/hw/xfree86/input/fpit/readme.txt 2004-04-23 15:54:03.000000000 -0400
+++ xc/programs/Xserver/hw/xfree86/input/fpit/readme.txt 2005-02-02 11:32:08.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
@@ -138,4 +166,4 @@
-/* $XFree86$ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/fpit/readme.txt,v 1.2 2002/11/22 03:37:37 dawes Exp $ */
diff -u xorg_xc/programs/Xserver/hw/xfree86/input/fpit/xf86Fpit.c xc/programs/Xserver/hw/xfree86/input/fpit/xf86Fpit.c
--- xorg_xc/programs/Xserver/hw/xfree86/input/fpit/xf86Fpit.c 2004-04-23 15:54:03.000000000 -0400
+++ xc/programs/Xserver/hw/xfree86/input/fpit/xf86Fpit.c 2005-02-02 11:35:55.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 <johnapf at linuxlsate.com>
*
@@ -40,7 +49,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*
*/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/input/fpit/xf86Fpit.c,v 1.3tsi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/fpit/xf86Fpit.c,v 1.6 2004/04/26 22:48:21 dawes Exp $ */
#include <xf86Version.h>
@@ -58,10 +67,7 @@
# include <xf86Xinput.h>
# include <exevents.h>
-# ifdef XFree86LOADER
-# include <xf86Module.h>
-# endif
-
+# include <xf86Module.h>
/*
@@ -80,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
+
+
/*
***************************************************************************
*
@@ -127,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;
@@ -156,12 +169,6 @@
*x = xf86ScaleAxis(v0, 0, priv->screen_width, priv->fpitMinX, priv->fpitMaxX);
*y = xf86ScaleAxis(v1, 0, priv->screen_height, priv->fpitMinY, priv->fpitMaxY);
}
- /*
- * Need to check if still on the correct screen.
- * This call is here so that this work can be done after
- * calib and before posting the event.
- */
- xf86XInputSetScreen(local, priv->screen_no, *x, *y);
return TRUE;
}
@@ -172,12 +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;
@@ -189,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
@@ -240,52 +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);
- /* coordonates 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);
- }
+ 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 */
+
+ if (prox!=priv->fpitOldProximity) /* proximity changed */
+ if (!is_core_pointer) xf86PostProximityEvent(device, prox, 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)
@@ -309,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 */
};
@@ -446,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;
@@ -521,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;
@@ -534,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;
More information about the xorg
mailing list