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