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