[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