1 /*
2    (c) Copyright 2001-2009  The world wide DirectFB Open Source Community (directfb.org)
3    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
4 
5    All rights reserved.
6 
7    Written by Denis Oliver Kropp <dok@directfb.org>,
8               Andreas Hundt <andi@fischlustig.de>,
9               Sven Neumann <neo@directfb.org>,
10               Ville Syrj�l� <syrjala@sci.fi> and
11               Claudio Ciccani <klan@users.sf.net>.
12 
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2 of the License, or (at your option) any later version.
17 
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22 
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the
25    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26    Boston, MA 02111-1307, USA.
27 */
28 
29 /*
30  * This is a driver for a Zytronic Touchscreen.
31  * Note that is not the standard Zytronic (microsoft-DLL controllable) touchscreen;
32  * It uses a micro-controller similar to the one of Elo or Mutouch touchscreens.
33  * The configuration inside directfbrc is equal to Elo/Mutouch config.
34  * All three touchscreens are conceptualised to use 4096x4096 virtual resolutions.
35  *
36  * This driver has been kindly provided by Jacques Luder.
37  * Written by Eric Wajman - Jacques Luder.
38  */
39 
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <errno.h>
45 #include <fcntl.h>
46 
47 #include <termios.h>
48 
49 #include <sys/ioctl.h>
50 #include <sys/types.h>
51 #include <sys/time.h>
52 
53 #include <linux/serial.h>
54 
55 #include <directfb.h>
56 
57 #include <core/coredefs.h>
58 #include <core/coretypes.h>
59 
60 #include <core/input.h>
61 #include <core/system.h>
62 
63 #include <misc/conf.h>
64 
65 #include <direct/debug.h>
66 #include <direct/mem.h>
67 #include <direct/messages.h>
68 #include <direct/memcpy.h>
69 #include <direct/thread.h>
70 
71 #include <core/input_driver.h>
72 
73 DFB_INPUT_DRIVER( zytronic )
74 
75 
76 // codes de retours :
77   #define ZYT_ERR_NOT_START_OF_READ                   -1 // erreur si on demande un lecture de msg alors que l'on ne
78                                                          // re�oit pas ':' comme premier caract�re (� priori ne devrait
79                                                          // jamais arriver...?)
80   #define ZYT_ERR_CANT_OPEN                           -2 // erreur si on n'arrive pas � ouvrir le "fichier" li� au device.
81   #define ZYT_ACK_NACK                                -3 // pr�vient que le message lu est un ack/nack
82                                                          // et non un vrai message
83   #define ZYT_END_OF_CONF_FILE                        -4 // pr�vient que l'on a atteint la fin du fichier de configuration
84 
85 // infos utiles :
86   #define ZYT_PAQUET_SIZE                           128 // taille max d'un msg envoy�/re�u (pour la taille du tableau)
87   #define ZYT_ENDOFMSG_CR                           13  // 1er caract�re de fin de message re�u
88   #define ZYT_ENDOFMSG_LF                           10  // 2�me caract�re de fin de message re�u
89 
90 // commandes protocoles (pas toutes utilis�es dans ce driver) :
91   #define ZYT_ENABLE_CONTROLLER                     201
92   #define ZYT_DISABLE_CONTROLLER                    200
93 
94   #define ZYT_XY_TOUCH_MESSAGE_MODE                 210
95   #define ZYT_INIT_FW_RESET                         72
96   #define ZYT_FORCE_EQUALISATION                    69
97   #define ZYT_SET_TOUCH_THRESHOLD                   100 // + valeur de Threshold voulue (entre 5 et 50)
98 
99   #define ZYT_REQ_FW_AND_ID                         86
100   #define ZYT_REQ_NON_VOLATILE_SETTINGS             88
101   #define ZYT_RESTORE_FACTORY_DEFAULT_SETTINGS      68
102   #define ZYT_REQ_SHORT_STATUS_MESSAGE              71
103 
104   #define ZYT_REQ_SINGLE_FRAME_OF_RAW_SENSOR_DATA   82
105   #define ZYT_ENABLE_CONTINUOUS_RAW_SENSOR_DATA     205
106   #define ZYT_DISABLE_CONTINUOUS_RAW_SENSOR_DATA    204
107 
108   #define ZYT_SET_FRAME_AVERAGING                   220 // + nombre de frame pour "xy averaging" voulue (1 � 9)
109   #define ZYT_SET_GLASS_THICKNESS                   230 // + valeur (ci dessous)
110     #define ZYT_GLASS_THIN                          0
111     #define ZYT_GLASS_MEDIUM                        1
112     #define ZYT_GLASS_THICK                         2
113 
114   #define ZYT_ENABLE_CONTROLLER_ACK_NAK             203
115   #define ZYT_DISABLE_CONTROLLER_ACK_NAK            202
116   #define ZYT_STORE_DATA_BLOCK                      213 // + le code � enregistrer (voir la doc du protocole...)
117   #define ZYT_RETRIEVE_DATA_BLOCK                   214 // + taile des infos � r�cup�rer (voir la doc du protocole...)
118 
119 // param�tres de notre fichier de configuration :
120   #define ZYT_CONF_FILE                             "/etc/zyposConf" // le nom de notre fichier de configuration
121   #define ZYT_CONF_DIM_DALLE_X                      "dimDalleX"
122   #define ZYT_CONF_DIM_DALLE_Y                      "dimDalleY"
123   #define ZYT_CONF_SEUIL                            "seuil"
124   #define ZYT_CONF_EPAISSEUR                        "epaisseur"
125   #define ZYT_CONF_ATTENTE_MULTI_CLIC               "attenteMultiClic"
126   #define ZYT_CONF_MODE                             "mode"
127   #define ZYT_CONF_FRAME_AVERAGING                  "frameAveraging"
128   #define ZYT_CONF_NB_CLIGN_TO_PRESS                "nbClignToPress"
129   #define ZYT_CONF_DEBUG                            "debug"
130 
131 // types d'action (pour ZytData->action):
132   #define ZYT_ACTION_TOUCH                          0x01
133   #define ZYT_ACTION_RELEASE                        0x00
134 
135 // les masques :
136   #define ZYT_MASK_ACTION                           0x40
137   #define ZYT_MASK_SYNC_MSG                         0x80
138 
139 typedef enum{
140   NO_DRAG_DROP=0,
141   CONTINUOUS=1,
142 } ZytMode;
143 
144 typedef enum{
145   NO_DEBUG=0,
146   DEBUG=1,
147 } ZytDebug;
148 
149 // structure du param�trage
150 typedef struct {
151   unsigned short dimDalleX;
152   unsigned short dimDalleY;
153   unsigned short seuil;
154   unsigned short epaisseur;
155   unsigned int attenteMultiClic;
156   ZytMode mode;
157   unsigned short frameRateAveraging;
158   unsigned short nbClignToPress;
159   ZytDebug debug;
160 } ZytConf_t;
161 
162 /* structure de data du Zytronic */
163 typedef struct __ZytData__ {
164   int fd;
165   DirectThread *thread;
166   CoreInputDevice *device;
167   unsigned short x;
168   unsigned short y;
169   unsigned char action;
170 } ZytData;
171 
172 /* Global Variables */
173 static unsigned char packet[ZYT_PAQUET_SIZE];
174 static struct termios options; // pour changer les configurations du port (avec cfmakeraw)
175 static struct termios saved_options;// pour sauvegarder l'ancienne configuration du port et la r�tablir apr�s
176 static ZytConf_t zytConf;
177 
178 // fonction pour faire des mini-pauses en millisecondes : (utile? on garde)
__mdelay(unsigned int msec)179 static inline void __mdelay(unsigned int msec)
180 {
181   struct timespec delay;
182 
183   delay.tv_sec = 0;
184   delay.tv_nsec = msec * 1000000;
185   nanosleep (&delay, NULL);
186 }
187 
188 // proc�dure pour envoyer un paquet au controleur Zytronic, encapsul� d'une certaine mani�re par rapport
189 // au protocole (pour Zytronic il y n'a rien autour du code OP_CODE lui m�me)
ZytSendPacket(int file,unsigned char * msg,unsigned char len)190 static inline void ZytSendPacket(int file, unsigned char *msg, unsigned char len)
191 {
192   write(file,msg,len);
193 }
194 
195 // proc�dure pour lire un "paquet" de donn�es venant du controleur (un message donc)
ZytReadMsg(int file,unsigned char * msg)196 static int ZytReadMsg(int file, unsigned char *msg)
197 {
198   int i=0;
199   read(file,&msg[0],1);
200 
201   if(msg[0]==':'){ // si c'est un r�ponse � une commande :
202     do{ // on lit tant qu'on trouve pas les 2 caract�res de fin :
203       i++; // on commence � lire � 1 (car le 0 est d�j� lu)
204       read(file,&msg[i],1);
205     }while(msg[i]!=ZYT_ENDOFMSG_LF || msg[i-1]!=ZYT_ENDOFMSG_CR);
206   }else if(msg[0]==0xC0 || msg[0]==0x80){ // si c'est un appui ou un relachement sur la dalle :
207     // on lit les 4 caract�res pour la position du touch� :
208     for(i=1;i<5;i++){
209       read(file,&msg[i],1);
210     }
211   }else if(msg[0]==0x06 || msg[0]==0x15){ // si c'est un ACK/NACK on le dit
212     if(zytConf.debug==DEBUG){
213       D_INFO("ZYT, reception d'un ACK/NACK (6=ACK, 21=NACK): %d\n",msg[0]); //debug
214     }
215     return ZYT_ACK_NACK;
216   }else { // sinon : ce n'est pas le d�but d'une lecture => on a perdu des donne�s pr�c�demment ...
217     D_INFO("ZYT_ERR_NOT_START_OF_READ\n"); // �a ne devrait PAS arriver !
218     return ZYT_ERR_NOT_START_OF_READ;
219   }
220   if(zytConf.debug==DEBUG){
221     D_INFO("ZYT_READ_MSG : nb octets recus= %d\n",i); // debug
222   }
223 
224   return 0;
225 }
226 
227 #define WORD_ASSEMBLY(b1,b2) (((b2) << 7) | (b1))
228 // fonction qui permet de r�cup�rer les informations contenues dans un "message" en mode "touch XY mode" ***
ZytReadTouchMessage(ZytData * event)229 static int ZytReadTouchMessage(ZytData* event){
230   if( ZytReadMsg(event->fd,packet) != 0 ) {
231     return 0; // on renvoit qu'on a pas pu lire correctement
232   }
233 
234   // on r�cup�re les infos x,y et appui ou relachement:
235   if( (packet[0] & ZYT_MASK_ACTION) == 0 ){
236     event->action = ZYT_ACTION_RELEASE;
237   }else{
238     event->action = ZYT_ACTION_TOUCH;
239   }
240 
241   event->x = (float)(4096*WORD_ASSEMBLY(packet[1], packet[2])/zytConf.dimDalleX);
242   event->y = (float)(4096*WORD_ASSEMBLY(packet[3], packet[4])/zytConf.dimDalleY);
243 
244  return 1; // on dit que on a effectivement bien lu
245 }
246 
247 // proc�dure pour �crire un param�tre dans le fichier de configuration Zytronic :
ecrireConf(int f,char * sp,char * sv)248 static void ecrireConf(int f,char *sp, char *sv){
249   char tmp[100];
250 
251   strcpy(tmp,":");
252   strcat(tmp,sp);
253   strcat(tmp,"=");
254   strcat(tmp,sv);
255   strcat(tmp,";\n");
256   write(f,tmp,strlen(tmp));
257 }
258 
259 // proc�dure pour cr�er le fichier de configuration avec les valeurs par d�faut
createConfigFile(int * fdConf)260 static void createConfigFile(int *fdConf){
261   char tmp[10];
262 
263   // cr�ation du fichier :
264   *fdConf = open(ZYT_CONF_FILE,O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
265 
266   // mise en place des valeurs par d�faut :
267   sprintf(tmp,"%d",zytConf.dimDalleX);
268   ecrireConf(*fdConf,ZYT_CONF_DIM_DALLE_X,tmp);
269   sprintf(tmp,"%d",zytConf.dimDalleY);
270   ecrireConf(*fdConf,ZYT_CONF_DIM_DALLE_Y,tmp);
271   sprintf(tmp,"%d",zytConf.seuil);
272   ecrireConf(*fdConf,ZYT_CONF_SEUIL,tmp);
273   sprintf(tmp,"%d",zytConf.epaisseur);
274   ecrireConf(*fdConf,ZYT_CONF_EPAISSEUR,tmp);
275   sprintf(tmp,"%d",zytConf.attenteMultiClic);
276   ecrireConf(*fdConf,ZYT_CONF_ATTENTE_MULTI_CLIC,tmp);
277   sprintf(tmp,"%d",zytConf.mode);
278   ecrireConf(*fdConf,ZYT_CONF_MODE,tmp);
279   sprintf(tmp,"%d",zytConf.frameRateAveraging);
280   ecrireConf(*fdConf,ZYT_CONF_FRAME_AVERAGING,tmp);
281   sprintf(tmp,"%d",zytConf.nbClignToPress);
282   ecrireConf(*fdConf,ZYT_CONF_NB_CLIGN_TO_PRESS,tmp);
283   sprintf(tmp,"%d",zytConf.debug);
284   ecrireConf(*fdConf,ZYT_CONF_DEBUG,tmp);
285   D_INFO("fsync renvoi la valeur: %d\n",fsync(*fdConf)); //pour s'assurer qu'on �crit bien dans le fichier
286 }
287 
288 // proc�dure qui retourne le prochain param�tre lu dans le fichier de configuration
nextConf(int fdConf,char * param,char * res)289 static int nextConf(int fdConf,char *param, char *res){
290   char charActuel;
291   int i,nb=1;
292 
293   // note : on suppose pour l'instant qu'aucune erreur de lecture n'intervient, ni de fichier mal format� *** ...
294 
295   // on cherche le d�but d'un param�tre de configuration (ou la fin du fichier) :
296   while(charActuel!=':' && nb==1){
297     nb = read(fdConf,&charActuel,1);
298   }
299   if(nb==0){ // le cas �ch�ant, on pr�vient que le fichier ne contient pas d'autres param�tres (fin du fichier)
300     return ZYT_END_OF_CONF_FILE;
301   }
302 
303   // on enregistre le nom du param�tre:
304   i=0;
305   read(fdConf,&charActuel,1);
306   while(charActuel!='='){
307     param[i]=charActuel;
308     read(fdConf,&charActuel,1);
309     i++;
310   }
311   param[i]='\0';
312 
313 
314   // on enregistre la valeur de ce param�tre :
315   i=0;
316   read(fdConf,&charActuel,1);
317   while(charActuel!=';'){
318     res[i]=charActuel;
319     read(fdConf,&charActuel,1);
320     i++;
321   }
322   res[i]='\0';
323 
324   // on retourne le tout (en indiquant que tout s'est bien pass�, on a pas atteint la fin du fichier)
325   return 0;
326 }
327 
328 // proc�dure pour "activer" le device, en l'occurence : mettre les param�tres de base qui nous int�ressent nous :
ZytActivateDevice(int fd)329 static void ZytActivateDevice(int fd)
330 {
331   int fdConf,val;
332   char param[100],res[10];
333 
334   //param�tres par d�faut : (�galement utilis�s pour cr�er le fichier de configuration par la suite, s'il n'existe pas)
335   zytConf.dimDalleX = 1024;
336   zytConf.dimDalleY = 768;
337   zytConf.seuil = 10;
338   zytConf.epaisseur = 1;
339   zytConf.attenteMultiClic = 300;
340   // par d�faut on ne garde que le premier appui d'une s�rie : la "souris" ne bougera pas entre un appui et un relachement
341   zytConf.mode=NO_DRAG_DROP;
342   zytConf.frameRateAveraging=3;
343   zytConf.nbClignToPress=5; // le nombre d'appuis successifs pour comprendre un appui apr�s un clignotement
344   zytConf.debug=NO_DEBUG;
345 
346   // r�cup�ration des param�tres choisis, et cr�ation du fichier si besoin :
347   fdConf = open(ZYT_CONF_FILE,O_RDWR);
348   if(fdConf==-1){
349     D_INFO("ZYT, le fichier %s de configuration de la dalle zytronic n'existe pas, creation en cours...\n",ZYT_CONF_FILE);
350     createConfigFile(&fdConf);
351     D_INFO("ZYT, ...creation de %s finie.\n",ZYT_CONF_FILE);
352   }else{
353     D_INFO("ZYT, le fichier %s de configuration de la dalle zytronic existe.\n",ZYT_CONF_FILE);
354   }
355 
356   // puis, on charge les valeurs de configuration, en gardant les valeurs par d�faut pour les param�tres non pr�cis�s :
357   lseek(fdConf,0,SEEK_SET); // on retourne au d�but du fichier (au cas o� on vient de le cr��)
358   while(nextConf(fdConf,param,res)!=ZYT_END_OF_CONF_FILE){
359     val = atoi(res);
360     D_INFO("parametre : %s = %d\n",param,val); //debug
361     if(strcmp(param,ZYT_CONF_DIM_DALLE_X)==0){
362       zytConf.dimDalleX=val;
363     }else if(strcmp(param,ZYT_CONF_DIM_DALLE_Y)==0){
364       zytConf.dimDalleY=val;
365     }else if(strcmp(param,ZYT_CONF_SEUIL)==0){
366       zytConf.seuil=val;
367     }else if(strcmp(param,ZYT_CONF_EPAISSEUR)==0){
368       zytConf.epaisseur=val;
369     }else if(strcmp(param,ZYT_CONF_ATTENTE_MULTI_CLIC)==0){
370       zytConf.attenteMultiClic=val*1000; //on passe les millisecondes en microsecondes
371     }else if(strcmp(param,ZYT_CONF_MODE)==0){
372       zytConf.mode=val;
373     }else if(strcmp(param,ZYT_CONF_FRAME_AVERAGING)==0){
374       zytConf.frameRateAveraging=val;
375     }else if(strcmp(param,ZYT_CONF_NB_CLIGN_TO_PRESS)==0){
376       zytConf.nbClignToPress=val;
377     }else if(strcmp(param,ZYT_CONF_DEBUG)==0){
378       zytConf.debug=val;
379     }else {
380       D_INFO("ZYT, parametre non reconnu : %s\n",param);
381       D_INFO("ZYT, veuillez verifier le  fichier de configuration %s!\n",ZYT_CONF_FILE);
382     }
383   }
384   close(fdConf);
385 
386   // envoi des param�tres du controleur pour utilisation normale :
387   //packet[0]=ZYT_INIT_FW_RESET; // permet de "mieux" initialiser le controleur, utile? (long : ~5sec)
388   //ZytSendPacket(fd,packet,1); // attention, commande inutilisable telle qu'elle, car elle coupe la liaison
389      // et donc emp�che les commandes suivantes...
390      // (ici en l'occurence tout le param�trage qui suit...) !!!
391   packet[0]=ZYT_RESTORE_FACTORY_DEFAULT_SETTINGS;
392   ZytSendPacket(fd,packet,1);
393   packet[0]=ZYT_SET_FRAME_AVERAGING + zytConf.frameRateAveraging;
394   ZytSendPacket(fd,packet,1);
395   packet[0]=ZYT_DISABLE_CONTINUOUS_RAW_SENSOR_DATA;
396   ZytSendPacket(fd,packet,1);
397   packet[0]=ZYT_SET_TOUCH_THRESHOLD + zytConf.seuil;
398   ZytSendPacket(fd,packet,1);
399   packet[0]=ZYT_SET_GLASS_THICKNESS + zytConf.epaisseur;
400   ZytSendPacket(fd,packet,1);
401   packet[0]=ZYT_ENABLE_CONTROLLER;
402   ZytSendPacket(fd,packet,1);
403   packet[0]=ZYT_FORCE_EQUALISATION;
404   ZytSendPacket(fd,packet,1);
405   packet[0]=ZYT_XY_TOUCH_MESSAGE_MODE;
406   ZytSendPacket(fd,packet,1);
407 }
408 
409 // fonction pour "ouvrir" le p�riph�rique
410 // (c�d: ouvrir le fichier sp�cial qui permet de communiquer avec le controleur)
ZytOpenDevice(char * device)411 static int ZytOpenDevice(char *device)
412 {
413      int fd;
414      fd = open (device, O_RDWR | O_NOCTTY); // pourquoi 0_NOCTTY ? ***
415      if ( fd == -1 ) {
416           return ZYT_ERR_CANT_OPEN;
417      }
418 
419      // on r�cup�re l'actuelle configuration du port :
420      tcgetattr(fd,&options);
421      tcgetattr(fd,&saved_options);
422 
423      // on passe en 96000 bauds :
424      cfsetospeed(&options,B9600);
425      cfsetispeed(&options,B9600);
426 
427      // on passe en mode de fonctionnement "pur" pour pouvoir utiliser correctement le port s�rie :
428      cfmakeraw(&options);
429      tcsetattr(fd,TCSANOW,&options);
430 
431      return fd;
432 }
433 
434 // le thread qui sert � recevoir des donn�es en continue :
ZytronicEventThread(DirectThread * thread,void * driver_data)435 static void *ZytronicEventThread(DirectThread *thread, void *driver_data)
436 {
437      ZytData *data = (ZytData *) driver_data;
438      int lastAction = ZYT_ACTION_RELEASE;
439      struct timeval unT;
440      unsigned int lastT,newT;
441      unsigned short nbClignot=0;
442      lastT = 0;
443      DFBInputEvent evt;
444 
445      /* Read data */
446      while (1) {
447           if (!ZytReadTouchMessage (data)){ // si jamais il y a eut mauvaise lecture (pas normal)
448                continue; // on ignore le mesage mal lu
449           }
450           // en mode sans drag&drop, si l'action actuelle est la m�me que la pr�c�dente, on l'ignore:
451           if (zytConf.mode==NO_DRAG_DROP && lastAction == data->action){
452                nbClignot=0; // et on dit que �a clignote pas (car c'est un appui long, pas un clignotement)
453                continue;		// permet de ne garder que le premier appui, et le relachement :
454           }
455           gettimeofday(&unT,NULL);
456           newT = unT.tv_sec*1000000 + unT.tv_usec;
457           if(zytConf.debug==DEBUG){
458                D_INFO("newT=%u\n",newT);
459                D_INFO("lastT=%u\n",lastT);
460                D_INFO("lastT+attente=%u\n",lastT+zytConf.attenteMultiClic);
461           }
462 
463           // si on "appui" trop vite, sans faire un appui continu, on r�enregistre la derni�re action,... :
464           if(data->action==ZYT_ACTION_TOUCH && nbClignot < zytConf.nbClignToPress && \
465           (lastT + zytConf.attenteMultiClic) > newT) {
466                nbClignot++;// ..on compte combien de fois de suite on essai d'appuyer (pour voir si c'est la fin
467                            // d'un clignotement justement parce qu'on a rapprocher le doigt suffisemment) ..
468                gettimeofday(&unT,NULL);
469                lastT = unT.tv_sec*1000000 + unT.tv_usec;
470                continue; // ..et on ignore cet appui (permet d'�viter le ph�nom�ne de clignotement..)
471           }
472           nbClignot=0; // on remet le compteur � z�ro, puisque c'est ici un appui r�el
473           direct_thread_testcancel (thread); // si cette ligne fait bien ce que je pense (regarder si on n'a pas
474             // demand� la fin du thread en cours) pourquoi est-elle l�, et pas avant le "if" ? Car si le controlleur
475             // n'envoi plus aucune information pendant un moment, le driver ne peut pas d�tecter de "cancel"
476             // pendant ce laps de temps .. ? ***
477 
478           // Dispatch axis
479           evt.type    = DIET_AXISMOTION;
480           evt.flags   = DIEF_AXISABS;
481           evt.axis    = DIAI_X;
482           evt.axisabs = data->x;
483           dfb_input_dispatch (data->device, &evt);
484 
485           evt.type    = DIET_AXISMOTION;
486           evt.flags   = DIEF_AXISABS;
487           evt.axis    = DIAI_Y;
488           evt.axisabs = data->y;
489           dfb_input_dispatch (data->device, &evt);
490 
491           // Dispatch touch event
492           switch (data->action) {
493                case ZYT_ACTION_TOUCH:
494                     evt.type = DIET_BUTTONPRESS;
495                     break;
496                case ZYT_ACTION_RELEASE:
497                     evt.type = DIET_BUTTONRELEASE;
498                     break;
499           }
500 
501 
502           evt.flags  = DIEF_NONE;
503           evt.button = DIBI_LEFT;
504           dfb_input_dispatch (data->device, &evt);
505 
506           lastAction = data->action; // on enregistre l'�v�nement
507           gettimeofday(&unT,NULL); // on enregistre quand s'est produit l'�v�nement
508           lastT = unT.tv_sec*1000000 + unT.tv_usec;
509 
510           if(zytConf.debug==DEBUG){
511                D_INFO("Zytronic TOUCH : x=%d y=%d action=%d\n", data->x,data->y,data->action);
512           }
513 
514           direct_thread_testcancel (thread);
515      }
516 
517      return NULL;
518 }
519 
520 
521 /* exported symbols */
522 
523 // proc�dure pour dire � directFB si c'est bien ce driver qu'il faut charger :
driver_get_available(void)524 static int driver_get_available( void )
525 {
526      int fd;
527 
528      /* we only try to open the device if it has been actually configured */
529      if( !dfb_config->zytronic_device )
530           return 0;
531 
532      fd = ZytOpenDevice(dfb_config->zytronic_device );
533      D_INFO( "Zytronic:driver_get_available %s fd %d\n", dfb_config->zytronic_device,fd );
534 
535      if (fd < 0){
536           D_INFO( "The Zytronic driver cannot be loaded from %s\n", dfb_config->zytronic_device );
537           return 0;
538      }
539 
540      close(fd);
541      return 1;
542 }
543 
544 // donne la description du driver :
driver_get_info(InputDriverInfo * info)545 static void driver_get_info( InputDriverInfo *info )
546 {
547      /* fill driver info structure */
548      snprintf(info->name, DFB_INPUT_DRIVER_INFO_NAME_LENGTH,
549                "Zypos" );
550      snprintf(info->vendor, DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH,
551                "Zytronic" );
552 
553      info->version.major = 0;
554      info->version.minor = 5;
555 }
556 
557 // "ouvre" le device et commnce � le pr�parer :
driver_open_device(CoreInputDevice * device,unsigned int number,InputDeviceInfo * info,void ** driver_data)558 static DFBResult driver_open_device(CoreInputDevice *device,
559           unsigned int number,
560           InputDeviceInfo *info,
561           void **driver_data)
562 {
563      int fd;
564      ZytData *data;
565 
566      /* open device */
567      fd = ZytOpenDevice (dfb_config->zytronic_device);
568      D_INFO("ZYT, driver_open_device %s fd %d\n", dfb_config->zytronic_device,fd);
569 
570      if (fd < 0) {
571           return DFB_INIT;
572      }
573 
574      ZytActivateDevice(fd); //on configure le controleur pour fonctionner en mode normal
575 
576      data = D_CALLOC (1, sizeof(ZytData));
577 
578      data->fd     = fd;
579      data->device = device;
580 
581      /* fill device info structure */
582      snprintf(info->desc.name, DFB_INPUT_DEVICE_DESC_NAME_LENGTH,
583                "Zypos");
584      snprintf(info->desc.vendor, DFB_INPUT_DEVICE_DESC_VENDOR_LENGTH,
585                "Zytronic");
586 
587      info->prefered_id     = DIDID_MOUSE;
588      info->desc.type       = DIDTF_MOUSE;
589      info->desc.caps       = DICAPS_AXES | DICAPS_BUTTONS;
590      info->desc.max_axis   = DIAI_Y;
591      info->desc.max_button = DIBI_LEFT;
592 
593      /* start input thread */
594      data->thread = direct_thread_create (DTT_INPUT, ZytronicEventThread, data, "Zytronic Input");
595 
596      /* set private data pointer */
597      *driver_data = data;
598 
599      return DFB_OK;
600 }
601 
602 /*
603  * Fetch one entry from the device's keymap if supported.
604  */
driver_get_keymap_entry(CoreInputDevice * device,void * driver_data,DFBInputDeviceKeymapEntry * entry)605 static DFBResult driver_get_keymap_entry(CoreInputDevice *device,
606           void        *driver_data,
607           DFBInputDeviceKeymapEntry *entry)
608 {
609      return DFB_UNSUPPORTED;
610 }
611 
612 // "fermeture" du driver ***
driver_close_device(void * driver_data)613 static void driver_close_device(void *driver_data)
614 {
615      ZytData *data = (ZytData *)driver_data;
616 
617      /* stop input thread */
618      direct_thread_cancel (data->thread);
619      direct_thread_join (data->thread);
620      direct_thread_destroy (data->thread);
621 
622      /* close device */
623      tcsetattr(data->fd,TCSANOW,&saved_options); // remise en l'�tat de l'ancienne configuration du port
624      close (data->fd);
625 
626      /* free private data */
627      D_FREE (data);
628 }
629