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
commit249fcdd8f49a8a922ee1eb88cbd8a01e8929328f (patch)
treefa808f1dd6dc1f6f9266441769108e92afabb3a8
Initial revisionXORG-STABLE
-rw-r--r--man/acecad.man40
-rw-r--r--src/acecad.c916
-rw-r--r--src/acecad.h111
3 files changed, 1067 insertions, 0 deletions
diff --git a/man/acecad.man b/man/acecad.man
new file mode 100644
index 0000000..0f89967
--- /dev/null
+++ b/man/acecad.man
@@ -0,0 +1,40 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/acecad.man,v 1.1 2001/08/13 19:35:00 dawes Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH ACECAD __drivermansuffix__ __vendorversion__
+.SH NAME
+acecad \- Acecad Flair input driver
+.SH SYNOPSIS
+.B "Section \*qInputDevice\*q"
+.br
+.BI " Identifier \*q" idevname \*q
+.br
+.B " Driver \*qacecad\*q"
+.br
+.BI " Option \*qDevice\*q \*q" devpath \*q
+.br
+\ \ ...
+.br
+.B EndSection
+.SH DESCRIPTION
+.B acecad
+is an XFree86 input driver for Acecad Flair devices...
+.PP
+The
+.B acecad
+driver functions as a pointer input device, and may be used as the
+X server's core pointer.
+THIS MAN PAGE NEEDS TO BE FILLED IN.
+.SH SUPPORTED HARDWARE
+What is supported...
+.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
+Config details...
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__).
+.SH AUTHORS
+Authors include...
+Edouard TISSERANT
diff --git a/src/acecad.c b/src/acecad.c
new file mode 100644
index 0000000..7365114
--- /dev/null
+++ b/src/acecad.c
@@ -0,0 +1,916 @@
+/*
+ * Copyright (c) 2001 Edouard TISSERANT <tissered@esstin.u-nancy.fr>
+ * Parts inspired from Shane Watts <shane@bofh.asn.au> XFree86 3 Acecad Driver
+ * Thanks to Emily, from AceCad, For giving me documents.
+ *
+ * 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.
+ *
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/acecad.c,v 1.2 2001/11/26 16:25:52 dawes Exp $ */
+
+#define _ACECAD_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#ifdef LINUX_INPUT
+#include <asm/types.h>
+#include <linux/input.h>
+#ifdef BUS_PCI
+#undef BUS_PCI
+#endif
+#ifdef BUS_ISA
+#undef BUS_ISA
+#endif
+#endif
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xisb.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+#include <xf86Module.h>
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "acecad.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+#undef read
+#define read(a,b,c) xf86ReadSerial((a),(b),(c))
+
+/* max number of input events to read in one read call */
+#define MAX_EVENTS 50
+
+
+static InputDriverRec ACECAD =
+{
+ 1,
+ "acecad",
+ NULL,
+ AceCadPreInit,
+ NULL,
+ NULL,
+ 0
+};
+
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "acecad",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0}
+};
+
+
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "Odd",
+ "Vmin", "1",
+ "Vtime", "10",
+ "FlowControl", "Xoff",
+ NULL
+};
+
+XF86ModuleData acecadModuleData = { &VersionRec, SetupProc, TearDownProc};
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+static pointer
+SetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ xf86AddInputDriver(&ACECAD, module, 0);
+ return module;
+}
+
+static void
+TearDownProc( pointer p )
+{
+#if 0
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) local->private;
+
+ DeviceOff (local->dev);
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+#endif
+}
+
+static int
+IsUSBLine(int fd)
+{
+ int version;
+ int err;
+
+ SYSCALL(err = ioctl(fd, EVIOCGVERSION, &version));
+
+ if (!err) {
+ xf86Msg(X_CONFIG,"Kernel Input driver version is %d.%d.%d\n",
+ version >> 16, (version >> 8) & 0xff, version & 0xff);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+static InputInfoPtr
+AceCadPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+ LocalDevicePtr local = xf86AllocateInput(drv, 0);
+ AceCadPrivatePtr priv = xcalloc (1, sizeof (AceCadPrivateRec));
+ int speed;
+ char *s;
+
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ memset(priv,0,sizeof (AceCadPrivateRec));
+
+ local->name = dev->identifier;
+ local->type_name = "AceCad Tablet";
+ local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ local->motion_history_proc = xf86GetMotionEvents;
+ local->control_proc = NULL;
+ local->close_proc = CloseProc;
+ local->switch_mode = NULL;
+ local->conversion_proc = ConvertProc;
+ local->reverse_conversion_proc = ReverseConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->conf_idev = dev;
+ local->device_control = DeviceControl;
+ /*local->always_core_feedback = 0;*/
+
+ xf86CollectInputOptions(local, default_options, NULL);
+
+ xf86OptionListReport(local->options);
+
+ priv->acecadInc = xf86SetIntOption(local->options, "Increment", 0 );
+
+ local->fd = xf86OpenSerial (local->options);
+ if (local->fd == -1)
+ {
+ xf86Msg(X_ERROR,"AceCad driver unable to open device\n");
+ goto SetupProc_fail;
+ }
+ xf86ErrorFVerb( 6, "tty port opened successfully\n" );
+
+ if(IsUSBLine(local->fd)){
+ priv->acecadUSB=1;
+
+ local->read_input = USBReadInput;
+
+ if (USBQueryHardware(local) != Success)
+ {
+ ErrorF ("Unable to query/initialize AceCad hardware.\n");
+ goto SetupProc_fail;
+ }
+ }
+ else{
+ priv->acecadUSB=0;
+
+ local->read_input = ReadInput;
+
+ speed = xf86SetIntOption(local->options, "ReportSpeed", 85 );
+
+ switch (speed)
+ {
+ case 120:
+ priv->acecadReportSpeed = 'Q';
+ break;
+ case 85:
+ priv->acecadReportSpeed = 'R';
+ break;
+ case 10:
+ priv->acecadReportSpeed = 'S';
+ break;
+ case 2:
+ priv->acecadReportSpeed = 'T';
+ break;
+ default:
+ priv->acecadReportSpeed = 'R';
+ speed = 85;
+ xf86Msg(X_CONFIG, "Acecad Tablet: ReportSpeed possible values:\n 120, 85, 10, 2 \n");
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet report %d points/s\n", speed);
+
+ priv->buffer = XisbNew (local->fd, 200);
+
+ /*
+ * Verify that hardware is attached and fuctional
+ */
+ if (QueryHardware(priv) != Success)
+ {
+ xf86Msg(X_ERROR,"Unable to query/initialize AceCad hardware.\n");
+ goto SetupProc_fail;
+ }
+ }
+
+ s = xf86FindOptionValue(local->options, "Mode");
+ if (s && (xf86NameCmp(s, "Relative") == 0))
+ {
+ priv->flags = priv->flags & ~ABSOLUTE_FLAG;
+ }
+ else
+ {
+ priv->flags = priv->flags | ABSOLUTE_FLAG;
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet is in %s mode\n",(priv->flags & ABSOLUTE_FLAG) ? "absolute" : "relative");
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ local->history_size = xf86SetIntOption(local->options , "HistorySize", 0);
+
+ xf86ProcessCommonOptions(local, local->options);
+
+ local->flags |= XI86_CONFIGURED;
+
+ if (local->fd != -1)
+ {
+ RemoveEnabledDevice (local->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(local->fd);
+ }
+ RemoveEnabledDevice (local->fd);
+ local->fd = -1;
+ return (local);
+
+ /*
+ * If something went wrong, cleanup and return NULL
+ */
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+ if (local)
+ xfree (local);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (NULL);
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ char buffer[256];
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+
+ xf86Msg(X_CONFIG, "Acecad Tablet Device On\n");
+
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd == -1)
+ {
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", local->name);
+ return (!Success);
+ }
+
+
+ if (priv->acecadUSB==0){
+ priv->buffer = XisbNew(local->fd, 200);
+ if (!priv->buffer)
+ {
+ xf86CloseSerial(local->fd);
+ local->fd = -1;
+ return (!Success);
+ }
+
+ /*Rets qu'a l'envoyer a la tablette */
+ sprintf(buffer, "%s%c%c%c%c", acecad_initstr, priv->acecadReportSpeed ,ACECAD_INCREMENT, 32 + priv->acecadInc, (priv->flags & ABSOLUTE_FLAG)? ACECAD_ABSOLUTE: ACECAD_RELATIVE);
+ XisbWrite (priv->buffer, (unsigned char *)buffer, strlen(buffer));
+ }
+
+ xf86FlushInput(local->fd);
+ xf86AddEnabledDevice (local);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+
+
+ if (local->fd != -1)
+ {
+ RemoveEnabledDevice (local->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(local->fd);
+ }
+
+
+ xf86RemoveEnabledDevice (local);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+static Bool
+DeviceClose (DeviceIntPtr dev)
+{
+ xf86Msg(X_CONFIG, "Acecad Tablet Device Close\n");
+ return (Success);
+}
+
+static void
+ControlProc(DeviceIntPtr device,
+ PtrCtrl *ctrl)
+{
+ xf86Msg(X_CONFIG, "Acecad Tablet Control Proc\n");
+}
+
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ int rx, ry;
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+ unsigned char map[] =
+ {0, 1, 2, 3};
+
+ xf86Msg(X_CONFIG, "Acecad Tablet Device Init\n");
+
+ /* 3 boutons */
+ if (InitButtonClassDeviceStruct (dev, 3, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate AceCad ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF("Unable to allocate AceCad FocusClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(dev,
+ ControlProc) == FALSE) {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+
+ /* 3 axes */
+ if (InitValuatorClassDeviceStruct (dev, 3, xf86GetMotionEvents,
+ local->history_size,
+ ((priv->flags & ABSOLUTE_FLAG)? Absolute: Relative)|OutOfProximity)
+ == FALSE)
+ {
+ ErrorF ("Unable to allocate AceCad ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+
+ InitValuatorAxisStruct(dev,
+ 0,
+ 0, /* min val */
+ priv->acecadMaxX, /* max val */
+ 1000, /* resolution */
+ 0, /* min_res */
+ 1000); /* max_res */
+ InitValuatorAxisStruct(dev,
+ 1,
+ 0, /* min val */
+ priv->acecadMaxY, /* max val */
+ 1000, /* resolution */
+ 0, /* min_res */
+ 1000); /* max_res */
+ InitValuatorAxisStruct(dev,
+ 2,
+ 0, /* min val */
+ priv->acecadMaxZ, /* max val */
+ 1000, /* resolution */
+ 0, /* min_res */
+ 1000); /* max_res */
+
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("Unable to allocate ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+ xf86MotionHistoryAllocate (local);
+
+
+ /* On ne peut pas calculer l'increment avant, faute d'ecran pour
+ connaitre la taille... */
+
+ if (priv->acecadInc > 95)
+ priv->acecadInc = 95;
+ if (priv->acecadInc < 1)
+ {
+ /* guess the best increment value given video mode */
+ rx=priv->acecadMaxX / screenInfo.screens[0]->width;
+ ry=priv->acecadMaxY / screenInfo.screens[0]->height;
+ if (rx < ry)
+ priv->acecadInc = rx;
+ else
+ priv->acecadInc = ry;
+ if (priv->acecadInc < 1)
+ priv->acecadInc = 1;
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet Increment: %d\n",priv->acecadInc);
+
+ return (Success);
+}
+
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x, y, z;
+ int prox, buttons;
+ int is_core_pointer, is_absolute;
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Read Input\n");*/
+
+ is_absolute = (priv->flags & ABSOLUTE_FLAG);
+ is_core_pointer = xf86IsCorePointer(local->dev);
+
+ /*
+ * 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 buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+
+ while (AceCadGetPacket (priv) == Success)
+ {
+ x = (int)priv->packet[1] | ((int)priv->packet[2] << 7);
+ y = (int)priv->packet[3] | ((int)priv->packet[4] << 7);
+
+ if (!(priv->flags & ABSOLUTE_FLAG))
+ {
+ x = priv->packet[0] & XSIGN_BIT? x:-x;
+ y = priv->packet[0] & YSIGN_BIT? y:-y;
+ }
+ else
+ {
+ y = priv->acecadMaxY - y ;
+ }
+
+
+ z = ((int)priv->packet[5] << 2) |
+ (((int)priv->packet[6] & 0x01) << 1) |
+ (((int)priv->packet[6] & 0x10) >> 4);
+
+ buttons = ((int)priv->packet[0] & 0x07) |
+ ((int)priv->packet[6] & 0x02 << 2);
+
+ prox = (priv->packet[0] & PROXIMITY_BIT)? 0: 1;
+
+ if (prox)
+ {
+ if (!(priv->acecadOldProximity))
+ if (!is_core_pointer)
+ {
+ /*xf86Msg(X_CONFIG, "Acecad Tablet ProxIN %d %d %d\n",x, y, z);*/
+ xf86PostProximityEvent(local->dev, 1, 0, 3 , x, y, z);
+ }
+
+ if ((is_absolute && ((priv->acecadOldX != x) || (priv->acecadOldY != y) || (priv->acecadOldZ != z)))
+ || (!is_absolute && (x || y)))
+ {
+ if (is_absolute || priv->acecadOldProximity)
+ {
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Motion %d %d %d\n", x, y, z);*/
+ xf86PostMotionEvent(local->dev, is_absolute, 0, 3, x, y, z);
+ }
+ }
+
+ if (priv->acecadOldButtons != buttons)
+ {
+ int delta;
+
+ delta = buttons ^ priv->acecadOldButtons;
+ while(delta)
+ {
+ int id;
+
+ id=ffs(delta);
+ delta &= ~(1 << (id-1));
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Button %d 0x%x\n",id,(buttons&(1<<(id-1))));*/
+ xf86PostButtonEvent(local->dev, is_absolute, id, (buttons&(1<<(id-1))), 0, 3, x, y,z);
+ }
+ }
+
+ priv->acecadOldButtons = buttons;
+ priv->acecadOldX = x;
+ priv->acecadOldY = y;
+ priv->acecadOldZ = z;
+ priv->acecadOldProximity = prox;
+ }
+ else
+ {
+ if (!is_core_pointer)
+ if (priv->acecadOldProximity)
+ {
+ /*xf86Msg(X_CONFIG, "Acecad Tablet ProxOUT %d %d %d\n",x, y, z);*/
+ xf86PostProximityEvent(local->dev, 0, 0, 3, x,y,z);
+ }
+ priv->acecadOldProximity = 0;
+ }
+ }
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Sortie Read Input\n");*/
+}
+
+#define set_bit(byte,nb,bit) (bit ? byte | (1<<nb) : byte & (~(1<<nb)))
+static void
+USBReadInput (LocalDevicePtr local)
+{
+ int len;
+ struct input_event * event;
+ char eventbuf[sizeof(struct input_event) * MAX_EVENTS];
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
+ int x = priv->acecadOldX;
+ int y = priv->acecadOldY;
+ int z = priv->acecadOldZ;
+ int prox = priv->acecadOldProximity;
+ int buttons = priv->acecadOldButtons;
+ int is_core_pointer;
+
+ is_core_pointer = xf86IsCorePointer(local->dev);
+
+ SYSCALL(len = read(local->fd, eventbuf, sizeof(eventbuf)));
+
+ if (len <= 0) {
+ ErrorF("Error reading wacom device : %s\n", strerror(errno));
+ return;
+ }
+
+ for (event=(struct input_event *)eventbuf;
+ event<(struct input_event *)(eventbuf+len); event++) {
+
+ switch (event->type) {
+ case EV_ABS:
+ switch (event->code) {
+ case ABS_X:
+ x = event->value;
+ break;
+
+ case ABS_Y:
+ y = event->value;
+ break;
+
+ case ABS_PRESSURE:
+ z = event->value;
+ break;
+
+ case ABS_MISC:
+ break;
+
+ }
+ break; /* EV_ABS */
+
+ case EV_KEY:
+ switch (event->code) {
+ case BTN_TOOL_PEN:
+ prox = event->value;
+ break;
+
+ case BTN_TOUCH:
+ buttons=set_bit(buttons,0,event->value);
+ break;
+
+ case BTN_STYLUS:
+ buttons=set_bit(buttons,1,event->value);
+ break;
+
+ case BTN_STYLUS2:
+ buttons=set_bit(buttons,2,event->value);
+ break;
+ }
+ break; /* EV_KEY */
+ default:
+ xf86Msg(X_ERROR, "UNKNOWN event->code=%d\n", event->code);
+ } /* switch event->type */
+
+ /* ABS_MISC is the event terminator */
+ if (event->type != EV_ABS || event->code != ABS_MISC) {
+ continue;
+ }
+
+ if (prox)
+ {
+ if (!(priv->acecadOldProximity))
+ if (!is_core_pointer)
+ {
+ xf86PostProximityEvent(local->dev, 1, 0, 3 , x, y, z);
+ }
+
+
+ xf86PostMotionEvent(local->dev, 1, 0, 3, x, y, z);
+
+ if (priv->acecadOldButtons != buttons)
+ {
+ int delta;
+
+ delta = buttons ^ priv->acecadOldButtons;
+ while(delta)
+ {
+ int id;
+
+ id=ffs(delta);
+ delta &= ~(1 << (id-1));
+
+ xf86PostButtonEvent(local->dev, 1, id, (buttons&(1<<(id-1))), 0, 3, x, y,z);
+ }
+ }
+ }
+ else
+ {
+ if (!is_core_pointer)
+ if (priv->acecadOldProximity)
+ {
+ xf86PostProximityEvent(local->dev, 0, 0, 3, x,y,z);
+ }
+ priv->acecadOldProximity = 0;
+ }
+
+ priv->acecadOldButtons = buttons;
+ priv->acecadOldX = x;
+ priv->acecadOldY = y;
+ priv->acecadOldZ = z;
+ priv->acecadOldProximity = prox;
+ }
+ /*xf86Msg(X_CONFIG, "Acecad Tablet Sortie Read Input\n");*/
+}
+
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+/*
+ * 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)
+{
+ AceCadPrivatePtr priv = (AceCadPrivatePtr)(local->private);
+
+ *x = v0 * screenInfo.screens[0]->width / priv->acecadMaxX;
+ *y = v1 * screenInfo.screens[0]->height / priv->acecadMaxY;
+ return TRUE;
+}
+
+
+static Bool
+ReverseConvertProc( LocalDevicePtr local,
+ int x,
+ int y,
+ int *valuators)
+{
+ AceCadPrivatePtr priv = (AceCadPrivatePtr)(local->private);
+
+ valuators[0] = x * priv->acecadMaxX / screenInfo.screens[0]->width;
+ valuators[1] = y * priv->acecadMaxY / screenInfo.screens[0]->height;
+
+ return TRUE;
+}
+
+
+#define WriteString(str)\
+XisbWrite (priv->buffer, (unsigned char *)(str), strlen(str))
+
+
+static Bool
+QueryHardware (AceCadPrivatePtr priv)
+{
+
+ /* Reset */
+ WriteString("z0");
+
+ /* Wait */
+ milisleep (250);
+
+ /* Prompt Mode in order to not be disturbed */
+ WriteString(ACECAD_PROMPT_MODE);
+
+ /* Flush */
+ while(XisbRead(priv->buffer)>=0);
+
+ /* Ask for Config packet*/
+ WriteString(ACECAD_CONFIG);
+
+ /* Read the packet */
+ XisbBlockDuration (priv->buffer, 1000000);
+ NewPacket (priv);
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet init envoyé \n");*/
+
+ if ((AceCadGetPacket (priv) == Success))
+ {
+ priv->acecadMaxX = (int)priv->packet[1] + ((int)priv->packet[2] << 7);
+ priv->acecadMaxY = (int)priv->packet[3] + ((int)priv->packet[4] << 7);
+ priv->acecadMaxZ = 512;
+ xf86Msg(X_CONFIG, "Acecad Tablet MaxX:%d MaxY:%d\n",priv->acecadMaxX,priv->acecadMaxY);
+ }
+ else
+ return (!Success);
+
+ /*xf86Msg(X_CONFIG, "Acecad Tablet query hardware fini \n");*/
+ return (Success);
+}
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+#define OFF(x) ((x)%BITS_PER_LONG)
+#define LONG(x) ((x)/BITS_PER_LONG)
+
+static Bool
+USBQueryHardware (LocalDevicePtr local)
+{
+ AceCadPrivatePtr priv = (AceCadPrivatePtr) local->private;
+ unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
+ int i, j;
+ int abs[5];
+ char name[256] = "Unknown";
+
+ ioctl(local->fd, EVIOCGNAME(sizeof(name)), name);
+ xf86Msg(X_CONFIG, "Kernel Input device name: \"%s\"\n", name);
+
+ memset(bit, 0, sizeof(bit));
+ ioctl(local->fd, EVIOCGBIT(0, EV_MAX), bit[0]);
+
+ for (i = 0; i < EV_MAX; i++)
+ if (test_bit(i, bit[0])) {
+ ioctl(local->fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
+ for (j = 0; j < KEY_MAX; j++)
+ if (test_bit(j, bit[i])) {
+ if (i == EV_ABS) {
+ ioctl(local->fd, EVIOCGABS(j), abs);
+ switch (j) {
+ case ABS_X:
+ priv->acecadMaxX = abs[2];
+ break;
+
+ case ABS_Y:
+ priv->acecadMaxY = abs[2];
+ break;
+
+ case ABS_PRESSURE:
+ priv->acecadMaxZ = abs[2];
+ break;
+ }
+ }
+ }
+ }
+
+ xf86Msg(X_CONFIG, "Acecad Tablet MaxX:%d MaxY:%d MaxZ:%d\n",priv->acecadMaxX,priv->acecadMaxY,priv->acecadMaxZ);
+ return (Success);
+}
+
+static void
+NewPacket (AceCadPrivatePtr priv)
+{
+ priv->packeti = 0;
+}
+
+static Bool
+AceCadGetPacket (AceCadPrivatePtr priv)
+{
+ int count = 0;
+ int c = 0;
+
+ 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)
+ {
+ NewPacket (priv);
+ return (!Success);
+ }
+
+ if (c & PHASING_BIT)
+ {
+ NewPacket(priv);
+
+ /*xf86Msg(X_CONFIG, "Push %2.2x\n",(char) c);*/
+ XisbBlockDuration (priv->buffer, 10000);
+ priv->packet[priv->packeti++] = c;
+ count=ACECAD_PACKET_SIZE-1;
+ while(count-- && (c = XisbRead(priv->buffer))>=0)
+ {
+ /*xf86Msg(X_CONFIG, "Push %2.2x\n",(char) c);*/
+ priv->packet[priv->packeti++] = c;
+ }
+ XisbBlockDuration (priv->buffer, 0);
+ if(c > 0)
+ return (Success);
+ }
+ }
+ return (!Success);
+}
diff --git a/src/acecad.h b/src/acecad.h
new file mode 100644
index 0000000..d1ec950
--- /dev/null
+++ b/src/acecad.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2001 Edouard TISSERANT <tissered@esstin.u-nancy.fr>
+ * Parts inspired from Shane Watts <shane@bofh.asn.au> Xfree 3 Acecad Driver
+ * Thanks to Emily, from AceCad, For giving me documents.
+ *
+ * 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.
+ *
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/acecad.h,v 1.1 2001/08/13 19:35:00 dawes Exp $ */
+
+#ifndef _ACECAD_H_
+#define _ACECAD_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define ACECAD_PACKET_SIZE 7
+
+#define ACECAD_CONFIG "a" /* Send configuration (max coords) */
+
+#define ACECAD_ABSOLUTE 'F' /* Absolute mode */
+#define ACECAD_RELATIVE 'E' /* Relative mode */
+
+#define ACECAD_UPPER_ORIGIN "b" /* Origin upper left */
+
+#define ACECAD_PROMPT_MODE "B" /* Prompt mode */
+#define ACECAD_STREAM_MODE "@" /* Stream mode */
+#define ACECAD_INCREMENT 'I' /* Set increment */
+#define ACECAD_BINARY_FMT "zb" /* Binary reporting */
+
+#define ACECAD_PROMPT "P" /* Prompt for current position */
+
+#define PHASING_BIT 0x80
+#define PROXIMITY_BIT 0x40
+#define TABID_BIT 0x20
+#define XSIGN_BIT 0x10
+#define YSIGN_BIT 0x08
+#define BUTTON_BITS 0x07
+#define COORD_BITS 0x7f
+
+#define ABSOLUTE_FLAG 1
+
+#define milisleep(ms) xf86usleep (ms * 1000)
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+static const char * acecad_initstr = ACECAD_BINARY_FMT ACECAD_STREAM_MODE;
+
+typedef struct
+{
+ XISBuffer *buffer;
+ int acecadInc; /* increment between transmits */
+ int acecadOldX; /* previous X position */
+ int acecadOldY; /* previous Y position */
+ int acecadOldZ; /* previous Z position */
+ int acecadOldProximity; /* previous proximity */
+ int acecadOldButtons; /* previous buttons state */
+ int acecadMaxX; /* max X value */
+ int acecadMaxY; /* max Y value */
+ int acecadMaxZ; /* max Y value */
+ char acecadReportSpeed; /* report speed */
+ int acecadUSB; /*USB flag*/
+ int flags; /* various flags */
+ int packeti; /* number of bytes read */
+ int PacketSize; /* number of bytes read */
+ unsigned char packet[ACECAD_PACKET_SIZE]; /* data read on the device */
+} AceCadPrivateRec, *AceCadPrivatePtr;
+
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+static MODULESETUPPROTO( SetupProc );
+static void TearDownProc (void *);
+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 USBReadInput (LocalDevicePtr);
+static void CloseProc (LocalDevicePtr);
+static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool ReverseConvertProc(LocalDevicePtr , int , int , int*);
+static Bool QueryHardware (AceCadPrivatePtr);
+static Bool USBQueryHardware (LocalDevicePtr);
+static void NewPacket (AceCadPrivatePtr priv);
+static Bool AceCadGetPacket (AceCadPrivatePtr);
+static InputInfoPtr AceCadPreInit(InputDriverPtr, IDevPtr , int);
+static int IsUSBLine(int);
+
+
+#endif