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