INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206
[xorg/acecad] / src / acecad.c
1 /*
2  * Copyright (c) 2001 Edouard TISSERANT <tissered@esstin.u-nancy.fr>
3  * Parts inspired from Shane Watts <shane@bofh.asn.au> XFree86 3 Acecad Driver
4  * Thanks to Emily, from AceCad, For giving me documents.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
21  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  *
25  */
26
27 #include "config.h"
28
29 #include <xorgVersion.h>
30 #define XORG_VERSION_BOTCHED XORG_VERSION_NUMERIC(1,4,0,0,0)
31 #if XORG_VERSION_CURRENT >= XORG_VERSION_BOTCHED
32 #define XORG_BOTCHED_INPUT 1
33 #else
34 #define XORG_BOTCHED_INPUT 0
35 #endif
36
37 /*****************************************************************************
38  *      Standard Headers
39  ****************************************************************************/
40
41 #ifdef LINUX_INPUT
42 #include <asm/types.h>
43 #include <linux/input.h>
44 #ifndef EV_SYN
45 #define EV_SYN EV_RST
46 #define SYN_REPORT 0
47 #endif
48 #ifdef BUS_PCI
49 #undef BUS_PCI
50 #endif
51 #ifdef BUS_ISA
52 #undef BUS_ISA
53 #endif
54 #endif
55
56 #include <misc.h>
57 #include <xf86.h>
58 #ifndef NEED_XF86_TYPES
59 #define NEED_XF86_TYPES
60 #endif
61 #include <xf86_OSproc.h>
62 #include <xisb.h>
63 #include <xf86Xinput.h>
64 #include <exevents.h>
65 #include <xf86Module.h>
66
67 #include <string.h>
68 #include <stdio.h>
69
70 #include <errno.h>
71 #ifdef LINUX_INPUT
72 #include <fcntl.h>
73 #ifdef LINUX_SYSFS
74 #include <sysfs/libsysfs.h>
75 #include <dlfcn.h>
76 #endif
77 #endif
78
79 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
80 #include <X11/Xatom.h>
81 #include <xserver-properties.h>
82 #endif
83
84 /* Previously found in xf86Xinput.h */
85 #ifdef DBG
86 #undef DBG
87 #endif
88 #define DBG(lvl, f) {if ((lvl) <= xf86GetVerbosity()) f;}
89
90 /*****************************************************************************
91  *      Local Headers
92  ****************************************************************************/
93 #include "acecad.h"
94
95 /*****************************************************************************
96  *      Variables without includable headers
97  ****************************************************************************/
98
99 /*****************************************************************************
100  *      Local Variables
101  ****************************************************************************/
102
103 /* max number of input events to read in one read call */
104 #define MAX_EVENTS 50
105
106 _X_EXPORT InputDriverRec ACECAD =
107 {
108         1,
109         "acecad",
110         NULL,
111         AceCadPreInit,
112         NULL,
113         NULL,
114         0
115 };
116
117 static XF86ModuleVersionInfo VersionRec =
118 {
119         "acecad",
120         MODULEVENDORSTRING,
121         MODINFOSTRING1,
122         MODINFOSTRING2,
123         XORG_VERSION_CURRENT,
124         PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
125         ABI_CLASS_XINPUT,
126         ABI_XINPUT_VERSION,
127         MOD_CLASS_XINPUT,
128         {0, 0, 0, 0}
129 };
130
131
132 _X_EXPORT XF86ModuleData acecadModuleData = {
133         &VersionRec,
134         SetupProc,
135         TearDownProc
136 };
137
138 /*****************************************************************************
139  *      Function Definitions
140  ****************************************************************************/
141
142 static pointer
143 SetupProc(      pointer module,
144                 pointer options,
145                 int *errmaj,
146                 int *errmin )
147 {
148         xf86AddInputDriver(&ACECAD, module, 0);
149         return module;
150 }
151
152 static void
153 TearDownProc( pointer p )
154 {
155 }
156
157 static const char *default_options[] =
158 {
159         "BaudRate", "9600",
160         "StopBits", "1",
161         "DataBits", "8",
162         "Parity", "Odd",
163         "Vmin", "1",
164         "Vtime", "10",
165         "FlowControl", "Xoff",
166         NULL
167 };
168
169 #ifdef LINUX_INPUT
170 static int
171 IsUSBLine(int fd)
172 {
173     int version;
174     int err;
175
176     SYSCALL(err = ioctl(fd, EVIOCGVERSION, &version));
177
178     if (!err) {
179         xf86MsgVerb(X_PROBED, 4, "Kernel Input driver version is %d.%d.%d\n",
180                 version >> 16, (version >> 8) & 0xff, version & 0xff);
181         return 1;
182     } else {
183         xf86MsgVerb(X_PROBED, 4, "No Kernel Input driver found\n");
184         return 0;
185     }
186 }
187
188 /* Heavily inspired by synaptics/eventcomm.c */
189
190 #define DEV_INPUT_EVENT "/dev/input/event"
191 #define EV_DEV_NAME_MAXLEN 64
192 #define SET_EVENT_NUM(str, num) \
193     snprintf(str, EV_DEV_NAME_MAXLEN, "%s%d", DEV_INPUT_EVENT, num)
194
195 static Bool
196 fd_query_acecad(int fd, char *ace_name) {
197     char name[256] = "Unknown";
198     int cmp_at = strlen(ace_name);
199     if (cmp_at > 255)
200         cmp_at = 255;
201     ioctl(fd, EVIOCGNAME(sizeof(name)), name);
202     name[cmp_at] = '\0';
203     if (xf86NameCmp(name, ace_name) == 0)
204         return TRUE;
205     return FALSE;
206 }
207
208 static char ace_name_default[7] = "acecad";
209
210 #ifdef LINUX_SYSFS
211 static char usb_bus_name[4] = "usb";
212 static char acecad_driver_name[11] = "usb_acecad";
213 #endif
214
215 static Bool
216 AceCadAutoDevProbe(LocalDevicePtr local, int verb)
217 {
218     /* We are trying to find the right eventX device */
219     int i = 0;
220     Bool have_evdev = FALSE;
221     int noent_cnt = 0;
222     const int max_skip = 10;
223     char *ace_name = xf86FindOptionValue(local->options, "Name");
224     char fname[EV_DEV_NAME_MAXLEN];
225     int np;
226
227 #ifdef LINUX_SYSFS
228     struct sysfs_bus *usb_bus = NULL;
229     struct sysfs_driver *acecad_driver = NULL;
230     struct sysfs_device *candidate = NULL;
231     char *link = NULL;
232     struct dlist *devs = NULL;
233     struct dlist *links = NULL;
234
235     xf86MsgVerb(X_INFO, verb, "%s: querying sysfs for Acecad tablets\n", local->name);
236     usb_bus = sysfs_open_bus(usb_bus_name);
237     if (usb_bus) {
238         xf86MsgVerb(X_PROBED, 4, "%s: usb bus opened\n", local->name);
239         acecad_driver = sysfs_get_bus_driver(usb_bus, acecad_driver_name);
240         if (acecad_driver) {
241             xf86MsgVerb(X_PROBED, 4, "%s: usb_acecad driver opened\n", local->name);
242             devs = sysfs_get_driver_devices(acecad_driver);
243             if (devs) {
244                 xf86MsgVerb(X_PROBED, 4, "%s: usb_acecad devices retrieved\n", local->name);
245                 dlist_for_each_data(devs, candidate, struct sysfs_device) {
246                     xf86MsgVerb(X_PROBED, 4, "%s: device %s at %s\n", local->name, candidate->name, candidate->path);
247                     links = sysfs_open_link_list(candidate->path);
248                     dlist_for_each_data(links, link, char) {
249                         if (sscanf(link, "input:event%d", &i) == 1) {
250                             xf86MsgVerb(X_PROBED, 4, "%s: device %s at %s: %s\n", local->name, candidate->name, candidate->path, link);
251                             break;
252                         }
253                     }
254                     sysfs_close_list(links);
255                     if (i > 0) /* We found something */
256                         break;
257                 }
258             } else
259                 xf86MsgVerb(X_WARNING, 4, "%s: no usb_acecad devices found\n", local->name);
260         } else
261             xf86MsgVerb(X_WARNING, 4, "%s: usb_acecad driver not found\n", local->name);
262     } else
263         xf86MsgVerb(X_WARNING, 4, "%s: usb bus not found\n", local->name);
264     sysfs_close_bus(usb_bus);
265
266     if (i > 0) {
267         /* We found something */
268         np = SET_EVENT_NUM(fname, i);
269         if (np < 0 || np >= EV_DEV_NAME_MAXLEN) {
270             xf86MsgVerb(X_WARNING, verb, "%s: unable to manage event device %d\n", local->name, i);
271         } else {
272             goto ProbeFound;
273         }
274     } else
275         xf86MsgVerb(X_WARNING, verb, "%s: no Acecad devices found via sysfs\n", local->name);
276
277 #endif
278
279     if (!ace_name)
280         ace_name = ace_name_default;
281
282     xf86MsgVerb(X_INFO, verb, "%s: probing event devices for Acecad tablets\n", local->name);
283     for (i = 0; ; i++) {
284         int fd = -1;
285         Bool is_acecad;
286
287         np = SET_EVENT_NUM(fname, i);
288         if (np < 0 || np >= EV_DEV_NAME_MAXLEN) {
289             xf86MsgVerb(X_WARNING, verb, "%s: too many devices, giving up %d\n", local->name, i);
290             break;
291         }
292         SYSCALL(fd = open(fname, O_RDONLY));
293         if (fd < 0) {
294             if (errno == ENOENT) {
295                 if (++noent_cnt >= max_skip)
296                     break;
297                 else
298                     continue;
299             } else {
300                 continue;
301             }
302         }
303         noent_cnt = 0;
304         have_evdev = TRUE;
305         is_acecad = fd_query_acecad(fd, ace_name);
306         SYSCALL(close(fd));
307         if (is_acecad) {
308             goto ProbeFound;
309         }
310     }
311     xf86MsgVerb(X_WARNING, verb, "%s: no Acecad event device found (checked %d nodes, no device name started with '%s')\n",
312             local->name, i + 1, ace_name);
313     if (i <= max_skip)
314         xf86MsgVerb(X_WARNING, verb, "%s: The /dev/input/event* device nodes seem to be missing\n",
315                 local->name);
316     if (i > max_skip && !have_evdev)
317         xf86MsgVerb(X_WARNING, verb, "%s: The evdev kernel module seems to be missing\n", local->name);
318     return FALSE;
319
320 ProbeFound:
321     xf86Msg(X_PROBED, "%s auto-dev sets device to %s\n",
322             local->name, fname);
323     xf86ReplaceStrOption(local->options, "Device", fname);
324     return TRUE;
325 }
326
327 #endif
328
329 static InputInfoPtr
330 AceCadPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
331 {
332     LocalDevicePtr local = xf86AllocateInput(drv, 0);
333     AceCadPrivatePtr priv = xcalloc (1, sizeof(AceCadPrivateRec));
334     int speed;
335     int msgtype;
336     char *s;
337
338     if ((!local) || (!priv))
339         goto SetupProc_fail;
340
341     memset(priv, 0, sizeof(AceCadPrivateRec));
342
343     local->name = dev->identifier;
344     local->type_name = XI_TABLET;
345     local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
346 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
347     local->motion_history_proc = xf86GetMotionEvents;
348 #endif
349     local->control_proc = NULL;
350     local->close_proc = CloseProc;
351     local->switch_mode = NULL;
352     local->conversion_proc = ConvertProc;
353     local->reverse_conversion_proc = ReverseConvertProc;
354     local->dev = NULL;
355     local->private = priv;
356     local->private_flags = 0;
357     local->conf_idev = dev;
358     local->device_control = DeviceControl;
359     /*local->always_core_feedback = 0;*/
360
361     xf86CollectInputOptions(local, default_options, NULL);
362
363     xf86OptionListReport(local->options);
364
365     priv->acecadInc = xf86SetIntOption(local->options, "Increment", 0 );
366
367     s = xf86FindOptionValue(local->options, "Device");
368     if (!s || (s && (xf86NameCmp(s, "auto-dev") == 0))) {
369 #ifdef LINUX_INPUT
370         priv->flags |= AUTODEV_FLAG;
371         if (!AceCadAutoDevProbe(local, 0))
372         {
373             xf86Msg(X_ERROR, "%s: unable to find device\n", local->name);
374             goto SetupProc_fail;
375         }
376 #else
377         xf86Msg(X_NOT_IMPLEMENTED, "%s: device autodetection not implemented, sorry\n", local->name);
378         goto SetupProc_fail;
379 #endif
380     }
381
382     local->fd = xf86OpenSerial (local->options);
383     if (local->fd == -1)
384     {
385         xf86Msg(X_ERROR, "%s: unable to open device\n", local->name);
386         goto SetupProc_fail;
387     }
388     xf86ErrorFVerb( 6, "tty port opened successfully\n" );
389
390 #ifdef LINUX_INPUT
391     if (IsUSBLine(local->fd)) {
392         priv->flags |= USB_FLAG;
393
394         local->read_input = USBReadInput;
395
396         if (USBQueryHardware(local) != Success)
397         {
398             xf86Msg(X_ERROR, "%s: unable to query/initialize hardware (not an %s?).\n", local->name, local->type_name);
399             goto SetupProc_fail;
400         }
401     } else
402 #endif
403     {
404         local->read_input = ReadInput;
405
406         msgtype = X_DEFAULT;
407         if (xf86FindOptionValue(local->options, "ReportSpeed")) {
408             msgtype = X_CONFIG;
409             speed = xf86SetIntOption(local->options, "ReportSpeed", 85 );
410         } else {
411             speed = 85;
412         }
413
414         switch (speed)
415         {
416             case 120:
417                 priv->acecadReportSpeed = 'Q';
418                 break;
419             case 85:
420                 priv->acecadReportSpeed = 'R';
421                 break;
422             case 10:
423                 priv->acecadReportSpeed = 'S';
424                 break;
425             case 2:
426                 priv->acecadReportSpeed = 'T';
427                 break;
428             default:
429                 priv->acecadReportSpeed = 'R';
430                 speed = 85;
431                 xf86Msg(X_ERROR, "%s: ReportSpeed value %d invalid. Possible values: 120, 85, 10, 2. Defaulting to 85\n", local->name, speed);
432                 msgtype = X_DEFAULT;
433         }
434
435         xf86Msg(msgtype, "%s report %d points/s\n", local->name, speed);
436
437         priv->buffer = XisbNew (local->fd, 200);
438
439         /*
440          * Verify that hardware is attached and fuctional
441          */
442         if (QueryHardware(priv) != Success)
443         {
444             xf86Msg(X_ERROR, "%s: unable to query/initialize hardware (not an %s?).\n", local->name, local->type_name);
445             goto SetupProc_fail;
446         }
447     }
448
449     s = xf86FindOptionValue(local->options, "Mode");
450     msgtype = s ? X_CONFIG : X_DEFAULT;
451     if (!(s && (xf86NameCmp(s, "relative") == 0)))
452     {
453         priv->flags |= ABSOLUTE_FLAG;
454     }
455
456     xf86Msg(msgtype, "%s is in %s mode\n", local->name, (priv->flags & ABSOLUTE_FLAG) ? "absolute" : "relative");
457     DBG (9, XisbTrace (priv->buffer, 1));
458
459     local->history_size = xf86SetIntOption(local->options , "HistorySize", 0);
460
461     xf86ProcessCommonOptions(local, local->options);
462
463     local->flags |= XI86_CONFIGURED;
464
465     if (local->fd != -1)
466     {
467         RemoveEnabledDevice (local->fd);
468         if (priv->buffer)
469         {
470             XisbFree(priv->buffer);
471             priv->buffer = NULL;
472         }
473         xf86CloseSerial(local->fd);
474     }
475     RemoveEnabledDevice (local->fd);
476     local->fd = -1;
477     return local;
478
479     /*
480      * If something went wrong, cleanup and return NULL
481      */
482 SetupProc_fail:
483     if ((local) && (local->fd))
484         xf86CloseSerial (local->fd);
485     if ((priv) && (priv->buffer))
486         XisbFree (priv->buffer);
487     if (priv) {
488         xfree (priv);
489         if (local)
490                 local->private = NULL;
491     }
492     xf86DeleteInput(local, 0);
493     return NULL;
494 }
495
496 static Bool
497 DeviceControl (DeviceIntPtr dev, int mode)
498 {
499     Bool RetValue;
500
501     switch (mode)
502     {
503         case DEVICE_INIT:
504             DeviceInit(dev);
505             RetValue = Success;
506             break;
507         case DEVICE_ON:
508             RetValue = DeviceOn(dev);
509             break;
510         case DEVICE_OFF:
511             RetValue = DeviceOff(dev);
512             break;
513         case DEVICE_CLOSE:
514             RetValue = DeviceClose(dev);
515             break;
516         default:
517             RetValue = BadValue;
518     }
519
520     return RetValue;
521 }
522
523 static Bool
524 DeviceOn (DeviceIntPtr dev)
525 {
526     char buffer[256];
527     LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
528     AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
529
530     xf86MsgVerb(X_INFO, 4, "%s Device On\n", local->name);
531
532     local->fd = xf86OpenSerial(local->options);
533     if (local->fd == -1)
534     {
535         xf86Msg(X_WARNING, "%s: cannot open input device %s: %s\n", local->name, xf86FindOptionValue(local->options, "Device"), strerror(errno));
536         priv->flags &= ~AVAIL_FLAG;
537 #ifdef LINUX_INPUT
538         if ((priv->flags & AUTODEV_FLAG) && AceCadAutoDevProbe(local, 4))
539             local->fd = xf86OpenSerial(local->options);
540         if (local->fd == -1)
541 #endif
542             return !Success;
543     }
544     priv->flags |= AVAIL_FLAG;
545
546
547     if (!(priv->flags & USB_FLAG)) {
548         priv->buffer = XisbNew(local->fd, 200);
549         if (!priv->buffer)
550         {
551             xf86CloseSerial(local->fd);
552             local->fd = -1;
553             return !Success;
554         }
555
556         /* Rets qu'a l'envoyer a la tablette */
557         sprintf(buffer, "%s%c%c%c%c", acecad_initstr, priv->acecadReportSpeed, ACECAD_INCREMENT, 32 + priv->acecadInc, (priv->flags & ABSOLUTE_FLAG)? ACECAD_ABSOLUTE: ACECAD_RELATIVE);
558         XisbWrite (priv->buffer, (unsigned char *)buffer, strlen(buffer));
559     }
560
561     xf86FlushInput(local->fd);
562     xf86AddEnabledDevice (local);
563     dev->public.on = TRUE;
564     return Success;
565 }
566
567 static Bool
568 DeviceOff (DeviceIntPtr dev)
569 {
570     LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
571     AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
572
573     xf86MsgVerb(X_INFO, 4, "%s Device Off\n", local->name);
574
575     if (local->fd != -1)
576     {
577         RemoveEnabledDevice (local->fd);
578         if (priv->buffer)
579         {
580             XisbFree(priv->buffer);
581             priv->buffer = NULL;
582         }
583         xf86CloseSerial(local->fd);
584     }
585
586
587     xf86RemoveEnabledDevice (local);
588     dev->public.on = FALSE;
589     return Success;
590 }
591
592 static Bool
593 DeviceClose (DeviceIntPtr dev)
594 {
595     LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
596
597     xf86MsgVerb(X_INFO, 4, "%s Device Close\n", local->name);
598
599     return Success;
600 }
601
602 static void
603 ControlProc(DeviceIntPtr dev, PtrCtrl *ctrl)
604 {
605     LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
606
607     xf86MsgVerb(X_INFO, 4, "%s Control Proc\n", local->name);
608 }
609
610 static Bool
611 DeviceInit (DeviceIntPtr dev)
612 {
613     int rx, ry;
614     LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
615     AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
616     unsigned char map[] = {0, 1, 2, 3};
617 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
618     Atom btn_labels[3];
619     Atom axes_labels[3];
620
621     btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
622     btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
623     btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
624
625     if ((priv->flags & ABSOLUTE_FLAG))
626     {
627         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
628         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
629         axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
630     } else
631     {
632         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
633         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
634         axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Z);
635     }
636 #endif
637
638     xf86MsgVerb(X_INFO, 4, "%s Init\n", local->name);
639
640     /* 3 boutons */
641     if (InitButtonClassDeviceStruct (dev, 3,
642 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
643                 btn_labels,
644 #endif
645                 map) == FALSE)
646     {
647         xf86Msg(X_ERROR, "%s: unable to allocate ButtonClassDeviceStruct\n", local->name);
648         return !Success;
649     }
650
651     if (InitFocusClassDeviceStruct (dev) == FALSE)
652     {
653         xf86Msg(X_ERROR, "%s: unable to allocate FocusClassDeviceStruct\n", local->name);
654         return !Success;
655     }
656
657     if (InitPtrFeedbackClassDeviceStruct(dev, ControlProc) == FALSE) {
658         xf86Msg(X_ERROR, "%s: unable to init ptr feedback\n", local->name);
659         return !Success;
660     }
661
662
663     /* 3 axes */
664     if (InitValuatorClassDeviceStruct (dev, 3,
665 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
666                 axes_labels,
667 #endif
668 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3
669                 xf86GetMotionEvents,
670 #endif
671                 local->history_size,
672                 ((priv->flags & ABSOLUTE_FLAG)? Absolute: Relative)|OutOfProximity)
673             == FALSE)
674     {
675         xf86Msg(X_ERROR, "%s: unable to allocate ValuatorClassDeviceStruct\n", local->name);
676         return !Success;
677     }
678     else
679     {
680
681         InitValuatorAxisStruct(dev,
682                 0,
683 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
684                 axes_labels[0],
685 #endif
686                 0,                      /* min val */
687 #if XORG_BOTCHED_INPUT
688                 screenInfo.screens[0]->width,
689 #else
690                 priv->acecadMaxX,       /* max val */
691 #endif
692                 1000,                   /* resolution */
693                 0,                      /* min_res */
694                 1000);                  /* max_res */
695         InitValuatorAxisStruct(dev,
696                 1,
697 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
698                 axes_labels[1],
699 #endif
700                 0,                      /* min val */
701 #if XORG_BOTCHED_INPUT
702                 screenInfo.screens[0]->height,
703 #else
704                 priv->acecadMaxY,       /* max val */
705 #endif
706                 1000,                   /* resolution */
707                 0,                      /* min_res */
708                 1000);                  /* max_res */
709         InitValuatorAxisStruct(dev,
710                 2,
711 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
712                 axes_labels[2],
713 #endif
714                 0,                      /* min val */
715                 priv->acecadMaxZ,       /* max val */
716                 1000,                   /* resolution */
717                 0,                      /* min_res */
718                 1000);          /* max_res */
719
720     }
721
722     if (InitProximityClassDeviceStruct (dev) == FALSE)
723     {
724         xf86Msg(X_ERROR, "%s: unable to allocate ProximityClassDeviceStruct\n", local->name);
725         return !Success;
726     }
727
728     xf86MotionHistoryAllocate (local);
729
730
731     /* On ne peut pas calculer l'increment avant, faute d'ecran pour
732        connaitre la taille... */
733
734     if (priv->acecadInc > 95)
735         priv->acecadInc = 95;
736     if (priv->acecadInc < 1)
737     {
738         /* guess the best increment value given video mode */
739         rx = priv->acecadMaxX / screenInfo.screens[0]->width;
740         ry = priv->acecadMaxY / screenInfo.screens[0]->height;
741         if (rx < ry)
742             priv->acecadInc = rx;
743         else
744             priv->acecadInc = ry;
745         if (priv->acecadInc < 1)
746             priv->acecadInc = 1;
747     }
748
749     xf86Msg(X_INFO, "%s Increment: %d\n", local->name, priv->acecadInc);
750
751     return Success;
752 }
753
754 static void
755 ReadInput (LocalDevicePtr local)
756 {
757     int x, y, z;
758     int prox, buttons;
759     int is_core_pointer = 0, is_absolute;
760     AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
761
762     /*xf86Msg(X_INFO, "ACECAD Tablet Read Input\n");*/
763
764     is_absolute = (priv->flags & ABSOLUTE_FLAG);
765 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
766     is_core_pointer = xf86IsCorePointer(local->dev);
767 #endif
768
769     /*
770      * set blocking to -1 on the first call because we know there is data to
771      * read. Xisb automatically clears it after one successful read so that
772      * succeeding reads are preceeded buy a select with a 0 timeout to prevent
773      * read from blocking indefinately.
774      */
775     XisbBlockDuration (priv->buffer, -1);
776
777     while (AceCadGetPacket (priv) == Success)
778     {
779         x = (int)priv->packet[1] | ((int)priv->packet[2] << 7);
780         y = (int)priv->packet[3] | ((int)priv->packet[4] << 7);
781
782         if (!(priv->flags & ABSOLUTE_FLAG))
783         {
784             x = priv->packet[0] & XSIGN_BIT? x:-x;
785             y = priv->packet[0] & YSIGN_BIT? y:-y;
786         }
787         else
788         {
789             y = priv->acecadMaxY - y ;
790         }
791
792
793         z = ((int)priv->packet[5] << 2) |
794             (((int)priv->packet[6] & 0x01) << 1) |
795             (((int)priv->packet[6] & 0x10) >> 4);
796
797         buttons = ((int)priv->packet[0] & 0x07) |
798             ((int)priv->packet[6] & 0x02 << 2);
799
800         prox = (priv->packet[0] & PROXIMITY_BIT)? 0: 1;
801
802         if (prox)
803         {
804             if (!(priv->acecadOldProximity))
805                 if (!is_core_pointer)
806                 {
807                     /*xf86Msg(X_INFO, "ACECAD Tablet ProxIN %d %d %d\n",x, y, z);*/
808                     xf86PostProximityEvent(local->dev, 1, 0, 3 , x, y, z);
809                 }
810
811             if ((is_absolute && ((priv->acecadOldX != x) || (priv->acecadOldY != y) || (priv->acecadOldZ != z)))
812                     || (!is_absolute && (x || y)))
813             {
814                 if (is_absolute || priv->acecadOldProximity)
815                 {
816                     /*xf86Msg(X_INFO, "ACECAD Tablet Motion %d %d %d\n", x, y, z);*/
817                     xf86PostMotionEvent(local->dev, is_absolute, 0, 3, x, y, z);
818                 }
819             }
820
821             if (priv->acecadOldButtons != buttons)
822             {
823                 int delta = buttons ^ priv->acecadOldButtons;
824                 while (delta)
825                 {
826                     int id = ffs(delta);
827                     delta &= ~(1 << (id-1));
828
829                     /*xf86Msg(X_INFO, "ACECAD Tablet Button %d 0x%x\n",id,(buttons&(1<<(id-1))));*/
830                     xf86PostButtonEvent(local->dev, is_absolute, id, (buttons&(1<<(id-1))), 0, 3, x, y,z);
831                 }
832             }
833
834             priv->acecadOldButtons = buttons;
835             priv->acecadOldX = x;
836             priv->acecadOldY = y;
837             priv->acecadOldZ = z;
838             priv->acecadOldProximity = prox;
839         }
840         else
841         {
842             if (!is_core_pointer)
843                 if (priv->acecadOldProximity)
844                 {
845                     /*xf86Msg(X_INFO, "ACECAD Tablet ProxOUT %d %d %d\n",x, y, z);*/
846                     xf86PostProximityEvent(local->dev, 0, 0, 3, x,y,z);
847                 }
848             priv->acecadOldProximity = 0;
849         }
850     }
851     /*xf86Msg(X_INFO, "ACECAD Tablet Sortie Read Input\n");*/
852 }
853
854 #ifdef LINUX_INPUT
855 #define set_bit(byte,nb,bit)    (bit ? byte | (1<<nb) : byte & (~(1<<nb)))
856 static void
857 USBReadInput (LocalDevicePtr local)
858 {
859     int len;
860     struct input_event * event;
861     char eventbuf[sizeof(struct input_event) * MAX_EVENTS];
862     AceCadPrivatePtr priv = (AceCadPrivatePtr) (local->private);
863     int x = priv->acecadOldX;
864     int y = priv->acecadOldY;
865     int z = priv->acecadOldZ;
866     int report_x, report_y;
867     int prox = priv->acecadOldProximity;
868     int buttons = priv->acecadOldButtons;
869     int is_core_pointer = 0;
870 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0
871     is_core_pointer = xf86IsCorePointer(local->dev);
872 #endif
873     /* Is autodev active? */
874     int autodev = priv->flags & AUTODEV_FLAG;
875     /* Was the device available last time we checked? */
876     int avail = priv->flags & AVAIL_FLAG;
877
878     SYSCALL(len = xf86ReadSerial(local->fd, eventbuf, sizeof(eventbuf)));
879
880     if (len <= 0) {
881         if (avail) {
882             xf86Msg(X_ERROR, "%s: error reading device %s: %s\n", local->name, xf86FindOptionValue(local->options, "Device"), strerror(errno));
883         }
884         if (NOTAVAIL) {
885             priv->flags &= ~AVAIL_FLAG;
886             if(autodev) {
887                 if (AceCadAutoDevProbe(local, 4)) {
888                     DeviceOff(local->dev);
889                     DeviceOn(local->dev);
890                 }
891             }
892         }
893         return;
894     } else {
895         if (!avail) {
896             /* If the device wasn't available last time we checked */
897             xf86Msg(X_INFO, "%s: device %s is available again\n", local->name, xf86FindOptionValue(local->options, "Device"));
898             priv->flags |= AVAIL_FLAG;
899         }
900     }
901
902     for (event = (struct input_event *)eventbuf;
903             event < (struct input_event *)(eventbuf+len); event++) {
904
905         switch (event->type) {
906             case EV_SYN: /* 2.6.x */
907                 if (event->code != SYN_REPORT)
908                     xf86Msg(X_ERROR, "%s: unknown EV_SYN code %d\n", local->name, event->code);
909                 break;
910             case EV_ABS:
911                 switch (event->code) {
912                     case ABS_X:
913                         x = event->value;
914                         break;
915
916                     case ABS_Y:
917                         y = event->value;
918                         break;
919
920                     case ABS_PRESSURE:
921                         z = event->value;
922                         break;
923
924                     case ABS_MISC:
925                         break;
926
927                 }
928                 break; /* EV_ABS */
929
930             case EV_KEY:
931                 switch (event->code) {
932                     case BTN_TOOL_PEN:
933                         prox = event->value;
934                         break;
935
936                     case BTN_TOUCH:
937                         buttons = set_bit(buttons,0,event->value);
938                         break;
939
940                     case BTN_STYLUS:
941                         buttons = set_bit(buttons,1,event->value);
942                         break;
943
944                     case BTN_STYLUS2:
945                         buttons = set_bit(buttons,2,event->value);
946                         break;
947                 }
948                 break; /* EV_KEY */
949             default:
950                 xf86Msg(X_ERROR, "%s: unknown event type/code %d/%d\n", local->name, event->type, event->code);
951         } /* switch event->type */
952
953         /* Linux Kernel 2.6.x sends EV_SYN/SYN_REPORT as an event terminator,
954          * whereas 2.4.x sends EV_ABS/ABS_MISC. We have to support both.
955          */
956         if (!(  (event->type == EV_SYN && event->code == SYN_REPORT) ||
957                     (event->type == EV_ABS && event->code == ABS_MISC)
958              )) {
959             continue;
960         }
961
962         if (prox)
963         {
964 #if XORG_BOTCHED_INPUT
965             ConvertProc(local, 0, 3, x, y, 0, 0, 0, 0, &report_x, &report_y);
966 #else
967             report_x = x;
968             report_y = y;
969 #endif
970             if (!(priv->acecadOldProximity))
971                 if (!is_core_pointer)
972                 {
973                     xf86PostProximityEvent(local->dev, 1, 0, 3 , report_x, report_y, z);
974                 }
975
976
977             xf86PostMotionEvent(local->dev, 1, 0, 3, report_x, report_y, z);
978
979             if (priv->acecadOldButtons != buttons)
980             {
981                 int delta = buttons ^ priv->acecadOldButtons;
982                 while (delta)
983                 {
984                     int id = ffs(delta);
985                     delta &= ~(1 << (id-1));
986
987                     xf86PostButtonEvent(local->dev, 1, id, (buttons&(1<<(id-1))), 0, 3, report_x, report_y, z);
988                 }
989             }
990         }
991         else
992         {
993             if (!is_core_pointer)
994                 if (priv->acecadOldProximity)
995                 {
996                     xf86PostProximityEvent(local->dev, 0, 0, 3, report_x, report_y, z);
997                 }
998             priv->acecadOldProximity = 0;
999         }
1000
1001         priv->acecadOldButtons = buttons;
1002         priv->acecadOldX = x;
1003         priv->acecadOldY = y;
1004         priv->acecadOldZ = z;
1005         priv->acecadOldProximity = prox;
1006     }
1007     /*xf86Msg(X_INFO, "ACECAD Tablet Sortie Read Input\n");*/
1008 }
1009 #endif
1010
1011 static void
1012 CloseProc (LocalDevicePtr local)
1013 {
1014 }
1015
1016 /*
1017  * The ConvertProc function may need to be tailored for your device.
1018  * This function converts the device's valuator outputs to x and y coordinates
1019  * to simulate mouse events.
1020  */
1021 static Bool
1022 ConvertProc (LocalDevicePtr local, int first, int num,
1023         int v0, int v1, int v2, int v3, int v4, int v5,
1024         int *x, int *y)
1025 {
1026     AceCadPrivatePtr priv = (AceCadPrivatePtr)(local->private);
1027
1028     /* TODO: should have a structure to hold which screen the
1029      * pointer is attached to? */
1030     // xf86Msg(X_INFO, "%s: coordinate conversion in : %d, %d\n", local->name, v0, v1);
1031     *x = v0 * screenInfo.screens[0]->width / priv->acecadMaxX;
1032     *y = v1 * screenInfo.screens[0]->height / priv->acecadMaxY;
1033     // xf86Msg(X_INFO, "%s: coordinate conversion out: %d, %d\n", local->name, *x, *y);
1034     return TRUE;
1035 }
1036
1037
1038 static Bool
1039 ReverseConvertProc (LocalDevicePtr local,
1040         int x, int  y,
1041         int *valuators)
1042 {
1043     AceCadPrivatePtr priv = (AceCadPrivatePtr)(local->private);
1044
1045     // xf86Msg(X_INFO, "%s: reverse coordinate conversion in : %d, %d\n", local->name, x, y);
1046     valuators[0] = x * priv->acecadMaxX / screenInfo.screens[0]->width;
1047     valuators[1] = y * priv->acecadMaxY / screenInfo.screens[0]->height;
1048     // xf86Msg(X_INFO, "%s: reverse coordinate conversion out: %d, %d\n", local->name, valuators[0], valuators[1]);
1049
1050     return TRUE;
1051 }
1052
1053
1054 #define WriteString(str)\
1055     XisbWrite (priv->buffer, (unsigned char *)(str), strlen(str))
1056
1057
1058 static Bool
1059 QueryHardware (AceCadPrivatePtr priv)
1060 {
1061
1062     /* Reset */
1063     WriteString("z0");
1064
1065     /* Wait */
1066     milisleep (250);
1067
1068     /* Prompt Mode in order to not be disturbed */
1069     WriteString(ACECAD_PROMPT_MODE);
1070
1071     /* Flush */
1072     while (XisbRead(priv->buffer) >= 0);
1073
1074     /* Ask for Config packet*/
1075     WriteString(ACECAD_CONFIG);
1076
1077     /* Read the packet */
1078     XisbBlockDuration (priv->buffer, 1000000);
1079     NewPacket (priv);
1080
1081     /*xf86Msg(X_CONFIG, "ACECAD Tablet init envoyé \n");*/
1082
1083     if ((AceCadGetPacket (priv) == Success))
1084     {
1085         priv->acecadMaxX = (int)priv->packet[1] + ((int)priv->packet[2] << 7);
1086         priv->acecadMaxY = (int)priv->packet[3] + ((int)priv->packet[4] << 7);
1087         priv->acecadMaxZ = 512;
1088         xf86Msg(X_PROBED, "ACECAD Tablet MaxX:%d MaxY:%d\n", priv->acecadMaxX, priv->acecadMaxY);
1089     }
1090     else
1091         return !Success;
1092
1093     /*xf86Msg(X_INFO, "ACECAD Tablet query hardware fini \n");*/
1094     return Success;
1095 }
1096
1097 #define BITS_PER_LONG (sizeof(long) * 8)
1098 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
1099 #define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
1100 #define OFF(x)  ((x)%BITS_PER_LONG)
1101 #define LONG(x) ((x)/BITS_PER_LONG)
1102
1103 #ifdef LINUX_INPUT
1104 static Bool
1105 USBQueryHardware (LocalDevicePtr local)
1106 {
1107     AceCadPrivatePtr    priv = (AceCadPrivatePtr) local->private;
1108     unsigned long       bit[EV_MAX][NBITS(KEY_MAX)];
1109     int                 i, j;
1110     int                 abs[5];
1111     char                name[256] = "Unknown";
1112
1113     ioctl(local->fd, EVIOCGNAME(sizeof(name)), name);
1114     xf86MsgVerb(X_PROBED, 4, "Kernel Input device name: \"%s\"\n", name);
1115
1116     memset(bit, 0, sizeof(bit));
1117     ioctl(local->fd, EVIOCGBIT(0, EV_MAX), bit[0]);
1118
1119     for (i = 0; i < EV_MAX; i++)
1120         if (test_bit(i, bit[0])) {
1121             ioctl(local->fd, EVIOCGBIT(i, KEY_MAX), bit[i]);
1122             for (j = 0; j < KEY_MAX; j++)
1123                 if (test_bit(j, bit[i])) {
1124                     if (i == EV_ABS) {
1125                         ioctl(local->fd, EVIOCGABS(j), abs);
1126                         switch (j) {
1127                             case ABS_X:
1128                                 priv->acecadMaxX = abs[2];
1129                                 break;
1130
1131                             case ABS_Y:
1132                                 priv->acecadMaxY = abs[2];
1133                                 break;
1134
1135                             case ABS_PRESSURE:
1136                                 priv->acecadMaxZ = abs[2];
1137                                 break;
1138                         }
1139                     }
1140                 }
1141         }
1142
1143     xf86Msg(X_PROBED, "ACECAD Tablet MaxX:%d MaxY:%d MaxZ:%d\n", priv->acecadMaxX, priv->acecadMaxY, priv->acecadMaxZ);
1144     return Success;
1145 }
1146 #endif
1147
1148 static void
1149 NewPacket (AceCadPrivatePtr priv)
1150 {
1151     priv->packeti = 0;
1152 }
1153
1154 static Bool
1155 AceCadGetPacket (AceCadPrivatePtr priv)
1156 {
1157     int count = 0;
1158     int c = 0;
1159
1160     while((c = XisbRead(priv->buffer)) >= 0 )
1161     {
1162
1163         /*
1164          * fail after 500 bytes so the server doesn't hang forever if a
1165          * device sends bad data.
1166          */
1167         if (count++ > 500)
1168         {
1169             NewPacket (priv);
1170             return !Success;
1171         }
1172
1173         if (c & PHASING_BIT)
1174         {
1175             NewPacket(priv);
1176
1177             /*xf86Msg(X_CONFIG, "Push %2.2x\n",(char) c);*/
1178             XisbBlockDuration (priv->buffer, 10000);
1179             priv->packet[priv->packeti++] = c;
1180             count = ACECAD_PACKET_SIZE - 1;
1181             while (count-- && (c = XisbRead(priv->buffer)) >= 0)
1182             {
1183                 /*xf86Msg(X_INFO, "Push %2.2x\n",(char) c);*/
1184                 priv->packet[priv->packeti++] = c;
1185             }
1186             XisbBlockDuration (priv->buffer, 0);
1187             if(c > 0)
1188                 return Success;
1189         }
1190     }
1191     return !Success;
1192 }