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