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

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/input/citron/citron.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
/* Id: citron.c,v 1.8 2001/03/28 08:24:38 pk Exp $
 
2
 * Copyright (c) 1998  Metro Link Incorporated
 
3
 *
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * the rights to use, cpy, modify, merge, publish, distribute, sublicense,
 
8
 * and/or sell copies of the Software, and to permit persons to whom the
 
9
 * Software is furnished to do so, subject to the following conditions:
 
10
 *
 
11
 * The above copyright notice and this permission notice shall be included in
 
12
 * all copies or substantial portions of the Software.
 
13
 *
 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
17
 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
18
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 
19
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
20
 * SOFTWARE.
 
21
 *
 
22
 * Except as contained in this notice, the name of the Metro Link shall not be
 
23
 * used in advertising or otherwise to promote the sale, use or other dealings
 
24
 * in this Software without prior written authorization from Metro Link.
 
25
 *
 
26
 */
 
27
 
 
28
/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.c,v 1.7 2001/07/02 17:29:20 dawes Exp $ */
 
29
 
 
30
/*
 
31
 * Based, in part, on code with the following copyright notice:
 
32
 *
 
33
 * Copyright 1999-2001 by Thomas Thanner, Citron GmbH, Germany. <support@citron.de>
 
34
 * Copyright 1999-2001 by Peter Kunzmann, Citron GmbH, Germany. <kunzmann@citron.de>
 
35
 *
 
36
 * Permission to use, copy, modify, distribute, and sell this software and its
 
37
 * documentation for any purpose is  hereby granted without fee, provided that
 
38
 * the above copyright notice appear in all copies and that both that copyright
 
39
 * notice and this permission notice appear in supporting documentation, and that
 
40
 * the name of Thomas Thanner and Citron GmbH not be used in advertising or
 
41
 * publicity pertaining to distribution of the software without specific, written
 
42
 * prior permission. Thomas Thanner and Citron GmbH makes no representations about
 
43
 * the suitability of this software for any purpose. It is provided "as is"
 
44
 * without express or implied warranty.
 
45
 *
 
46
 * THOMAS THANNER AND CITRON GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
 
47
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
 
48
 * IN NO EVENT SHALL THOMAS THANNER OR CITRON GMBH BE LIABLE FOR ANY SPECIAL,
 
49
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RSULTING FROM
 
50
 * LOSS OF USE, DATA  OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 
51
 * OR OTHER TORTIOUS  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
52
 * PERFORMANCE OF THIS SOFTWARE.
 
53
 *
 
54
 */
 
55
 
 
56
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
57
 * Citron specific extensions:
 
58
 *
 
59
 * 1) Configuration file entries:
 
60
 *      a) "SleepTime"  Touch idle time in seconds before sleep mode
 
61
 *                      (reduced scanning) is entered.
 
62
 *                        0 = immediately; 65535=never;
 
63
 *                        default=65535
 
64
 *      b) "ActivePWM"  PWM duty cycle during regular operation.
 
65
 *                        default=255
 
66
 *      c) "SleepPWM"   PWM duty cycle during sleep mode.
 
67
 *                        default=255
 
68
 *      d) "ClickMode"  Button click emulation mode;
 
69
 *                        1 = Enter Mode
 
70
 *                        2 = Dual Touch Mode
 
71
 *                        3 = Dual Exit Mode
 
72
 *                        4 = Z-Press Mode
 
73
 *                                                5 = Z-Press Exit Mode
 
74
 *                        default = 1
 
75
 *
 
76
 * 2) Additional modes in SetMode() function:
 
77
 *    (These modes are only activated if the CIT_MODE_EXT macro is defined
 
78
 *     at compile time. Until now the mode values are not defined, yet)
 
79
 *      a) ClickMode_Enter              set the button click emulation mode to 1
 
80
 *      b) ClickMode_Dual               set the button click emulation mode to 2
 
81
 *      c) ClickMode_DualExit   set the button click emulation mode to 3
 
82
 *      d) ClickMode_ZPress             set the button click emulation mode to 4
 
83
 *              e) ClickMode_ZPressExit set the button click emulation mode to 5
 
84
 *
 
85
 *!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
 
86
/*
 
87
 ---------------------------------------------------------------------------
 
88
 Revision history:
 
89
           
 
90
 Ver    Date            Description of changes                                                          Name
 
91
 ---------------------------------------------------------------------------
 
92
 2.03   17.09.00        Reconnect when getting breaks changed, changes
 
93
                                        when powering off the system and reconnecting
 
94
                                        parser for commands from "xcit" added 
 
95
                                        "cit_ParseCommand" to set the variables not
 
96
                                        only on the touch side but also in the priv rec         pk
 
97
 2.04   19.10.00        reconnect enhanced                                                                      pk
 
98
 2.05   27.02.01        QueryHardware enhanced, connection faster                       pk
 
99
 2.06   15.03.01        cit_SetBlockDuration added, cit_Flush modified          pk
 
100
 2.07   16.03.01        The problem that the touch didn't connect to the 
 
101
                                        X-server was a hardware problem
 
102
                                        with the winbond chip (interrupt was dead after
 
103
                                        receiving spurious characters when the touch screen
 
104
                                        is switched on). The SIO has to be reinitialized to
 
105
                                        get rid of that problem.                                                        pk
 
106
 2.08   20.03.01        if cit_GetPacket has an overrun 
 
107
                                        cit_ReinitSerial has to be called, Vmin set to "1"      
 
108
                                        cit_SuperVisionTimer, cit_SetEnterCount added
 
109
                                        debuglevel, entercount(z) from external now poss.
 
110
                                        enter_touched not reset by coord_exit                           pk
 
111
 2.09   25.03.01        enter_touched also reset by press_exit, a new 
 
112
                                        command (SetPWMFreq) for backlight dimming added        pk
 
113
 ============================================================================
 
114
 
 
115
*/
 
116
 
 
117
 
 
118
#define _citron_C_
 
119
#define PK      0
 
120
#define INITT 0         /* Initialisation of touch in first loop */
 
121
 
 
122
 
 
123
#define CITOUCH_VERSION 0x209
 
124
char version[]="Touch Driver V2.09  (c) 1999-2001 Citron GmbH";
 
125
 
 
126
#define CITOUCH_VERSION_MAJOR ((CITOUCH_VERSION >> 8) & 0xf)
 
127
#define CITOUCH_VERSION_MINOR ((CITOUCH_VERSION >> 4) & 0xf)
 
128
#define CITOUCH_VERSION_PATCH ((CITOUCH_VERSION >> 0) & 0xf)
 
129
 
 
130
 
 
131
/*****************************************************************************
 
132
 *      Standard Headers
 
133
 ****************************************************************************/
 
134
 
 
135
#include "misc.h"
 
136
#include "xf86.h"
 
137
#define NEED_XF86_TYPES
 
138
#include "xf86_ansic.h"
 
139
#include "xf86_OSproc.h"
 
140
#include "xf86Xinput.h"
 
141
#include "xisb.h"
 
142
#include "exevents.h"           /* Needed for InitValuator/Proximity stuff*/
 
143
 
 
144
 
 
145
/* #define CIT_TIM      */      /* Enable timer */
 
146
#define CIT_BEEP                /* enable beep feature */
 
147
 
 
148
/*****************************************************************************
 
149
 *      Local Headers
 
150
 ****************************************************************************/
 
151
#include "citron.h"
 
152
 
 
153
/*****************************************************************************
 
154
 *      Variables without includable headers
 
155
 ****************************************************************************/
 
156
 
 
157
/*****************************************************************************
 
158
 *      defines
 
159
 ****************************************************************************/
 
160
#define CIT_DEF_MIN_X   0
 
161
#define CIT_DEF_MAX_X   0xFFFF
 
162
#define CIT_DEF_MIN_Y   0
 
163
#define CIT_DEF_MAX_Y   0xFFFF
 
164
 
 
165
#define CIT_BUFFER_SIZE 1024
 
166
 
 
167
 
 
168
 
 
169
/******************************************************************************
 
170
 * debugging macro
 
171
 *****************************************************************************/
 
172
#ifdef DBG
 
173
#undef DBG
 
174
#endif
 
175
#ifdef DEBUG
 
176
#undef DEBUG
 
177
#endif
 
178
 
 
179
static int      debug_level = 0;
 
180
 
 
181
/*
 
182
 debug is always on, because we can set the debug-level
 
183
 in XF86Config (Option DebugLevel)
 
184
*/
 
185
#define DEBUG
 
186
 
 
187
#ifdef DEBUG
 
188
#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
 
189
#else
 
190
#define DBG(lvl, f)
 
191
#endif
 
192
 
 
193
/* Debugging levels for various routines */
 
194
#define PP      5               /* cit_ProcessPacket */
 
195
#define RI      6               /* cit_ReadInput */
 
196
#define GP      6               /* cit_GetPacket */
 
197
#define DDS 5           /* DDS package */
 
198
#define DC      5               /* cit_DriverComm */
 
199
 
 
200
#define XFREE86_V4
 
201
 
 
202
#ifdef XFREE86_V4
 
203
#define WAIT(t)                                                                                         \
 
204
    err = xf86WaitForInput(-1, ((t) * 1000));                           \
 
205
    if (err == -1) {                                                                            \
 
206
        ErrorF("Citron select error\n");        \
 
207
        return !Success;                                                                                \
 
208
    }
 
209
#else
 
210
#define WAIT(t)                                                                                         \
 
211
    timeout.tv_sec = 0;                                                                         \
 
212
    timeout.tv_usec = (t) * 1000;                                                       \
 
213
    SYSCALL(err = select(0, NULL, NULL, NULL, &timeout));       \
 
214
    if (err == -1) {                                                                            \
 
215
        ErrorF("Citron select error : %s\n", strerror(errno));  \
 
216
        return !Success;                                                                                \
 
217
    }
 
218
#endif
 
219
 
 
220
 
 
221
 
 
222
 
 
223
/*****************************************************************************
 
224
 *      Local Variables
 
225
 ****************************************************************************/
 
226
 
 
227
 
 
228
static InputInfoPtr CitronPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
 
229
 
 
230
 
 
231
InputDriverRec CITRON = {
 
232
        1,
 
233
        "citron",
 
234
        NULL,
 
235
        CitronPreInit,
 
236
        /*CitronUnInit*/ NULL,
 
237
        NULL,
 
238
        0
 
239
};
 
240
 
 
241
#ifdef XFree86LOADER
 
242
 
 
243
 
 
244
/*
 
245
 ***************************************************************************
 
246
 *
 
247
 * Dynamic loading functions
 
248
 *
 
249
 ***************************************************************************
 
250
 */
 
251
 
 
252
 
 
253
static XF86ModuleVersionInfo VersionRec =
 
254
{
 
255
        "citron",                                       /* name of module */
 
256
        MODULEVENDORSTRING,                     /* vendor specific string */
 
257
        MODINFOSTRING1,                         
 
258
        MODINFOSTRING2,
 
259
        XF86_VERSION_CURRENT,           /* Current XFree version */
 
260
        CITOUCH_VERSION_MAJOR,          /* Module-specific major version */
 
261
        CITOUCH_VERSION_MINOR,          /* Module-specific minor version */
 
262
        CITOUCH_VERSION_PATCH,          /* Module-specific patch level */
 
263
        ABI_CLASS_XINPUT,
 
264
        ABI_XINPUT_VERSION,
 
265
        MOD_CLASS_XINPUT,
 
266
        {0, 0, 0, 0}                            /* signature of the version info structure */
 
267
};
 
268
 
 
269
 
 
270
/* ************************************************************************
 
271
 * [SetupProc] --
 
272
 *
 
273
 * called when the module subsection is found in XF86Config
 
274
 *
 
275
 * ************************************************************************/
 
276
 
 
277
static pointer
 
278
SetupProc(      pointer module,
 
279
                        pointer options,
 
280
                        int *errmaj,
 
281
                        int *errmin )
 
282
{
 
283
/*      xf86LoaderReqSymLists(reqSymbols, NULL); */
 
284
        xf86AddInputDriver(&CITRON, module, 0);
 
285
        DBG(5, ErrorF ("%sSetupProc called\n", CI_INFO));
 
286
 
 
287
        return (pointer) 1;
 
288
}
 
289
 
 
290
/*****************************************************************************
 
291
 *      [TearDownProc]
 
292
 ****************************************************************************/
 
293
static void
 
294
TearDownProc (pointer p)
 
295
{
 
296
        DBG(5, ErrorF ("%sTearDownProc Called\n", CI_INFO));
 
297
}
 
298
 
 
299
 
 
300
XF86ModuleData citronModuleData = { &VersionRec, SetupProc, TearDownProc};
 
301
 
 
302
#endif /* XFree86LOADER */
 
303
 
 
304
 
 
305
 
 
306
 
 
307
 
 
308
/*
 
309
 * Be sure to set vmin appropriately for your device's protocol. You want to
 
310
 * read a full packet before returning
 
311
 */
 
312
static const char *default_options[] =
 
313
{
 
314
 
 
315
        "BaudRate",     "19200",
 
316
        "StopBits",     "1",
 
317
        "DataBits",     "8",
 
318
        "Parity",               "None",
 
319
/*
 
320
  In non-canonical input processing mode, input is not assembled into
 
321
  lines and input processing (erase, kill, delete, etc.) does not occur.
 
322
  Two parameters control the behavior of this mode: c_cc[VTIME] sets the
 
323
  character timer, and c_cc[VMIN] sets the minimum number of characters
 
324
  to receive before satisfying the read.
 
325
 
 
326
  If MIN > 0 and TIME = 0, MIN sets the number of characters to receive
 
327
  before the read is satisfied. As TIME is zero, the timer is not used.
 
328
 
 
329
  If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will
 
330
  be satisfied if a single character is read, or TIME is exceeded (t =
 
331
  TIME *0.1 s). If TIME is exceeded, no character will be returned.
 
332
 
 
333
 
 
334
  If MIN > 0 and TIME > 0, TIME serves as an inter-character timer. The
 
335
  read will be satisfied if MIN characters are received, or the time
 
336
  between two characters exceeds TIME. The timer is restarted every time
 
337
  a character is received and only becomes active after the first
 
338
  character has been received.
 
339
 
 
340
  If MIN = 0 and TIME = 0, read will be satisfied immediately. The
 
341
  number of characters currently available, or the number of characters
 
342
  requested will be returned. According to Antonino (see contributions),
 
343
  you could issue a fcntl(fd, F_SETFL, FNDELAY); before reading to get
 
344
  the same result.
 
345
 
 
346
  By modifying newtio.c_cc[VTIME] and newtio.c_cc[VMIN] all modes
 
347
  described above can be tested.
 
348
  (Copied from serial-programming-howto)
 
349
*/
 
350
 
 
351
 
 
352
/*      Vmin was set to 3 (Three characters have to arrive until Read_Input is called).
 
353
        I set it to 1 because of the winbond SIO (maybe the interrupt disappears after 1 character
 
354
        and X waits for another two.
 
355
*/
 
356
 
 
357
        "Vmin",                 "1",    /* blocking read until 1 chars received */
 
358
        "Vtime",                "1",
 
359
        "FlowControl",  "None",
 
360
        "ClearDTR",     ""
 
361
};
 
362
 
 
363
 
 
364
/*****************************************************************************
 
365
 *      Function Definitions
 
366
 ****************************************************************************/
 
367
 
 
368
 
 
369
 
 
370
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
371
/* [xf86CitronFeedback]                                                                                                 */
 
372
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
373
/*  Online driver parameter change                                                                              */
 
374
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
375
 
 
376
static void
 
377
cit_SendtoTouch(DeviceIntPtr dev)
 
378
{
 
379
        LocalDevicePtr          local = (LocalDevicePtr) dev->public.devicePrivate;
 
380
    cit_PrivatePtr              priv  = (cit_PrivatePtr)(local->private);
 
381
        int i,j;
 
382
        unsigned char buf[MAX_BYTES_TO_TRANSFER*2+2];
 
383
 
 
384
        DBG(DDS, ErrorF("%scit_SendtoTouch(numbytes=0x%02X, data[0]=%02x, data[1]=%02x, data[2]=%02x, data[3]=%02x, ...)\n", CI_INFO, priv->dds.numbytes,
 
385
                priv->dds.data[0], priv->dds.data[1], priv->dds.data[2], priv->dds.data[3]));
 
386
 
 
387
        j=0;
 
388
        buf[j++] = CTS_STX;                     /* transmit start of packet     */
 
389
 
 
390
        for(i=0; i<priv->dds.numbytes; i++)
 
391
        {
 
392
                if (priv->dds.data[i] >= CTS_CTRLMIN && priv->dds.data[i] <= CTS_CTRLMAX)
 
393
                {       /* data has to be encoded       */
 
394
                        buf[j++] = CTS_ESC;
 
395
                        buf[j++] = priv->dds.data[i] | CTS_ENCODE;
 
396
                }
 
397
                else buf[j++] = priv->dds.data[i];
 
398
        }
 
399
        buf[j++] = CTS_ETX;             /* end of packet */
 
400
 
 
401
        XisbWrite(priv->buffer, buf, j);
 
402
 
 
403
 
 
404
        for(i=0; i<j; i++)
 
405
        {
 
406
                if(i%16 == 0) DBG(DDS, ErrorF("\n"));
 
407
                DBG(DDS, ErrorF("%02x ",buf[i]));
 
408
        }
 
409
 
 
410
 
 
411
        DBG(DDS, ErrorF("\n"));
 
412
}
 
413
 
 
414
 
 
415
static void
 
416
cit_ParseCommand(DeviceIntPtr dev)
 
417
{
 
418
        LocalDevicePtr          local = (LocalDevicePtr) dev->public.devicePrivate;
 
419
    cit_PrivatePtr              priv  = (cit_PrivatePtr)(local->private);
 
420
        int i;
 
421
 
 
422
        DBG(DDS, ErrorF("%scit_ParseCommand(numbytes=0x%02X, data= ", CI_INFO, priv->dds.numbytes));
 
423
 
 
424
        for(i=0; i<priv->dds.numbytes; i++)
 
425
                DBG(DDS, ErrorF("%02x ", priv->dds.data[i]));
 
426
                
 
427
        DBG(DDS,ErrorF("\n"));
 
428
 
 
429
        switch(priv->dds.data[0]&0xff)
 
430
        {
 
431
                case C_SETPWM:
 
432
                        priv->pwm_active = priv->dds.data[1];
 
433
                        priv->pwm_sleep = priv->dds.data[2];
 
434
                        DBG(DDS, ErrorF("%scit_ParseCommand(PWM Active:%d PWM Sleep:%d \n", CI_INFO, priv->pwm_active, priv->pwm_sleep));
 
435
                break;
 
436
                
 
437
                case C_SETPWMFREQ:
 
438
                        priv->pwm_freq = (int)priv->dds.data[1] | (int)(priv->dds.data[2] << 8);
 
439
                        DBG(DDS, ErrorF("%scit_ParseCommand: PWM Freq:%d\n", CI_INFO, priv->pwm_freq));
 
440
                break;
 
441
                
 
442
                case C_SETSLEEPMODE:
 
443
                        if(priv->dds.data[1] == 0)
 
444
                        {
 
445
                                priv->sleep_time_act = priv->dds.data[2] | (priv->dds.data[3] << 8);
 
446
                        }
 
447
                        DBG(DDS, ErrorF("%scit_ParseCommand: Sleep Time act:%d \n", CI_INFO, priv->sleep_time_act));
 
448
                break;
 
449
                
 
450
                case C_SETDOZEMODE:
 
451
                        if(priv->dds.data[1] == 0)
 
452
                        {
 
453
                                priv->doze_time_act = priv->dds.data[2] | (priv->dds.data[3] << 8);
 
454
                        }
 
455
                        DBG(DDS, ErrorF("%scit_ParseCommand: Doze Time act:%d \n", CI_INFO, priv->doze_time_act));
 
456
                break;
 
457
                
 
458
                case C_SETAREAPRESSURE:
 
459
                        priv->button_threshold = priv->dds.data[1];
 
460
                        DBG(DDS, ErrorF("%scit_ParseCommand: Button Threshold:%d \n", CI_INFO, priv->button_threshold));
 
461
                break;
 
462
                
 
463
                default:
 
464
                        DBG(DDS, ErrorF("%scit_ParseCommand: Command %d not found\n", CI_INFO, priv->dds.data[0]));
 
465
                break;
 
466
 
 
467
        }
 
468
}
 
469
 
 
470
 
 
471
 
 
472
static void
 
473
cit_DriverComm(DeviceIntPtr dev)
 
474
{
 
475
        LocalDevicePtr          local = (LocalDevicePtr) dev->public.devicePrivate;
 
476
    cit_PrivatePtr              priv  = (cit_PrivatePtr)(local->private);
 
477
        int i;
 
478
        unsigned short tmp;
 
479
 
 
480
        DBG(DC, ErrorF("%scit_DriverComm(numbytes=0x%02X, data[1]=%02x, ...)\n", CI_INFO, priv->dds.numbytes, priv->dds.data[1]));
 
481
 
 
482
        i=1;
 
483
        switch(priv->dds.data[i++])     /* command word */
 
484
        {
 
485
                case D_SETCLICKMODE:
 
486
                        priv->click_mode = priv->dds.data[i++];
 
487
                        ErrorF("%sClick Mode: %d\n", CI_INFO, priv->click_mode);
 
488
                        cit_SetEnterCount(priv);        /* set enter_count according to click_mode */
 
489
                break;
 
490
                
 
491
                case D_BEEP:
 
492
                        priv->beep = priv->dds.data[i++];
 
493
                        ErrorF("%sBeep: %s\n", CI_INFO, (priv->beep > 0) ? "activated":"not activated");
 
494
                break;
 
495
                
 
496
                case D_SETBEEP:
 
497
                        priv->press_vol = priv->dds.data[i++];
 
498
                        ErrorF("%sBeep Pressure Volume: %d\n", CI_INFO, priv->press_vol);
 
499
                        tmp = priv->dds.data[i++];
 
500
                        tmp += priv->dds.data[i++] << 8;
 
501
                        priv->press_pitch = tmp;
 
502
                        ErrorF("%sBeep Pressure Pitch: %d\n", CI_INFO, priv->press_pitch);
 
503
                        priv->press_dur = priv->dds.data[i++];
 
504
                        ErrorF("%sBeep Pressure Duration: %d\n", CI_INFO, priv->press_dur);
 
505
                        priv->rel_vol = priv->dds.data[i++];
 
506
                        ErrorF("%sBeep Release Volume: %d\n", CI_INFO, priv->rel_vol);
 
507
                        tmp = priv->dds.data[i++];
 
508
                        tmp += priv->dds.data[i++] << 8;
 
509
                        priv->rel_pitch = tmp;
 
510
                        ErrorF("%sBeep Release Pitch: %d\n", CI_INFO, priv->rel_pitch);
 
511
                        priv->rel_dur = priv->dds.data[i++];
 
512
                        ErrorF("%sBeep Release Duration: %d\n", CI_INFO, priv->rel_dur);
 
513
                break;
 
514
                
 
515
                case D_DEBUG:
 
516
                        debug_level = priv->dds.data[i++];
 
517
                        ErrorF("%sDebug level set to %d \n", CI_INFO, debug_level);
 
518
                break;
 
519
 
 
520
                case D_ENTERCOUNT:
 
521
                        priv->enter_count_no_Z = priv->dds.data[i++];
 
522
                        cit_SetEnterCount(priv);        /* set enter_count according click_mode */
 
523
                        ErrorF("%sEnterCount set to %d \n", CI_INFO, priv->enter_count_no_Z);
 
524
                break;
 
525
 
 
526
                case D_ZENTERCOUNT:
 
527
                        priv->enter_count_Z = priv->dds.data[i++];
 
528
                        cit_SetEnterCount(priv);        /* set enter_count according click_mode */
 
529
                        ErrorF("%sZEnterCount set to %d \n", CI_INFO, priv->enter_count_Z);
 
530
                break;
 
531
                
 
532
                default:
 
533
                        ErrorF("%sNot known command: %d - Get a recent driver\n", CI_WARNING, priv->dds.data[1]);
 
534
                break;          
 
535
        }
 
536
}
 
537
 
 
538
 
 
539
static void
 
540
xf86CitronPrint (int nr, LedCtrl *ctrl)
 
541
{
 
542
        DBG(8, ErrorF("%s------------------------------------------\n", CI_INFO));
 
543
        DBG(8, ErrorF("%sxf86CitronFeedback%d(dev, ctrl)\n", CI_INFO, nr));
 
544
        DBG(8, ErrorF("%s  ctrl->led_values.......:%d [0x%08lX]\n", CI_INFO, ctrl->led_values, ctrl->led_values));
 
545
        DBG(8, ErrorF("%s  ctrl->led_mask.........:%d [0x%08lX]\n", CI_INFO, ctrl->led_mask, ctrl->led_mask));
 
546
        DBG(8, ErrorF("%s  ctrl->id...............:%d\n", CI_INFO, ctrl->id));
 
547
}
 
548
 
 
549
 
 
550
static void 
 
551
xf86CitronFeedback0 (DeviceIntPtr dev, LedCtrl *ctrl)
 
552
{
 
553
        LocalDevicePtr          local = (LocalDevicePtr) dev->public.devicePrivate;
 
554
        cit_PrivatePtr          priv  = (cit_PrivatePtr)(local->private);
 
555
        COMMAND *cmd;
 
556
 
 
557
        DBG(DDS, ErrorF("%sEntering xf86CitronFeedback0()...\n",CI_INFO));
 
558
 
 
559
        cmd = (COMMAND *)&ctrl->led_values;
 
560
 
 
561
        DBG(DDS, ErrorF("%scmd->packet = %d\n", CI_INFO, cmd->packet));
 
562
 
 
563
        
 
564
    if(cmd->packet == 0)                /* test if first packet has come (with number of bytes in first byte) */
 
565
        {
 
566
                if(cmd->par[0] == 0)            /* test if something is to do at all */
 
567
                        return;
 
568
                priv->dds.curbyte = 2;
 
569
                priv->dds.numbytes = cmd->par[0];
 
570
                priv->dds.data[0] =  cmd->par[1];
 
571
                priv->dds.data[1] =  cmd->par[2];
 
572
                priv->dds.packet = 1;
 
573
        }
 
574
    else
 
575
        {
 
576
                if(priv->dds.packet == cmd->packet)
 
577
                {
 
578
                        priv->dds.data[priv->dds.packet*3-1] = cmd->par[0];
 
579
                        priv->dds.data[priv->dds.packet*3] = cmd->par[1];
 
580
                        priv->dds.data[priv->dds.packet*3+1] = cmd->par[2];
 
581
                        priv->dds.packet++;
 
582
                        priv->dds.curbyte += 3;
 
583
                }
 
584
                else
 
585
                        DBG(DDS, ErrorF("%sPacket error: should be %d is %d\n", CI_WARNING, priv->dds.packet, cmd->packet));
 
586
 
 
587
        }
 
588
        DBG(DDS, ErrorF("%snumbytes = %d curbyte=%d\n", CI_INFO, priv->dds.numbytes, priv->dds.curbyte));
 
589
        if(priv->dds.curbyte >= priv->dds.numbytes)
 
590
        {
 
591
                if(priv->dds.data[0] == DRIVCOMM)
 
592
                        cit_DriverComm(dev);                    /* process command in the driver */
 
593
                else
 
594
                {
 
595
                        cit_ParseCommand(dev);                  /* First parse command and set parameters in priv rec */
 
596
                        cit_SendtoTouch(dev);                   /* send message to the touch and execute command there */
 
597
                }
 
598
        }
 
599
 
 
600
        DBG(DDS, ErrorF("%s 1 led_values = %08x\n", CI_INFO, ctrl->led_values));
 
601
        ctrl->led_values = 0x12345678;
 
602
        DBG(DDS, ErrorF("%s 2 led_values = %08x\n", CI_INFO, ctrl->led_values));
 
603
 
 
604
}
 
605
 
 
606
 
 
607
static void
 
608
xf86CitronFeedback1 (DeviceIntPtr dev, LedCtrl *ctrl)
 
609
{
 
610
        static int test = 0;
 
611
        xf86CitronPrint (1, ctrl);
 
612
        ctrl->led_values = 0x8765432;
 
613
        ctrl->led_mask = test++;
 
614
}
 
615
 
 
616
static void
 
617
xf86CitronFeedback2 (DeviceIntPtr dev, LedCtrl *ctrl)
 
618
{
 
619
        xf86CitronPrint (2, ctrl);
 
620
        ctrl->led_values = (unsigned long)GetTimeInMillis();
 
621
        ctrl->led_mask = (unsigned long)GetTimeInMillis()&0xff;
 
622
}
 
623
 
 
624
 
 
625
 
 
626
#if(PK)
 
627
/* Hexdump a number of Words  */
 
628
/* len is number of words to dump */
 
629
static void hexdump (void *ioaddr, int len)
 
630
{
 
631
        int i;
 
632
        unsigned long *ptr = (unsigned long *)ioaddr;
 
633
         
 
634
        ErrorF("  ADDR        0-3       4-7       8-B       C-F\n");
 
635
        ErrorF("---------+-----+----+----+----+----+----+----+----\n");
 
636
 
 
637
        while (len > 0)
 
638
        {
 
639
                ErrorF ("%08X: ", (unsigned long)ptr);
 
640
                                                 
 
641
                for (i=0;i < ( (len>4)?4:len);i++)
 
642
                        ErrorF ("  %08x", *ptr++);
 
643
                ErrorF ("\n");
 
644
                len -= 8;
 
645
        }
 
646
        
 
647
        ErrorF("---------+-----+----+----+----+----+----+----+----\n");
 
648
}
 
649
#endif
 
650
 
 
651
 
 
652
/*****************************************************************************
 
653
 *      [cit_StartTimer]
 
654
 ****************************************************************************/
 
655
 
 
656
static void
 
657
cit_StartTimer(cit_PrivatePtr priv, int nr)
 
658
{
 
659
        priv->timer_ptr[nr] = TimerSet(priv->timer_ptr[nr], 0, priv->timer_val1[nr],
 
660
                         priv->timer_callback[nr], (pointer)priv);
 
661
        DBG(5, ErrorF ("%scit_StartTimer[%d] called PTR=%08x\n", CI_INFO, nr, priv->timer_ptr));
 
662
}
 
663
 
 
664
 
 
665
/*****************************************************************************
 
666
 *      [cit_CloseTimer]
 
667
 ****************************************************************************/
 
668
static void
 
669
cit_CloseTimer(cit_PrivatePtr priv, int nr)
 
670
{
 
671
 
 
672
        DBG(5, ErrorF ("%scit_CloseTimer[%d] called PTR=%08x\n", CI_INFO, nr, priv->timer_ptr));
 
673
        if(priv->timer_ptr[nr])
 
674
        {
 
675
                TimerFree(priv->timer_ptr[nr]);
 
676
                priv->timer_ptr[nr] = NULL;
 
677
        }
 
678
        else
 
679
                DBG(5, ErrorF ("%scit_CloseTimer[%d]: Nothing to close\n", CI_WARNING, nr));
 
680
}
 
681
 
 
682
 
 
683
 
 
684
/*****************************************************************************
 
685
 *      [cit_SuperVisionTimer] If called reset Serial device
 
686
 ****************************************************************************/
 
687
static CARD32
 
688
cit_SuperVisionTimer(OsTimerPtr timer, CARD32 now, pointer arg)
 
689
{
 
690
        cit_PrivatePtr priv = (cit_PrivatePtr) arg;
 
691
    int sigstate;
 
692
 
 
693
        DBG(5, ErrorF ("%scit_SuperVisionTimer called %d\n", CI_INFO, GetTimeInMillis()));
 
694
 
 
695
    sigstate = xf86BlockSIGIO ();
 
696
        
 
697
        cit_ReinitSerial(priv);
 
698
 
 
699
    xf86UnblockSIGIO (sigstate);
 
700
 
 
701
        return (0);     /* stop timer */
 
702
}
 
703
 
 
704
 
 
705
#ifdef CIT_TIM
 
706
 
 
707
/*****************************************************************************
 
708
 *      [cit_DualTouchTimer]
 
709
 ****************************************************************************/
 
710
static CARD32
 
711
cit_DualTouchTimer(OsTimerPtr timer, CARD32 now, pointer arg)
 
712
{
 
713
        cit_PrivatePtr priv = (cit_PrivatePtr) arg;
 
714
    int sigstate;
 
715
 
 
716
        DBG(5, ErrorF ("%scit_DualTouchTimer called %d\n", CI_INFO, GetTimeInMillis()));
 
717
 
 
718
        priv->packet[0] = R_EXIT;       /* build a exit message */
 
719
        priv->packet[1] = LOBYTE(priv->raw_x);
 
720
        priv->packet[2] = HIBYTE(priv->raw_x);
 
721
        priv->packet[3] = LOBYTE(priv->raw_y);
 
722
        priv->packet[4] = HIBYTE(priv->raw_y);
 
723
        priv->packeti = 5;
 
724
        priv->fake_exit = TRUE;
 
725
    sigstate = xf86BlockSIGIO ();
 
726
        
 
727
 
 
728
        priv->local->read_input(priv->local);           /* faking up an exit message */
 
729
    xf86UnblockSIGIO (sigstate);
 
730
 
 
731
        DBG(3, ErrorF ("%scit_DualTouchTimer: Faking Exit Message Sent\n", CI_INFO));
 
732
 
 
733
        return (0);     /* stop timer */
 
734
}
 
735
 
 
736
#endif
 
737
 
 
738
/*****************************************************************************
 
739
 *      [CitronPreInit]
 
740
 ****************************************************************************/
 
741
static InputInfoPtr
 
742
CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags)
 
743
{
 
744
        LocalDevicePtr local = xf86AllocateInput(drv, 0);
 
745
        cit_PrivatePtr priv = (cit_PrivatePtr) xcalloc (1, sizeof (cit_PrivateRec));
 
746
        char *s;
 
747
#if(INITT)
 
748
        int errmaj, errmin;
 
749
#endif
 
750
 
 
751
        ErrorF ("%sCitronPreInit called - xcalloc=%d\n", CI_INFO, sizeof(cit_PrivateRec));
 
752
/*      DBG(2, ErrorF("\txf86Verbose=%d\n", xf86Verbose));*/
 
753
        if ((!local) || (!priv))
 
754
        {
 
755
                ErrorF("%s\t- unable to allocate structures!\n", CI_ERROR);
 
756
                goto SetupProc_fail;
 
757
        }
 
758
 
 
759
        priv->local = local;                            /* save local device pointer */
 
760
 
 
761
 
 
762
        /* this results in an xf86strdup that must be freed later */
 
763
        local->name = xf86SetStrOption(local->options, "DeviceName", "CiTouch");
 
764
        ErrorF("%sDevice name: %s\n", CI_INFO, local->name);
 
765
 
 
766
        local->type_name = XI_TOUCHSCREEN;
 
767
 
 
768
        /*
 
769
         * Standard setup for the local device record
 
770
         */
 
771
        local->device_control = DeviceControl;
 
772
        local->read_input = ReadInput;
 
773
        local->control_proc = ControlProc;
 
774
        local->close_proc = CloseProc;
 
775
        local->switch_mode = SwitchMode;
 
776
        local->conversion_proc = ConvertProc;
 
777
        local->dev = NULL;
 
778
        local->private = priv;
 
779
        local->private_flags = 0;
 
780
        local->history_size = xf86SetIntOption(local->options, "HistorySize", 0);
 
781
        local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
 
782
        local->conf_idev = dev;
 
783
 
 
784
        xf86CollectInputOptions(local, default_options, NULL);
 
785
 
 
786
/*      xf86OptionListReport(local->options); */
 
787
 
 
788
 
 
789
 
 
790
        debug_level = xf86SetIntOption(local->options, "DebugLevel", 0);
 
791
        if(debug_level)
 
792
        {
 
793
#ifdef DEBUG
 
794
            ErrorF("%sDebug level set to %d\n", CI_CONFIG, debug_level);
 
795
#else
 
796
        ErrorF("%sDebug not available\n", CI_INFO);
 
797
#endif
 
798
        }
 
799
 
 
800
 
 
801
#if(INITT)
 
802
 
 
803
 
 
804
        DBG(5, ErrorF ("%sOpenSerial will be called\n", CI_INFO));
 
805
 
 
806
        local->fd = xf86OpenSerial (local->options);
 
807
        if (local->fd == -1)
 
808
        {
 
809
                ErrorF ("%s\t- unable to open device %s\n", CI_ERROR, xf86FindOptionValue (local->options, "Device"));
 
810
                goto SetupProc_fail;
 
811
        }
 
812
 
 
813
        DBG(6, ErrorF("%s\t+ %s opened successfully.\n", CI_INFO, xf86FindOptionValue (local->options, "Device")));
 
814
#endif
 
815
 
 
816
        /* 
 
817
         * Process the options for the IRT
 
818
         */
 
819
        priv->screen_num = xf86SetIntOption(local->options, "ScreenNumber", 0);
 
820
        ErrorF("%sAssociated screen: %d\n", CI_CONFIG, priv->screen_num);
 
821
        priv->min_x = xf86SetIntOption(local->options, "MinX", CIT_DEF_MIN_X);
 
822
        ErrorF("%sMinimum x position: %d\n", CI_CONFIG, priv->min_x);
 
823
        priv->max_x = xf86SetIntOption(local->options, "MaxX", CIT_DEF_MAX_X);
 
824
        ErrorF("%sMaximum x position: %d\n", CI_CONFIG, priv->max_x);
 
825
        priv->min_y = xf86SetIntOption(local->options, "MinY", CIT_DEF_MIN_Y);
 
826
        ErrorF("%sMinimum y position: %d\n", CI_CONFIG, priv->min_y);
 
827
        priv->max_y = xf86SetIntOption(local->options, "MaxY", CIT_DEF_MAX_Y);
 
828
        ErrorF("%sMaximum y position: %d\n", CI_CONFIG, priv->max_y);
 
829
        priv->button_number = xf86SetIntOption(local->options, "ButtonNumber", 1);
 
830
        ErrorF("%sButton Number: %d\n", CI_CONFIG, priv->button_number);
 
831
        priv->button_threshold = xf86SetIntOption(local->options, "ButtonThreshold", 10);
 
832
        ErrorF("%sButton Threshold: %d\n", CI_CONFIG, priv->button_threshold);
 
833
        priv->sleep_mode = xf86SetIntOption(local->options, "SleepMode", 0);
 
834
        ErrorF("%sSleep Mode: %d\n", CI_CONFIG, priv->sleep_mode);
 
835
        priv->sleep_time_act = xf86SetIntOption(local->options, "SleepTime", 65535);
 
836
        ErrorF("%sSleep Time: %d\n", CI_CONFIG, priv->sleep_time_act);
 
837
        priv->sleep_time_scan = xf86SetIntOption(local->options, "SleepScan", 65535);
 
838
        ErrorF("%sSleep Scan: %d\n", CI_CONFIG, priv->sleep_time_scan);
 
839
        priv->pwm_active = xf86SetIntOption(local->options, "PWMActive", 255);
 
840
        ErrorF("%sPWM Active: %d\n", CI_CONFIG, priv->pwm_active);
 
841
        priv->pwm_sleep = xf86SetIntOption(local->options, "PWMSleep", 255);
 
842
        ErrorF("%sPWM Sleep: %d\n", CI_CONFIG, priv->pwm_sleep);
 
843
        priv->click_mode = xf86SetIntOption(local->options, "ClickMode", NO_CLICK_MODE);
 
844
        ErrorF("%sClick Mode: %d\n", CI_CONFIG, priv->click_mode);
 
845
        priv->origin = xf86SetIntOption(local->options, "Origin", 0);
 
846
        ErrorF("%sOrigin: %d\n", CI_CONFIG, priv->origin);
 
847
        priv->doze_mode = xf86SetIntOption(local->options, "DozeMode", 0);
 
848
        ErrorF("%sDoze Mode: %d\n", CI_CONFIG, priv->doze_mode);
 
849
        priv->doze_time_act = xf86SetIntOption(local->options, "DozeTime", 10);
 
850
        ErrorF("%sDoze Time: %d\n", CI_CONFIG, priv->doze_time_act);
 
851
        priv->doze_time_scan = xf86SetIntOption(local->options, "DozeScan", 25);
 
852
        ErrorF("%sDoze Scan: %d\n", CI_CONFIG, priv->doze_time_scan);
 
853
        priv->delta_x = xf86SetIntOption(local->options, "DeltaX", 0) & 0xff;
 
854
        ErrorF("%sDelta X: %d\n", CI_CONFIG, priv->delta_x);
 
855
        priv->delta_y = xf86SetIntOption(local->options, "DeltaY", 0) & 0xff;
 
856
        ErrorF("%sDelta Y: %d\n", CI_CONFIG, priv->delta_y);
 
857
        priv->beep = xf86SetIntOption(local->options, "Beep", 0);
 
858
        ErrorF("%sBeep: %s\n", CI_CONFIG, (priv->beep > 0) ? "activated":"not activated");
 
859
        priv->press_vol = xf86SetIntOption(local->options, "PressVol", 100);
 
860
        ErrorF("%sBeep Pressure Volume: %d\n", CI_CONFIG, priv->press_vol);
 
861
        priv->press_pitch = xf86SetIntOption(local->options, "PressPitch", 880);
 
862
        ErrorF("%sBeep Pressure Pitch: %d\n", CI_CONFIG, priv->press_pitch);
 
863
        priv->press_dur = xf86SetIntOption(local->options, "PressDur", 15) & 0xff;
 
864
        ErrorF("%sBeep Pressure Duration: %d\n", CI_CONFIG, priv->press_dur);
 
865
        priv->rel_vol = xf86SetIntOption(local->options, "ReleaseVol", 100);
 
866
        ErrorF("%sBeep Release Volume: %d\n", CI_CONFIG, priv->rel_vol);
 
867
        priv->rel_pitch = xf86SetIntOption(local->options, "ReleasePitch", 1200);
 
868
        ErrorF("%sBeep Release Pitch: %d\n", CI_CONFIG, priv->rel_pitch);
 
869
        priv->rel_dur = xf86SetIntOption(local->options, "ReleaseDur", 10) & 0xff;
 
870
        ErrorF("%sBeep Release Duration: %d\n", CI_CONFIG, priv->rel_dur);
 
871
        priv->beam_timeout = xf86SetIntOption(local->options, "BeamTimeout", 30) & 0xffff;
 
872
        ErrorF("%sBeam Timeout: %d\n", CI_CONFIG, priv->beam_timeout);
 
873
        priv->touch_time = xf86SetIntOption(local->options, "TouchTime", 0) & 0xff;
 
874
        ErrorF("%sTouch Time: %d\n", CI_CONFIG, priv->touch_time);
 
875
        priv->max_dual_count = xf86SetIntOption(local->options, "DualCount", MAX_DUAL_TOUCH_COUNT);
 
876
        ErrorF("%sDual Count: %d\n", CI_CONFIG, priv->max_dual_count);
 
877
        priv->enter_count_no_Z = xf86SetIntOption(priv->local->options, "EnterCount", 3);
 
878
        ErrorF("%sEnterCount: %d\n", CI_CONFIG, priv->enter_count_no_Z);
 
879
        priv->enter_count_Z = xf86SetIntOption(priv->local->options, "ZEnterCount", 2);
 
880
        ErrorF("%sZEnterCount: %d\n", CI_CONFIG, priv->enter_count_Z);
 
881
        priv->pwm_freq = xf86SetIntOption(priv->local->options, "PWMFreq", -1);
 
882
        ErrorF("%sPWMFreq: %d\n", CI_CONFIG, priv->pwm_freq);
 
883
 
 
884
        cit_SetEnterCount(priv);        /* set enter_count according click_mode */
 
885
 
 
886
/* trace the min and max values */
 
887
        priv->raw_min_x = CIT_DEF_MAX_X;
 
888
        priv->raw_max_x = 0;
 
889
        priv->raw_min_y = CIT_DEF_MAX_Y;
 
890
        priv->raw_max_y = 0;
 
891
 
 
892
#ifdef CIT_TIM
 
893
/* preset timer values */
 
894
        priv->timer_ptr[FAKE_TIMER] = NULL;
 
895
        priv->timer_val1[FAKE_TIMER] = 0;
 
896
        priv->timer_val2[FAKE_TIMER] = 0;
 
897
        priv->timer_callback[FAKE_TIMER] = NULL;
 
898
#endif
 
899
        priv->timer_ptr[SV_TIMER] = NULL;
 
900
        priv->timer_val1[SV_TIMER] = 0;
 
901
        priv->timer_val2[SV_TIMER] = 0;
 
902
        priv->timer_callback[SV_TIMER] = NULL;
 
903
 
 
904
        priv->fake_exit = FALSE;
 
905
        priv->enter_touched = 0;                        /* preset */
 
906
 
 
907
        DBG(6, ErrorF("%s\t+ options read\n", CI_INFO));
 
908
        s = xf86FindOptionValue (local->options, "ReportingMode");
 
909
        if ((s) && (xf86NameCmp (s, "raw") == 0))
 
910
                priv->reporting_mode = TS_Raw;
 
911
        else
 
912
                priv->reporting_mode = TS_Scaled;
 
913
 
 
914
#if(INITT)
 
915
        /* 
 
916
         * Create an X Input Serial Buffer, because IRT is connected to a serial port
 
917
         */
 
918
        priv->buffer = XisbNew (local->fd, CIT_BUFFER_SIZE);
 
919
#endif
 
920
        priv->proximity = FALSE;
 
921
        priv->button_down = FALSE;
 
922
        priv->dual_touch_count = 0;
 
923
        priv->dual_flg = 0;
 
924
        priv->state = 0;
 
925
        priv->lex_mode = cit_idle;
 
926
        priv->last_x = 0;
 
927
        priv->last_y = 0;
 
928
        priv->query_state = 0;  /* first query */
 
929
 
 
930
 
 
931
#if(INITT)
 
932
        DBG (8, XisbTrace (priv->buffer, 1));
 
933
 
 
934
 
 
935
        /* 
 
936
         * Verify that the IRT is attached and functional
 
937
         */
 
938
        if (QueryHardware (local, &errmaj, &errmin) != Success)
 
939
        {
 
940
                ErrorF ("%s\t- Unable to query/initialize Citron hardware.\n", CI_INFO);
 
941
                goto SetupProc_fail;
 
942
        }
 
943
#endif
 
944
 
 
945
        xf86ProcessCommonOptions(local, local->options);
 
946
        local->flags |= XI86_CONFIGURED;
 
947
#if(PK)
 
948
        if (xf86FindOption (local->options, "DemandLoaded"))
 
949
        {
 
950
                DBG (5, ErrorF ("%s\tCitron module was demand loaded\n", CI_INFO));
 
951
                xf86AddLocalDevice (local, TRUE);
 
952
        }
 
953
        else
 
954
                xf86AddLocalDevice (local, FALSE);
 
955
#endif
 
956
 
 
957
        if (local->fd >= 0)
 
958
        {
 
959
                RemoveEnabledDevice (local->fd);
 
960
#if(INITT)
 
961
                if (priv->buffer)
 
962
                {
 
963
                        XisbFree(priv->buffer);
 
964
                        priv->buffer = NULL;
 
965
                }
 
966
                xf86CloseSerial(local->fd);
 
967
                local->fd = 0;
 
968
                
 
969
#endif
 
970
        }
 
971
 
 
972
 
 
973
        /* return the LocalDevice */
 
974
        DBG(5, ErrorF ("%sCitronPreInit success\n", CI_INFO));
 
975
        return (local);
 
976
 
 
977
 
 
978
        /*
 
979
         * If something went wrong, cleanup and return NULL
 
980
         */
 
981
  SetupProc_fail:
 
982
#if(INITT)
 
983
        if ((local) && (local->fd))
 
984
        {
 
985
                xf86CloseSerial (local->fd);
 
986
                local->fd = 0;
 
987
        }
 
988
#endif
 
989
        if ((local) && (local->name))
 
990
                xfree (local->name);
 
991
        if (local)
 
992
                xfree (local);
 
993
#if(INITT)
 
994
        if ((priv) && (priv->buffer))
 
995
                XisbFree (priv->buffer);
 
996
#endif
 
997
        if (priv)
 
998
                xfree (priv);
 
999
        ErrorF ("%sCitronPreInit returning NULL\n", CI_ERROR);
 
1000
        return (NULL);
 
1001
}
 
1002
 
 
1003
 
 
1004
 
 
1005
/*****************************************************************************
 
1006
 *      [DeviceControl]
 
1007
 ****************************************************************************/
 
1008
static Bool
 
1009
DeviceControl (DeviceIntPtr dev, int mode)
 
1010
{
 
1011
        Bool RetVal;
 
1012
 
 
1013
        DBG(5, ErrorF ("%sDeviceControl called; mode = %d\n", CI_INFO, mode));
 
1014
        switch (mode)
 
1015
        {
 
1016
        case DEVICE_INIT:
 
1017
                DBG(6, ErrorF ("%s\tINIT\n", CI_INFO));
 
1018
                DeviceInit (dev);
 
1019
                RetVal = Success;
 
1020
                break;
 
1021
        case DEVICE_ON:
 
1022
                DBG(6, ErrorF ("%s\tON\n", CI_INFO));
 
1023
                RetVal = DeviceOn (dev);
 
1024
                break;
 
1025
        case DEVICE_OFF:
 
1026
                DBG(6, ErrorF ("%s\tOFF\n", CI_INFO));
 
1027
                RetVal = DeviceOff (dev);
 
1028
                break;
 
1029
        case DEVICE_CLOSE:
 
1030
                DBG(6, ErrorF ("%s\tCLOSE\n", CI_INFO));
 
1031
                RetVal = DeviceClose (dev);
 
1032
                break;
 
1033
        default:
 
1034
                ErrorF ("%sDeviceControl Mode (%d) not found\n", CI_ERROR, mode);
 
1035
                RetVal = BadValue;
 
1036
        }
 
1037
        DBG(2, ErrorF ("%sDeviceControl: RetVal = %d\n", CI_INFO, RetVal));
 
1038
        return(RetVal);
 
1039
}
 
1040
 
 
1041
/*****************************************************************************
 
1042
 *      [DeviceOn]
 
1043
 ****************************************************************************/
 
1044
static Bool
 
1045
DeviceOn (DeviceIntPtr dev)
 
1046
{
 
1047
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
 
1048
        cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
 
1049
        int errmaj, errmin;
 
1050
 
 
1051
        DBG(5, ErrorF ("%sDeviceOn called\n", CI_INFO));
 
1052
 
 
1053
        local->fd = xf86OpenSerial(local->options);
 
1054
        if (local->fd == -1)
 
1055
        {
 
1056
                DBG(5, ErrorF("%s%s: cannot open input device\n", CI_ERROR, local->name));
 
1057
                goto DeviceOn_fail;
 
1058
        }
 
1059
        priv->buffer = XisbNew (local->fd, CIT_BUFFER_SIZE);
 
1060
        if (!priv->buffer)
 
1061
                goto DeviceOn_fail;
 
1062
 
 
1063
        xf86FlushInput(local->fd);
 
1064
 
 
1065
        cit_SendCommand(priv->buffer, C_SOFTRESET, 0);  /* Make a Reset in case of a connected touch */
 
1066
 
 
1067
        if (QueryHardware (local, &errmaj, &errmin) != Success)
 
1068
        {
 
1069
                ErrorF ("%s\t- DeviceOn: Unable to query/initialize hardware.\n", CI_ERROR);
 
1070
                goto DeviceOn_fail;
 
1071
        }
 
1072
 
 
1073
        AddEnabledDevice(local->fd);
 
1074
        dev->public.on = TRUE;
 
1075
        DBG(5, ErrorF ("%sDeviceOn Success\n", CI_INFO));
 
1076
        return (Success);
 
1077
 
 
1078
        /*
 
1079
         * If something went wrong, cleanup
 
1080
         */
 
1081
  DeviceOn_fail:
 
1082
 
 
1083
        if ((local) && (local->fd))
 
1084
        {
 
1085
                xf86CloseSerial (local->fd);
 
1086
                local->fd = 0;
 
1087
        }
 
1088
 
 
1089
        if ((local) && (local->name))
 
1090
                xfree (local->name);
 
1091
        if (local)
 
1092
        {
 
1093
                xfree (local);
 
1094
                local = NULL;
 
1095
        }
 
1096
        if ((priv) && (priv->buffer))
 
1097
                XisbFree (priv->buffer);
 
1098
        if (priv)
 
1099
        {
 
1100
                xfree (priv);
 
1101
                priv = NULL;
 
1102
        }
 
1103
        ErrorF ("%sDeviceOn failed\n", CI_ERROR);
 
1104
        return (!Success);
 
1105
}
 
1106
 
 
1107
/*****************************************************************************
 
1108
 *      [DeviceOff]
 
1109
 ****************************************************************************/
 
1110
static Bool
 
1111
DeviceOff (DeviceIntPtr dev)
 
1112
{
 
1113
        DBG(5, ErrorF ("%sDeviceOff called\n", CI_INFO));
 
1114
        return DeviceClose(dev);
 
1115
}
 
1116
 
 
1117
/*****************************************************************************
 
1118
 *      [DeviceClose]
 
1119
 ****************************************************************************/
 
1120
static Bool
 
1121
DeviceClose (DeviceIntPtr dev)
 
1122
{
 
1123
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
 
1124
        cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
 
1125
        int c;
 
1126
 
 
1127
        DBG(5, ErrorF ("%sDeviceClose called\n",CI_INFO));
 
1128
 
 
1129
        cit_Flush(priv);
 
1130
 
 
1131
        cit_SendCommand(priv->buffer, C_SOFTRESET, 0);
 
1132
#ifdef CIT_TIM
 
1133
        cit_CloseTimer(priv, FAKE_TIMER);               /* Close timer if started */
 
1134
#endif
 
1135
        cit_CloseTimer(priv, SV_TIMER);                 /* Do not know if it is running, close anyway */
 
1136
 
 
1137
        XisbTrace(priv->buffer, 1); /* trace on */
 
1138
        cit_SetBlockDuration (priv, 500000);
 
1139
        c = XisbRead (priv->buffer);
 
1140
        if(c == CTS_NAK)
 
1141
        {
 
1142
                DBG(6, ErrorF ("%sTouch Reset executed\n",CI_INFO));
 
1143
        }
 
1144
        else
 
1145
        {
 
1146
                DBG(6, ErrorF ("%sTouch Reset not executed\n",CI_ERROR));
 
1147
        }
 
1148
 
 
1149
 
 
1150
/* Now free all allocated memory */
 
1151
        if (local->fd >= 0)
 
1152
        {
 
1153
                RemoveEnabledDevice (local->fd);
 
1154
                if (priv->buffer)
 
1155
                {
 
1156
                        XisbFree(priv->buffer);
 
1157
                        priv->buffer = NULL;
 
1158
                }
 
1159
                xf86CloseSerial(local->fd);
 
1160
                local->fd = 0;
 
1161
        }
 
1162
 
 
1163
        dev->public.on = FALSE;
 
1164
        ErrorF("%sx-range = [%d..%d]\n", CI_INFO, priv->raw_min_x, priv->raw_max_x);
 
1165
        ErrorF("%sy-range = [%d..%d]\n", CI_INFO, priv->raw_min_y, priv->raw_max_y);
 
1166
 
 
1167
        return (Success);
 
1168
}
 
1169
 
 
1170
 
 
1171
/*****************************************************************************
 
1172
 *      [DeviceInit]
 
1173
 ****************************************************************************/
 
1174
static Bool
 
1175
DeviceInit (DeviceIntPtr dev)
 
1176
{
 
1177
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
 
1178
        cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
 
1179
 
 
1180
        unsigned char map[] =
 
1181
        {0, 1};
 
1182
 
 
1183
        DBG (5, ErrorF("%sDeviceInit called\n", CI_INFO));
 
1184
        /* 
 
1185
         * these have to be here instead of in the SetupProc, because when the
 
1186
         * SetupProc is run and server startup, screenInfo is not setup yet
 
1187
         */
 
1188
        priv->screen_width = screenInfo.screens[priv->screen_num]->width;
 
1189
        priv->screen_height = screenInfo.screens[priv->screen_num]->height;
 
1190
 
 
1191
        DBG (5, ErrorF("%sScreen Number: %d Screen Width: %d Screen Height: %d\n", CI_INFO,
 
1192
                                                priv->screen_num, priv->screen_width, priv->screen_height));
 
1193
 
 
1194
        /* 
 
1195
         * Device reports button press for up to 1 button.
 
1196
         */
 
1197
        if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
 
1198
        {
 
1199
                ErrorF ("%sUnable to allocate Citron touchscreen ButtonClassDeviceStruct\n", CI_ERROR);
 
1200
                return !Success;
 
1201
        }
 
1202
 
 
1203
        /* 
 
1204
         * Device reports motions on 2 axes in absolute coordinates.
 
1205
         * Axes min and max values are reported in raw coordinates.
 
1206
         * Resolution is computed roughly by the difference between
 
1207
         * max and min values scaled from the approximate size of the
 
1208
         * screen to fit one meter.
 
1209
         * Device may reports touch pressure on the 3rd axis.
 
1210
         */
 
1211
        if (InitValuatorClassDeviceStruct (dev, 2, xf86GetMotionEvents,
 
1212
                                                                        local->history_size, Absolute) == FALSE)
 
1213
        {
 
1214
                ErrorF ("%sUnable to allocate Citron touchscreen ValuatorClassDeviceStruct\n", CI_ERROR);
 
1215
                return !Success;
 
1216
        }
 
1217
        else
 
1218
        {
 
1219
                InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
 
1220
                                                                CIT_DEF_MAX_X,
 
1221
                                                                CIT_DEF_MIN_X /* min_res */ ,
 
1222
                                                                CIT_DEF_MAX_X /* max_res */ );
 
1223
                InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
 
1224
                                                                CIT_DEF_MAX_Y,
 
1225
                                                                CIT_DEF_MIN_Y /* min_res */ ,
 
1226
                                                                CIT_DEF_MAX_Y /* max_res */ );
 
1227
        }
 
1228
 
 
1229
        if (InitProximityClassDeviceStruct (dev) == FALSE)
 
1230
        {
 
1231
                ErrorF ("%sUnable to allocate Citron touchscreen ProximityClassDeviceStruct\n", CI_ERROR);
 
1232
                return !Success;
 
1233
        }
 
1234
 
 
1235
 
 
1236
        /*
 
1237
         * Use the LedFeedbackClass to set some driver parameters
 
1238
         */
 
1239
 
 
1240
        /* ID=0 --> Return driver version (RO) */
 
1241
        
 
1242
        if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback0) == FALSE)
 
1243
        {
 
1244
                ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=0\n");
 
1245
                return !Success;
 
1246
        }
 
1247
        /* ID=1 --> ENTER_COUNT  */
 
1248
        if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback1) == FALSE)
 
1249
        {
 
1250
                ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=1\n");
 
1251
                return !Success;
 
1252
        }
 
1253
        
 
1254
        /* ID=2 -->   */
 
1255
        if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback2) == FALSE)
 
1256
        {
 
1257
                ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=2\n");
 
1258
                return !Success;
 
1259
        }
 
1260
 
 
1261
 
 
1262
        /*
 
1263
         * Allocate the motion events buffer.
 
1264
         */
 
1265
        xf86MotionHistoryAllocate (local);
 
1266
        return (Success);
 
1267
}
 
1268
 
 
1269
/*****************************************************************************
 
1270
 *      [ReadInput]
 
1271
 ****************************************************************************/
 
1272
static void
 
1273
ReadInput (LocalDevicePtr local)
 
1274
{
 
1275
        int x, y;
 
1276
        cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
 
1277
 
 
1278
        DBG(RI, ErrorF("%sReadInput called\n", CI_INFO));
 
1279
 
 
1280
        /* 
 
1281
         * set blocking to -1 on the first call because we know there is data to
 
1282
         * read. Xisb automatically clears it after one successful read so that
 
1283
         * succeeding reads are preceeded by a select with a 0 timeout to prevent
 
1284
         * read from blocking indefinately.
 
1285
         */
 
1286
        if(!priv->fake_exit)
 
1287
        {
 
1288
                cit_SetBlockDuration (priv, -1);
 
1289
        }
 
1290
        while (
 
1291
#ifdef CIT_TIM
 
1292
                        priv->fake_exit ||
 
1293
#endif
 
1294
                        (cit_GetPacket (priv) == Success))
 
1295
        {
 
1296
                cit_ProcessPacket(priv);
 
1297
 
 
1298
 
 
1299
 
 
1300
                if (priv->reporting_mode == TS_Scaled)
 
1301
                {
 
1302
                        x = xf86ScaleAxis (priv->raw_x, 0, priv->screen_width, priv->min_x,
 
1303
                                                           priv->max_x);
 
1304
                        y = xf86ScaleAxis (priv->raw_y, 0, priv->screen_height, priv->min_y,
 
1305
                                                           priv->max_y);
 
1306
                        DBG(RI, ErrorF("%s\tscaled coordinates: (%d, %d)\n", CI_INFO, x, y));
 
1307
                }
 
1308
                else
 
1309
                {
 
1310
                        x = priv->raw_x;
 
1311
                        y = priv->raw_y;
 
1312
                }
 
1313
 
 
1314
                xf86XInputSetScreen (local, priv->screen_num, x, y);
 
1315
 
 
1316
                if ((priv->proximity == FALSE) && (priv->state & CIT_TOUCHED))
 
1317
                {
 
1318
                        priv->proximity = TRUE;
 
1319
                        xf86PostProximityEvent (local->dev, 1, 0, 2, x, y);
 
1320
                        DBG(RI, ErrorF("%s\tproximity(TRUE, x=%d, y=%d)\n", CI_INFO, x, y));
 
1321
                }
 
1322
 
 
1323
                /*
 
1324
                 * Send events.
 
1325
                 *
 
1326
                 * We *must* generate a motion before a button change if pointer
 
1327
                 * location has changed as DIX assumes this. This is why we always
 
1328
                 * emit a motion, regardless of the kind of packet processed.
 
1329
                 * First test if coordinates have changed a predefined amount of pixels
 
1330
                 */
 
1331
 
 
1332
                if ( ((x >= (priv->last_x + priv->delta_x)) ||
 
1333
                          (x <= (priv->last_x - priv->delta_x)) ||
 
1334
                          (y >= (priv->last_y + priv->delta_y)) ||
 
1335
                          (y <= (priv->last_y - priv->delta_y)))        ||
 
1336
                   ( ((x < priv->delta_x) ||
 
1337
                          (x > (priv->screen_width - priv->delta_x))) ||
 
1338
                         ((y < priv->delta_x) ||
 
1339
                          (y > (priv->screen_height - priv->delta_y)))) )
 
1340
                {
 
1341
                xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
 
1342
                        DBG(RI, ErrorF("%s\tPostMotionEvent(x=%d, y=%d, last_x=%d, last_y=%d)\n", CI_INFO,
 
1343
                                                         x, y, priv->last_x, priv->last_y));
 
1344
 
 
1345
                        priv->last_x = x;               /* save cooked data */
 
1346
                        priv->last_y = y;
 
1347
                }
 
1348
 
 
1349
                /* 
 
1350
                 * Emit a button press or release.
 
1351
                 */
 
1352
 
 
1353
                if ((priv->button_down == FALSE) && (priv->state & CIT_BUTTON))
 
1354
                {
 
1355
                        if(priv->enter_touched < priv->enter_count)
 
1356
                                priv->enter_touched++;
 
1357
 
 
1358
                        if(priv->enter_touched == priv->enter_count)
 
1359
                        {
 
1360
                                priv->enter_touched++; /* increment count one more time to prevent further enter events */
 
1361
                                xf86PostButtonEvent (local->dev, TRUE,
 
1362
                                             priv->button_number, 1, 0, 2, x, y);
 
1363
                                cit_Beep(priv, 1);
 
1364
 
 
1365
                                DBG(RI, ErrorF("%s\tPostButtonEvent(DOWN, x=%d, y=%d)\n", CI_INFO, x, y));
 
1366
 
 
1367
                                priv->button_down = TRUE;
 
1368
                        }
 
1369
                }
 
1370
 
 
1371
                if ((priv->button_down == TRUE) && !(priv->state & CIT_BUTTON))
 
1372
                {
 
1373
                        xf86PostButtonEvent (local->dev, TRUE,
 
1374
                                             priv->button_number, 0, 0, 2, x, y);
 
1375
                        cit_Beep(priv, 0);
 
1376
                        DBG(RI, ErrorF("%s\tPostButtonEvent(UP, x=%d, y=%d)\n", CI_INFO, x, y));
 
1377
                        priv->button_down = FALSE;
 
1378
                }
 
1379
                /* 
 
1380
                 * the untouch should always come after the button release
 
1381
                 */
 
1382
                if ((priv->proximity == TRUE) && !(priv->state & CIT_TOUCHED))
 
1383
                {
 
1384
                        priv->proximity = FALSE;
 
1385
                        xf86PostProximityEvent (local->dev, 0, 0, 2, x, y);
 
1386
                        DBG(RI, ErrorF("%s\tproximity(FALSE, x=%d, y=%d)\n", CI_INFO, x, y));
 
1387
                }
 
1388
                
 
1389
 
 
1390
                DBG (RI, ErrorF ("%sTouchScreen: x(%d), y(%d), %s\n",
 
1391
                                                CI_INFO, x, y,
 
1392
                                                (priv->state == CIT_TOUCHED) ? "Touched" : "Released"));
 
1393
 
 
1394
#ifdef CIT_TIM
 
1395
                if(priv->fake_exit)
 
1396
                {
 
1397
                        priv->fake_exit = FALSE;                /* do not sent any further faked exit messages */
 
1398
                        return;
 
1399
                }
 
1400
#endif
 
1401
        }
 
1402
        DBG(RI, ErrorF("%sExit ReadInput\n", CI_INFO));
 
1403
}
 
1404
 
 
1405
/*****************************************************************************
 
1406
 *      [ControlProc]
 
1407
 ****************************************************************************/
 
1408
static int
 
1409
ControlProc (LocalDevicePtr local, xDeviceCtl * control)
 
1410
{
 
1411
        xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control;
 
1412
        cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
 
1413
 
 
1414
        DBG(5, ErrorF("%sControlProc called\n", CI_INFO));
 
1415
 
 
1416
        priv->min_x = c->min_x;
 
1417
        priv->max_x = c->max_x;
 
1418
        priv->min_y = c->min_y;
 
1419
        priv->max_y = c->max_y;
 
1420
 
 
1421
 
 
1422
        return (Success);
 
1423
}
 
1424
 
 
1425
/*****************************************************************************
 
1426
 *      [CloseProc]
 
1427
 ****************************************************************************/
 
1428
static void
 
1429
CloseProc (LocalDevicePtr local)
 
1430
{
 
1431
        DBG(5, ErrorF("%sCloseProc called\n", CI_INFO));
 
1432
}
 
1433
 
 
1434
/*****************************************************************************
 
1435
 *      [SwitchMode]
 
1436
 ****************************************************************************/
 
1437
static int
 
1438
SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
 
1439
{
 
1440
        LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
 
1441
        cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
 
1442
        DBG(5, ErrorF("%sSwitchMode called; mode = %d\n", CI_INFO, mode));
 
1443
        if ((mode == TS_Raw) || (mode == TS_Scaled))
 
1444
        {
 
1445
                priv->reporting_mode = mode;
 
1446
                DBG(6, ErrorF("%s\treporting mode = %s\n", CI_INFO, mode==TS_Raw?"raw":"scaled"));
 
1447
                return (Success);
 
1448
        }
 
1449
        else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents))
 
1450
        {
 
1451
                xf86XInputSetSendCoreEvents (local, (mode == SendCoreEvents));
 
1452
                DBG(6, ErrorF("%s\tmode = %sSend Core Events\n", CI_INFO, mode==DontSendCoreEvents?"Don\'t ":""));
 
1453
                return (Success);
 
1454
        }
 
1455
#ifdef CIT_MODE_EXT
 
1456
        else if (mode == ClickMode_Enter)
 
1457
        {
 
1458
                priv->click_mode = CM_ENTER;
 
1459
                DBG(6, ErrorF("%s\tset click mode to ENTER\n", CI_INFO));
 
1460
                return (Success);
 
1461
        }
 
1462
        else if (mode == ClickMode_Dual)
 
1463
        {
 
1464
                priv->click_mode = CM_DUAL;
 
1465
                DBG(6, ErrorF("%s\tset click mode to DUAL TOUCH\n", CI_INFO));
 
1466
                return (Success);
 
1467
        }
 
1468
        else if (mode == ClickMode_ZPress)
 
1469
        {
 
1470
                priv->click_mode = CM_ZPRESS;
 
1471
                DBG(6, ErrorF("%s\tset click mode to Z-Press\n", CI_INFO));
 
1472
                return (Success);
 
1473
        }
 
1474
#endif
 
1475
        else
 
1476
        {
 
1477
                ErrorF("%sUnknown mode for Citron Touchscreen Switchmode Function: 0x%02x!\n", CI_ERROR, mode);
 
1478
                return (!Success);
 
1479
        }
 
1480
}
 
1481
 
 
1482
/*****************************************************************************
 
1483
 *      [ConvertProc]
 
1484
 ****************************************************************************/
 
1485
static Bool
 
1486
ConvertProc (LocalDevicePtr local,
 
1487
                         int first,
 
1488
                         int num,
 
1489
                         int v0,
 
1490
                         int v1,
 
1491
                         int v2,
 
1492
                         int v3,
 
1493
                         int v4,
 
1494
                         int v5,
 
1495
                         int *x,
 
1496
                         int *y)
 
1497
{
 
1498
        cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
 
1499
 
 
1500
        DBG(5, ErrorF("%sConvertProc called(first=%d, num=%d, v0=%d, v1=%d, v2=%d, v3=%d\n",
 
1501
                                        CI_INFO, first, num, v0, v1, v2, v3));
 
1502
        if (priv->reporting_mode == TS_Raw)
 
1503
        {
 
1504
                *x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x,
 
1505
                                                        priv->max_x);
 
1506
                *y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y,
 
1507
                                                        priv->max_y);
 
1508
        }
 
1509
        else
 
1510
        {
 
1511
                *x = v0;
 
1512
                *y = v1;
 
1513
        }
 
1514
        DBG(6, ErrorF("%s\t+ x=%d, y=%d\n",CI_INFO, *x, *y));
 
1515
        return (TRUE);
 
1516
}
 
1517
 
 
1518
/*****************************************************************************
 
1519
 *      [QueryHardware]
 
1520
 ****************************************************************************/
 
1521
static Bool
 
1522
QueryHardware (LocalDevicePtr local, int *errmaj, int *errmin)
 
1523
{
 
1524
        cit_PrivatePtr  priv = (cit_PrivatePtr) (local->private);
 
1525
        unsigned char   x;
 
1526
        int             i, cnt;
 
1527
        int err;                /* for WAIT */
 
1528
 
 
1529
 
 
1530
        /* Reset the IRT from any mode and wait for end of warmstart */
 
1531
        DBG(5, ErrorF("%sQueryHardware called\n", CI_INFO));
 
1532
 
 
1533
 
 
1534
 
 
1535
/* Will not work with XFree86 4.0.1 */
 
1536
/*      xf86SerialSendBreak (local->fd, 2); */
 
1537
        cit_Flush(priv); 
 
1538
 
 
1539
 
 
1540
 
 
1541
        /*
 
1542
         * IRT signals end of startup by sending BREAKS with 100 ms length.
 
1543
         * wait a maximum of 2 seconds for at least 2 consecutive breaks
 
1544
         * to be sure the IRT is really initialized
 
1545
        */
 
1546
        cit_Flush(priv); /* clear the buffer and wait for break */
 
1547
        DBG(6, ErrorF("%s\t* waiting for BREAKS...\n", CI_INFO));
 
1548
        
 
1549
        cit_SetBlockDuration (priv, 1);
 
1550
 
 
1551
        for (i=0, cnt=0; (i<20) && (cnt<3); i++)
 
1552
        {
 
1553
                cit_Flush(priv); /* clear the buffer and wait for break */
 
1554
                WAIT(150);      /* wait a little bit longer than 100 ms */
 
1555
                DBG(7, ErrorF("%s\t (loop %d)\n", CI_INFO, i));
 
1556
                if (XisbRead(priv->buffer) == 0)
 
1557
                {
 
1558
                        cnt++;
 
1559
                        DBG(6, ErrorF("%s\t+ BREAK %d detected\n", CI_INFO, cnt));
 
1560
                }
 
1561
                else
 
1562
                {
 
1563
                        cnt = 0;
 
1564
                }
 
1565
                if ( i == 12)
 
1566
                {
 
1567
                        cit_SendCommand(priv->buffer, C_SOFTRESET, 0);
 
1568
                        DBG(6, ErrorF("%s\t+ SOFTRESET sent\n", CI_INFO));
 
1569
                }
 
1570
#if(0)
 
1571
                /* maybe we are in Debug Mode and have to sent a soft reset */
 
1572
                if(i == 15)
 
1573
                {
 
1574
                        XisbWrite(priv->buffer, (unsigned char *)"r2", 2);
 
1575
                        x = 0x0d;
 
1576
                        XisbWrite(priv->buffer, &x, 1);
 
1577
                        DBG(6, ErrorF("%s\t+ DEBUG-MODE SOFTRESET sent\n", CI_INFO));
 
1578
                }
 
1579
#endif
 
1580
        }
 
1581
        if (cnt < 2)
 
1582
        {
 
1583
                ErrorF("%sCannot reset Citron Infrared Touch!\n", CI_ERROR);
 
1584
 
 
1585
/*      Workaround - bugfix
 
1586
        Normally when the touch is connected and the driver thinks it didn't sent
 
1587
        breaks we have the problem, that spurious characters, which are sent at
 
1588
        the startup of the touch screen make the winbond SIO chip not to sent
 
1589
        any further interrupts. To overcome     this problem we reinitialize the
 
1590
        winbond chip with a close and open of the serial line.
 
1591
        Thanks a lot winbond team. Without it I wouldn't have
 
1592
        written these wonderful lines of source code ;-).
 
1593
*/ 
 
1594
                cit_ReinitSerial(priv);
 
1595
                return (!Success);
 
1596
        }
 
1597
        /* Now initialize IRT to CTS Protocol */
 
1598
        DBG(6, ErrorF("%s\t* initializing to CTS mode\n", CI_INFO));
 
1599
        x = 0x0d;
 
1600
        for (i=0; i<2; i++)
 
1601
        {
 
1602
                XisbWrite(priv->buffer, &x, 1);
 
1603
                WAIT(50);
 
1604
        }
 
1605
        x = MODE_D;
 
1606
        XisbWrite(priv->buffer, &x, 1);
 
1607
 
 
1608
        /* wait max. 0.5 seconds for acknowledge */
 
1609
        DBG(6, ErrorF("%s\t* waiting for acknowledge\n", CI_INFO));
 
1610
        cit_SetBlockDuration (priv, 500000);
 
1611
        cnt = 0;
 
1612
        while ((i=XisbRead(priv->buffer)) != -1)
 
1613
        {
 
1614
            DBG(7, ErrorF("%s\t* 0x%02X received - waiting for CTS_XON\n",CI_INFO, i));
 
1615
                if ((unsigned char)i == CTS_XON)
 
1616
                break;
 
1617
                if(cnt++ > 50) return (Success);        /* emergency stop */
 
1618
        }
 
1619
        if ((unsigned char)i != CTS_XON)
 
1620
        {
 
1621
            ErrorF("%sNo acknowledge from Citron Infrared Touch!\n", CI_ERROR);
 
1622
                cit_ReinitSerial(priv);
 
1623
        return (!Success);
 
1624
        }
 
1625
 
 
1626
        /* now we have the touch connected, do the initialization stuff */
 
1627
        DBG(6, ErrorF("%s\t+ Touch connected!\n",CI_INFO));
 
1628
        cit_Flush(priv);
 
1629
 
 
1630
        DBG(6, ErrorF("%s\t+ requesting pressure sensors report\n",CI_INFO));
 
1631
        if (cit_GetPressureSensors(priv)!=Success)
 
1632
        {
 
1633
                ErrorF("%sNo pressure sensors report received from Citron Touchscreen!\n",CI_ERROR);
 
1634
        }
 
1635
 
 
1636
        DBG(5, ErrorF("%s ClickMode is %d\n",CI_INFO, priv->click_mode));
 
1637
        if(priv->click_mode == NO_CLICK_MODE)   /* if no click mode set in XF86Config set it automatically */
 
1638
        {
 
1639
                priv->click_mode = (priv->pressure_sensors > 0) ? CM_ZPRESS : CM_ENTER;
 
1640
                DBG(5, ErrorF("%sClickMode set to %d\n",CI_INFO, priv->click_mode));
 
1641
                cit_SetEnterCount(priv);
 
1642
        }
 
1643
 
 
1644
        cit_SendCommand(priv->buffer, C_SETAREAFLAGS, 1,  AOF_ADDEXIT
 
1645
                                                                                                        | AOF_ADDCOORD
 
1646
                                                                                                        | AOF_ACTIVE
 
1647
                                                                                                        | AOF_ADDPRESS);
 
1648
 
 
1649
        cit_SendCommand(priv->buffer, C_SETAREAMODE, 1, AOM_CONT);
 
1650
 
 
1651
        cit_SendCommand(priv->buffer, C_SETCONTTIME, 1, 20);
 
1652
 
 
1653
        cit_SendCommand(priv->buffer, C_SETDUALTOUCHING, 1, DT_ERROR);
 
1654
 
 
1655
        cit_SendCommand(priv->buffer, C_SETAREAPRESSURE, 1, LOBYTE(priv->button_threshold));
 
1656
 
 
1657
        cit_SendCommand(priv->buffer, C_SETRESOLUTION, 4,
 
1658
                                                                                                        LOBYTE(CIT_DEF_MAX_X),
 
1659
                                                                                                        HIBYTE(CIT_DEF_MAX_X),
 
1660
                                                                                                        LOBYTE(CIT_DEF_MAX_Y),
 
1661
                                                                                                        HIBYTE(CIT_DEF_MAX_Y));
 
1662
 
 
1663
        cit_SendCommand(priv->buffer, C_SETPWM, 2,
 
1664
                                                                                                        LOBYTE(priv->pwm_active),
 
1665
                                                                                                        LOBYTE(priv->pwm_sleep));
 
1666
 
 
1667
        cit_SendCommand(priv->buffer, C_SETBEAMTIMEOUT, 2,
 
1668
                                                                                                        LOBYTE(priv->beam_timeout),
 
1669
                                                                                                        HIBYTE(priv->beam_timeout));
 
1670
 
 
1671
        cit_SendCommand(priv->buffer, C_SETORIGIN, 1, LOBYTE(priv->origin));
 
1672
        cit_SendCommand(priv->buffer, C_SETTOUCHTIME, 1, LOBYTE(priv->touch_time));
 
1673
 
 
1674
        cit_SendCommand(priv->buffer, C_SETSLEEPMODE, 5,
 
1675
                                                                                                        LOBYTE(priv->sleep_mode),
 
1676
                                                                                                        LOBYTE(priv->sleep_time_act),
 
1677
                                                                                                        HIBYTE(priv->sleep_time_act),
 
1678
                                                                                                        LOBYTE(priv->sleep_time_scan),
 
1679
                                                                                                        HIBYTE(priv->sleep_time_scan));
 
1680
 
 
1681
        cit_SendCommand(priv->buffer, C_SETDOZEMODE, 5,
 
1682
                                                                                                        LOBYTE(priv->doze_mode),
 
1683
                                                                                                        LOBYTE(priv->doze_time_act),
 
1684
                                                                                                        HIBYTE(priv->doze_time_act),
 
1685
                                                                                                        LOBYTE(priv->doze_time_scan),
 
1686
                                                                                                        HIBYTE(priv->doze_time_scan));
 
1687
 
 
1688
        cit_SendCommand(priv->buffer, C_SETTRANSMISSION, 1, TM_TRANSMIT);
 
1689
        cit_SendCommand(priv->buffer, C_SETSCANNING, 1, 1);
 
1690
 
 
1691
        cit_SendPWMFreq(priv);                  /* Set PWM Frequency */
 
1692
 
 
1693
        if(priv->query_state == 0)              /* do error reporting only 1 time */
 
1694
        {
 
1695
                priv->query_state++;
 
1696
 
 
1697
                DBG(6, ErrorF("%s\t+ requesting initial errors report\n",CI_INFO));
 
1698
                if (cit_GetInitialErrors(priv)!=Success)
 
1699
                {
 
1700
                        ErrorF("%sNo initial error report received from Citron Touchscreen!\n",CI_ERROR);
 
1701
                        *errmaj = LDR_NOHARDWARE;
 
1702
                return (!Success);
 
1703
                }
 
1704
                DBG(6, ErrorF("\t+ requesting defective beams report\n"));
 
1705
                if (cit_GetDefectiveBeams(priv)!=Success)
 
1706
                {
 
1707
                        ErrorF("%sNo defective beams report received from Citron Touchscreen!\n",CI_ERROR);
 
1708
                        *errmaj = LDR_NOHARDWARE;
 
1709
                        return (!Success);
 
1710
                }
 
1711
                DBG(6, ErrorF("\t+ requesting touch revisions\n"));
 
1712
                if (cit_GetDesignator(priv)!=Success)
 
1713
                {
 
1714
                        ErrorF("%sNo designator received from Citron Touchscreen!\n",CI_ERROR);
 
1715
                        *errmaj = LDR_NOHARDWARE;
 
1716
                        return (!Success);
 
1717
                }
 
1718
                if (cit_GetRevision(priv, GR_SYSMGR)!=Success)
 
1719
                {
 
1720
                        ErrorF("%sNo system manager module revision received from Citron Touchscreen!\n",CI_ERROR);
 
1721
                        *errmaj = LDR_NOHARDWARE;
 
1722
                        return (!Success);
 
1723
                }
 
1724
                if (cit_GetRevision(priv, GR_HARDWARE)!=Success)
 
1725
                {
 
1726
                        ErrorF("%sNo hardware module revision received from Citron Touchscreen!\n",CI_ERROR);
 
1727
                        *errmaj = LDR_NOHARDWARE;
 
1728
                        return (!Success);
 
1729
                }
 
1730
                if (cit_GetRevision(priv, GR_PROCESS)!=Success)
 
1731
                {
 
1732
                        ErrorF("%sNo process module revision received from Citron Touchscreen!\n",CI_ERROR);
 
1733
                        *errmaj = LDR_NOHARDWARE;
 
1734
                        return (!Success);
 
1735
                }
 
1736
                if (cit_GetRevision(priv, GR_PROTOCOL)!=Success)
 
1737
                {
 
1738
                        ErrorF("%sNo protocol module revision received from Citron Touchscreen!\n",CI_ERROR);
 
1739
                        *errmaj = LDR_NOHARDWARE;
 
1740
                        return (!Success);
 
1741
                }
 
1742
                if (cit_GetRevision(priv, GR_HWPARAM)!=Success)
 
1743
                {
 
1744
                        ErrorF("%sNo hardware parameter module revision received from Citron Touchscreen!\n",CI_ERROR);
 
1745
                        *errmaj = LDR_NOHARDWARE;
 
1746
                        return (!Success);
 
1747
                }
 
1748
        }
 
1749
        
 
1750
        DBG(6, ErrorF("%s\t+ Touch initialized - %d\n",CI_INFO, priv->query_state));
 
1751
        
 
1752
        return (Success);
 
1753
}
 
1754
 
 
1755
 
 
1756
/*****************************************************************************
 
1757
 *      [cit_GetPacket]
 
1758
 ****************************************************************************/
 
1759
static Bool
 
1760
cit_GetPacket (cit_PrivatePtr priv)
 
1761
{
 
1762
        int c;
 
1763
        int errmaj, errmin;
 
1764
        int loop = 0;
 
1765
        DBG(GP, ErrorF("%scit_GetPacket called\n", CI_INFO));
 
1766
        DBG(GP, ErrorF("%s\t* initial lex_mode =%d (%s)\n", CI_INFO, priv->lex_mode,
 
1767
                            priv->lex_mode==cit_idle    ?"idle":
 
1768
                            priv->lex_mode==cit_getID   ?"getID":
 
1769
                            priv->lex_mode==cit_collect ?"collect":
 
1770
                            priv->lex_mode==cit_escape  ?"escape":
 
1771
                            "???"));
 
1772
        while ((c = XisbRead (priv->buffer)) >= 0)
 
1773
        {
 
1774
#if(0)          
 
1775
                DBG(GP, ErrorF("%s c=%d\n",CI_INFO, c));
 
1776
#endif
 
1777
                loop++;
 
1778
                if (c == CTS_STX)
 
1779
                {
 
1780
                        DBG(GP, ErrorF("%s\t+ STX detected\n", CI_INFO));
 
1781
                        /* start of report received */
 
1782
                        if (priv->lex_mode != cit_idle)
 
1783
                                DBG(7, ErrorF("%s\t- no ETX received before this STX!\n", CI_WARNING));
 
1784
                        priv->lex_mode = cit_getID;
 
1785
                        DBG(GP, ErrorF("%s\t+ new lex_mode == getID\n", CI_INFO));
 
1786
                        /* Start supervision timer at the beginning of a command */
 
1787
                        priv->timer_val1[SV_TIMER] = 2000;              /* Timer delay [ms] 2s */
 
1788
                        priv->timer_callback[SV_TIMER] = (OsTimerCallback)cit_SuperVisionTimer;         /* timer callback routine       */
 
1789
                        cit_StartTimer(priv, SV_TIMER);                 
 
1790
 
 
1791
                }
 
1792
                else if (c == CTS_ETX)
 
1793
                {
 
1794
                        DBG(GP, ErrorF("%s\t+ ETX detected\n", CI_INFO));
 
1795
                        /* end of command received */
 
1796
                        /* always IDLE after report completion */
 
1797
                        DBG(GP, ErrorF("%s\t+ new lex_mode == idle\n", CI_INFO));
 
1798
                        if (priv->lex_mode == cit_collect)
 
1799
                        {
 
1800
                            DBG(GP, ErrorF("%s\t+ Good report received\n", CI_INFO));
 
1801
                            priv->lex_mode = cit_idle;
 
1802
                                cit_CloseTimer(priv, SV_TIMER);                 /* stop supervision */
 
1803
                            return (Success);
 
1804
                        }
 
1805
                        DBG(GP, ErrorF("%s\t- unexpected ETX received!\n", CI_WARNING));
 
1806
                        priv->lex_mode = cit_idle;
 
1807
                }
 
1808
                else if (c == CTS_ESC)
 
1809
                {
 
1810
                        DBG(GP, ErrorF("%s\t+ escape detected\n", CI_INFO));
 
1811
                        /* next character is encoded */
 
1812
                        if (priv->lex_mode != cit_collect)
 
1813
                        {
 
1814
                                DBG(GP, ErrorF("%s\t- unexpected control character received\n", CI_WARNING));
 
1815
                        }
 
1816
                        else
 
1817
                        {
 
1818
                                priv->lex_mode = cit_escape;
 
1819
                                DBG(GP, ErrorF("%s\t+ new lex_mode == escape\n", CI_INFO));
 
1820
                        }
 
1821
                }
 
1822
                else if ((c < CTS_CTRLMIN) || (c > CTS_CTRLMAX))
 
1823
                {
 
1824
                        /* regular report data received */
 
1825
                        if (priv->lex_mode == cit_getID)
 
1826
                        {       /* receive report ID */
 
1827
                                priv->packeti = 0;
 
1828
                                priv->packet[priv->packeti++] = (unsigned char)c;
 
1829
                                priv->lex_mode = cit_collect;
 
1830
                                DBG(GP, ErrorF("%s\t+ identifier captured, new lex_mode == collect\n", CI_INFO));
 
1831
                        }
 
1832
                        else if ((priv->lex_mode == cit_collect) || (priv->lex_mode == cit_escape))
 
1833
                        {       /* receive command data */
 
1834
                                if (priv->lex_mode == cit_escape)
 
1835
                                {       /* decode encoded data byte */
 
1836
                                        c &= CTS_DECODE;        /* decode data */
 
1837
                                        priv->lex_mode = cit_collect;
 
1838
                                        DBG(GP, ErrorF("%s\t+ decoded character = 0x%02X\n", CI_INFO, c));
 
1839
                                        DBG(GP, ErrorF("%s\t+ new lex_mode = collect\n", CI_INFO));
 
1840
                                }
 
1841
                                if (priv->packeti < CTS_PACKET_SIZE)
 
1842
                                {       /* add data bytes to buffer */
 
1843
                                        priv->packet[priv->packeti++] = (unsigned char)c;
 
1844
                                }
 
1845
                                else
 
1846
                                {
 
1847
                                        DBG(GP, ErrorF("%s\t- command buffer overrun, loop[%d]\n", CI_ERROR, loop));
 
1848
                                        /* let's reinitialize the touch - maybe it sends breaks */
 
1849
                                        /* The touch assembles breaks until the buffer has an overrun */
 
1850
                                        /* 100ms x 256 -> 26 seconds */
 
1851
                                        
 
1852
                                        priv->lex_mode = cit_idle;
 
1853
                                        cit_ReinitSerial(priv);
 
1854
 
 
1855
                                }
 
1856
                        }
 
1857
                        else
 
1858
                        {
 
1859
                                /* this happens e.g. when the touch sends breaks, so we try to reconnect */
 
1860
                                DBG(GP, ErrorF("%s\t- unexpected non control received! [%d, 0x%02x, loop[%d]]\n", CI_WARNING, c, c, loop));
 
1861
                                DBG(GP, ErrorF("%s\t- Device not connected - trying to reconnect ...\n", CI_WARNING));
 
1862
                                if (QueryHardware (priv->local, &errmaj, &errmin) != Success)
 
1863
                                        ErrorF ("%s\t- Unable to query/initialize Citron Touch hardware.\n", CI_ERROR);
 
1864
                                else
 
1865
                                        ErrorF ("%s\t- Citron Touch reconnected\n", CI_INFO);
 
1866
 
 
1867
                                return(!Success);
 
1868
                        }
 
1869
                }
 
1870
                else if (c != CTS_XON && c != CTS_XOFF)
 
1871
                {
 
1872
                        DBG(GP, ErrorF("%s\t- unhandled control character received! loop[%d]\n", CI_WARNING, loop));
 
1873
                }
 
1874
        } /* end while */
 
1875
        DBG(GP, ErrorF("%scit_GetPacket exit !Success - loop[%d]\n", CI_INFO, loop));
 
1876
 
 
1877
        return (!Success);
 
1878
}
 
1879
 
 
1880
 
 
1881
/*****************************************************************************
 
1882
 *      [cit_ReinitSerial] Reinitialize serial port
 
1883
 ****************************************************************************/
 
1884
static void
 
1885
cit_ReinitSerial(cit_PrivatePtr priv)
 
1886
{
 
1887
        if(priv->local->fd)
 
1888
        {
 
1889
                xf86CloseSerial(priv->local->fd);
 
1890
                priv->local->fd = 0;
 
1891
                priv->local->fd = xf86OpenSerial (priv->local->options);
 
1892
                DBG(6, ErrorF("%s\t* cit_ReinitSerial: Serial connection reinitialized\n", CI_INFO));
 
1893
        }
 
1894
        else
 
1895
                DBG(6, ErrorF("%s\t* cit_ReinitSerial: Serial connection not opened\n", CI_ERROR));
 
1896
}
 
1897
 
 
1898
/*****************************************************************************
 
1899
 *      [cit_Flush]
 
1900
 ****************************************************************************/
 
1901
static void
 
1902
cit_Flush (cit_PrivatePtr priv)
 
1903
{
 
1904
        int old_block_duration;
 
1905
        
 
1906
        DBG(7, ErrorF("%scit_Flush called\n", CI_INFO));
 
1907
        old_block_duration = priv->buffer->block_duration;
 
1908
        XisbBlockDuration(priv->buffer, 1000);          /* wait for at least 10ms for the next character */
 
1909
        while (XisbRead(priv->buffer) >= 0);
 
1910
        cit_SetBlockDuration(priv, old_block_duration);                 /* Restore the last set block duration (cit_SetBlockDuration) */
 
1911
}
 
1912
 
 
1913
/*****************************************************************************
 
1914
 *      [cit_SetBlockDuration]
 
1915
 ****************************************************************************/
 
1916
static void
 
1917
cit_SetBlockDuration (cit_PrivatePtr priv, int block_duration)
 
1918
{
 
1919
        DBG(7, ErrorF("%scit_SetBlockDuration called [%d]\n", CI_INFO, block_duration));
 
1920
        XisbBlockDuration(priv->buffer, block_duration);
 
1921
}
 
1922
 
 
1923
 
 
1924
/*****************************************************************************
 
1925
 *      [cit_Beep]
 
1926
 ****************************************************************************/
 
1927
static void
 
1928
cit_Beep(cit_PrivatePtr priv, int press)
 
1929
{
 
1930
#ifdef CIT_BEEP
 
1931
        if(priv->beep == 0)
 
1932
                return;
 
1933
 
 
1934
        /* ring release bell */
 
1935
        if(press == 0)
 
1936
 
 
1937
        /*               [0]: volume, [1]: pitch, [2]: duration */
 
1938
        /* formula is: ((1193190 / freq) & 0xffff) |                            */
 
1939
        /*            (((unsigned long)duration * loudness / 50) << 16)) */
 
1940
        /* .. whatever the inventor wants to intend by it, I don't know (PK) */
 
1941
 
 
1942
                xf86SoundKbdBell(priv->rel_vol, priv->rel_pitch, priv->rel_dur);
 
1943
 
 
1944
        else
 
1945
        /* ring press bell */
 
1946
                xf86SoundKbdBell(priv->press_vol,priv->press_pitch, priv->press_dur);
 
1947
 
 
1948
        DBG(7, ErrorF("%scit_Beep called - %s\n", CI_INFO, (press == 0) ? "release" : "press"));
 
1949
#endif
 
1950
}
 
1951
 
 
1952
 
 
1953
/*****************************************************************************
 
1954
 *      [cit_SendCommand]
 
1955
 ****************************************************************************/
 
1956
static void
 
1957
cit_SendCommand (XISBuffer *b, unsigned char cmd, int cnt, ...)
 
1958
{
 
1959
        va_list ap;
 
1960
        unsigned char   data, x;
 
1961
        
 
1962
        va_start(ap, cnt);
 
1963
 
 
1964
        DBG(7, ErrorF("%scit_SendCommand(cmd=0x%02X, cnt=%d, ...)\n", CI_INFO, cmd, cnt));
 
1965
        x = CTS_STX;
 
1966
        XisbWrite(b, &x, 1);                    /* transmit start of packet     */
 
1967
        XisbWrite(b, &cmd, 1);                  /* transmit command code        */
 
1968
        x = CTS_ESC;
 
1969
        while (cnt-- > 0)
 
1970
        {       /* encode and transmit optional parameters      */
 
1971
                data = va_arg(ap, int);
 
1972
                if (data >= CTS_CTRLMIN && data <= CTS_CTRLMAX)
 
1973
                {       /* data has to be encoded       */
 
1974
                        data |= CTS_ENCODE;
 
1975
                        XisbWrite(b, &x, 1);    /* mark coded data      */
 
1976
                }
 
1977
                XisbWrite(b, &data, 1);         /* transmit data */
 
1978
        }
 
1979
        x = CTS_ETX;
 
1980
        XisbWrite(b, &x, 1);                    /* transmit end of packet       */
 
1981
        va_end(ap);
 
1982
}
 
1983
 
 
1984
 
 
1985
/*****************************************************************************
 
1986
 *      [cit_GetInitialErrors]
 
1987
 ****************************************************************************/
 
1988
static Bool cit_GetInitialErrors(cit_PrivatePtr priv)
 
1989
{
 
1990
        unsigned long   errors;
 
1991
        int                             i;
 
1992
        Bool                    res;
 
1993
 
 
1994
        cit_Flush(priv);
 
1995
        cit_SendCommand(priv->buffer, C_GETERRORS, 1, GE_INITIAL);
 
1996
        /*
 
1997
            touch responds within 1 millisecond,
 
1998
            but it takes some time, until the command is sent!
 
1999
        */
 
2000
        for (i=0; i<5; i++)
 
2001
        {
 
2002
                cit_SetBlockDuration(priv, 500000);
 
2003
                res = cit_GetPacket(priv);
 
2004
                if ((res == Success) || (priv->lex_mode == cit_idle));
 
2005
                        break;
 
2006
        }
 
2007
        if (res != Success)
 
2008
        {
 
2009
                DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
 
2010
                return (!Success);
 
2011
        }
 
2012
        /* examine packet */
 
2013
        if (priv->packeti != 6)
 
2014
        {
 
2015
                DBG(5, ErrorF("%sWrong packet length (expected 6, received %d bytes)\n", CI_NOTICE, priv->packeti));
 
2016
                return (!Success);
 
2017
        }
 
2018
        if (priv->packet[0] != (C_GETERRORS & CMD_REP_CONV))
 
2019
        {
 
2020
                DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2021
                                                (C_GETERRORS & CMD_REP_CONV), priv->packet[0]));
 
2022
                return (!Success);
 
2023
        }
 
2024
        if (priv->packet[1] != GE_INITIAL)
 
2025
        {
 
2026
                DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2027
                                                GE_INITIAL, priv->packet[1]));
 
2028
                return (!Success);
 
2029
        }
 
2030
        /* this is our packet! check contents */
 
2031
        errors =  0x00000001UL * (unsigned long)priv->packet[2]
 
2032
                        + 0x00000100UL * (unsigned long)priv->packet[3]
 
2033
                        + 0x00010000UL * (unsigned long)priv->packet[4]
 
2034
                        + 0x10000000UL * (unsigned long)priv->packet[5];
 
2035
        DBG(6, ErrorF("%sinitial errors = 0x%08lX\n", CI_NOTICE, errors));
 
2036
        if (errors == 0x00000000UL)
 
2037
        {
 
2038
            ErrorF("%sNo initialization errors detected.\n", CI_INFO);
 
2039
        }
 
2040
        if (errors & IE_SMCHKSUM)
 
2041
        {
 
2042
                ErrorF("%sSystem Manager Module checksum error!\n", CI_ERROR);
 
2043
        }
 
2044
        if (errors & IE_SMINIT)
 
2045
        {
 
2046
                ErrorF("%sSystem Manager Module initialization error!\n", CI_ERROR);
 
2047
        }
 
2048
        if (errors & IE_HWCHKSUM)
 
2049
        {
 
2050
                ErrorF("%sHardware Module checksum error!\n", CI_ERROR);
 
2051
        }
 
2052
        if (errors & IE_HWINIT)
 
2053
        {
 
2054
                ErrorF("%sHardware Module initialization error!\n", CI_ERROR);
 
2055
        }
 
2056
        if (errors & IE_HW_BEAMS)
 
2057
        {
 
2058
                ErrorF("%s              broken beams during initialization detected!\n", CI_ERROR);
 
2059
        }
 
2060
        if (errors & IE_HW_PSU)
 
2061
        {
 
2062
                ErrorF("%s              force sensors not operating!\n", CI_ERROR);
 
2063
        }
 
2064
        if (errors & IE_HW_CPU)
 
2065
        {
 
2066
                ErrorF("%s              CPU integrity test failed!\n", CI_ERROR);
 
2067
        }
 
2068
        if (errors & IE_HW_IRAM)
 
2069
        {
 
2070
                ErrorF("%s              internal RAM error!\n", CI_ERROR);
 
2071
        }
 
2072
        if (errors & IE_HW_XRAM)
 
2073
        {
 
2074
                ErrorF("%s              external SRAM error!\n", CI_ERROR);
 
2075
        }
 
2076
        if (errors & IE_PCCHKSUM)
 
2077
        {
 
2078
                ErrorF("%sProcess Module checksum error!\n", CI_ERROR);
 
2079
        }
 
2080
        if (errors & IE_PCINIT)
 
2081
        {
 
2082
                ErrorF("%sProcess Module initialization error!\n", CI_ERROR);
 
2083
        }
 
2084
        if (errors & IE_PTCHKSUM)
 
2085
        {
 
2086
                ErrorF("%sProtocol Module checksum error!\n", CI_ERROR);
 
2087
        }
 
2088
        if (errors & IE_PTINIT)
 
2089
        {
 
2090
                ErrorF("%sProtocol Module initialization error!\n", CI_ERROR);
 
2091
        }
 
2092
        if (errors & IE_BICHK)
 
2093
        {
 
2094
                ErrorF("%sBurnIn Module checksum error!\n", CI_ERROR);
 
2095
        }
 
2096
        if (errors & IE_BIINIT)
 
2097
        {
 
2098
                ErrorF("%sBurnIn Module initialization error!\n", CI_ERROR);
 
2099
        }
 
2100
        if (errors & IE_FPGACHK)
 
2101
        {
 
2102
                ErrorF("%sFPGA configuration checksum error!\n", CI_ERROR);
 
2103
        }
 
2104
        if (errors & IE_HWPCHK)
 
2105
        {
 
2106
                ErrorF("%sHardware Parameter checksum error!\n", CI_ERROR);
 
2107
        }
 
2108
        return (Success);
 
2109
}
 
2110
 
 
2111
 
 
2112
/*****************************************************************************
 
2113
 *      [cit_GetDefectiveBeams]
 
2114
 ****************************************************************************/
 
2115
static Bool cit_GetDefectiveBeams(cit_PrivatePtr priv)
 
2116
{
 
2117
        unsigned        nx, ny;
 
2118
        int                     i;
 
2119
        Bool            res;
 
2120
 
 
2121
        cit_Flush(priv);
 
2122
        cit_SendCommand(priv->buffer, C_GETERRORS, 1, GE_DEFECTBEAMS);
 
2123
        /*
 
2124
            touch responds within 1 millisecond,
 
2125
            but it takes some time, until the command is sent!
 
2126
        */
 
2127
        for (i=0; i<5; i++)
 
2128
        {
 
2129
                cit_SetBlockDuration(priv, 500000);
 
2130
                res = cit_GetPacket(priv);
 
2131
                if ((res == Success) || (priv->lex_mode == cit_idle));
 
2132
                        break;
 
2133
        }
 
2134
        if (res != Success)
 
2135
        {
 
2136
                DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
 
2137
                return (!Success);
 
2138
        }
 
2139
        /* examine packet */
 
2140
        if (priv->packeti < 6)
 
2141
        {
 
2142
                DBG(5, ErrorF("%sWrong packet length (expected >= 6, received %d bytes)\n", CI_NOTICE, priv->packeti));
 
2143
                return (!Success);
 
2144
        }
 
2145
        if (priv->packet[0] != (C_GETERRORS & CMD_REP_CONV))
 
2146
        {
 
2147
                DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2148
                                                (C_GETERRORS & CMD_REP_CONV), priv->packet[0]));
 
2149
                return (!Success);
 
2150
        }
 
2151
        if (priv->packet[1] != GE_DEFECTBEAMS)
 
2152
        {
 
2153
                DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2154
                                                GE_DEFECTBEAMS, priv->packet[1]));
 
2155
                return (!Success);
 
2156
        }
 
2157
        /* this is our packet! check contents */
 
2158
        nx =  0x0001U * (unsigned)priv->packet[2]
 
2159
            + 0x0100U * (unsigned)priv->packet[3];
 
2160
 
 
2161
        ny =  0x0001U * (unsigned)priv->packet[4]
 
2162
            + 0x0100U * (unsigned)priv->packet[5];
 
2163
        /* list defective X-beams */
 
2164
        if (nx > 0)
 
2165
        {
 
2166
            ErrorF("%s%u defective X-Beams detected:\n", CI_ERROR, nx);
 
2167
            for (i=0; i<nx; i++)
 
2168
            {
 
2169
                        ErrorF("%s\tX%02u\n", CI_ERROR, (unsigned)priv->packet[6+i]);
 
2170
            }
 
2171
        }
 
2172
        else
 
2173
        {
 
2174
            ErrorF("%sNo defective X-beams detected.\n", CI_INFO);
 
2175
        }
 
2176
        
 
2177
        /* list defective Y-beams */
 
2178
        if (ny > 0)
 
2179
        {
 
2180
            ErrorF("%s%u defective Y-Beams detected:\n", CI_ERROR, ny);
 
2181
            for (i=0; i<ny; i++)
 
2182
            {
 
2183
                ErrorF("%s\tY%02u\n", CI_ERROR, (unsigned)priv->packet[6+nx+i]);
 
2184
            }
 
2185
        }
 
2186
        else
 
2187
        {
 
2188
            ErrorF("%sNo defective Y-beams detected.\n", CI_INFO);
 
2189
        }
 
2190
        return (Success);
 
2191
}
 
2192
 
 
2193
 
 
2194
/*****************************************************************************
 
2195
 *      [cit_GetDesignator]
 
2196
 ****************************************************************************/
 
2197
static Bool cit_GetDesignator(cit_PrivatePtr priv)
 
2198
{
 
2199
        int             i,n;
 
2200
        Bool    res;
 
2201
 
 
2202
        cit_Flush(priv);
 
2203
        cit_SendCommand(priv->buffer, C_GETREVISIONS, 1, GR_DESIGNATOR);
 
2204
        /*
 
2205
            touch responds within 1 millisecond,
 
2206
            but it takes some time, until the command is sent and received!
 
2207
        */
 
2208
        for (i=0; i<5; i++)
 
2209
        {
 
2210
                cit_SetBlockDuration(priv, 500000);
 
2211
                res = cit_GetPacket(priv);
 
2212
                if ((res == Success) || (priv->lex_mode == cit_idle));
 
2213
                        break;
 
2214
        }
 
2215
        if (res != Success)
 
2216
        {
 
2217
                DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
 
2218
                return (!Success);
 
2219
        }
 
2220
        /* examine packet */
 
2221
        if (priv->packeti < 2+CTS_DESIGNATOR_LEN+CTS_ASSY_LEN)
 
2222
        {
 
2223
                DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
 
2224
                    2+CTS_DESIGNATOR_LEN+CTS_ASSY_LEN,
 
2225
                    priv->packeti));
 
2226
                return (!Success);
 
2227
        }
 
2228
        if (priv->packet[0] != (C_GETREVISIONS & CMD_REP_CONV))
 
2229
        {
 
2230
                DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2231
                                                (C_GETREVISIONS & CMD_REP_CONV), priv->packet[0]));
 
2232
                return (!Success);
 
2233
        }
 
2234
        if (priv->packet[1] != GR_DESIGNATOR)
 
2235
        {
 
2236
                DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2237
                                                GR_DESIGNATOR, priv->packet[1]));
 
2238
                return (!Success);
 
2239
        }
 
2240
        /* this is our packet! check contents */
 
2241
        ErrorF("%sDesignator \"", CI_INFO);
 
2242
        i = 2;
 
2243
        n = 0;
 
2244
        while (n++ < CTS_DESIGNATOR_LEN && priv->packet[i]!=0)
 
2245
        {
 
2246
            ErrorF("%c", priv->packet[i++]);
 
2247
        }
 
2248
        ErrorF("\"\n%sAssembly   \"", CI_INFO);
 
2249
        i = 2 + CTS_DESIGNATOR_LEN;
 
2250
        n = 0;
 
2251
        while (n++ < CTS_ASSY_LEN && priv->packet[i]!=0)
 
2252
        {
 
2253
            ErrorF("%c", priv->packet[i++]);
 
2254
        }
 
2255
        ErrorF("\"\n");
 
2256
        return (Success);
 
2257
}
 
2258
 
 
2259
 
 
2260
/*****************************************************************************
 
2261
 *      [cit_GetRevision]
 
2262
 ****************************************************************************/
 
2263
static Bool cit_GetRevision(cit_PrivatePtr priv, int selection)
 
2264
{
 
2265
        int     i,n;
 
2266
        Bool    res;
 
2267
 
 
2268
        cit_Flush(priv);
 
2269
        cit_SendCommand(priv->buffer, C_GETREVISIONS, 1, (unsigned char)selection);
 
2270
        /*
 
2271
            touch responds within 1 millisecond,
 
2272
            but it takes some time, until the command is sent and received!
 
2273
        */
 
2274
        cit_SetBlockDuration(priv, 500000);
 
2275
        while (((res = cit_GetPacket(priv)) != Success) && (priv->lex_mode != cit_idle));
 
2276
        if (res != Success)
 
2277
        {
 
2278
                DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
 
2279
                return (!Success);
 
2280
        }
 
2281
        /* examine packet */
 
2282
        if (priv->packeti < 2)
 
2283
        {
 
2284
                DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
 
2285
                    2, priv->packeti));
 
2286
                return (!Success);
 
2287
        }
 
2288
        if (priv->packet[0] != (C_GETREVISIONS & CMD_REP_CONV))
 
2289
        {
 
2290
                DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2291
                                                (C_GETREVISIONS & CMD_REP_CONV), priv->packet[0]));
 
2292
                return (!Success);
 
2293
        }
 
2294
        if (priv->packet[1] != selection)
 
2295
        {
 
2296
                DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2297
                                                selection, priv->packet[1]));
 
2298
                return (!Success);
 
2299
        }
 
2300
        /* this is our packet! check contents */
 
2301
        DBG(5, ErrorF("%s%s module revision ", CI_INFO,
 
2302
            selection == GR_SYSMGR              ? "SysMgr  " :
 
2303
            selection == GR_HARDWARE    ? "Hardware" : 
 
2304
            selection == GR_PROCESS             ? "Process " :
 
2305
            selection == GR_PROTOCOL    ? "Protocol" :
 
2306
            selection == GR_HWPARAM             ? "HWParam " :
 
2307
            "???"));
 
2308
        i = 2;
 
2309
        n = 0;
 
2310
        DBG(5, ErrorF("\""));
 
2311
        while (n < priv->packeti && priv->packet[i]!=0)
 
2312
        {
 
2313
            DBG(5, ErrorF("%c", priv->packet[i]));
 
2314
            i++;
 
2315
        }
 
2316
        DBG(5, ErrorF("\"\n"));
 
2317
        return (Success);
 
2318
}
 
2319
 
 
2320
 
 
2321
/*****************************************************************************
 
2322
 *      [cit_ProcessPacket]
 
2323
 ****************************************************************************/
 
2324
static void cit_ProcessPacket(cit_PrivatePtr priv)
 
2325
{
 
2326
        int     i;
 
2327
 
 
2328
        DBG(PP, ErrorF("%scit_ProcessPacket called\n", CI_INFO));
 
2329
        DBG(PP, ErrorF("%s\t+ enter state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
 
2330
        /* examine message identifier */
 
2331
 
 
2332
        priv->dual_flg = TRUE;                  /* Dual Touch Error occurred */
 
2333
#ifdef CIT_TIM
 
2334
        priv->timer_val1[FAKE_TIMER] = 1000;            /* Timer delay [ms]*/
 
2335
        priv->timer_callback[FAKE_TIMER] = (OsTimerCallback)cit_DualTouchTimer;         /* timer callback routine       */
 
2336
        cit_StartTimer(priv, FAKE_TIMER);                       
 
2337
#endif
 
2338
 
 
2339
        switch (priv->packet[0])
 
2340
        {
 
2341
                case R_COORD:   /* new touch coordinates received */
 
2342
                        if (priv->packeti < 5)
 
2343
                        {
 
2344
                                DBG(PP, ErrorF("%s\t- coordinate message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
 
2345
                                break;
 
2346
                        }
 
2347
 
 
2348
 
 
2349
                        if (priv->dual_touch_count > 0)
 
2350
                                priv->dual_touch_count--;
 
2351
 
 
2352
                        priv->raw_x = 0x0001U * priv->packet[1]
 
2353
                                                + 0x0100U * priv->packet[2];
 
2354
                        priv->raw_y = 0x0001U * priv->packet[3]
 
2355
                                                + 0x0100U * priv->packet[4];
 
2356
 
 
2357
                        priv->raw_min_x = min(priv->raw_min_x, priv->raw_x);
 
2358
                        priv->raw_max_x = max(priv->raw_max_x, priv->raw_x);
 
2359
                        priv->raw_min_y = min(priv->raw_min_y, priv->raw_y);
 
2360
                        priv->raw_max_y = max(priv->raw_max_y, priv->raw_y);
 
2361
 
 
2362
                        priv->state |= CIT_TOUCHED;
 
2363
 
 
2364
                        DBG(PP, ErrorF("%s\t+ COORD message raw (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
 
2365
                        break;
 
2366
                
 
2367
                case R_EXIT:    /* touch area no longer interrupted */
 
2368
                        if (priv->packeti < 5)
 
2369
                        {
 
2370
                                DBG(PP, ErrorF("%s\t- exit message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
 
2371
                                break;
 
2372
                        }
 
2373
 
 
2374
                        priv->state &= ~(CIT_TOUCHED | CIT_PRESSED);
 
2375
                        priv->dual_touch_count = 0;
 
2376
                        priv->enter_touched = 0;                /* reset coordinate report counter */
 
2377
                        priv->raw_x = 0x0001U * priv->packet[1]
 
2378
                                                + 0x0100U * priv->packet[2];
 
2379
                        priv->raw_y = 0x0001U * priv->packet[3]
 
2380
                                                + 0x0100U * priv->packet[4];
 
2381
#ifdef CIT_TIM
 
2382
                        cit_CloseTimer(priv, FAKE_TIMER);       /* close timer if exit message was received */
 
2383
#endif
 
2384
                        DBG(PP, ErrorF("%s\t+ EXIT message (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
 
2385
                        break;
 
2386
                
 
2387
                case R_DUALTOUCHERROR:
 
2388
                        if (priv->dual_touch_count < priv->max_dual_count)
 
2389
                                priv->dual_touch_count++;
 
2390
                        DBG(PP, ErrorF("%s\t+ DUAL TOUCH ERROR message received\n", CI_INFO));
 
2391
                        break;
 
2392
                
 
2393
                case R_PRESSURE:        /* pressure message received */
 
2394
                        if (priv->packeti < 2)
 
2395
                        {
 
2396
                                DBG(PP, ErrorF("%s\t- pressure message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
 
2397
                                break;
 
2398
                        }
 
2399
                        priv->state |= CIT_TOUCHED;
 
2400
                        if (priv->packet[1] == PRESS_EXCEED)
 
2401
                                priv->state |= CIT_PRESSED;
 
2402
                        else if(priv->packet[1] == PRESS_BELOW)
 
2403
                        {
 
2404
                                priv->enter_touched = 0;                /* reset coordinate report counter */
 
2405
                                priv->state &= ~CIT_PRESSED;
 
2406
                        }
 
2407
                        else
 
2408
                                DBG(PP, ErrorF("%sPressure Message Error\n", CI_ERROR));
 
2409
 
 
2410
                        DBG(PP, ErrorF("%s\t+ pressure %s message\n", CI_INFO, priv->packet[1] ? "enter":"exit"));
 
2411
                        break;
 
2412
                
 
2413
                default:
 
2414
                        DBG(PP, ErrorF("%s\t* unhandled message:", CI_ERROR));
 
2415
                        for (i=0; i<priv->packeti; i++)
 
2416
                        {
 
2417
                                DBG(PP, ErrorF(" 0x%02X", priv->packet[i]));
 
2418
                        }
 
2419
                        DBG(PP, ErrorF("\n"));
 
2420
        }
 
2421
        /* generate button state */
 
2422
        switch (priv->click_mode)
 
2423
        {
 
2424
                case CM_ZPRESS:
 
2425
                        DBG(PP, ErrorF("%s\t+ ZPress, button ", CI_INFO));
 
2426
                        if (priv->state & CIT_PRESSED)
 
2427
                        {
 
2428
                                priv->state |= CIT_BUTTON;
 
2429
                                DBG(PP, ErrorF("down"));
 
2430
                        }
 
2431
                        else
 
2432
                        {
 
2433
                                priv->state &= ~CIT_BUTTON;
 
2434
                                DBG(PP, ErrorF("up"));
 
2435
                        }
 
2436
 
 
2437
                        break;
 
2438
 
 
2439
                case CM_ZPRESSEXIT:
 
2440
                        DBG(PP, ErrorF("%s\t+ ZPressExit, button ", CI_INFO));
 
2441
                        if (priv->state & CIT_PRESSED)
 
2442
                        {
 
2443
                                priv->state |= CIT_BUTTON;
 
2444
                                DBG(PP, ErrorF("down"));
 
2445
                        }
 
2446
                        else if (!(priv->state & CIT_TOUCHED))
 
2447
                        {
 
2448
                                priv->state &= ~CIT_BUTTON;
 
2449
                                DBG(PP, ErrorF("up"));
 
2450
                        }
 
2451
                        break;
 
2452
 
 
2453
                case CM_DUAL:
 
2454
                        DBG(PP, ErrorF("%s\t+ Dual Touch, button ", CI_INFO));
 
2455
                        if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
 
2456
                        {
 
2457
                                priv->state |= CIT_BUTTON;
 
2458
                                DBG(PP, ErrorF("down"));
 
2459
                        }
 
2460
                        else if (priv->dual_touch_count == 0)
 
2461
                        {
 
2462
                                priv->state &= ~CIT_BUTTON;
 
2463
                                DBG(PP, ErrorF("up"));
 
2464
                        }
 
2465
                        break;
 
2466
                
 
2467
                case CM_DUALEXIT:
 
2468
                        DBG(PP, ErrorF("%s\t+ Dual Exit, button ", CI_INFO));
 
2469
                        if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
 
2470
                        {
 
2471
                                priv->dual_flg = TRUE;
 
2472
                                priv->state |= CIT_BUTTON;
 
2473
                                DBG(PP, ErrorF("down"));
 
2474
                        }
 
2475
                        else if (!(priv->state & CIT_TOUCHED))
 
2476
                        {
 
2477
                                priv->state &= ~CIT_BUTTON;
 
2478
                                DBG(PP, ErrorF("up"));
 
2479
                        }
 
2480
                        break;
 
2481
 
 
2482
                default:        /* default to enter mode */
 
2483
                        DBG(PP, ErrorF("%s\t+ Enter Mode, button ", CI_INFO));
 
2484
                        if (priv->state & CIT_TOUCHED)
 
2485
                        {
 
2486
                                priv->state |= CIT_BUTTON;
 
2487
                                DBG(PP, ErrorF("down"));
 
2488
                        }
 
2489
                        else
 
2490
                        {
 
2491
                                priv->state &= ~CIT_BUTTON;
 
2492
                                DBG(PP, ErrorF("up"));
 
2493
                        }
 
2494
                        break;
 
2495
        }
 
2496
        DBG(PP, ErrorF("\n"));
 
2497
        DBG(PP, ErrorF("%s\t+ Click Mode=%d\n", CI_INFO, priv->click_mode));
 
2498
        DBG(PP+1, ErrorF("%s\t+ exit state  = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
 
2499
        DBG(PP+1, ErrorF("%s\t  raw_x=%d, raw_y=%d\n", CI_INFO, priv->raw_x, priv->raw_y));
 
2500
}
 
2501
 
 
2502
 
 
2503
 
 
2504
/*****************************************************************************
 
2505
 *      [cit_GetPressureSensors]
 
2506
 ****************************************************************************/
 
2507
static Bool cit_GetPressureSensors(cit_PrivatePtr priv)
 
2508
{
 
2509
        int             i;
 
2510
        Bool    res;
 
2511
 
 
2512
        cit_Flush(priv);
 
2513
        cit_SendCommand(priv->buffer, C_GETHARDWARE, 1, GH_SENSORCOUNT);
 
2514
        /*
 
2515
            touch responds within 1 millisecond,
 
2516
            but it takes some time, until the command is sent and received!
 
2517
        */
 
2518
        for (i=0; i<5; i++)
 
2519
        {
 
2520
                cit_SetBlockDuration(priv, 500000);
 
2521
                res = cit_GetPacket(priv);
 
2522
                if ((res == Success) || (priv->lex_mode == cit_idle));
 
2523
                        break;
 
2524
        }
 
2525
        if (res != Success)
 
2526
        {
 
2527
                DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
 
2528
                return (!Success);
 
2529
        }
 
2530
        /* examine packet */
 
2531
        if (priv->packeti < 2+CTS_SENSORCOUNT_LEN)
 
2532
        {
 
2533
                DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
 
2534
                    2+CTS_SENSORCOUNT_LEN,
 
2535
                    priv->packeti));
 
2536
                return (!Success);
 
2537
        }
 
2538
        if (priv->packet[0] != (C_GETHARDWARE & CMD_REP_CONV))
 
2539
        {
 
2540
                DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2541
                                                (C_GETHARDWARE & CMD_REP_CONV), priv->packet[0]));
 
2542
                return (!Success);
 
2543
        }
 
2544
        if (priv->packet[1] != GH_SENSORCOUNT)
 
2545
        {
 
2546
                DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
 
2547
                                                GH_SENSORCOUNT, priv->packet[1]));
 
2548
                return (!Success);
 
2549
        }
 
2550
        /* this is our packet! check contents */
 
2551
        ErrorF("%sPressureSensors: \"%d\"\n", CI_INFO, priv->packet[2]);
 
2552
        priv->pressure_sensors = priv->packet[2];
 
2553
        return (Success);
 
2554
}
 
2555
 
 
2556
 
 
2557
/*****************************************************************************
 
2558
 *      [cit_ZPress] tell if click mode is ZPress (True if ZPress)
 
2559
 ****************************************************************************/
 
2560
static int cit_ZPress(cit_PrivatePtr priv)
 
2561
{
 
2562
        if((priv->click_mode == CM_ZPRESS) || (priv->click_mode == CM_ZPRESSEXIT))
 
2563
                return (TRUE);
 
2564
        else
 
2565
                return (FALSE);
 
2566
}
 
2567
 
 
2568
 
 
2569
/*****************************************************************************
 
2570
 *      [cit_SetEnterCount] set enter_count according click_mode
 
2571
 ****************************************************************************/
 
2572
static void cit_SetEnterCount(cit_PrivatePtr priv)
 
2573
{
 
2574
        if(cit_ZPress(priv))    /* Test if 3D Mode is active and set Options according */
 
2575
                priv->enter_count = priv->enter_count_Z;
 
2576
        else priv->enter_count = priv->enter_count_no_Z;
 
2577
        ErrorF("%scit_SetEnterCount: Count=%d\n", CI_CONFIG, priv->enter_count);
 
2578
}
 
2579
 
 
2580
 
 
2581
/*****************************************************************************
 
2582
 *      [cit_SendPWMFreq] send pwm frequency of PWM signal to the touch
 
2583
 ****************************************************************************/
 
2584
static void cit_SendPWMFreq(cit_PrivatePtr priv)
 
2585
{
 
2586
        if(priv->pwm_freq >= 0) /* -1 is switched off (no SetPWMFreq set in XF86Config */
 
2587
        {
 
2588
                cit_SendCommand(priv->buffer, C_SETPWMFREQ, 2,
 
2589
                                                                                                                LOBYTE(priv->pwm_freq),
 
2590
                                                                                                                HIBYTE(priv->pwm_freq));
 
2591
                DBG(3,ErrorF("%scit_SendPWMFreq: Freq=%d\n", CI_CONFIG, priv->pwm_freq));
 
2592
        }
 
2593
        else
 
2594
                DBG(3,ErrorF("%scit_SendPWMFreq: Frequency not set\n", CI_CONFIG));
 
2595
}
 
2596
 
 
2597
 
 
2598