Merge "Update packages changelog." into 2.0alpha-wayland
[profile/ivi/ico-uxf-device-input-controller.git] / touch_egalax / ico_ictl-egalax_calibration.c
1 /*
2  * Copyright (c) 2013, TOYOTA MOTOR CORPORATION.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9 /**
10  * @brief   Touchpanel(eGalax) Calibration Tool
11  *
12  * @date    Feb-20-2013
13  */
14
15 #include "ico_ictl-touch_egalax.h"
16
17 /* Number of times to repeat a touch about each point   */
18 #define CALIBCONF_READ_NUM  (5)
19 #define XY_COORDNATE_DELTA  (50)
20
21 /* Macro for adjust coordinate      */
22 #define delta_add(x)    \
23     (x) > 256 ? (x) + XY_COORDNATE_DELTA : ((x) > XY_COORDNATE_DELTA ? (x) - XY_COORDNATE_DELTA : 0);
24
25 static void print_usage(const char *pName);
26 static char *find_event_device(void);
27 static FILE *open_conffile(void);
28 static void get_coordinates(int evfd);
29 static void read_event(int evfd, int *x, int *y);
30 static void sort_data(int buff[], int left, int right);
31
32 int             mDispWidth = CALIBRATION_DISP_WIDTH;
33 int             mDispHeight = CALIBRATION_DISP_HEIGHT;
34 int             mPosX[4];
35 int             mPosY[4];
36
37 int             mDebug = 0;
38
39 /*--------------------------------------------------------------------------*/
40 /**
41  * @brief   Touchpanel(eGalax) Calibration Tool main routine
42  *
43  * @param   arguments of standard main routeins(argc, argv)
44  * @return  result
45  * @retval  0       sucess
46  * @retval  8       configuration file Error
47  * @retval  9       can not open event device(touchpanel)
48  */
49 /*--------------------------------------------------------------------------*/
50 int
51 main(int argc, char *argv[])
52 {
53     int     ii, cnt;
54     int     evfd;                               /* event device fd */
55     char    *eventDeviceName = NULL;            /* event device name to hook */
56     FILE    *fp;
57     char    buff[128];
58
59     /* Get options                      */
60     for (ii = 1; ii < argc; ii++) {
61         if (strcasecmp(argv[ii], "-h") == 0) {
62             /* Help                     */
63             print_usage(argv[0]);
64             exit(0);
65         }
66         else if (strcasecmp(argv[ii], "-width") == 0)   {
67             /* Screen width             */
68             ii++;
69             if (ii >= argc) {
70                 print_usage(argv[0]);
71                 exit(0);
72             }
73             mDispWidth = strtol(argv[ii], (char **)0, 0);
74             if ((mDispWidth <= 0) || (mDispWidth > 8192))   {
75                 print_usage(argv[0]);
76                 exit(0);
77             }
78         }
79         else if (strcasecmp(argv[ii], "-height") == 0)  {
80             /* Screen height            */
81             ii++;
82             if (ii >= argc) {
83                 print_usage(argv[0]);
84                 exit(0);
85             }
86             mDispHeight = strtol(argv[ii], (char **)0, 0);
87             if ((mDispHeight <= 0) || (mDispHeight > 8192)) {
88                 print_usage(argv[0]);
89                 exit(0);
90             }
91         }
92         else {
93             /* Input event device name  */
94             eventDeviceName = argv[ii];
95         }
96     }
97
98     if (eventDeviceName == NULL) {
99         /* If event device not present, get default device  */
100         eventDeviceName = find_event_device();
101         if (eventDeviceName == NULL) {
102             /* System has no touchpanel, Error  */
103             exit(9);
104         }
105     }
106
107     evfd = open(eventDeviceName, O_RDONLY);
108     if (evfd < 0) {
109         perror("Open event device");
110         exit(9);
111     }
112
113     /* Open configuration file for output   */
114     fp = open_conffile();
115     if (fp == NULL) {
116         fprintf(stderr, "%s: Can not open config file\n", argv[0]);
117         close(evfd);
118         exit(8);
119     }
120
121     CALIBRATION_PRINT("\n");
122     CALIBRATION_PRINT("+================================================+\n");
123     CALIBRATION_PRINT("| Configration Tool for Calibration Touch ver0.1 |\n");
124     CALIBRATION_PRINT("+------------------------------------------------+\n");
125     CALIBRATION_PRINT("| use display width = %d\n", CALIBRATION_DISP_WIDTH);
126     CALIBRATION_PRINT("| use display height = %d\n", CALIBRATION_DISP_HEIGHT);
127     CALIBRATION_PRINT("+------------------------------------------------+\n");
128
129     get_coordinates(evfd);
130
131     CALIBRATION_PRINT("+------------------------------------------------+\n");
132     CALIBRATION_PRINT("| save config                                    |\n");
133     CALIBRATION_PRINT("+------------------------------------------------+\n");
134
135     cnt = sprintf(buff, "%s=%d\n", CALIBRATOIN_STR_DISP_W, mDispWidth);
136     fwrite(buff, sizeof(char), cnt, fp);
137     CALIBRATION_PRINT("| %s", buff);
138
139     cnt = sprintf(buff, "%s=%d\n", CALIBRATOIN_STR_DISP_H, mDispHeight);
140     fwrite(buff, sizeof(char), cnt, fp);
141     CALIBRATION_PRINT("| %s", buff);
142
143     cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS1, mPosX[0], mPosY[0]);
144     fwrite(buff, sizeof(char), cnt, fp);
145     CALIBRATION_PRINT("| %s", buff);
146
147     cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS2, mPosX[1], mPosY[1]);
148     fwrite(buff, sizeof(char), cnt, fp);
149     CALIBRATION_PRINT("| %s", buff);
150
151     cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS3, mPosX[2], mPosY[2]);
152     fwrite(buff, sizeof(char), cnt, fp);
153     CALIBRATION_PRINT("| %s", buff);
154
155     cnt = sprintf(buff, "%s=%d*%d\n", CALIBRATOIN_STR_POS4, mPosX[3], mPosY[3]);
156     fwrite(buff, sizeof(char), cnt, fp);
157     CALIBRATION_PRINT("| %s", buff);
158
159     if (evfd >= 0) {
160         close(evfd);
161     }
162
163     /* Close outputed configuration file    */
164     fclose(fp);
165
166     CALIBRATION_PRINT("|                                                |\n");
167     CALIBRATION_PRINT("| finish Tools                                   |\n");
168
169     exit(0);
170 }
171
172 /*--------------------------------------------------------------------------*/
173 /**
174  * @brief   find_event_device: Find eGalax touchpanel device
175  *
176  * @param       nothing
177  * @return      device name
178  * @retval      != NULL     device name string
179  * @retvel      == NULL     system has no eGalax touchpanel
180  */
181 /*--------------------------------------------------------------------------*/
182 static char *
183 find_event_device(void)
184 {
185     FILE    *fp;
186     int     eGalax = 0;
187     int     i, j, k;
188     char    buf[240];
189     static char edevice[64];
190
191     /* Search input device      */
192     fp = fopen("/proc/bus/input/devices", "r");
193     if (!fp)    {
194         CALIBRATION_INFO("find_event_device: /proc/bus/input/devices Open Error\n");
195         return(NULL);
196     }
197
198     while (fgets(buf, sizeof(buf), fp)) {
199         if (eGalax == 0)    {
200             for (i = 0; buf[i]; i++)    {
201                 if (strncmp(&buf[i], "eGalax", 6) == 0) {
202                     /* Find eGalax touchpanel device    */
203                     eGalax = 1;
204                     break;
205                 }
206             }
207         }
208         else    {
209             for (i = 0; buf[i]; i++)    {
210                 if (strncmp(&buf[i], "Handlers", 8) == 0)   {
211                     /* Find eGalax device and Handlers  */
212                     for (j = i+8; buf[j]; j++)  {
213                         if (buf[j] != ' ')  continue;
214                         strcpy(edevice, "/dev/input/");
215                         for (k = strlen(edevice); k < (int)sizeof(edevice); k++)    {
216                             j++;
217                             if ((buf[j] == 0) || (buf[j] == ' ') ||
218                                 (buf[j] == '\t') || (buf[j] == '\n') ||
219                                 (buf[j] == '\r'))   break;
220                             edevice[k] = buf[j];
221                         }
222                         edevice[k] = 0;
223                         CALIBRATION_INFO("Event device of eGalax=<%s>\n", edevice);
224                         fclose(fp);
225                         return(edevice);
226                     }
227                     break;
228                 }
229             }
230         }
231     }
232     fclose(fp);
233
234     CALIBRATION_PRINT("System has no eGalax Touchpanel\n");
235     return(NULL);
236 }
237
238 /*--------------------------------------------------------------------------*/
239 /**
240  * @brief       read coordinates form touchpanel
241  *
242  * @param[in]   evfd        touchpanel event device
243  * @return      nothing
244  */
245 /*--------------------------------------------------------------------------*/
246 static void
247 get_coordinates(int evfd)
248 {
249     int     bufX[CALIBCONF_READ_NUM];
250     int     bufY[CALIBCONF_READ_NUM];
251     int     x, y;
252     int     ii;
253
254     CALIBRATION_PRINT("| Touch the Top-Left corner of the screen %d times\n",
255                       CALIBCONF_READ_NUM);
256     for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
257         read_event(evfd, &x, &y);
258         bufX[ii] = x;
259         bufY[ii] = y;
260         CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
261     }
262     sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
263     sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
264     mPosX[0] = delta_add(bufX[CALIBCONF_READ_NUM / 2]);
265     mPosY[0] = delta_add(bufY[CALIBCONF_READ_NUM / 2]);
266
267     CALIBRATION_PRINT("+------------------------------------------------+\n");
268     CALIBRATION_PRINT("| Touch the Top-Right corner of the screen %d times\n",
269                       CALIBCONF_READ_NUM);
270     for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
271         read_event(evfd, &x, &y);
272         bufX[ii] = x;
273         bufY[ii] = y;
274         CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
275     }
276     sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
277     sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
278     mPosX[1] = delta_add(bufX[CALIBCONF_READ_NUM / 2]);
279     mPosY[1] = delta_add(bufY[CALIBCONF_READ_NUM / 2]);
280
281     CALIBRATION_PRINT("+------------------------------------------------+\n");
282     CALIBRATION_PRINT("| Touch the Bottom-Left corner of the screen %d times\n",
283                       CALIBCONF_READ_NUM);
284     for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
285         read_event(evfd, &x, &y);
286         bufX[ii] = x;
287         bufY[ii] = y;
288         CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
289     }
290     sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
291     sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
292     mPosX[2] = delta_add(bufX[CALIBCONF_READ_NUM / 2]);
293     mPosY[2] = delta_add(bufY[CALIBCONF_READ_NUM / 2]);
294
295     CALIBRATION_PRINT("+------------------------------------------------+\n");
296     CALIBRATION_PRINT("| Touch the Bottom-Right corner of the screen %d times\n",
297                       CALIBCONF_READ_NUM);
298     for (ii = 0; ii < CALIBCONF_READ_NUM; ii++) {
299         read_event(evfd, &x, &y);
300         bufX[ii] = x;
301         bufY[ii] = y;
302         CALIBRATION_PRINT("| # %d: %dx%d \n", ii, x, y);
303     }
304     sort_data(bufX, 0, CALIBCONF_READ_NUM - 1);
305     sort_data(bufY, 0, CALIBCONF_READ_NUM - 1);
306     mPosX[3] = delta_add(bufX[CALIBCONF_READ_NUM / 2]);
307     mPosY[3] = delta_add(bufY[CALIBCONF_READ_NUM / 2]);
308 }
309
310 /*--------------------------------------------------------------------------*/
311 /**
312  * @brief       sort integer dates
313  *
314  * @param[in]   buff    array of integer datas
315  * @param[in]   left    array start index
316  * @param[in]   right   array end index
317  * @return      nothing
318  */
319 /*--------------------------------------------------------------------------*/
320 static void
321 sort_data(int buff[], int left, int right)
322 {
323     int     ii, jj, pivot;
324     int     tmp;
325
326     ii = left;
327     jj = right;
328
329     pivot = buff[(left + right) / 2];
330     while (1) {
331         while (buff[ii] < pivot) {
332             ii++;
333         }
334         while (pivot < buff[jj]) {
335             jj--;
336         }
337         if (ii >= jj) {
338             break;
339         }
340         tmp = buff[ii];
341         buff[ii] = buff[jj];
342         buff[jj] = tmp;
343         ii++;
344         jj--;
345     }
346
347     if (left < (ii - 1)) {
348         sort_data(buff, left, ii - 1);
349     }
350     if ((jj + 1) < right) {
351         sort_data(buff, jj + 1, right);
352     }
353 }
354
355 /*--------------------------------------------------------------------------*/
356 /**
357  * @brief       event read from touchpanel
358  *
359  * @param[in]   evfd        touchpanel event device
360  * @return      nothing
361  */
362 /*--------------------------------------------------------------------------*/
363 static void
364 read_event(int evfd, int *x, int *y)
365 {
366     fd_set      fds;
367     int         ret;
368     int         rsize;
369     int         ii;
370     int         flagX = 0;
371     int         flagY = 0;
372     struct timeval  delay;
373     struct input_event events[64];
374
375     while (1) {
376         /* select timeoutt value    */
377         delay.tv_sec = 0;
378         delay.tv_usec = 100*1000;
379         /* fs_set                   */
380         FD_ZERO(&fds);
381         FD_SET(evfd, &fds);
382
383         /* wait for event read or timedout  */
384         ret = select(evfd + 1, &fds, NULL, NULL, &delay);
385         if (ret <= 0) {
386             continue;
387         }
388         if (FD_ISSET(evfd, &fds)) {
389             /* event read           */
390             rsize = read(evfd, events, sizeof(events) );
391             for (ii = 0; ii < (int)(rsize/sizeof(struct input_event)); ii++) {
392                 if ((events[ii].type == EV_ABS) && (events[ii].code == ABS_X)) {
393                     /* X       */
394                     flagX++;
395                     *x = events[ii].value;
396                 }
397                 else if ((events[ii].type == EV_ABS) && (events[ii].code == ABS_Y)) {
398                     /* Y       */
399                     flagY++;
400                     *y = events[ii].value;
401                 }
402             }
403         }
404         /* Input 2 times (Touch On and Off) */
405         if ((flagX >= 2) && (flagY >= 2)) {
406             break;
407         }
408     }
409
410     while (1) {
411         delay.tv_sec = 0;
412         delay.tv_usec = 200*1000;
413         FD_ZERO(&fds);
414         FD_SET(evfd, &fds);
415
416         /* wait for input (or timedout) */
417         ret = select(evfd + 1, &fds, NULL, NULL, &delay);
418         if (ret == 0) {
419             break;
420         }
421         else if (ret < 0) {
422             continue;
423         }
424         rsize = read(evfd, events, sizeof(events));
425     }
426 }
427
428 /*--------------------------------------------------------------------------*/
429 /**
430  * @brief       open configuration file
431  *
432  * @param       nothing
433  * @return      file descriptor
434  * @retval      != NULL     file descriptor
435  * @retval      NULL        open error
436  */
437 /*--------------------------------------------------------------------------*/
438 static FILE *
439 open_conffile(void)
440 {
441     char    *confp;
442     FILE    *fp;
443
444     /* Get configuration file path  */
445     confp = getenv(CALIBRATOIN_CONF_ENV);
446     if (! confp)  {
447         confp = CALIBRATOIN_CONF_FILE;
448     }
449
450     /* Open configuration file      */
451     fp = fopen(confp, "w");
452     if (fp == NULL) {
453         perror(confp);
454         return fp;
455     }
456     return fp;
457 }
458
459 /*--------------------------------------------------------------------------*/
460 /**
461  * @brief       print help
462  *
463  * @param[in]   pName       program name
464  * @return      nothing
465  */
466 /*--------------------------------------------------------------------------*/
467 static void
468 print_usage(const char *pName)
469 {
470     fprintf(stderr, "Usage: %s [-h][-width width][-height height] [device]\n", pName);
471 }
472