~ubuntu-branches/ubuntu/gutsy/xf86-input-evtouch/gutsy

1 by Mattia Dongili
Import upstream version 0.8.3
1
/*
2
 * Copyright 2004 by Kenan Esau <kenan.esau@conan.de>, Baltmannsweiler, 
3
 * Germany.
4
 *
5
 * Permission to use, copy, modify, distribute, and sell this software and its
6
 * documentation for any purpose is hereby granted without fee, provided that
7
 * the above copyright notice appear in all copies and that both that
8
 * copyright notice and this permission notice appear in supporting
9
 * documentation, and that the names of copyright holders not be
10
 * used in advertising or publicity pertaining to distribution of the
11
 * software without specific, written prior permission.  The copyright holders
12
 * make no representations about the suitability of this
13
 * software for any purpose.  It is provided "as is" without express or
14
 * implied warranty.
15
 *
16
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18
 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21
 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
 *
24
 */
25
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
#endif
29
30
#define _evdev_touch_C_
31
/*****************************************************************************
32
 *        Standard Headers
33
 ****************************************************************************/
34
#define SYSCALL(call)        while(((call) == -1) && (errno == EINTR))
35
36
#include <X11/Xos.h>
37
#include <misc.h>
38
#include <xf86.h>
39
#define NEED_XF86_TYPES
40
#include <xf86_ansic.h>
41
#include <xf86_OSproc.h>
42
#include <xf86Xinput.h>
43
#include <xisb.h>
44
#include <exevents.h>
45
#include <string.h>
46
47
48
/*****************************************************************************
49
 *        Local Headers
50
 ****************************************************************************/
51
#include "libtouch.h"
52
#include "evtouch.h"
53
54
/*****************************************************************************
55
 *        Variables without includable headers
56
 ****************************************************************************/
57
58
/*****************************************************************************
59
 *        Local Variables
60
 ****************************************************************************/
61
62
63
static InputInfoPtr
64
EVTouchPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
65
66
static int debug_level = 0;
67
68
InputDriverRec EVTOUCH = {
69
        1,
70
        "evtouch",
71
        NULL,
72
        EVTouchPreInit,
73
        /*EVTouchUnInit*/ NULL,
74
        NULL,
75
        0
76
};
77
78
#ifdef XFree86LOADER
79
ModuleInfoRec EVTouchInfo = {
80
        1,
81
        "EVTOUCH",
82
        NULL,
83
        0,
84
        NULL /*EVTouchAvailableOptions*/,
85
};
86
87
88
static XF86ModuleVersionInfo VersionRec =
89
{
90
        "evtouch",
91
        "Kenan Esau",
92
        MODINFOSTRING1,
93
        MODINFOSTRING2,
94
        XF86_VERSION_CURRENT,
95
        0, 8, 3,
96
        ABI_CLASS_XINPUT,
97
        ABI_XINPUT_VERSION,
98
        MOD_CLASS_XINPUT,
99
        {0, 0, 0, 0}                                /* signature, to be patched into the file by
100
                                                     * a tool */
101
};
102
103
104
static pointer
105
Plug( pointer module,
106
      pointer options,
107
      int *errmaj,
108
      int *errmin )
109
{
110
        xf86AddModuleInfo(&EVTouchInfo, module);
111
        xf86AddInputDriver(&EVTOUCH, module, 0);
112
        return module;
113
}
114
115
116
static void
117
Unplug(pointer        p)
118
{
119
        DBGOUT(1, "EVTouch: Unplug\n");
120
}
121
122
123
XF86ModuleData evtouchModuleData = {&VersionRec, Plug, Unplug };
124
125
#endif /* XFree86LOADER */
126
127
128
static const char *default_options[] =
129
{
130
        "BaudRate", "9600",
131
        "StopBits", "1",
132
        "DataBits", "8",
133
        "Parity", "None",
134
        "Vmin", "5",
135
        "Vtime", "1",
136
        "FlowControl", "None"
137
};
138
139
static void
140
ControlProc(DeviceIntPtr device, PtrCtrl *ctrl);
141
142
/*****************************************************************************
143
 *        Function Definitions
144
 ****************************************************************************/
145
146
147
static CARD32
148
emulate3Timer(OsTimerPtr timer, CARD32 now, pointer _local)
149
{
150
        int sigstate;
151
152
        DBGOUT(2,"EVTouch: %s\n", __FUNCTION__);
153
154
        LocalDevicePtr local = (LocalDevicePtr)_local;
155
        EVTouchPrivatePtr priv = (EVTouchPrivatePtr) local->private;
156
157
        sigstate = xf86BlockSIGIO();
158
159
        xf86PostMotionEvent(local->dev, TRUE, 0, 2, 
160
                            priv->cur_x, 
161
                            priv->cur_y);
162
163
        /* 
164
         * Emit a button press -- release is handled in EVTouchLBRBEvent
165
         */
166
        if ( ( priv->touch_flags & LB_STAT ) &&
167
             !( priv->touch_flags & RB_STAT ) ) {
168
                DBGOUT(2, "EVTouch: Left Press\n");
169
                xf86PostButtonEvent (local->dev, TRUE,
170
                                     1, 1, 0, 2, 
171
                                     priv->cur_x, 
172
                                     priv->cur_y);
173
        }
174
175
        if ( ( priv->touch_flags & RB_STAT ) &&
176
             !( priv->touch_flags & LB_STAT ) ) {
177
                DBGOUT(2, "EVTouch: Right Press\n");
178
                xf86PostButtonEvent (local->dev, TRUE,
179
                                     3, 1, 0, 2, 
180
                                     priv->cur_x, 
181
                                     priv->cur_y);
182
        }
183
184
        /*
185
          Handling "middle" button press
186
        */
187
        if ( ( priv->touch_flags & RB_STAT ) &&
188
             ( priv->touch_flags & LB_STAT ) ) {
189
                DBGOUT(2, "EVTouch: Middle Press\n");
190
                xf86PostButtonEvent (local->dev, TRUE,
191
                                     2, 1, 0, 2, 
192
                                     priv->cur_x, 
193
                                     priv->cur_y);
194
        }
195
196
197
        priv->emulate3_timer_expired = TRUE;
198
        xf86UnblockSIGIO(sigstate);
199
             
200
        return 0;
201
}
202
203
204
205
206
void EVTouchProcessAbs(EVTouchPrivatePtr priv)
207
{
208
        struct input_event *ev; /* packet being/just read */
209
210
        ev = &priv->ev;
211
        priv->old_x = priv->cur_x;
212
        priv->old_y = priv->cur_y;
213
214
        if (ev->code == ABS_X) {
215
                priv->cur_x = ev->value;
216
		libtouchSetXPos(priv->libtouch, priv->cur_x);
217
	}
218
219
        if (ev->code == ABS_Y) {
220
                priv->cur_y = ev->value;
221
		libtouchSetYPos(priv->libtouch, priv->cur_y);
222
	}
223
224
	if (ev->code == ABS_WHEEL) {
225
		LocalDevicePtr local = priv->local;
226
227
		if (ev->value > 0) {
228
			for (; ev->value > 0; ev->value--) {
229
				xf86PostButtonEvent (local->dev, TRUE,
230
						     4, 1, 0, 2, 
231
						     priv->cur_x, 
232
						     priv->cur_y);
233
				xf86PostButtonEvent (local->dev, TRUE,
234
						     4, 0, 0, 2, 
235
						     priv->cur_x, 
236
						     priv->cur_y);
237
			}
238
		} else if (ev->value < 0) {
239
			for (ev->value = -ev->value; ev->value > 0; ev->value--) {
240
				xf86PostButtonEvent (local->dev, TRUE,
241
						     5, 1, 0, 2, 
242
						     priv->cur_x, 
243
						     priv->cur_y);
244
				xf86PostButtonEvent (local->dev, TRUE,
245
						     5, 0, 0, 2, 
246
						     priv->cur_x, 
247
						     priv->cur_y);
248
			}
249
		}			
250
	}
251
}
252
253
254
255
256
void EVTouchProcessRel(EVTouchPrivatePtr priv)
257
{
258
        struct input_event *ev; /* packet being/just read */
259
260
        ev = &priv->ev;
261
        priv->old_x = priv->cur_x;
262
        priv->old_y = priv->cur_y;
263
        if ( ev->code == REL_X ) {
264
                priv->cur_x += ev->value;
265
                if (priv->cur_x > priv->max_x)
266
                        priv->cur_x = priv->max_x;
267
                if (priv->cur_x < priv->min_x)
268
                        priv->cur_x = priv->min_x;
269
                return;
270
        } 
271
        if ( ev->code == REL_Y ) {
272
                priv->cur_y += ev->value;
273
                if (priv->cur_y > priv->max_y)
274
                        priv->cur_y = priv->max_y;
275
                if (priv->cur_y < priv->min_y)
276
                        priv->cur_y = priv->min_y;
277
                return;
278
        }
279
	
280
        libtouchSetPos(priv->libtouch, priv->cur_x, priv->cur_y);
281
}
282
283
284
285
286
void EVTouchLBRBEvent(EVTouchPrivatePtr priv)
287
{
288
        struct input_event *ev; /* packet being/just read */
289
        LocalDevicePtr local = priv->local;
290
        static OsTimerPtr emulate3_timer = NULL;
291
        int btn = 0;  
292
293
        ev = &priv->ev;
294
        DBGOUT(2, "EVTouch: %s\n", __FUNCTION__);
295
296
        if (priv->emulate3) {
297
                if ( (ev->value==1) && (emulate3_timer==NULL) )
298
                        emulate3_timer = TimerSet(emulate3_timer, 0,
299
                                                  priv->emulate3_timeout,
300
                                                  emulate3Timer,
301
                                                  local);
302
303
                if ( (ev->value == 1) && (ev->code == BTN_LEFT) )
304
                        priv->touch_flags |= LB_STAT;
305
                if ( (ev->value == 1) && (ev->code == BTN_RIGHT) )
306
                        priv->touch_flags |= RB_STAT;
307
308
                if ( (ev->value == 0) && 
309
                     (priv->touch_flags & RB_STAT) && 
310
                     (priv->touch_flags & LB_STAT) ) {
311
                        DBGOUT(2, "EVTouch: Middle Release\n");
312
                        priv->touch_flags &= ~LB_STAT;
313
                        priv->touch_flags &= ~RB_STAT;
314
                        btn = 2;                  
315
                } else if ( (ev->value == 0) && (ev->code == BTN_LEFT) &&
316
                     (priv->touch_flags & LB_STAT) ) {
317
                        DBGOUT(2, "EVTouch: Left Release\n");
318
                        priv->touch_flags &= ~LB_STAT;
319
                        btn = 1;
320
                } else if ( (ev->value == 0) && (ev->code == BTN_RIGHT) &&
321
                     (priv->touch_flags & RB_STAT) ) {
322
                        DBGOUT(2, "EVTouch: Right Release\n");
323
                        priv->touch_flags &= ~RB_STAT;
324
                        btn = 3;
325
                }                
326
                if (ev->value == 0) {
327
                        TimerFree(emulate3_timer);
328
                        emulate3_timer=NULL;
329
                        priv->emulate3_timer_expired = FALSE;
330
                        xf86PostButtonEvent(local->dev, TRUE,
331
                                            btn, ev->value, 0, 2, 
332
                                            priv->cur_x, 
333
                                            priv->cur_y);
334
                }
335
                
336
        } else {
337
                if (ev->code == BTN_LEFT) {
338
                        xf86PostButtonEvent(local->dev, TRUE,
339
                                            1, ev->value, 0, 2, 
340
                                            priv->cur_x, 
341
                                            priv->cur_y);
342
                }
343
344
		if (ev->code == BTN_MIDDLE) {
345
			xf86PostButtonEvent(local->dev, TRUE,
346
					    2, ev->value, 0, 2,
347
					    priv->cur_x,
348
					    priv->cur_y);
349
		}
350
351
                if (ev->code == BTN_RIGHT) {
352
                        xf86PostButtonEvent (local->dev, TRUE,
353
                                             3, ev->value, 0, 2,
354
                                             priv->cur_x, 
355
                                             priv->cur_y);
356
                }
357
        }
358
}
359
360
361
362
363
void EVTouchProcessKey(EVTouchPrivatePtr priv)
364
{
365
        struct input_event *ev; /* packet being/just read */
366
367
        DBGOUT(2, "EVTouch: %s\n", __FUNCTION__);
368
        ev = &priv->ev;
369
        if ( (ev->code == BTN_LEFT) || 
370
             (ev->code == BTN_RIGHT) ||
371
             (ev->code == BTN_MIDDLE) ) {
372
373
                /* give lb and rb-events some special treatment 
374
                   (emulate3 or not, ...) */
375
                EVTouchLBRBEvent(priv);
376
                return;
377
        }
378
379
#ifdef _0_
380
        switch (ev->code) {
381
        case BTN_SIDE:
382
                break;
383
        case BTN_EXTRA:
384
                break;
385
        case BTN_FORWARD:
386
                break;
387
        case BTN_BACK:
388
                break;
389
        case BTN_TASK:
390
                break;
391
        default:
392
                return;
393
        }
394
        xf86PostButtonEvent(local->dev, TRUE,
395
                            btn, ev->value, 0, 2, 
396
                            priv->cur_x, 
397
                            priv->cur_y);
398
#endif
399
400
        return;
401
}
402
403
404
405
406
static Bool
407
DeviceOn (DeviceIntPtr dev)
408
{
409
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
410
        EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
411
        
412
        local->fd = xf86OpenSerial(local->options);
413
414
        DBGOUT(2, "EVTouch: Device ON\n");
415
416
        if (local->fd == -1)
417
        {
418
                xf86Msg(X_WARNING, "%s: cannot open input device\n", local->name);
419
                return (!Success);
420
        }
421
422
        priv->buffer = XisbNew(local->fd, 64);
423
424
425
        if (!priv->buffer) 
426
        {
427
                xf86CloseSerial(local->fd);
428
                local->fd = -1;
429
                return (!Success);
430
        }
431
        xf86FlushInput(local->fd);
432
433
#ifndef XFREE86_V4
434
        xf86AddEnabledDevice(local);
435
#else
436
        AddEnabledDevice(local->fd);
437
#endif
438
439
440
        dev->public.on = TRUE;
441
442
        return (Success);
443
}
444
445
446
447
448
static Bool
449
DeviceOff (DeviceIntPtr dev)
450
{
451
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
452
        EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
453
454
        DBGOUT(2, "EVTouch: Device OFF\n");
455
456
        if (local->fd != -1)
457
        { 
458
                xf86RemoveEnabledDevice (local);
459
                if (priv->buffer)
460
                {
461
                        XisbFree(priv->buffer);
462
                        priv->buffer = NULL;
463
                }
464
                xf86CloseSerial(local->fd);
465
        }
466
467
        xf86RemoveEnabledDevice (local);
468
        dev->public.on = FALSE;
469
470
        if ( (priv->calibrate) && (priv->fifo>0) ){
471
                SYSCALL(close (priv->fifo));
472
        }
473
474
        return (Success);
475
}
476
477
478
479
480
static Bool
481
DeviceInit (DeviceIntPtr dev)
482
{
483
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
484
        EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
485
        unsigned char map[] = {0, 1, 2, 3, 4, 5};
486
487
   
488
        /* 
489
         * these have to be here instead of in the SetupProc, because when the
490
         * SetupProc is run at server startup, screenInfo is not setup yet
491
         */
492
493
        ScrnInfoPtr   pScrn = xf86Screens[priv->screen_num];
494
495
        priv->phys_width = pScrn->currentMode->HDisplay;  /* physical screen resolution */
496
        priv->phys_height = pScrn->currentMode->VDisplay;
497
        priv->screen_width  = pScrn->virtualX;     /* It's the virtual screen size ! */
498
        priv->screen_height = pScrn->virtualY;
499
        priv->pViewPort_X0  = &(pScrn->frameX0);   /* initialize the pointers to the viewport coords */
500
        if ( (priv->screen_width != priv->phys_width) ||
501
             (priv->screen_height != priv->phys_height) ) 
502
              priv->virtual = 1;
503
        else  
504
                priv->virtual = 0;
505
506
        priv->pViewPort_Y0  = &(pScrn->frameY0);
507
        priv->pViewPort_X1  = &(pScrn->frameX1);
508
        priv->pViewPort_Y1  = &(pScrn->frameY1);
509
510
        DBGOUT(2, "EVTouch: DeviceInit\n");
511
        DBGOUT(2, "EVTouch: Display X,Y: %d %d\n", priv->phys_width, priv->phys_height);
512
        DBGOUT(2, "EVTouch: Virtual X,Y: %d %d\n", priv->screen_width, priv->screen_height);
513
        DBGOUT(2, "EVTouch: DriverName, Rev.: %s %d\n", pScrn->driverName, pScrn->driverVersion);
514
        DBGOUT(2, "EVTouch: Viewport X0,Y0: %d %d\n", *priv->pViewPort_X0, *priv->pViewPort_Y0);
515
        DBGOUT(2, "EVTouch: Viewport X1,Y1: %d %d\n", *priv->pViewPort_X1, *priv->pViewPort_Y1);
516
        DBGOUT(2, "EVTouch: MaxValue H,V: %d %d\n", pScrn->maxHValue, pScrn->maxVValue);
517
518
519
520
        priv->screen_width = screenInfo.screens[priv->screen_num]->width;
521
        priv->screen_height = screenInfo.screens[priv->screen_num]->height;
522
523
524
        if (InitPtrFeedbackClassDeviceStruct((DeviceIntPtr) dev, 
525
                                             ControlProc) == FALSE) 
526
        {
527
                ErrorF("Unable to init ptr feedback for EVTouch\n");
528
                return !Success;
529
        }
530
531
        /* 
532
         * Device reports button press for 5 buttons.
533
         */
534
        if (InitButtonClassDeviceStruct (dev, 5, map) == FALSE)
535
        {
536
                ErrorF("Unable to allocate EVTouch touchscreen ButtonClassDeviceStruct\n");
537
                return !Success;
538
        }
539
540
        if (InitFocusClassDeviceStruct(dev) == FALSE) {
541
                ErrorF("Unable to allocate EVTouch touchscreen FocusClassDeviceStruct\n");
542
                return !Success;
543
        }
544
545
        /* 
546
         * Device reports motions on 2 axes in absolute coordinates.
547
         * Axes min and max values are reported in raw coordinates.
548
         */
549
        if (InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents,
550
                                          local->history_size, Absolute) == FALSE)
551
        {
552
                ErrorF ("Unable to allocate EVTouch touchscreen ValuatorClassDeviceStruct\n");
553
                return !Success;
554
        }
555
        else
556
        {
557
                InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
558
                                        1024,
559
                                        EV_AXIS_MIN_RES /* min_res */ ,
560
                                        EV_AXIS_MAX_RES /* max_res */ );
561
                InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
562
                                        1024,
563
                                        EV_AXIS_MIN_RES /* min_res */ ,
564
                                        EV_AXIS_MAX_RES /* max_res */ );
565
        }
566
567
        /* Initial position of pointer on screen: Centered */
568
        priv->cur_x=(priv->max_x - priv->min_x)/2;
569
        priv->cur_y=(priv->max_y - priv->min_y)/2;
570
        libtouchSetPos(priv->libtouch, priv->cur_x, priv->cur_y);
571
572
        
573
        if (InitProximityClassDeviceStruct (dev) == FALSE)
574
        {
575
                ErrorF ("Unable to allocate EVTouch touchscreen ProximityClassDeviceStruct\n");
576
                return !Success;
577
        }
578
579
        /* 
580
         * Allocate the motion events buffer.
581
         */
582
        xf86MotionHistoryAllocate (local);
583
584
585
        return (Success);
586
}
587
588
589
590
591
static Bool
592
DeviceControl (DeviceIntPtr dev,
593
               int mode)
594
{
595
        Bool        RetValue;
596
597
        switch (mode)
598
        {
599
        case DEVICE_INIT:
600
                DeviceInit(dev);
601
                RetValue = Success;
602
                break;
603
        case DEVICE_ON:
604
                RetValue = DeviceOn(dev);
605
                break;
606
        case DEVICE_OFF:
607
        case DEVICE_CLOSE:
608
                RetValue = DeviceOff(dev);
609
                break;
610
        default:
611
                RetValue = BadValue;
612
        }
613
614
        return( RetValue );
615
}
616
617
618
619
620
static void
621
EVTouchNewPacket (EVTouchPrivatePtr priv)
622
{
623
        xf86memset(&priv->ev, 0, sizeof(struct input_event));
624
        priv->packeti = 0;
625
        priv->binary_pkt = FALSE;
626
}
627
628
629
630
631
static unsigned char
632
EVTouchRead(EVTouchPrivatePtr priv)
633
{
634
        unsigned char c;
635
        XisbBlockDuration (priv->buffer, EV_TIMEOUT);
636
        c = XisbRead(priv->buffer);
637
        return (c);
638
}
639
640
641
642
static Bool
643
EVTouchGetPacket (EVTouchPrivatePtr priv)
644
{
645
        static int count = 0;
646
        int c;
647
	CARD32 now;
648
649
        if (count==0) EVTouchNewPacket(priv);
650
651
        while ((c = XisbRead(priv->buffer)) >= 0) {
652
	        if (count == 0) {
653
		        now = GetTimeInMillis();
654
		        libtouchSetTime(priv->libtouch, now);
655
	        }
656
657
                ((char *)&priv->ev)[count] = c;
658
                count ++;
659
660
                if (sizeof(priv->ev) == count) {
661
                        count = 0;
662
                        EVTouchDumpPacketToLog(priv);
663
                        
664
                        return Success;
665
                }
666
        }
667
        return (!Success);
668
}
669
670
671
672
673
static void ReadInput (LocalDevicePtr local)
674
{
675
        struct input_event *ev; /* packet being/just read */
676
677
        EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
678
679
680
        /* 
681
         * set blocking to -1 on the first call because we know there is data to
682
         * read. Xisb automatically clears it after one successful read so that
683
         * succeeding reads are preceeded buy a select with a 0 timeout to prevent
684
         * read from blocking infinately.
685
         */
686
        XisbBlockDuration (priv->buffer, -1);
687
        while (EVTouchGetPacket (priv) == Success)
688
        {
689
                ev = &priv->ev;
690
691
                xf86XInputSetScreen(local, 
692
                                    priv->screen_num, 
693
                                    priv->cur_x, 
694
                                    priv->cur_y);
695
                
696
                xf86PostProximityEvent(local->dev, 1, 0, 2, 
697
                                       priv->cur_x, 
698
                                       priv->cur_y);
699
700
                priv->old_x = priv->cur_x;
701
                priv->old_y = priv->cur_y;
702
                switch (ev->type) {
703
                case EV_ABS:
704
                        EVTouchProcessAbs(priv);
705
                        break;
706
                case EV_REL:
707
                        EVTouchProcessRel(priv);
708
                        break;
709
		case EV_KEY:
710
			if (priv->ev.code == BTN_TOUCH) {
711
				if (priv->ev.value == 1) {
712
					priv->touch_flags |= TOUCHED;
713
					DBGOUT(2, "EVTouch: TOUCHED\n");
714
				}
715
				else {
716
					priv->touch_flags &= ~TOUCHED;
717
					DBGOUT(2, "EVTouch: UNTOUCHED\n");
718
				}
719
			}
720
			break;
721
		case EV_SYN:
722
			if ( priv->touch_flags & TOUCHED )
723
				libtouchTriggerSM(priv->libtouch, PEN_TOUCHED);
724
			else
725
				libtouchTriggerSM(priv->libtouch, PEN_UNTOUCHED);
726
                        break;
727
                }
728
729
                DBGOUT( 2, "EVTouch: setting (x/y)=(%d/%d)\n", 
730
                        priv->cur_x, priv->cur_y);
731
732
                /* 
733
                 * Send events.
734
                 *
735
                 * We *must* generate a motion before a button change if pointer
736
                 * location has changed as DIX assumes this. This is why we always
737
                 * emit a motion, regardless of the kind of packet processed.
738
                 */
739
                xf86PostMotionEvent (local->dev, TRUE, 0, 2, 
740
                                     priv->cur_x, 
741
                                     priv->cur_y);
742
743
                if (ev->type == EV_KEY)
744
                        EVTouchProcessKey(priv);
745
746
747
        }
748
}
749
750
751
752
753
static void
754
ControlProc(DeviceIntPtr device, PtrCtrl *ctrl)
755
{
756
        DBGOUT(2, "EVTouch: ControlProc\n");
757
}
758
759
760
761
762
static void
763
CloseProc (LocalDevicePtr local)
764
{
765
        xf86ErrorFVerb(2, "CLOSEPROC\n" );
766
}
767
768
769
770
771
static int
772
SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
773
{
774
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
775
        EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);
776
777
778
        if ((mode == TS_Raw) || (mode == TS_Scaled))
779
        {
780
                priv->reporting_mode = mode;
781
                return (Success);
782
        }
783
        else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents))
784
        {
785
                xf86XInputSetSendCoreEvents (local, (mode == SendCoreEvents));
786
                return (Success);
787
        }
788
        else
789
                return (!Success);
790
}
791
792
793
794
795
static Bool
796
ConvertProc ( LocalDevicePtr local,
797
              int first,
798
              int num,
799
              int v0,
800
              int v1,
801
              int v2,
802
              int v3,
803
              int v4,
804
              int v5,
805
              int *x,
806
              int *y )
807
{
808
        /*
809
          correction factors depending on current position of pointer
810
        */
811
        float cx[3];
812
        float cy[3];
813
        float dx = 0, dy = 0;
814
815
        int max_x, max_y;
816
        int xc, yc;
817
        int screen_width  = 0;
818
        int screen_height = 0;
819
#ifdef EVDBG
820
        int i = 0;
821
#endif
822
823
        EVTouchPrivatePtr priv = (EVTouchPrivatePtr) (local->private);  
824
825
        DBGOUT(2, "FIRST: v0=%d   v1=%d\n", v0, v1);
826
827
        /*correction of raw coordinates*/
828
        if ( (priv->fifo>0) && (priv->calibrate) ){
829
                DBGOUT(2, "writing to FIFO\n");
830
                SYSCALL(write (priv->fifo, &v0, sizeof(v0)));
831
                SYSCALL(write (priv->fifo, &v1, sizeof(v1)));
832
        }
833
834
        if (!priv->calibrate) {
835
                xc = v0 - priv->min_x;
836
                yc = v1 - priv->min_y;
837
        
838
                max_x = priv->max_x - priv->min_x;
839
                max_y = priv->max_y - priv->min_y;
840
841
                if (priv->rotate == EV_ROTATE_NONE) {
842
                        screen_width  = priv->phys_width;
843
                        screen_height = priv->phys_height;
844
                } else {
845
                        screen_width  = priv->phys_height;
846
                        screen_height = priv->phys_width;
847
                }
848
849
850
                if (xc < (max_x / 2)) {
851
                        /*
852
                          left
853
                        */
854
                        if (yc>(max_y / 2)) {
855
                                /*
856
                                  upper
857
                                */
858
                                cx[1] = ((float) xc / (max_x / 2) );
859
                                cx[0] = (float) 1 - cx[1];
860
                                cy[0] = ((float) (yc-(max_y/2)) / (max_y/2) );
861
                                cy[1] = (float) 1 - cy[0];
862
863
                                dx = ((float) (cx[1] * cy[0] * priv->diff[1][0]) +
864
                                      (float)(cx[0] * cy[0] * priv->diff[0][0]) +
865
                                      (float)(cx[1] * cy[1] * priv->diff[4][0]) +
866
                                      (float)(cx[0] * cy[1] * priv->diff[3][0]));
867
                                
868
                                dy = ((float) (cx[1] * cy[0] * priv->diff[1][1]) +
869
                                      (float)(cx[0] * cy[0] * priv->diff[0][1]) +
870
                                      (float)(cx[1] * cy[1] * priv->diff[4][1]) +
871
                                      (float)(cx[0] * cy[1] * priv->diff[3][1]));
872
                        }
873
                        else {
874
                                /*
875
                                  lower
876
                                */
877
                                cx[1] = ((float) xc / (max_x/2) );
878
                                cx[0] = (float) 1 - cx[1];
879
                                cy[0] = ((float) yc / (max_y/2) );
880
                                cy[1] = (float) 1 - cy[0];
881
882
                                dx = ((float) (cx[1] * cy[0] * priv->diff[4][0]) +
883
                                      (float)(cx[0] * cy[0] * priv->diff[3][0]) +
884
                                      (float)(cx[1] * cy[1] * priv->diff[7][0]) +
885
                                      (float)(cx[0] * cy[1] * priv->diff[6][0]));
886
                                
887
                                dy = ((float) (cx[1] * cy[0] * priv->diff[4][1]) +
888
                                      (float)(cx[0] * cy[0] * priv->diff[3][1]) +
889
                                      (float)(cx[1] * cy[1] * priv->diff[7][1]) +
890
                                      (float)(cx[0] * cy[1] * priv->diff[6][1]));
891
892
                        }
893
                } else {
894
                        /*
895
                          right
896
                        */
897
                        if (yc>(max_y/2)) {
898
                                /*
899
                                  upper
900
                                */
901
                                cx[1] = ((float) (xc-(max_x/2)) / (max_x/2) );
902
                                cx[0] = (float)1 - cx[1];
903
                                cy[0] = ((float) (yc-(max_y/2)) / (max_y/2) );
904
                                cy[1] = (float)1 - cy[0];
905
906
                                dx = ((float) (cx[1] * cy[0] * priv->diff[2][0]) +
907
				      (float)(cx[0] * cy[0] * priv->diff[1][0]) +
908
				      (float)(cx[1] * cy[1] * priv->diff[5][0]) +
909
				      (float)(cx[0] * cy[1] * priv->diff[4][0]));
910
                        
911
                                dy = ((float) (cx[1] * cy[0] * priv->diff[2][1]) +
912
				      (float)(cx[0] * cy[0] * priv->diff[1][1]) +
913
                                      (float)(cx[1] * cy[1] * priv->diff[5][1]) +
914
                                      (float)(cx[0] * cy[1] * priv->diff[4][1]));
915
916
                                DBGOUT(2, "TEST: dx=%f   dy=%f\n", dx, dy);
917
                        } else {
918
                                /*
919
                                  lower
920
                                */
921
                                cx[1] = ((float) (xc-(max_x/2)) / (max_x/2) );
922
                                cx[0] = (float) 1 - cx[1];
923
                                cy[0] = ((float) yc / (max_y/2) );
924
                                cy[1] = (float) 1 - cy[0];
925
926
                                dx = ((float) (cx[1] * cy[0] * priv->diff[5][0]) +
927
                                      (float)(cx[0] * cy[0] * priv->diff[4][0]) +
928
                                      (float)(cx[1] * cy[1] * priv->diff[8][0]) +
929
                                      (float)(cx[0] * cy[1] * priv->diff[7][0]));
930
                                
931
                                dy = ((float) (cx[1] * cy[0] * priv->diff[5][1]) +
932
                                      (float)(cx[0] * cy[0] * priv->diff[4][1]) +
933
                                      (float)(cx[1] * cy[1] * priv->diff[8][1]) +
934
                                      (float)(cx[0] * cy[1] * priv->diff[7][1]));
935
                        }
936
                }
937
938
939
#ifdef EVDBG
940
                for (i=0; i<3; i++) 
941
                        xf86ErrorFVerb(2, "cx[%d]=%f   cy[%d]=%f\n", i, cx[i]
942
                                       ,i, cy[i]);
943
                
944
                DBGOUT(2, "ViewPort_X0=%d   ViewPort_Y0=%d\n", 
945
                    *(priv->pViewPort_X0), 
946
                    *(priv->pViewPort_Y0));
947
                DBGOUT(2, "dx=%f   dy=%f\n", dx, dy);
948
#endif
949
950
                xc = ( ((float)xc / max_x) * screen_width ) + dx;
951
                yc = ( ((float)yc / max_y) * screen_height) + dy;
952
953
                if (priv->swap_y == TRUE)
954
                        yc = screen_height - yc;
955
956
                /* ususally we DON'T swap x -- but if swap_x is 1 
957
                   => go on and swap */
958
                if (priv->swap_x == TRUE)
959
                        xc = screen_width - xc;
960
961
                /* rotation mixes x and y up a bit */
962
                if (priv->rotate == EV_ROTATE_CW) {
963
                        v0 = yc;
964
                        v1 = screen_width - xc;
965
                } else if (priv->rotate == EV_ROTATE_CCW) {
966
                        v0 = screen_height - yc;
967
                        v1 = xc;
968
                } else {
969
                        v0 = xc;
970
                        v1 = yc;
971
                }
972
        }
973
974
        DBGOUT(2, "FINAL: v0=%d   v1=%d\n", v0, v1);
975
976
        *x = v0;
977
        *y = v1;
978
979
        return (TRUE);
980
}
981
982
983
984
985
static Bool
986
QueryHardware (LocalDevicePtr local)
987
{
988
        xf86ErrorFVerb(2, "QUERY HARDWARE\n" );
989
990
        return Success;
991
}
992
993
994
995
996
static InputInfoPtr
997
EVTouchPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
998
{
999
        /* LocalDevicePtr local; */
1000
        InputInfoPtr local;
1001
        EVTouchPrivatePtr priv;
1002
1003
        int i = 0;
1004
        char *s;
1005
        char tmp_str[8];
1006
        int timeo = 0;
1007
1008
        priv = xcalloc (1, sizeof (EVTouchPrivateRec));
1009
        if (!priv)
1010
                return NULL;
1011
1012
        local = xf86AllocateInput(drv, 0);
1013
        if (!local) {
1014
                xfree(priv);
1015
                return NULL;
1016
        }
1017
1018
        local->name = dev->identifier;
1019
        local->type_name = XI_TOUCHSCREEN;
1020
        local->device_control = DeviceControl;
1021
        local->read_input = ReadInput;
1022
        local->control_proc = NULL; /* ControlProc; */
1023
        local->close_proc = CloseProc;
1024
        local->switch_mode = SwitchMode;
1025
        local->conversion_proc = ConvertProc;
1026
        local->reverse_conversion_proc = NULL;
1027
        local->fd = -1;
1028
        local->dev = NULL;
1029
        local->private = priv;
1030
        priv->local = local;
1031
        local->private_flags = 0;
1032
        local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
1033
        local->conf_idev = dev;
1034
1035
        xf86CollectInputOptions(local, default_options, NULL);
1036
1037
        xf86OptionListReport(local->options);
1038
1039
        local->fd = xf86OpenSerial (local->options);
1040
        if (local->fd == -1)
1041
        {
1042
                ErrorF ("EVTouch driver unable to open device\n");
1043
                goto SetupProc_fail;
1044
        }
1045
        xf86ErrorFVerb( 3, "evdev device opened successfully\n" );
1046
1047
	priv->libtouch = xcalloc(1, sizeof(LibTouchRec));
1048
	libtouchInit(priv->libtouch, local);
1049
        priv->calibrate = xf86SetIntOption(local->options, "Calibrate", 0);
1050
        priv->min_x = xf86SetIntOption(local->options, "MinX", 0 );
1051
        priv->max_x = xf86SetIntOption(local->options, "MaxX", EV_SCREEN_WIDTH );
1052
        priv->min_y = xf86SetIntOption(local->options, "MinY", 0 );
1053
        priv->max_y = xf86SetIntOption(local->options, "MaxY", EV_SCREEN_HEIGHT );
1054
        priv->screen_num    = xf86SetIntOption(local->options, "ScreenNumber", 0 );
1055
        priv->button_number = xf86SetIntOption(local->options, "ButtonNumber", 2 );
1056
1057
        priv->emulate3      = xf86SetBoolOption(local->options, "Emulate3Buttons", TRUE);
1058
        priv->emulate3_timeout = xf86SetIntOption(local->options, 
1059
                                                  "Emulate3Timeout", 50);
1060
        priv->buttonless     = xf86SetBoolOption(local->options, "ButtonlessDevice", FALSE);
1061
1062
        debug_level = xf86SetIntOption(local->options, "DebugLevel", 0);
1063
        libtouchSetDebugLevel(debug_level);
1064
1065
        timeo = xf86SetIntOption(local->options, "TapTimer", 90);
1066
        libtouchSetTapTimeo(priv->libtouch, timeo);
1067
1068
        timeo = xf86SetIntOption(local->options, "LongtouchTimer", 160);
1069
        libtouchSetLongtouchTimeo(priv->libtouch, timeo);
1070
1071
        libtouchSetMoveLimit(priv->libtouch, 
1072
                             xf86SetIntOption( local->options, 
1073
                                               "MoveLimit", 180 ));
1074
1075
        priv->rotate     = EV_ROTATE_NONE;
1076
        s = xf86FindOptionValue(local->options, "Rotate");
1077
        if (s) {
1078
                if (xf86NameCmp(s, "CW") == 0) {
1079
                        priv->rotate = EV_ROTATE_CW;                           
1080
                } else if (xf86NameCmp(s, "CCW") == 0 ) {
1081
                        priv->rotate = EV_ROTATE_CCW;
1082
                } 
1083
        }
1084
1085
        if (priv->rotate == EV_ROTATE_NONE) {
1086
                priv->max_rel_x = priv->max_x;
1087
                priv->max_rel_y = priv->max_y;
1088
                priv->min_rel_x = priv->min_x;
1089
                priv->min_rel_y = priv->min_y;             
1090
        } else {
1091
                priv->max_rel_x = priv->max_y;
1092
                priv->max_rel_y = priv->max_x;
1093
                priv->min_rel_x = priv->min_y;
1094
                priv->min_rel_y = priv->min_x;             
1095
        }
1096
1097
        priv->swap_y = xf86SetBoolOption(local->options, "SwapY", FALSE);
1098
        priv->swap_x = xf86SetBoolOption(local->options, "SwapX", FALSE);
1099
1100
        /* 
1101
           get calibration parameters from XF86Config 
1102
        */
1103
        for (i=0; i<9; i++){
1104
                sprintf(tmp_str, "x%d", i);
1105
                priv->diff[i][0] = xf86SetIntOption( local->options,
1106
                                                     tmp_str, 0 );
1107
                sprintf(tmp_str, "y%d", i);
1108
                priv->diff[i][1] = xf86SetIntOption( local->options,
1109
                                                     tmp_str, 0 );
1110
                DBGOUT(2, "(diff[%d][0]/diff[%d][1])=(%d/%d)\n", i, i, 
1111
                    priv->diff[i][0], priv->diff[i][1]);
1112
        }
1113
        
1114
        xf86AlwaysCore(local, TRUE);
1115
1116
        s = xf86FindOptionValue (local->options, "ReportingMode");
1117
        if ((s) && (xf86NameCmp (s, "raw") == 0))
1118
                priv->reporting_mode = TS_Raw;
1119
        else
1120
                priv->reporting_mode = TS_Scaled;
1121
1122
        priv->buffer = XisbNew (local->fd, 200);
1123
        priv->touch_flags = 0;
1124
1125
        DBG (9, XisbTrace (priv->buffer, 1));
1126
1127
        if (QueryHardware(local) != Success)
1128
        {
1129
                ErrorF ("Unable to query/initialize EVTouch hardware.\n");
1130
                goto SetupProc_fail;
1131
        }
1132
1133
        local->history_size = xf86SetIntOption( local->options, "HistorySize", 0 );
1134
1135
        /* prepare to process touch packets */
1136
        EVTouchNewPacket (priv);
1137
1138
        /* 
1139
           if started in calibration-mode:
1140
           - open named pipe 
1141
        */
1142
        if (priv->calibrate) {
1143
                SYSCALL(priv->fifo=open("/tmp/ev_calibrate", O_RDWR, 0));
1144
                if (priv->fifo < 0)
1145
                        xf86ErrorFVerb(2, "open FIFO FAILED\n");
1146
        }
1147
1148
        /* this results in an xstrdup that must be freed later */
1149
        local->name = xf86SetStrOption( local->options, "DeviceName", "EVTouch TouchScreen" );
1150
        xf86ProcessCommonOptions(local, local->options);
1151
        local->flags |= XI86_CONFIGURED;
1152
1153
        if (local->fd != -1)
1154
        { 
1155
                if (priv->buffer)
1156
                {
1157
                        XisbFree(priv->buffer);
1158
                        priv->buffer = NULL;
1159
                }
1160
                xf86CloseSerial(local->fd);
1161
        }
1162
        local->fd = -1;
1163
        return (local);
1164
1165
 SetupProc_fail:
1166
        if ((local) && (local->fd))
1167
                xf86CloseSerial (local->fd);
1168
        if ((local) && (local->name))
1169
                xfree (local->name);
1170
1171
        if ((priv) && (priv->buffer))
1172
                XisbFree (priv->buffer);
1173
        if (priv)
1174
                xfree (priv);
1175
        return (local);
1176
}