summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:56 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:56 +0000
commit82141c852d890ca247dde30af3ae016f24494d7c (patch)
tree04bd6a80b5e36a5a40d4eb7017d49bdeb9f85cac
-rw-r--r--man/calcomp.man82
-rw-r--r--src/xf86Calcomp.c839
-rw-r--r--src/xf86Calcomp.h146
3 files changed, 1067 insertions, 0 deletions
diff --git a/man/calcomp.man b/man/calcomp.man
new file mode 100644
index 0000000..2b025c0
--- /dev/null
+++ b/man/calcomp.man
@@ -0,0 +1,82 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/calcomp/calcomp.man,v 1.2 2001/08/12 22:51:29 alanh Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH CALCOMP __drivermansuffix__ __vendorversion__
+.SH NAME
+calcomp \- Calcomp input driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qInputDevice\*q"
+.BI " Identifier \*q" idevname \*q
+.B " Driver \*qcalcomp\*q"
+.BI " Option \*qDevice\*q \*q" devpath \*q
+\ \ ...
+.B EndSection
+.fi
+.SH DESCRIPTION
+.B calcomp
+is an XFree86 input driver for Calcomp devices.
+.PP
+The
+.B calcomp
+driver functions as a pointer input device, and may be used as the
+X server's core pointer.
+.SH SUPPORTED HARDWARE
+This driver supports the Calcomp binary format used by the Drawing Board II
+and III series.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details and for options that can be used with all input drivers. This
+section only covers configuration details specific to this driver.
+.PP
+Both the 3 button stylus and the 4- or 16 button lens cursors can be used
+without changing the configuration file. Support for pressure sensitivity
+has not been tested, so the solid-tip stylus will probably not work.
+.PP
+This device supports the following entries:
+.RS 8
+.TP 4
+.B Option \fI"Device"\fP \fI"path"\fP
+sets the path to the special file which represents the serial line where
+the tablet is plugged. This option is mandatory.
+.TP 4
+.B Option \fI"Cursor"\fP \fI"Stylus"|"Puck"\fP
+this option is supported for backward compatibility only, but it should
+not be necessary.
+.TP 4
+.B Option \fI"DeviceName"\fP \fI"name"\fP
+sets the name of the X device. Some user-space programs may require a fixed
+name, e.g. TABLET, to recognize the digitizer.
+.TP 4
+.B Option \fI"Mode"\fP \fI"Relative"|"Absolute"\fP
+sets the mode of the device. Currently only Absolute mode is supported.
+.TP 4
+.B Option \fI"Pressure"\fP \fI"on"\fP
+enables pressure reporting if your tablet supports it. This option is
+untested and may not work.
+.TP 4
+.B Option \fI"AlwaysCore"\fP \fI"on"\fP
+enables the sharing of the core pointer. When this feature is enabled, the
+device will take control of the core pointer (and thus will emit core events)
+and at the same time will be able, when asked so, to report extended events.
+.TP 4
+.B Option \fI"MinX"\fP \fI"number"\fP
+X coordinate of the bottom left corner of the active zone.
+.TP 4
+.B Option \fI"MinY"\fP \fI"number"\fP
+Y coordinate of the bottom left corner of the active zone.
+.TP 4
+.B Option \fI"MaxX"\fP \fI"Inumber"\fP
+X coordinate of the top right corner of the active zone.
+.TP 4
+.B Option \fI"MaxY"\fP \fI"number"\fP
+Y coordinate of the top right corner of the active zone.
+.TP 4
+.B Option \fI"DebugLevel"\fP \fInumber \fP
+sets the level of debugging info reported.
+.TP 4
+.RE
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__).
+.SH AUTHORS
+Martin Kroeker <mk@daveg.com>
diff --git a/src/xf86Calcomp.c b/src/xf86Calcomp.c
new file mode 100644
index 0000000..accbfe3
--- /dev/null
+++ b/src/xf86Calcomp.c
@@ -0,0 +1,839 @@
+/*
+ * Copyright (c) 2000,2001 Martin Kroeker (mk@daveg.com)
+ * sample driver used :
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ * Except as contained in this notice, the names of Martin Kroeker and/or
+ * Daveg GmbH shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from Martin Kroeker or Daveg GmbH.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.c,v 1.8 2003/01/15 03:43:58 dawes Exp $ */
+
+#define _CALCOMP_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "xf86Calcomp.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+#define DEBUG 1
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+InputDriverRec CALCOMP = {
+ 1,
+ "calcomp",
+ NULL,
+ CalcompPreInit, /*preinit ?*/
+ NULL,
+ NULL,
+ 0
+ };
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static const char *default_options[] =
+{
+ "Device", "/dev/ttyS1",
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "1",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+
+#ifdef XFree86LOADER
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "calcomp",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+static const char *reqSymbols[] = {
+ "AddEnabledDevice",
+ "ErrorF",
+ "InitButtonClassDeviceStruct",
+ "InitProximityClassDeviceStruct",
+ "InitValuatorAxisStruct",
+ "InitValuatorClassDeviceStruct",
+ "InitPtrFeedbackClassDeviceStruct",
+ "RemoveEnabledDevice",
+ "Xcalloc",
+ "Xfree",
+ "XisbBlockDuration",
+ "XisbFree",
+ "XisbNew",
+ "XisbRead",
+ "XisbTrace",
+ "screenInfo",
+ "xf86AddInputDriver",
+ "xf86AllocateInput",
+ "xf86CloseSerial",
+ "xf86CollectInputOptions",
+ "xf86ErrorFVerb",
+ "xf86FindOptionValue",
+ "xf86GetMotionEvents",
+ "xf86GetVerbosity",
+ "xf86MotionHistoryAllocate",
+ "xf86NameCmp",
+ "xf86OpenSerial",
+ "xf86OptionListCreate",
+ "xf86OptionListMerge",
+ "xf86OptionListReport",
+ "xf86PostButtonEvent",
+ "xf86PostMotionEvent",
+ "xf86PostProximityEvent",
+ "xf86ProcessCommonOptions",
+ "xf86ScaleAxis",
+ "xf86SetIntOption",
+ "xf86SetStrOption",
+ "xf86XInputSetScreen",
+ "xf86XInputSetSendCoreEvents",
+ NULL
+ };
+
+
+static pointer
+CalcompSetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+ {
+ xf86LoaderReqSymLists(reqSymbols, NULL);
+ xf86AddInputDriver(&CALCOMP, module, 0);
+ return (pointer) 1;
+ }
+
+
+
+XF86ModuleData calcompModuleData = { &VersionRec, CalcompSetupProc, NULL };
+
+
+#endif /* XFree86LOADER */
+
+
+
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+/*
+ * The TearDownProc may have to be tailored to your device
+ */
+/******************************************************
+static void
+TearDownProc( pointer p )
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ CALCOMPPrivatePtr priv = (CALCOMPPrivatePtr) local->private;
+
+ ErrorF ("Calcomp TearDownProc Called\n");
+
+ DeviceOff (local->dev);
+
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+}
+**********************************************************/
+
+
+
+/*
+ * The DeviceControl function should not need to be changed
+ * except to remove ErrorFs
+ */
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+/* ErrorF ("DeviceControl called mode = %d\n", mode);*/
+ switch (mode)
+ {
+ case DEVICE_INIT:
+/* ErrorF ("\tINIT\n");*/
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+/* ErrorF ("\tON\n");*/
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+/* ErrorF ("\tOFF\n");*/
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+/* ErrorF ("\tCLOSE\n");*/
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ ErrorF ("\tBAD MODE\n");
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+/*
+ * The DeviceOn function should not need to be changed
+ */
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ AddEnabledDevice (local->fd);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+/*
+ * The DeviceOff function should not need to be changed
+ */
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+/*
+ * The DeviceClose function should not need to be changed
+ */
+static Bool
+DeviceClose (DeviceIntPtr dev)
+{
+ return (Success);
+}
+
+/*
+ * The DeviceInit function will need to be tailored to your device
+ */
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ CALCOMPPrivatePtr priv = (CALCOMPPrivatePtr) (local->private);
+ unsigned char map[] =
+ {0, 1};
+
+ /*
+ * Set up buttons, valuators etc for your device
+ */
+ if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate CALCOMP ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+ if (InitFocusClassDeviceStruct (dev) == FALSE) { /* is this necessary? */
+ ErrorF ("Unable to allocate CALCOMP focus class device\n");
+ return !Success;
+ }
+
+ /*
+ * this example device reports motions on 2 axes in absolute coordinates.
+ * Device may reports touch pressure on the 3rd axis.
+ */
+ if (InitValuatorClassDeviceStruct (dev, 3, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate CALCOMP ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
+ 39400,
+ 0 /* min_res */ ,
+ 12000 /* max_res */ );
+ InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
+ 39400,
+ 0 /* min_res */ ,
+ 39400 /* max_res */ );
+
+ InitValuatorAxisStruct (dev, 2, priv->min_z, priv->max_z,
+ 32,
+ 0 /* min_res */ ,
+ 32 /* max_res */ );
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("unable to allocate CALCOMP ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+
+ if (InitPtrFeedbackClassDeviceStruct(dev,
+ ControlProc) == FALSE) {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (local);
+ return (Success);
+}
+
+/*
+ * The ReadInput function will have to be tailored to your device
+ */
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x=0, y=0 , z=0;
+ /*int state;*/
+ int prox,buttons;
+ Bool is_absolute = TRUE; /* FIXME */
+ CALCOMPPrivatePtr priv = (CALCOMPPrivatePtr) (local->private);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded by a select with a 0 timeout to prevent
+ * read from blocking indefinitely.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (CALCOMPGetPacket (priv) == Success)
+ {
+ /*
+ * Examine priv->packet and call these functions as appropriate:
+ *
+ xf86PostProximityEvent
+ xf86PostMotionEvent
+ xf86PostButtonEvent
+ */
+ /* Format of 6 bytes data packet in Calcomp Binary Encoding
+
+ Byte 1
+ bit 7 Phasing bit, always 1
+ bit 6 Buttons on a 16bit cursor
+ bit 5 Button 3
+ bit 4 Button 2
+ bit 3 Button 1
+ bit 2 Button 0 (Stylus tip)
+ bit 1 X15
+ bit 0 X14
+ Byte 2
+ bit 7 Always 0
+ bits 6-0 = X13 - X7
+ Byte 3
+ bit 7 Always 0
+ bits 6-0 = X6 - X0
+ Byte 4
+ bit 7 Always 0
+ bit 6 Proximity
+ bits 3-0 = Y17 - Y14
+ Byte 5
+ bit 7 Always 0
+ bits 6-0 = Y13 - Y7
+ Byte 6
+ bit 7 Always 0
+ bits 6-0 = Y6 - Y0
+ */
+ x = priv->packet[2] + priv->packet[1] * 128
+ +(priv->packet[0] & 0x03) *128*128;
+ y = priv->packet[5] + priv->packet[4]*128 +priv->packet[3]*128*128;
+ y = priv->max_y -y;
+ prox = ((int)priv->packet[3] & PROXIMITY_BIT)? 0: 1;
+
+ buttons = (((int)priv->packet[0] & BUTTON_BITS) >>2);
+ if (buttons && ! priv->pressure ) {
+ if (buttons >15) {
+ buttons = buttons -15;
+ }else{
+ buttons = buttons /2;
+ if (buttons <4 ) buttons = buttons +1;
+ }
+ }else{
+ z = buttons; /* button bits convey pressure data*/
+ if (z >= priv->button_threshold) buttons = 1;
+#if 0
+xf86Msg(X_INFO,"Tablett pressurebutton = %d >= %d\n",z,priv->button_threshold);
+#endif
+ }
+#if 0
+xf86Msg(X_INFO,"Tablett x y prox buttons = %d %d %d %d\n",x,y,prox,buttons);
+#endif
+ if (prox) {
+ if (!(priv->prox)) {
+ xf86PostProximityEvent(local->dev, 1, 0, 2, x, y);
+ }
+
+ if ((is_absolute && ((priv->x != x) || (priv->y != y)))
+ || (!is_absolute && (x || y))) {
+ priv->x = x;
+ priv->y = y;
+
+ if (is_absolute || priv->prox) {
+ xf86PostMotionEvent(local->dev, is_absolute, 0, 3, x, y, z);
+
+ }
+ }
+ if (priv->buttons != buttons) {
+ int delta;
+ int button;
+ delta = buttons - priv->buttons;
+ button = (delta > 0)? delta: ((delta == 0)? priv->buttons : -delta);
+ if (priv->buttons != buttons) {
+ xf86PostButtonEvent(local->dev, is_absolute, button,
+ (delta > 0), 0, 2, x, y);
+ }
+ }
+ priv->buttons = buttons;
+ priv->x = x;
+ priv->y = y;
+ priv->prox = prox;
+ } else { /* !PROXIMITY */
+ /* Any changes in buttons are ignored when !proximity */
+ if (priv->prox) xf86PostProximityEvent(local->dev, 0, 0, 2, x, y);
+ priv->prox = 0;
+ }
+
+ } /* while packets come in */
+}
+
+/*
+ * The ControlProc function may need to be tailored for your device
+ */
+static void
+ControlProc (DeviceIntPtr device, PtrCtrl * control)
+{
+}
+static int
+ChangeControlProc(LocalDevicePtr local, xDeviceCtl *control)
+{
+return(Success);
+}
+/*
+ * the CloseProc should not need to be tailored to your device
+ */
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+/*
+ * The SwitchMode function may need to be tailored for your device
+ */
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ return (Success);
+}
+
+/*
+ * The ConvertProc function may need to be tailored for your device.
+ * This function converts the device's valuator outputs to x and y coordinates
+ * to simulate mouse events.
+ */
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+CALCOMPPrivatePtr priv=(CALCOMPPrivatePtr) local->private;
+double factorX,factorY;
+
+xf86Msg(X_INFO,"Calcomp ConvertProc called\n");
+if (first !=0 || num == 1) return FALSE;
+
+factorX= ((double) priv->screen_width)
+ /(priv->max_x - priv->min_x);
+factorY= ((double) priv->screen_height)
+ /(priv->max_y - priv->min_y);
+
+ *x = v0*factorX;
+ *y = v1*factorY;
+ return (Success);
+}
+
+/*
+ * the QueryHardware fuction should be tailored to your device to
+ * verify the device is attached and functional and perform any
+ * needed initialization.
+ */
+static Bool
+QueryHardware (int fd, CALCOMPPrivatePtr priv)
+{
+char buffer[255];
+int err;
+
+ SYSCALL(err = write(fd, DB_COMM_SETUP, strlen(DB_COMM_SETUP)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_UPPER_ORIGIN, strlen(DB_UPPER_ORIGIN)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_BINARY_FMT, strlen(DB_BINARY_FMT)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_XINCREMENT, strlen(DB_XINCREMENT)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_YINCREMENT, strlen(DB_YINCREMENT)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_1000LPI, strlen(DB_1000LPI)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ SYSCALL(err = write(fd, DB_STREAM_MODE, strlen(DB_STREAM_MODE)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+ if (priv->pressure)
+ SYSCALL(err = write(fd, DB_PRESSURE_ON, strlen(DB_PRESSURE_ON)));
+ else
+ SYSCALL(err = write(fd, DB_PRESSURE_OFF, strlen(DB_PRESSURE_OFF)));
+ if (err<0) return !Success;
+
+ xf86WaitForInput(-1,500);
+
+ if (!xf86CalWriteAndRead(fd, DB_FIRMID, buffer, 35, 1))
+ return !Success;
+
+ xf86Msg(X_INFO,"Calcomp firmware ID : %s\n", buffer);
+ memset(buffer,32,35);
+
+ xf86WaitForInput(-1,500);
+
+ if (!xf86CalWriteAndRead(fd, DB_PRODID, buffer, 20, 1))
+ return !Success;
+ xf86Msg(X_INFO,"Product ID : %s\n", buffer);
+
+ memset(buffer,32,20);
+
+ xf86WaitForInput(-1,500);
+
+ if (!xf86CalWriteAndRead(fd, DB_CONFIG, buffer, 6, 1))
+ return !Success;
+ priv->max_x = (int)buffer[2] + ((int)buffer[1] << 7)
+ + (((int)buffer[0]&0x03)<<14);
+ priv->max_y = (int)buffer[5] + ((int)buffer[4] << 7);
+
+ xf86Msg(X_INFO,"Tablet size : %d x %d \n", priv->max_x,priv->max_y);
+
+
+ xf86WaitForInput(-1,500);
+
+
+ SYSCALL(err = write(fd, DB_ABSOLUTE, strlen(DB_ABSOLUTE)));
+ if (err<0) return !Success;
+
+
+
+/*
+*/
+ return (Success);
+
+}
+
+static InputInfoPtr
+CalcompPreInit( InputDriverPtr drv,
+ IDevPtr dev, int flags)
+ {
+
+ InputInfoPtr local;
+ CALCOMPPrivatePtr priv = xcalloc (1, sizeof (CALCOMPPrivateRec));
+ char *s;
+
+ if (!(local = xf86AllocateInput(drv, 0)))
+ return NULL;
+
+ xf86Msg (X_INFO,"Calcomp SetupProc called\n");
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ local->conf_idev = dev;
+
+ xf86CollectInputOptions(local, default_options, NULL);
+
+ xf86OptionListReport( local->options );
+ local->fd = xf86OpenSerial (local->options);
+
+
+
+
+
+
+
+ if (local->fd == -1)
+ {
+ xf86Msg (X_ERROR,"CALCOMP driver unable to open device\n");
+ goto SetupProc_fail;
+ } else {
+ xf86Msg( X_INFO,"CALCOMP driver: Serial device opened\n");
+ }
+
+ priv->min_x = xf86SetIntOption( local->options, "MinX", 0 );
+ priv->max_x = xf86SetIntOption( local->options, "MaxX", 1000 );
+ priv->min_y = xf86SetIntOption( local->options, "MinY", 0 );
+ priv->max_y = xf86SetIntOption( local->options, "MaxY", 1000 );
+ priv->min_z = xf86SetIntOption( local->options, "MinZ", 0 );
+ priv->max_z = xf86SetIntOption( local->options, "MaxZ", 32 );
+ priv->button_threshold = xf86SetIntOption (local->options, "ButtonThreshold", 16 );
+ priv->pressure = xf86SetIntOption (local->options, "Pressure", 0);
+ priv->untouch_delay = xf86SetIntOption( local->options, "UntouchDelay", 10 );
+ priv->report_delay = xf86SetIntOption( local->options, "ReportDelay", 40 );
+ priv->screen_num = xf86SetIntOption( local->options, "ScreenNumber", 0 );
+ priv->button_number = xf86SetIntOption( local->options, "ButtonNumber", 1 );
+
+ xf86Msg(X_INFO,"options read MaxX=%d, MaxY=%d\n",priv->max_x,priv->max_y);
+
+ s = xf86FindOptionValue (local->options, "ReportingMode");
+ if ((s) && (xf86NameCmp (s, "raw") == 0))
+
+ priv->reporting_mode = TS_Raw;
+ else
+ priv->reporting_mode = TS_Scaled;
+
+ priv->checksum = 0;
+ priv->buffer = XisbNew (local->fd, 200);
+
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ /*
+ * Verify that your hardware is attached and fuctional if you can
+ */
+ if (QueryHardware (local->fd, priv) != Success)
+ {
+ xf86Msg (X_ERROR,"Unable to query/initialize CALCOMP hardware.\n");
+ goto SetupProc_fail;
+ }else
+ xf86Msg (X_INFO,"Calcomp tablet queried OK\n");
+
+ local->name = xf86SetStrOption( local->options, "DeviceName", "CALCOMP XInput Device");
+ xf86Msg(X_CONFIG," Calcomp device name is %s\n",local->name);
+ /* Set the type that's appropriate for your device
+ * XI_KEYBOARD
+ * XI_MOUSE
+ * XI_TABLET
+ * XI_TOUCHSCREEN
+ * XI_TOUCHPAD
+ * XI_BARCODE
+ * XI_BUTTONBOX
+ * XI_KNOB_BOX
+ * XI_ONE_KNOB
+ * XI_NINE_KNOB
+ * XI_TRACKBALL
+ * XI_QUADRATURE
+ * XI_ID_MODULE
+ * XI_SPACEBALL
+ * XI_DATAGLOVE
+ * XI_EYETRACKER
+ * XI_CURSORKEYS
+ * XI_FOOTMOUSE
+ */
+ local->type_name = XI_TABLET;
+ /*
+ * Standard setup for the local device record
+ */
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ChangeControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->conf_idev = dev;
+ local->history_size = xf86SetIntOption( local->options, "HistorySize", 0 );
+ local->flags |= XI86_CONFIGURED;
+
+ xf86Msg(X_INFO,"Calcomp base setup finished\n");
+ return (local);
+SetupProc_fail:
+ xf86Msg (X_ERROR,"Calcomp setup failed, unloading tablet driver\n");
+/* taken from xf86Wacom*/
+ xfree (priv);
+ xf86DeleteInput(local, 0);
+/* * */
+ return (NULL);
+
+
+ }
+
+/*
+ * This function should be renamed for your device and tailored to handle
+ * your device's protocol.
+ */
+static Bool
+CALCOMPGetPacket (CALCOMPPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ return (!Success);
+
+
+ if (c > 127) /* phasing bit set, start of packet */
+ {
+ priv->packeti=0;
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ }
+ else {
+ if (priv->packeti >0 && priv->packeti < CALCOMP_BODY_LEN)
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ if (priv->packeti == CALCOMP_BODY_LEN)
+ {
+ priv->packeti=0;
+ return (Success);
+ }
+ }
+ }
+ return (!Success);
+}
+
+/*
+** xf86CalWriteAndRead
+** Write data, and get the response.
+*/
+static char *
+xf86CalWriteAndRead(int fd, char *data, char *buffer, int len, int cr_term)
+{
+ int err, numread = 0;
+ int retries = 5;
+
+
+
+ xf86FlushInput(fd);
+
+ SYSCALL(err = write(fd, data, strlen(data)));
+ if (err == -1) {
+ xf86Msg(X_ERROR,"Calcomp write");
+ return NULL;
+ }
+do {
+ err=xf86WaitForInput(fd, 2000);
+ if (err < 0 ) {
+ xf86Msg(X_ERROR,"Calcomp select failed\n");
+ return NULL;
+ }
+ retries--;
+ }
+ while (err<1 && retries >0);
+
+if (retries<=0) {
+ xf86Msg(X_WARNING,"Timeout while reading Calcomp tablet. No tablet connected ???\n");
+ return NULL;
+ }
+
+ while (numread < len) {
+ if (err == -1) {
+ xf86Msg(X_ERROR,"Calcomp select");
+ return NULL;
+ }
+
+ SYSCALL(err = read(fd, buffer + numread++, 1));
+ if (err == -1) {
+ xf86Msg(X_ERROR,"Calcomp read");
+ return NULL;
+ }
+ if (!err) {
+ --numread;
+ break;
+ }
+ if (cr_term && buffer[numread - 1] == '\r') {
+ buffer[numread - 1] = 0;
+ break;
+ }
+ }
+ buffer[numread] = 0;
+ return buffer;
+ }
+
diff --git a/src/xf86Calcomp.h b/src/xf86Calcomp.h
new file mode 100644
index 0000000..a3787fc
--- /dev/null
+++ b/src/xf86Calcomp.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2000-2001 Martin Kroeker (mk@daveg.com)
+ * code derived from sample driver
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/calcomp/xf86Calcomp.h,v 1.2 2001/10/28 03:33:55 tsi Exp $ */
+
+#ifndef _CALCOMP_H_
+#define _CALCOMP_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define CALCOMP_PACKET_SIZE 5
+#define CALCOMP_INIT_CHECKSUM 0
+#define CALCOMP_BODY_LEN 6
+
+
+
+/*************************************************************************/
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define DB_COMM_SETUP "\033%C1N81\r" /* Serial communication setup */
+#define DB_FIRMID "\033%__V\r" /* Request firmware ID string */
+#define DB_PRODID "\033%__p\r" /* Request product ID string */
+#define DB_CONFIG "\033%VS\r" /* Send configuration (max coords) */
+
+#define DB_ABSOLUTE "\033%IR\r" /* Absolute mode */
+#define DB_RELATIVE "\033%IT\r" /* Relative mode */
+
+#define DB_UPPER_ORIGIN "\033%L1\r" /* Origin upper left */
+#define DB_1000LPI "\033%JR1000,0\r" /* 1000 lines per inch */
+
+#define DB_PROMPT_MODE "\033%Q?\r" /* Prompt mode (untested!) */
+#define DB_STREAM_MODE "\033%IR\r" /* Stream mode */
+#define DB_XINCREMENT "\033%X1\r"
+#define DB_YINCREMENT "\033%Y1\r" /* Set increment to 1 */
+#define DB_BINARY_FMT "\033%^23\r" /* Calcomp binary mode */
+#define DB_PRESSURE_OFF "\033%VA0\r" /* Select button or pressure */
+#define DB_PRESSURE_ON "\033%VA1\r" /* reporting */
+#define DB_PROMPT "?" /* Prompt for current position */
+
+#define PHASING_BIT 0x80
+#define PROXIMITY_BIT 0x20
+#define BUTTON_BITS 0x7c
+#define COORD_BITS 0x7f
+#define tcflush(fd, n) xf86FlushInput((fd))
+#undef read
+#define read(a,b,c) xf86ReadSerial((a),(b),(c))
+#undef write
+#define write(a,b,c) xf86WriteSerial((a),(char*)(b),(c))
+#undef close
+#define close(a) xf86CloseSerial((a))
+
+/*************************************************************************/
+typedef enum
+{
+ CALCOMP_normal, /*CALCOMP_type,*/ CALCOMP_body, CALCOMP_checksum
+}
+CALCOMPState;
+
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
+
+typedef struct _CALCOMPPrivateRec
+{
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ int min_z;
+ int max_z;
+ int button_threshold; /* Z > button threshold = button click */
+ int pressure; /* 0 or 1, do we need pressure info */
+ int axes;
+ int prox; /* Proximity */
+ int x,y; /* x,y values */
+ int buttons; /* button state */
+ Bool button_down; /* is the "button" currently down */
+ int button_number; /* which button to report */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+
+ int untouch_delay; /* Delay before reporting an untouch (in ms) */
+ int report_delay; /* Delay between touch report packets */
+
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ XISBuffer *buffer;
+ unsigned char packet[CALCOMP_PACKET_SIZE]; /* packet being/just read */
+ int packeti; /* index into packet */
+ unsigned char checksum; /* Current checksum of data in assembly *
+ * buffer */
+ CALCOMPState lex_mode;
+}
+CALCOMPPrivateRec, *CALCOMPPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+#ifdef XFree86LOADER
+static MODULESETUPPROTO( CalcompSetupProc );
+#endif
+/*static void TearDownProc (pointer p);*/
+static Bool DeviceControl (DeviceIntPtr, int);
+static Bool DeviceOn (DeviceIntPtr);
+static Bool DeviceOff (DeviceIntPtr);
+static Bool DeviceClose (DeviceIntPtr);
+static Bool DeviceInit (DeviceIntPtr);
+static void ReadInput (LocalDevicePtr);
+static void ControlProc (DeviceIntPtr, PtrCtrl *);
+static int ChangeControlProc (LocalDevicePtr, xDeviceCtl *);
+static void CloseProc (LocalDevicePtr);
+static int SwitchMode (ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool QueryHardware (int , CALCOMPPrivatePtr);
+static Bool CALCOMPGetPacket (CALCOMPPrivatePtr priv);
+static char * xf86CalWriteAndRead(int, char *, char *, int , int );
+static InputInfoPtr CalcompPreInit(InputDriverPtr, IDevPtr, int) ;
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif