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