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