2
* $XFree86: xc/programs/Xserver/hw/xfree86/input/magictouch/xf86MagicTouch.c,v 1.3 2003/01/12 03:55:50 tsi Exp $
5
#include <xf86Version.h>
6
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0)
21
#include <xf86_ansic.h>
23
#include <xf86_OSproc.h>
24
#include <xf86Xinput.h>
28
#include <xf86Module.h>
31
#else /* XFREE86_V4 */
40
#include "scrnintstr.h"
45
#if defined(sun) && !defined(i386)
52
#else /* defined(sun) && !defined(i386) */
56
#include "xf86Procs.h"
57
#include "xf86_OSlib.h"
58
#include "xf86_Config.h"
59
#include "xf86Xinput.h"
60
#include "xf86Version.h"
61
#endif /* defined(sun) && !defined(i386) */
63
#if !defined(sun) || defined(i386)
68
#include "extnsionst.h"
70
#endif /* !defined(sun) || defined(i386) */
72
#endif /* XFREE86_V4 */
76
#if !defined(sun) || defined(i386)
78
***************************************************************************
80
* Configuration descriptor.
82
***************************************************************************
86
#define MAGIC_DEVICE_NAME 2
93
#define HISTORY_SIZE 9
95
#define ALWAYS_CORE 11
100
static SymTabRec MagicTab[] = {
101
{ ENDSUBSECTION, "endsubsection" },
103
{ MAGIC_DEVICE_NAME, "devicename" },
104
{ SCREEN_NO, "screenno" },
105
{ MAXX, "maximumxposition" },
106
{ MAXY, "maximumyposition" },
107
{ MINX, "minimumxposition" },
108
{ MINY, "minimumyposition" },
109
{ DEBUG_LEVEL, "debuglevel" },
110
{ HISTORY_SIZE, "historysize" },
111
{ LINK_SPEED, "linkspeed" },
112
{ ALWAYS_CORE, "alwayscore" },
113
{ SWAP_AXES, "swapxy" },
114
{ N_SAMPLE_X, "numsamplex" },
115
{ N_SAMPLE_Y, "numsampley" },
125
static SymTabRec LinkSpeedTab[] = {
131
#endif /* !defined(sun) || defined(i386) */
134
* This struct connects a line speed with
135
* a compatible motion packet delay. The
136
* driver will attempt to enforce a correct
137
* delay (according to this table) in order to
138
* avoid losing data in the touchscreen controller.
139
* LinkSpeedValues should be kept in sync with
145
} LinkParameterStruct;
147
static LinkParameterStruct LinkSpeedValues[] = {
153
#endif /* XFREE86_V4 */
157
***************************************************************************
161
***************************************************************************
163
#define MAGIC_PACKET_SIZE 5
164
#define MAGIC_PORT "/dev/magictouch"
165
#define MAGIC_LINK_SPEED B9600
167
/* First byte of the packet */
168
#define MGCT_TOUCH 0x01
169
#define MGCT_RKEY 0x02
170
#define MGCT_LKEY 0x04
171
#define MGCT_MKEY 0x08
172
#define MGCT_CLICK_STATUS 0x10
179
***************************************************************************
183
***************************************************************************
185
#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
186
#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
188
/* This one is handy, thanx Fred ! */
196
static int debug_level = 0;
199
#define DBG(lvl, f) {if ((lvl) == debug_level) { f; } }
211
#define SYSCALL(call) call
212
#define read(fd, ptr, num) xf86ReadSerial(fd, ptr, num)
213
#define write(fd, ptr, num) xf86WriteSerial(fd, ptr, num)
214
#define close(fd) xf86CloseSerial(fd)
215
#define strdup(str) xf86strdup(str)
224
***************************************************************************
226
* Device private records.
228
***************************************************************************
230
typedef struct _MagicPrivateRec {
231
char *input_dev; /* The touchscreen input tty */
232
int min_x; /* Minimum x reported by calibration */
233
int max_x; /* Maximum x */
234
int min_y; /* Minimum y reported by calibration */
235
int max_y; /* Maximum y */
237
int link_speed; /* Speed of the RS232 link connecting the ts. */
239
int screen_no; /* Screen associated with the device */
240
int screen_width; /* Width of the associated X screen */
241
int screen_height; /* Height of the screen */
242
int swap_axes; /* Swap X an Y axes if != 0 */
243
unsigned char packet_buf[MAGIC_PACKET_SIZE]; /* Assembly buffer */
245
int buf_x[MEDIE_X], i_x, num_medie_x;
246
int buf_y[MEDIE_Y], i_y, num_medie_y;
247
Bool first_x, first_y;
251
} MagicPrivateRec, *MagicPrivatePtr;
255
#if !defined(sun) || defined(i386)
257
****************************************************************************
259
* Configure the device driver from configuration data
260
****************************************************************************
263
xf86MagicConfig(LocalDevicePtr *array,
268
LocalDevicePtr local = array[inx];
269
MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
272
while ((token = xf86GetToken(MagicTab)) != ENDSUBSECTION) {
276
if (xf86GetToken(NULL) != STRING) {
277
xf86ConfigError("MagicTouch input port expected");
279
priv->input_dev = strdup(val->str);
281
ErrorF("%s MagicTouch input port: %s\n",
282
XCONFIG_GIVEN, priv->input_dev);
286
case MAGIC_DEVICE_NAME:
287
if (xf86GetToken(NULL) != STRING) {
288
xf86ConfigError("Magictouch device name expected");
290
local->name = strdup(val->str);
292
ErrorF("%s MagicTouch X device name: %s\n",
293
XCONFIG_GIVEN, local->name);
298
if (xf86GetToken(NULL) != NUMBER) {
299
xf86ConfigError("MagicTouch screen number expected");
301
priv->screen_no = val->num;
303
ErrorF("%s MagicTouch associated screen: %d\n",
304
XCONFIG_GIVEN, priv->screen_no);
310
int ltoken = xf86GetToken(LinkSpeedTab);
314
xf86ConfigError("MagicTouch link speed expected");
316
priv->link_speed = LinkSpeedValues[ltoken-1].speed;
318
ErrorF("%s MagicTouch link speed: %s bps\n",
319
XCONFIG_GIVEN, (LinkSpeedTab[ltoken-1].name)+1);
325
if (xf86GetToken(NULL) != NUMBER) {
326
xf86ConfigError("MagicTouch maximum x position expected");
328
priv->max_x = val->num;
330
ErrorF("%s MagicTouch maximum x position: %d\n",
331
XCONFIG_GIVEN, priv->max_x);
336
if (xf86GetToken(NULL) != NUMBER) {
337
xf86ConfigError("MagicTouch maximum y position expected");
339
priv->max_y = val->num;
341
ErrorF("%s MagicTouch maximum y position: %d\n",
342
XCONFIG_GIVEN, priv->max_y);
347
if (xf86GetToken(NULL) != NUMBER) {
348
xf86ConfigError("MagicTouch minimum x position expected");
350
priv->min_x = val->num;
352
ErrorF("%s MagicTouch minimum x position: %d\n",
353
XCONFIG_GIVEN, priv->min_x);
358
if (xf86GetToken(NULL) != NUMBER) {
359
xf86ConfigError("MagicTouch minimum y position expected");
361
priv->min_y = val->num;
363
ErrorF("%s MagicTouch minimum y position: %d\n",
364
XCONFIG_GIVEN, priv->min_y);
369
if (xf86GetToken(NULL) != NUMBER) {
370
xf86ConfigError("MagicTouch driver debug level expected");
372
debug_level = val->num;
375
ErrorF("%s MagicTouch debug level sets to %d\n", XCONFIG_GIVEN,
378
ErrorF("%s MagicTouch debug not available\n",
379
XCONFIG_GIVEN, debug_level);
385
if (xf86GetToken(NULL) != NUMBER) {
386
xf86ConfigError("MagicTouch motion history size expected");
388
local->history_size = val->num;
390
ErrorF("%s MagicTouch motion history size is %d\n", XCONFIG_GIVEN,
391
local->history_size);
396
xf86AlwaysCore(local, TRUE);
398
ErrorF("%s MagicTouch device will always stays core pointer\n",
406
ErrorF("%s MagicTouch device will work with X and Y axes swapped\n",
412
if (xf86GetToken(NULL) != NUMBER) {
413
xf86ConfigError("MagicTouch driver NumSamplesX expected");
415
priv->num_medie_x = val->num;
418
if (priv->num_medie_x>MEDIE_X)
419
priv->num_medie_x=MEDIE_X;
422
ErrorF("NumSampleX = %d\n", priv->num_medie_x)
428
if (xf86GetToken(NULL) != NUMBER) {
429
xf86ConfigError("MagicTouch driver NumSamplesY expected");
431
priv->num_medie_y = val->num;
433
if (priv->num_medie_y>MEDIE_Y)
434
priv->num_medie_y=MEDIE_Y;
437
ErrorF("NumSampleY = %d\n", priv->num_medie_y)
442
FatalError("Unexpected EOF (missing EndSubSection)");
446
xf86ConfigError("MagicTouch subsection keyword expected");
451
if (priv->max_x - priv->min_x <= 0) {
452
ErrorF("%s MagicTouch: reverse x mode (minimum x position >= maximum x position)\n",
455
if (priv->max_y - priv->min_y <= 0) {
456
ErrorF("%s MagicTouch: reverse y mode (minimum y position >= maximum y position)\n",
460
DBG(2, ErrorF("xf86MagicConfig port name=%s\n", priv->input_dev))
465
#endif /* !defined(sun) || defined(i386) */
466
#endif /* XFREE86_V4 */
468
/****************************************************************************
470
* xf86MagicQueryOK --
471
* Testa la presenza del touch controller.
472
* Si osserva che al primo accesso al touch dopo l'accensione e'
473
* presente nel buffer di ricezione il codice 0xF che identifica la
474
* vera presenza del touch controller.
475
* Dal secondo accesso in poi bisogna interrogare il touch controller
476
* per verificarne l'esistenza.
477
****************************************************************************
480
xf86MagicQueryOK(int fd)
488
/* Provo a leggere un byte dal buffer di ricezione */
489
SYSCALL( result = read(fd, &buf, 1) );
491
DBG(4, ErrorF("<<%s[%d]>> QueryOK: read --> %d\n", __FILE__, __LINE__, result) );
493
/* Se result e' -1 vuol dire che non c'e' nessun carattere nel
494
buffer. Allora X/Window e' stato avviato almeno una volta */
497
ErrorF("Avvio n-esimo di X/Windows\n");
498
ErrorF("Controllo presenza Touch Controller\n")
501
/* Cerco il touch controller. Invio il carattere 0x00. */
503
SYSCALL( result = write(fd, &buf, 1) );
505
/* Attendo 20 ms per dare il tempo al touch controller di
509
/* Leggo la risposta */
510
SYSCALL( result = read(fd, &buf, 1) );
513
ErrorF("QueryOK: buf==%X, result==%d\n", buf, result)
517
/* Se result<0 allora il touch controller non e' presente sul
518
disposito. Non posso proseguire */
521
ErrorF("<<%s[%d]>> result<0\n", __FILE__, __LINE__)
525
/* Se il touch controller ha risposto allora controllo cosa ha
528
ok = (buf==0xF ? Success : !Success);
530
ErrorF("<<%s[%d]>> QueryOK buf==%x\n", __FILE__, __LINE__, buf)
538
***********************************************************************
542
***********************************************************************
545
xf86MagicControl(DeviceIntPtr dev,
548
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
549
MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
550
unsigned char map[] = { 0, 1 };
551
unsigned char req[MAGIC_PACKET_SIZE], replay[MAGIC_PACKET_SIZE];
556
DBG(2, ErrorF("MagicTouch init...\n") );
558
/* Controlla il numero di schermo selezionato */
559
if (priv->screen_no >= screenInfo.numScreens || priv->screen_no<0)
561
/* Legge le dimensioni dello schermo */
562
priv->screen_width = screenInfo.screens[priv->screen_no]->width;
563
priv->screen_height = screenInfo.screens[priv->screen_no]->height;
565
if (InitButtonClassDeviceStruct(dev, 1, map)==FALSE) {
566
ErrorF("Impossibile allocare ButtonClassDeviceStruct per MagicTouch\n");
570
if (InitFocusClassDeviceStruct(dev)==FALSE) {
571
ErrorF("Impossibile allocare FocusClassDeviceStruct per MagicTouch\n");
576
* Il movimento viene eseguito su due assi in coordinate assolute.
578
if (InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents, local->history_size, Absolute) == FALSE )
580
ErrorF("MagicTouch ValuatorClassDeviceStruct: ERRORE\n");
584
InitValuatorAxisStruct(dev, 0, priv->min_x, priv->max_x,
589
InitValuatorAxisStruct(dev, 1, priv->min_y, priv->max_y,
595
if (InitFocusClassDeviceStruct(dev)==FALSE) {
596
ErrorF("Impossibile allocare FocusClassDeviceStruct per MagicTouch\n");
600
* Alloca il buffer degli eventi spostamento
602
xf86MotionHistoryAllocate(local);
605
AssignTypeAndName(dev, local->atom, local->name);
606
#endif /* XFREE86_V4 */
608
DBG(2, ErrorF("MagicTouch INIT OK\n") );
610
break; /* DEVICE_INIT*/
613
DBG(2, ErrorF("MagicTouch ON\n") );
616
struct termios termios_tty;
620
DBG(2, ErrorF("Opening device...\n") );
623
local->fd = xf86OpenSerial(local->options);
625
ErrorF("Impossibile aprire MagicTouch\n");
629
SYSCALL( local->fd = open(priv->input_dev, O_RDWR | O_NDELAY, 0) );
631
Error("Impossibile aprire MagicTouch\n");
635
DBG(3, ErrorF("Provo a configurare il MagicTouch\n") );
638
memset(&termios_tty, 0, sizeof(termios_tty) );
639
termios_tty.c_iflag = 0;
640
termios_tty.c_cflag = priv->link_speed | CS8 | CREAD | CLOCAL;
641
termios_tty.c_oflag = 0;
642
termios_tty.c_lflag = 0;
643
termios_tty.c_cc[VTIME]=0;
644
termios_tty.c_cc[VMIN]=1;
647
* Attivo l'RTS per abilitare il touch controller
650
SYSCALL( result = ioctl(local->fd, TIOCMGET, &status_line) );
653
Error("Impossibile leggere stato linee seriale\n");
657
status_line |= TIOCM_RTS;
658
SYSCALL( result = ioctl(local->fd, TIOCMSET, &status_line) );
661
Error("Impossibile settare stato linee seriale\n");
667
SYSCALL( result = tcsetattr(local->fd, TCSANOW, &termios_tty) );
670
Error("Impossibile configurare MagicTouch\n");
677
/* Controlla se e' presente il touch controller.*/
679
if (xf86MagicQueryOK(local->fd)!=Success) {
680
ErrorF("MagicTouch not present\n");
685
priv->e_presente = TRUE;
687
AddEnabledDevice(local->fd);
688
dev->public.on = TRUE;
689
} /* if (local->fd<0) */
690
break; /* DEVICE_ON */
694
DBG(2, ErrorF("MagicTouch OFF\n") );
695
dev->public.on = FALSE;
697
emoveEnabledDevice(local->fd);
699
SYSCALL( close(local->fd) );
701
DBG(2, ErrorF("OK\n") );
702
break; /* DEVICE_OFF*/
705
ErrorF("unsupported mode %d\n", mode);
707
} /* switch (mode) */
715
***************************************************************************
719
***************************************************************************
722
GetPacket(LocalDevicePtr local, unsigned char *buffer, int *n_rx, int fd)
727
MagicPrivatePtr priv=(MagicPrivatePtr) local->private;
729
DBG(6, ErrorF("Entering GetPacket with packet_pos == %d\n", *n_rx) );
732
num_bytes=read(fd, buffer+*n_rx, MAGIC_PACKET_SIZE-*n_rx)
735
/* Se e' il primo ingresso nella procedura e ho letto un solo byte,
736
allora e' arrivato lo 0x0F di risposta all-inizializzazione del
738
/* Sto gia' leggendo un pacchetto normale */
742
for (i=0; i<*n_rx; i++)
743
ErrorF("%3X", buffer[i]);
747
ok = (*n_rx==MAGIC_PACKET_SIZE ? Success : !Success );
754
ErrorF("GetPacket OK\n");
756
ErrorF("GetPacket FAIL\n")
763
************************************************************************
767
************************************************************************
770
int medie_x(LocalDevicePtr local, int x)
774
MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
777
ErrorF("Medie in X = %d\n", priv->num_medie_x)
781
priv->first_x = FALSE;
782
for (i=0; i<priv->num_medie_x; i++)
788
priv->buf_x[priv->i_x] = x;
790
if (priv->i_x>=priv->num_medie_x)
794
for (i=0; i<priv->num_medie_x; i++)
795
medie += priv->buf_x[i];
797
res = (int)(medie/priv->num_medie_x);
804
int medie_y(LocalDevicePtr local, int y)
808
MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
811
ErrorF("Medie in Y = %d\n", priv->num_medie_y)
815
priv->first_y = FALSE;
816
for (i=0; i<priv->num_medie_y; i++)
822
priv->buf_y[priv->i_y] = y;
824
if (priv->i_y>=priv->num_medie_y)
828
for (i=0; i<priv->num_medie_y; i++)
829
medie += priv->buf_y[i];
831
res = (int)(medie/priv->num_medie_y);
839
int MAX(int x, int y)
841
return (x>=y ? x : y);
845
#define MAX(x,y) (x>=y ? x : y)
848
xf86MagicReadInput(LocalDevicePtr local)
850
MagicPrivatePtr priv = (MagicPrivatePtr)(local->private);
853
static int n_coms = 0;
855
if (!priv->e_presente) {
857
ErrorF("<<%s[%d]>> ReadInput: Touch Controller non inizializzato\n")
862
DBG(4, ErrorF("Entering ReadInput\n"));
864
* Try to get a packet.
866
if (GetPacket(local, priv->packet_buf, &priv->packet_pos, local->fd)==Success)
868
/* Calculate the (x,y) coord of pointer */
869
cur_x = priv->packet_buf[1];
871
cur_x |= priv->packet_buf[2];
873
cur_y = priv->packet_buf[3];
875
cur_y |= priv->packet_buf[4];
877
touch_now = priv->packet_buf[0] & MGCT_TOUCH == MGCT_TOUCH;
879
/* Se c'e' pressione sul touch inizio a calcolare la posizione
880
e a spostare il cursore grafico */
883
ErrorF("Touch premuto: medio i valori di posizione\n")
885
cur_x = medie_x(local, cur_x);
886
cur_y = medie_y(local, cur_y);
890
ErrorF("Touch rilasciato:\n"
891
"\tazzeramento buffer memoria\n"
892
"\tposizionamento immediato\n")
895
/* Se non ho pressione allora comando lo spostamento
896
del cursore senza mediare. Svuoto il buffer delle medie */
897
priv->first_x = TRUE;
898
priv->first_y = TRUE;
900
/* Comando lo spostamento */
901
xf86PostMotionEvent(local->dev, TRUE, 0, 2, cur_x, cur_y);
902
/* comanda la pressione del tasto */
905
ErrorF("touch_now==%s\n", (touch_now==TRUE ? "TRUE" : "FALSE") )
907
if (touch_now!=priv->click_on) {
909
ErrorF("Bottone == %s\n", (touch_now==TRUE ? "PREMUTO" : "RILASCAITO") )
911
priv->click_on = touch_now;
912
xf86PostButtonEvent(local->dev, TRUE, 1, touch_now, 0, 2, cur_x, cur_y);
919
************************************************************************
923
************************************************************************
926
xf86MagicConvert(LocalDevicePtr local,
938
MagicPrivatePtr priv = (MagicPrivatePtr) local->private;
939
int width = priv->max_x - priv->min_x;
940
int height = priv->max_y - priv->min_y;
941
int input_x, input_y;
943
if (first != 0 || num != 2) {
947
DBG(3, ErrorF("MagicConvert: v0(%d), v1(%d)\n", v0, v1));
949
if (priv->swap_axes) {
957
*x = (priv->screen_width * (input_x - priv->min_x)) / width;
958
*y = (priv->screen_height - (priv->screen_height * (input_y - priv->min_y)) / height);
962
* Need to check if still on the correct screen.
963
* This call is here so that this work can be done after
964
* calib and before posting the event.
966
xf86XInputSetScreen(local, priv->screen_no, *x, *y);
969
DBG(3, ErrorF("MagicConvert: x(%d), y(%d)\n", *x, *y));
977
************************************************************************
981
************************************************************************
983
static LocalDevicePtr
985
xf86MagicAllocate(void)
987
xf86MagicAllocate(InputDriverPtr drv)
991
LocalDevicePtr local = (LocalDevicePtr) xalloc( sizeof(LocalDeviceRec) );
993
LocalDevicePtr local = xf86AllocateInput(drv, 0);
996
MagicPrivatePtr priv = (MagicPrivatePtr) xalloc( sizeof(MagicPrivateRec) );
998
/* Controlla la corretta allocazione di buffers. Se uno dei buffers non
999
e' stato allocato correttamente termina l'inizializzazione
1013
/* I buffers sono allocati correttamente */
1015
priv->input_dev = strdup(MAGIC_PORT);
1017
priv->input_dev = MAGIC_PORT;
1018
priv->link_speed = MAGIC_LINK_SPEED;
1025
priv->screen_no = 0;
1026
priv->screen_width = -1;
1027
priv->screen_height = -1;
1028
priv->swap_axes = 0;
1030
priv->first_y = TRUE;
1031
priv->first_entry = TRUE;
1032
priv->e_presente = FALSE;
1033
priv->click_on = FALSE;
1036
priv->packet_pos = 0;
1037
bzero(priv->buf_x, MEDIE_X);
1038
bzero(priv->buf_y, MEDIE_Y);
1039
priv->num_medie_x = MEDIE_X;
1040
priv->num_medie_y = MEDIE_Y;
1042
local->name = XI_TOUCHSCREEN;
1046
#if !defined(sun) || defined(i386)
1047
local->device_config = xf86MagicConfig;
1048
#endif /* !defined(sun) || defined(i386) */
1049
#endif /* XFREE86_V4*/
1051
local->device_control = xf86MagicControl;
1052
local->read_input = xf86MagicReadInput;
1053
local->control_proc = NULL;
1054
local->close_proc = NULL;
1055
local->switch_mode = NULL;
1056
local->conversion_proc = xf86MagicConvert;
1057
local->reverse_conversion_proc = NULL;
1061
local->private = priv;
1062
local->type_name = "MagicTouch";
1063
local->history_size = 0;
1067
} /* xf86MagicAllocae */
1074
* Sezione relativa a X < 4.0.0
1077
DeviceAssocRec magictouch_assoc = {
1082
#ifdef DYNAMIC_MODULE
1085
int init_module(unsigned long server_version)
1087
int init_xf86Magic(unsigned long server_version)
1090
/* Aggiunge l'assiocazione per il touchscreen */
1091
xf86AddDeviceAssoc(&magictouch_assoc);
1093
/* Controlla la versione */
1094
if (server_version != XF86_VERSION_CURRENT) {
1095
ErrorF("Warining: MagicTouch module compiled for version %s\n", XF86_VERSION);
1100
#endif /* DYNAMIC_MODULE */
1104
* Sezione relativa a X >= 4.0.0
1107
#endif /* XFREE86_V4 */