~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/input/acecad/acecad.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

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