Test tool The name of test_send_input is changed into ico_send_inputevent.
[profile/ivi/ico-uxf-weston-plugin.git] / tools / ico_send_inputevent.c
1 /*
2  * Copyright © 2013 TOYOTA MOTOR CORPORATION.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 /**
23  * @brief   System Test Tool for send device input event
24  *
25  * @date    Feb-20-2013
26  */
27
28 #include    <stdio.h>
29 #include    <stdlib.h>
30 #include    <unistd.h>
31 #include    <stdarg.h>
32 #include    <string.h>
33 #include    <errno.h>
34 #include    <pthread.h>
35 #include    <sys/ioctl.h>
36 #include    <sys/ipc.h>
37 #include    <sys/msg.h>
38 #include    <sys/time.h>
39 #include    <sys/types.h>
40 #include    <sys/stat.h>
41 #include    <signal.h>
42 #include    <fcntl.h>
43 #include    <linux/input.h>
44 #include    <linux/uinput.h>
45 #include    <linux/joystick.h>
46
47 #define DEV_TOUCH   0
48 #define DEV_JS      1
49 #define SPECIALTYPE_XY  9991
50
51 static const struct {
52     char    *prop;
53     short   devtype;
54     short   type;
55     short   code;
56     short   value;
57 }               event_key[] = {
58     { "X", DEV_TOUCH, EV_ABS, ABS_X, -1 },
59     { "Y", DEV_TOUCH, EV_ABS, ABS_Y, -1 },
60     { "Down", DEV_TOUCH, EV_KEY, BTN_TOUCH, 1 },
61     { "Up", DEV_TOUCH, EV_KEY, BTN_TOUCH, 0 },
62     { "Touch", DEV_TOUCH, EV_KEY, BTN_TOUCH, -1 },
63     { "XY", DEV_TOUCH, SPECIALTYPE_XY, 0, -1 },
64     { "SYN", DEV_TOUCH, 0, 0, 0 },
65     { "Button", DEV_TOUCH, EV_KEY, BTN_LEFT, -1 },
66     { "ButtonOn", DEV_TOUCH, EV_KEY, BTN_LEFT, 1 },
67     { "ButtonOff", DEV_TOUCH, EV_KEY, BTN_LEFT, 0 },
68
69     { "UpDown", DEV_JS, 2, 3, 1 },
70     { "UD", DEV_JS, 2, 3, 1 },
71     { "LeftRight", DEV_JS, 2, 2, 2 },
72     { "LR", DEV_JS, 2, 2, 2 },
73     { "Cross", DEV_JS, 1, 0, 3 },
74     { "Squere", DEV_JS, 1, 1, 4 },
75     { "Circle", DEV_JS, 1, 2, 5 },
76     { "Triangle", DEV_JS, 1, 3, 6 },
77     { "\0", 0, 0, 0, 0 } };
78
79 static int  uifd = -1;
80 static int  mqid = -1;
81 static int  mDebug = 0;
82 static int  mRun = 1;
83 static int  mTouch = 1;
84 static int  mWidth = 1080;
85 static int  mHeight = 1920;
86 static int  mConvert = 0;
87
88 static void print_log(const char *fmt, ...);
89
90 static void
91 term_signal(const int signo)
92 {
93     mRun = 0;
94 }
95
96 static void
97 init_mq(const int mqkey)
98 {
99     char    dummy[256];
100
101     if (mqkey == 0) {
102         mqid = -1;
103     }
104     else    {
105         mqid = msgget(mqkey, 0);
106         if (mqid < 0)   {
107             mqid = msgget(mqkey, IPC_CREAT);
108         }
109         if (mqid < 0)   {
110             print_log("Can not create message queue(%d(0x%x))[%d]",
111                       mqkey, mqkey, errno);
112             fflush(stderr);
113             return;
114         }
115         while (msgrcv(mqid, dummy, sizeof(dummy)-sizeof(long), 0, IPC_NOWAIT) > 0)  ;
116     }
117 }
118
119 static void
120 init_device(const char *device)
121 {
122     int     fd;
123     int     ii;
124     char    devFile[64];
125     char    devName[64];
126     struct uinput_user_dev  uinputDevice;
127     uifd = open("/dev/uinput", O_RDWR);
128
129     if (uifd < 0)   {
130         print_log("/dev/uinput open error[%d]", errno);
131         fflush(stderr);
132         exit(1);
133     }
134
135     memset(&uinputDevice, 0, sizeof(uinputDevice));
136     strncpy(uinputDevice.name, device, UINPUT_MAX_NAME_SIZE-1);
137     uinputDevice.absmax[ABS_X] = mHeight;
138     uinputDevice.absmax[ABS_Y] = mWidth;
139
140     /* uinput device configuration  */
141     if (write(uifd, &uinputDevice, sizeof(uinputDevice)) < (int)sizeof(uinputDevice)) {
142         print_log("/dev/uinput regist error[%d]", errno);
143         fflush(stderr);
144         close(uifd);
145         exit(1);
146     }
147
148     /* uinput set event bits        */
149     ioctl(uifd, UI_SET_EVBIT, EV_SYN);
150
151     if ((mTouch != 0) && (mTouch != 3)) {
152         ioctl(uifd, UI_SET_EVBIT, EV_ABS);
153         ioctl(uifd, UI_SET_ABSBIT, ABS_X);
154         ioctl(uifd, UI_SET_ABSBIT, ABS_Y);
155         ioctl(uifd, UI_SET_EVBIT, EV_KEY);
156         if (mTouch == 1)    {
157             ioctl(uifd, UI_SET_KEYBIT, BTN_LEFT);
158         }
159         else    {
160             ioctl(uifd, UI_SET_KEYBIT, BTN_TOUCH);
161             ioctl(uifd, UI_SET_KEYBIT, BTN_TOOL_PEN);
162         }
163     }
164     else    {
165         ioctl(uifd, UI_SET_EVBIT, EV_REL);
166         ioctl(uifd, UI_SET_RELBIT, REL_X);
167         ioctl(uifd, UI_SET_RELBIT, REL_Y);
168         ioctl(uifd, UI_SET_RELBIT, REL_Z);
169         ioctl(uifd, UI_SET_RELBIT, REL_RX);
170         ioctl(uifd, UI_SET_RELBIT, REL_RY);
171         ioctl(uifd, UI_SET_RELBIT, REL_RZ);
172         ioctl(uifd, UI_SET_EVBIT, EV_KEY);
173         ioctl(uifd, UI_SET_KEYBIT, KEY_RESERVED);
174         ioctl(uifd, UI_SET_KEYBIT, KEY_ESC);
175         ioctl(uifd, UI_SET_KEYBIT, KEY_1);
176         ioctl(uifd, UI_SET_KEYBIT, KEY_2);
177         ioctl(uifd, UI_SET_KEYBIT, KEY_3);
178         ioctl(uifd, UI_SET_KEYBIT, KEY_4);
179         ioctl(uifd, UI_SET_KEYBIT, KEY_5);
180         ioctl(uifd, UI_SET_KEYBIT, KEY_6);
181         ioctl(uifd, UI_SET_KEYBIT, KEY_7);
182         ioctl(uifd, UI_SET_KEYBIT, KEY_8);
183         ioctl(uifd, UI_SET_KEYBIT, KEY_9);
184         ioctl(uifd, UI_SET_KEYBIT, KEY_0);
185     }
186
187     ioctl(uifd, UI_SET_EVBIT, EV_MSC);
188     ioctl(uifd, UI_SET_MSCBIT, MSC_SCAN);
189
190     /* create event device          */
191     if (ioctl(uifd, UI_DEV_CREATE, NULL) < 0)   {
192         print_log("/dev/uinput create error[%d]", errno);
193         fflush(stderr);
194         close(uifd);
195         exit(1);
196     }
197     print_log("## created event device %s", device);
198
199     for (ii = 0; ii < 16; ii++) {
200         snprintf(devFile, 64, "/dev/input/event%d", ii);
201         fd = open(devFile, O_RDONLY);
202         if (fd < 0)     continue;
203
204         memset(devName, 0, sizeof(devName));
205         ioctl(fd, EVIOCGNAME(sizeof(devName)), devName);
206         close(fd);
207         print_log("%d.event device(%s) is %s", ii+1, devFile, devName);
208     }
209     usleep(200*1000);
210 }
211
212 static int
213 convert_value(const char *value, char **errp, int base)
214 {
215     int i;
216
217     for (i = 0; value[i]; i++)  {
218         if ((value[i] == ',') || (value[i] == ';') ||
219             (value[i] == ';') || (value[i] == ' ')) {
220             break;
221         }
222     }
223     if (errp)   {
224         *errp = (char *)&value[i];
225     }
226
227     if ((strncasecmp(value, "on", i) == 0) ||
228         (strncasecmp(value, "true", i) == 0) ||
229         (strncasecmp(value, "push", i) == 0) ||
230         (strncasecmp(value, "down", i) == 0) ||
231         (strncasecmp(value, "right", i) == 0))  {
232         return 1;
233     }
234     else if ((strncasecmp(value, "off", i) == 0) ||
235              (strncasecmp(value, "false", i) == 0) ||
236              (strncasecmp(value, "pop", i) == 0) ||
237              (strncasecmp(value, "up", i) == 0) ||
238              (strncasecmp(value, "left", i) == 0))  {
239         return 0;
240     }
241     return strtol(value, (char **)0, 0);
242 }
243
244 static void
245 send_event(const char *cmd)
246 {
247     int     i, j;
248     int     key;
249     char    prop[64];
250     char    value[128];
251     int     sec, msec;
252     char    *errp;
253     struct input_event  event;
254     struct js_event     js;
255
256     j = 0;
257     for (i = 0; cmd[i]; i++)    {
258         if ((cmd[i] == '=') || (cmd[i] == ' ')) break;
259         if (j < (int)(sizeof(prop)-1))  {
260             prop[j++] = cmd[i];
261         }
262     }
263
264     prop[j] = 0;
265     j = 0;
266     if (cmd[i] != 0)    {
267         for (i++; cmd[i]; i++)  {
268             if (cmd[i] == ' ')  continue;
269             if (j < (int)(sizeof(value)-1)) {
270                 value[j++] = cmd[i];
271             }
272         }
273     }
274     value[j] = 0;
275
276     if (strcasecmp(prop, "sleep") == 0) {
277         sec = 0;
278         msec = 0;
279         for (i = 0; value[i]; i++)  {
280             if (value[i] == '.')        break;
281             sec = sec * 10 + (value[i] & 0x0f);
282         }
283         if (value[i] == '.')    {
284             i++;
285             if (value[i] != 0)  {
286                 msec = (value[i] & 0x0f) * 100;
287                 i++;
288             }
289             if (value[i] != 0)  {
290                 msec = msec + (value[i] & 0x0f) * 10;
291                 i++;
292             }
293             if (value[i] != 0)  {
294                 msec = msec + (value[i] & 0x0f);
295             }
296         }
297         if (sec > 0)    sleep(sec);
298         if (msec > 0)   usleep(msec * 1000);
299
300         return;
301     }
302
303     for (key = 0; event_key[key].prop[0]; key++)    {
304         if (strcasecmp(prop, event_key[key].prop) == 0) break;
305     }
306     if (! event_key[key].prop[0])   {
307         print_log("UnKnown Event name[%s]", prop);
308         return;
309     }
310
311     if (mTouch != 0)    {
312         memset(&event, 0, sizeof(event));
313         gettimeofday(&event.time, NULL);
314         if (event_key[key].type == SPECIALTYPE_XY)  {
315             event.type = EV_ABS;
316             if (mConvert)   event.code = ABS_Y;
317             else            event.code = ABS_X;
318             event.value = convert_value(value, &errp, 0);
319             if (mDebug) {
320                 print_log("Send Event ABS_%c=%d\t# %d.%03d", mConvert ? 'Y' : 'X',
321                           event.value,
322                           (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
323                 fflush(stderr);
324             }
325             if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
326                 print_log("event write error 1[%d]", errno);
327                 fflush(stderr);
328                 return;
329             }
330             if (mConvert)   event.code = ABS_X;
331             else            event.code = ABS_Y;
332             if (*errp == ',')   {
333                 event.value = convert_value(errp + 1, (char **)0, 0);
334             }
335             else    {
336                 event.value = 0;
337             }
338             if (mConvert)   {
339                 event.value = mHeight - event.value - 1;
340             }
341             event.time.tv_usec += 200;
342             if (event.time.tv_usec >= 1000000)  {
343                 event.time.tv_sec ++;
344                 event.time.tv_usec -= 1000000;
345             }
346             if (mDebug) {
347                 print_log("Send Event ABS_%c=%d\t# %d.%03d", mConvert ? 'X' : 'Y',
348                           event.value,
349                           (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
350                 fflush(stderr);
351             }
352         }
353         else    {
354             event.type = event_key[key].type;
355
356             if (event_key[key].code == -1)   {
357                 event.code = convert_value(value, (char **)0, 0);
358             }
359             else    {
360                 event.code = event_key[key].code;
361                 if (value[0] == 0)  {
362                     event.value = event_key[key].value;
363                 }
364                 else    {
365                     event.value = convert_value(value, (char **)0, 0);
366                 }
367             }
368             if (mDebug) {
369                 if ((event.type == EV_ABS) && (event.code == ABS_X))    {
370                     print_log("Send Event X=%d\t# %d.%03d", event.value,
371                               (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
372                 }
373                 else if ((event.type == EV_ABS) && (event.code == ABS_Y))    {
374                     print_log("Send Event Y=%d\t %d.%03d", event.value,
375                               (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
376                 }
377                 else if ((event.type == EV_KEY) &&
378                          (event.code == BTN_TOUCH) && (event.value == 1))    {
379                     print_log("Send Event BTN_TOUCH=Down\t# %d.%03d",
380                               (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
381                 }
382                 else if ((event.type == EV_KEY) &&
383                          (event.code == BTN_TOUCH) && (event.value == 0))    {
384                     print_log("Send Event BTN_TOUCH=Up\t# %d.%03d",
385                               (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
386                 }
387                 else if ((event.type == EV_KEY) &&
388                          (event.code == BTN_LEFT) && (event.value == 1))    {
389                     print_log("Send Event BTN_LEFT=Down\t# %d.%03d",
390                               (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
391                 }
392                 else if ((event.type == EV_KEY) &&
393                          (event.code == BTN_LEFT) && (event.value == 0))   {
394                     print_log("Send Event BTN_LEFT=Up\t# %d.%03d",
395                               (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
396                 }
397                 else    {
398                     if ((event.type == EV_REL) && (event.value == 0))   {
399                         event.value = 9;
400                     }
401                     else if ((event.type == EV_KEY) && (event.code == 0))   {
402                         event.code = 9;
403                     }
404                     print_log("Send Event type=%d code=%d value=%d\t# %d.%03d",
405                               event.type, event.code, event.value,
406                               (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
407                 }
408                 fflush(stderr);
409             }
410         }
411         if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
412             print_log("event write error 2[%d]", errno);
413             fflush(stderr);
414         }
415         else    {
416             /* send EV_SYN */
417             memset(&event, 0, sizeof(event));
418             gettimeofday(&event.time, NULL);
419             event.type = EV_SYN;
420             event.code = SYN_REPORT;
421             if (write(uifd, &event, sizeof(struct input_event)) < 0)    {
422                 print_log("syn event write error 3[%d]", errno);
423             }
424         }
425     }
426     else    {
427         memset(&js, 0, sizeof(js));
428         gettimeofday(&event.time, NULL);
429         js.time = (event.time.tv_sec * 1000) + (event.time.tv_usec / 1000);
430         js.type = event_key[key].type;
431         js.number = event_key[key].code;
432         js.value = convert_value(value, (char **)0, 0);
433         if (mDebug) {
434             print_log("Send Event JS=%d,%d,%d\t# %d",
435                       (int)js.type, (int)js.number, (int)js.value, (int)js.time);
436         }
437         if (write(uifd, &js, sizeof(struct js_event)) < 0)  {
438             print_log("event write error 4[%d]", errno);
439             fflush(stderr);
440         }
441     }
442 }
443
444 void
445 print_log(const char *fmt, ...)
446 {
447     va_list     ap;
448     char        log[128];
449     struct timeval  NowTime;
450     extern long timezone;
451     static int  sTimeZone = (99*60*60);
452
453     va_start(ap, fmt);
454     vsnprintf(log, sizeof(log)-2, fmt, ap);
455     va_end(ap);
456
457     gettimeofday( &NowTime, (struct timezone *)0 );
458     if( sTimeZone > (24*60*60) )    {
459         tzset();
460         sTimeZone = timezone;
461     }
462     NowTime.tv_sec -= sTimeZone;
463     fprintf(stderr, "[%02d:%02d:%02d.%03d@%d] %s\n", (int)((NowTime.tv_sec/3600) % 24),
464             (int)((NowTime.tv_sec/60) % 60), (int)(NowTime.tv_sec % 60),
465             (int)NowTime.tv_usec/1000, getpid(), log);
466 }
467
468 static void
469 usage(const char *prog)
470 {
471     fprintf(stderr, "Usage: %s [-device=device] [-w=w] [-h=h] [-c] [{-m/-t/-j/-J}] "
472             "[-mq[=key]] [-d] [event[=value]] [event[=value]] ...\n", prog);
473     exit(0);
474 }
475
476 int
477 main(int argc, char *argv[])
478 {
479     int     i, j, k;
480     int     mqkey = 0;
481     struct {
482         long    mtype;
483         char    buf[240];
484     }       mqbuf;
485     char    buf[240];
486
487     j = 0;
488     mWidth = 1080;
489     mHeight = 1920;
490     strcpy(buf, "ico_test_device");
491     for (i = 1; i < argc; i++)  {
492         if (argv[i][0] == '-')  {
493             if (strncasecmp(argv[i], "-device=", 8) == 0)   {
494                 strcpy(buf, &argv[i][8]);
495             }
496             else if (strncasecmp(argv[i], "-w=", 3) == 0)   {
497                 mWidth = strtol(&argv[i][3], (char **)0, 0);
498             }
499             else if (strncasecmp(argv[i], "-h=", 3) == 0)   {
500                 mHeight = strtol(&argv[i][3], (char **)0, 0);
501             }
502             else if (strcasecmp(argv[i], "-c") == 0)   {
503                 mConvert = 1;               /* Convert logical to physical  */
504             }
505             else if (strcasecmp(argv[i], "-m") == 0)   {
506                 mTouch = 1;                 /* Simulate mouse               */
507             }
508             else if (strcasecmp(argv[i], "-t") == 0)   {
509                 mTouch = 2;                 /* Simulate touch-panel         */
510             }
511             else if (strcmp(argv[i], "-j") == 0)   {
512                 mTouch = 0;                 /* Simulate joystick            */
513             }
514             else if (strcmp(argv[i], "-J") == 0)   {
515                 mTouch = 3;                 /* Simulate joystick, but event is mouse    */
516             }
517             else if (strncasecmp(argv[i], "-mq", 3) == 0)   {
518                 if (argv[i][3] == '=')  {
519                     mqkey = strtol(&argv[i][4], (char **)0, 0);
520                 }
521                 else    {
522                     mqkey = 55551;          /* default message queue key    */
523                 }
524             }
525             else if (strcasecmp(argv[i], "-d") == 0)   {
526                 mDebug = 1;
527             }
528             else    {
529                 usage(argv[0]);
530             }
531         }
532         else    {
533             j++;
534         }
535     }
536
537     init_mq(mqkey);
538
539     init_device(buf);
540
541     mRun = 1;
542
543     signal(SIGTERM, term_signal);
544     signal(SIGINT, term_signal);
545
546     if (mqid >= 0)  {
547         while (mRun)  {
548             memset(&mqbuf, 0, sizeof(mqbuf));
549             if (msgrcv(mqid, &mqbuf, sizeof(mqbuf)-sizeof(long), 0, 0) < 0) {
550                 if (errno == EINTR) continue;
551                 print_log("ico_send_inputevent: mq(%d) receive error[%d]",
552                           mqkey, errno);
553                 fflush(stderr);
554                 break;
555             }
556             k = 0;
557             j = -1;
558             for (i = 0; mqbuf.buf[i]; i++)    {
559                 if ((mqbuf.buf[i] == '#') || (mqbuf.buf[i] == '\n')
560                     || (mqbuf.buf[i] == '\r'))    break;
561                 if (mqbuf.buf[i] == '\t') buf[k++] = ' ';
562                 else                        buf[k++] = mqbuf.buf[i];
563                 if ((j < 0) && (mqbuf.buf[i] != ' ')) j = i;
564             }
565             if (j < 0)  continue;
566             buf[k] = 0;
567             send_event(&buf[j]);
568         }
569         msgctl(mqid, IPC_RMID, NULL);
570     }
571     else if (j <= 0) {
572         while ((mRun != 0) && (fgets(buf, sizeof(buf), stdin) != NULL))  {
573             j = -1;
574             for (i = 0; buf[i]; i++)    {
575                 if ((buf[i] == '#') || (buf[i] == '\n') || (buf[i] == '\r'))    break;
576                 if (buf[i] == '\t') buf[i] = ' ';
577                 if ((j < 0) && (buf[i] != ' ')) j = i;
578             }
579             if (j < 0)  continue;
580             buf[i] = 0;
581             send_event(&buf[j]);
582         }
583     }
584     else    {
585         for (i = 1; i < argc; i++)  {
586             if (argv[i][0] == '-')  continue;
587             if (mRun == 0)  break;
588             send_event(argv[i]);
589         }
590     }
591     usleep(300*1000);
592     exit(0);
593 }
594