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