2 * Copyright © 2013 TOYOTA MOTOR CORPORATION.
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.
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.
23 * @brief System Test Tool for send device input event
34 #include <sys/ioctl.h>
38 #include <sys/types.h>
42 #include <linux/input.h>
43 #include <linux/uinput.h>
44 #include <linux/joystick.h>
45 #include "test-common.h"
49 #define SPECIALTYPE_XY 9991
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 },
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 } };
81 static int mDebug = 0;
83 static int mTouch = 1;
86 term_signal(const int signo)
92 init_mq(const int mqkey)
100 mqid = msgget(mqkey, 0);
102 mqid = msgget(mqkey, IPC_CREAT);
105 print_log("Can not create message queue(%d(0x%x))[%d]",
106 mqkey, mqkey, errno);
110 while (msgrcv(mqid, dummy, sizeof(dummy)-sizeof(long), 0, IPC_NOWAIT) > 0) ;
115 init_device(const char *device)
121 struct uinput_user_dev uinputDevice;
122 uifd = open("/dev/uinput", O_RDWR);
125 print_log("/dev/uinput open error[%d]", errno);
130 memset(&uinputDevice, 0, sizeof(uinputDevice));
131 strcpy(uinputDevice.name, device);
132 uinputDevice.absmax[ABS_X] = 1920;
133 uinputDevice.absmax[ABS_Y] = 1080;
135 /* uinput device configuration */
136 if (write(uifd, &uinputDevice, sizeof(uinputDevice)) < (int)sizeof(uinputDevice)) {
137 print_log("/dev/uinput regist error[%d]", errno);
143 /* uinput set event bits */
144 ioctl(uifd, UI_SET_EVBIT, EV_SYN);
146 if ((mTouch != 0) && (mTouch != 3)) {
147 ioctl(uifd, UI_SET_EVBIT, EV_ABS);
148 ioctl(uifd, UI_SET_ABSBIT, ABS_X);
149 ioctl(uifd, UI_SET_ABSBIT, ABS_Y);
150 ioctl(uifd, UI_SET_EVBIT, EV_KEY);
152 ioctl(uifd, UI_SET_KEYBIT, BTN_LEFT);
155 ioctl(uifd, UI_SET_KEYBIT, BTN_TOUCH);
156 ioctl(uifd, UI_SET_KEYBIT, BTN_TOOL_PEN);
160 ioctl(uifd, UI_SET_EVBIT, EV_REL);
161 ioctl(uifd, UI_SET_RELBIT, REL_X);
162 ioctl(uifd, UI_SET_RELBIT, REL_Y);
163 ioctl(uifd, UI_SET_RELBIT, REL_Z);
164 ioctl(uifd, UI_SET_RELBIT, REL_RX);
165 ioctl(uifd, UI_SET_RELBIT, REL_RY);
166 ioctl(uifd, UI_SET_RELBIT, REL_RZ);
167 ioctl(uifd, UI_SET_EVBIT, EV_KEY);
168 ioctl(uifd, UI_SET_KEYBIT, KEY_RESERVED);
169 ioctl(uifd, UI_SET_KEYBIT, KEY_ESC);
170 ioctl(uifd, UI_SET_KEYBIT, KEY_1);
171 ioctl(uifd, UI_SET_KEYBIT, KEY_2);
172 ioctl(uifd, UI_SET_KEYBIT, KEY_3);
173 ioctl(uifd, UI_SET_KEYBIT, KEY_4);
174 ioctl(uifd, UI_SET_KEYBIT, KEY_5);
175 ioctl(uifd, UI_SET_KEYBIT, KEY_6);
176 ioctl(uifd, UI_SET_KEYBIT, KEY_7);
177 ioctl(uifd, UI_SET_KEYBIT, KEY_8);
178 ioctl(uifd, UI_SET_KEYBIT, KEY_9);
179 ioctl(uifd, UI_SET_KEYBIT, KEY_0);
182 ioctl(uifd, UI_SET_EVBIT, EV_MSC);
183 ioctl(uifd, UI_SET_MSCBIT, MSC_SCAN);
185 /* create event device */
186 if (ioctl(uifd, UI_DEV_CREATE, NULL) < 0) {
187 print_log("/dev/uinput create error[%d]", errno);
192 print_log("## created event device %s", device);
194 for (ii = 0; ii < 16; ii++) {
195 snprintf(devFile, 64, "/dev/input/event%d", ii);
196 fd = open(devFile, O_RDONLY);
197 if (fd < 0) continue;
199 memset(devName, 0, sizeof(devName));
200 ioctl(fd, EVIOCGNAME(sizeof(devName)), devName);
202 print_log("%d.event device(%s) is %s", ii+1, devFile, devName);
207 convert_value(const char *value, char **errp, int base)
211 for (i = 0; value[i]; i++) {
212 if ((value[i] == ',') || (value[i] == ';') ||
213 (value[i] == ';') || (value[i] == ' ')) {
218 *errp = (char *)&value[i];
221 if ((strncasecmp(value, "on", i) == 0) ||
222 (strncasecmp(value, "true", i) == 0) ||
223 (strncasecmp(value, "push", i) == 0) ||
224 (strncasecmp(value, "down", i) == 0) ||
225 (strncasecmp(value, "right", i) == 0)) {
228 else if ((strncasecmp(value, "off", i) == 0) ||
229 (strncasecmp(value, "false", i) == 0) ||
230 (strncasecmp(value, "pop", i) == 0) ||
231 (strncasecmp(value, "up", i) == 0) ||
232 (strncasecmp(value, "left", i) == 0)) {
235 return strtol(value, (char **)0, 0);
239 send_event(const char *cmd)
247 struct input_event event;
251 for (i = 0; cmd[i]; i++) {
252 if ((cmd[i] == '=') || (cmd[i] == ' ')) break;
253 if (j < (int)(sizeof(prop)-1)) {
261 for (i++; cmd[i]; i++) {
262 if (cmd[i] == ' ') continue;
263 if (j < (int)(sizeof(value)-1)) {
270 if (strcasecmp(prop, "sleep") == 0) {
273 for (i = 0; value[i]; i++) {
274 if (value[i] == '.') break;
275 sec = sec * 10 + (value[i] & 0x0f);
277 if (value[i] == '.') {
280 msec = (value[i] & 0x0f) * 100;
284 msec = msec + (value[i] & 0x0f) * 10;
288 msec = msec + (value[i] & 0x0f);
291 if (sec > 0) sleep(sec);
292 if (msec > 0) usleep(msec * 1000);
297 for (key = 0; event_key[key].prop[0]; key++) {
298 if (strcasecmp(prop, event_key[key].prop) == 0) break;
300 if (! event_key[key].prop[0]) {
301 print_log("UnKnown Event name[%s]", prop);
306 memset(&event, 0, sizeof(event));
307 gettimeofday(&event.time, NULL);
308 if (event_key[key].type == SPECIALTYPE_XY) {
311 event.value = convert_value(value, &errp, 0);
313 print_log("Send Event ABS_X=%d\t# %d.%03d", event.value,
314 (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
317 if (write(uifd, &event, sizeof(struct input_event)) < 0) {
318 print_log("event write error 1[%d]", errno);
324 event.value = convert_value(errp + 1, (char **)0, 0);
329 event.time.tv_usec += 200;
330 if (event.time.tv_usec >= 1000000) {
331 event.time.tv_sec ++;
332 event.time.tv_usec -= 1000000;
335 print_log("Send Event ABS_Y=%d\t# %d.%03d", event.value,
336 (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
341 event.type = event_key[key].type;
343 if (event_key[key].code == -1) {
344 event.code = convert_value(value, (char **)0, 0);
347 event.code = event_key[key].code;
348 event.value = convert_value(value, (char **)0, 0);
351 if ((event.type == EV_ABS) && (event.code == ABS_X)) {
352 print_log("Send Event X=%d\t# %d.%03d", event.value,
353 (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
355 else if ((event.type == EV_ABS) && (event.code == ABS_Y)) {
356 print_log("Send Event Y=%d\t %d.%03d", event.value,
357 (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
359 else if ((event.type == EV_KEY) &&
360 (event.code == BTN_LEFT) && (event.value == 1)) {
361 print_log("Send Event BTN_LEFT=Down\t# %d.%03d",
362 (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
364 else if ((event.type == EV_KEY) &&
365 (event.code == BTN_LEFT) && (event.value == 0)) {
366 print_log("Send Event BTN_LEFT=Up\t# %d.%03d",
367 (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
370 if ((event.type == EV_REL) && (event.value == 0)) {
373 else if ((event.type == EV_KEY) && (event.code == 0)) {
376 print_log("Send Event type=%d code=%d value=%d\t# %d.%03d",
377 event.type, event.code, event.value,
378 (int)event.time.tv_sec, (int)(event.time.tv_usec/1000));
383 if (write(uifd, &event, sizeof(struct input_event)) < 0) {
384 print_log("event write error 2[%d]", errno);
389 memset(&event, 0, sizeof(event));
390 gettimeofday(&event.time, NULL);
392 event.code = SYN_REPORT;
393 if (write(uifd, &event, sizeof(struct input_event)) < 0) {
394 print_log("syn event write error 3[%d]", errno);
399 memset(&js, 0, sizeof(js));
400 gettimeofday(&event.time, NULL);
401 js.time = (event.time.tv_sec * 1000) + (event.time.tv_usec / 1000);
402 js.type = event_key[key].type;
403 js.number = event_key[key].code;
404 js.value = convert_value(value, (char **)0, 0);
406 print_log("Send Event JS=%d,%d,%d\t# %d",
407 (int)js.type, (int)js.number, (int)js.value, (int)js.time);
409 if (write(uifd, &js, sizeof(struct js_event)) < 0) {
410 print_log("event write error 4[%d]", errno);
417 usage(const char *prog)
419 fprintf(stderr, "Usage: %s [-device=device] [{-m/-t/-j}] [-mq[=key]] "
420 "[-d] [event=value] [event=value] ...\n", prog);
425 main(int argc, char *argv[])
436 strcpy(buf, "ico_test_device");
437 for (i = 1; i < argc; i++) {
438 if (argv[i][0] == '-') {
439 if (strncasecmp(argv[i], "-device=", 8) == 0) {
440 strcpy(buf, &argv[i][8]);
442 else if (strcasecmp(argv[i], "-m") == 0) {
443 mTouch = 1; /* Simulate mouse */
445 else if (strcasecmp(argv[i], "-t") == 0) {
446 mTouch = 2; /* Simulate touch-panel */
448 else if (strcmp(argv[i], "-j") == 0) {
449 mTouch = 0; /* Simulate joystick */
451 else if (strcmp(argv[i], "-J") == 0) {
452 mTouch = 3; /* Simulate joystick, but event is mouse */
454 else if (strncasecmp(argv[i], "-mq", 3) == 0) {
455 if (argv[i][3] == '=') {
456 mqkey = strtol(&argv[i][4], (char **)0, 0);
459 mqkey = 55551; /* default message queue key */
462 else if (strcasecmp(argv[i], "-d") == 0) {
480 signal(SIGTERM, term_signal);
481 signal(SIGINT, term_signal);
485 memset(&mqbuf, 0, sizeof(mqbuf));
486 if (msgrcv(mqid, &mqbuf, sizeof(mqbuf)-sizeof(long), 0, 0) < 0) {
487 if (errno == EINTR) continue;
488 print_log("test-send_event: mq(%d) receive error[%d]",
495 for (i = 0; mqbuf.buf[i]; i++) {
496 if ((mqbuf.buf[i] == '#') || (mqbuf.buf[i] == '\n')
497 || (mqbuf.buf[i] == '\r')) break;
498 if (mqbuf.buf[i] == '\t') buf[k++] = ' ';
499 else buf[k++] = mqbuf.buf[i];
500 if ((j < 0) && (mqbuf.buf[i] != ' ')) j = i;
506 msgctl(mqid, IPC_RMID, NULL);
509 while ((mRun != 0) && (fgets(buf, sizeof(buf), stdin) != NULL)) {
511 for (i = 0; buf[i]; i++) {
512 if ((buf[i] == '#') || (buf[i] == '\n') || (buf[i] == '\r')) break;
513 if (buf[i] == '\t') buf[i] = ' ';
514 if ((j < 0) && (buf[i] != ' ')) j = i;
522 for (i = 1; i < argc; i++) {
523 if (argv[i][0] == '-') continue;
524 if (mRun == 0) break;