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