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