f61e84b246cedb9d39fc7b627c4ca6224ea5172f
[platform/core/uifw/libds-tizen.git] / src / clients / input-generator.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/epoll.h>
6
7 #include <wayland-client.h>
8 #include <tizen-extension-client-protocol.h>
9
10 #define MAX_STR 1024
11 #define SIZE_EPOLL 16
12
13 enum enum_key_type
14 {
15     KEY_UP = 0,
16     KEY_DOWN,
17     KEY_ALL
18 };
19
20 enum enum_touch_type
21 {
22     TOUCH_BEGIN = 0,
23     TOUCH_UPDATE,
24     TOUCH_END,
25     TOUCH_ALL
26 };
27
28 struct display
29 {
30     struct wl_display *display;
31     struct wl_registry *registry;
32     struct wl_compositor *compositor;
33
34     struct tizen_input_device_manager *devicemgr;
35     enum tizen_input_device_manager_clas clas;
36     struct wl_event_queue *queue;
37
38     int run;
39     int fd_epoll;
40     int fd_display;
41
42     int request_notified;
43     int init;
44
45     int enable_log;
46 };
47
48 struct display data_wl;
49
50 static void
51 usage(void)
52 {
53     printf("  Supported commands:  init  (Initialize input generator)\n");
54     printf("                    :  deinit  (Deinitialize input generator)\n");
55     printf("                    :  key  (Generate key events)\n");
56     printf("                    :  touch  (Generate touch events)\n");
57     printf("                    :  help  (Print this help text)\n");
58     printf("                    :  q/quit  (Quit program)\n");
59     printf("                    :  log  (Print detailed logs)\n");
60     printf("init {device type}\n");
61     printf("  : device type:\n");
62     printf("    - default: all\n");
63     printf("    - key/keyboard: keyboard\n");
64     printf("    - touch: touch screen\n");
65     printf("    - all: all of devices\n");
66     printf("  : ex> init keyboard / init\n");
67     printf("\n");
68     printf("deinit\n");
69     printf("  : ex> deinit\n");
70     printf("\n");
71     printf("key [keyname] {pressed}\n");
72     printf("  : pressed:\n");
73     printf("    - default: down&up pair\n");
74     printf("    - key down: 1\n");
75     printf("    - key up: 0\n");
76     printf("  : ex> key XF86Back 1\n");
77     printf("\n");
78     printf("touch {index} {type} {x} {y}\n");
79     printf("  : index:\n");
80     printf("    - default: first finger(0)\n");
81     printf("    - first finger is 0\n");
82     printf("  : type:\n");
83     printf("    - default: generate sample touch events\n");
84     printf("    - touch begin: 1\n");
85     printf("    - touch update: 2\n");
86     printf("    - touch end: 3\n");
87     printf("  : x/y:\n");
88     printf("    - default: 0\n");
89     printf("  : ex> touch / touch 0 1 100 100\n");
90     printf("\n");
91 }
92
93 static void
94 init_input_generator(enum tizen_input_device_manager_clas clas)
95 {
96     if (data_wl.init) {
97         printf("Already init input generator\n");
98         return;
99     }
100
101     tizen_input_device_manager_init_generator(data_wl.devicemgr, clas);
102
103     while (data_wl.request_notified == -1)
104         wl_display_dispatch_queue(data_wl.display, data_wl.queue);
105
106     if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
107         data_wl.init = 1;
108         printf("Success to init input generator\n");
109     } else {
110         printf("Failed to init input generator: %d\n", data_wl.request_notified);
111     }
112
113     data_wl.clas = clas;
114     data_wl.request_notified = -1;
115 }
116
117 static void
118 deinit_input_generator(void)
119 {
120     if (!data_wl.init) {
121         printf("input generator is not initialized\n");
122         return;
123     }
124
125     tizen_input_device_manager_deinit_generator(data_wl.devicemgr, data_wl.clas);
126
127     while (data_wl.request_notified == -1)
128         wl_display_dispatch_queue(data_wl.display, data_wl.queue);
129
130     if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
131         data_wl.init = 0;
132         printf("Success to deinit input generator\n");
133     } else {
134         printf("Failed to deinit input generator: %d\n", data_wl.request_notified);
135     }
136
137     data_wl.request_notified = -1;
138 }
139
140 static void
141 input_generator_key(char *name, int type)
142 {
143     tizen_input_device_manager_generate_key(data_wl.devicemgr, name, !!type);
144
145     while (data_wl.request_notified == -1)
146         wl_display_dispatch_queue(data_wl.display, data_wl.queue);
147
148     if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
149         if (data_wl.enable_log) {
150             printf("Success to generate key: %s key %s\n", name, type?"down":"up");
151         }
152     } else {
153         printf("Failed to generate %s key %s: %d\n", name, type?"down":"up", data_wl.request_notified);
154     }
155
156     data_wl.request_notified = -1;
157 }
158
159 static void
160 key_generate(char *name, int type)
161 {
162     printf("name: %s, type: %d\n", name, type);
163
164     if (!data_wl.init) {
165         printf("Input genrator is not initialized\n");
166         return;
167     }
168
169     if (!name) {
170         printf("Type which key is generated\n");
171         return;
172     }
173
174     if (type == KEY_ALL) {
175         input_generator_key(name, 1);
176         input_generator_key(name, 0);
177     } else {
178         input_generator_key(name, !!type);
179     }
180 }
181
182 static char *
183 touch_type_string_get(int type)
184 {
185     switch (type) {
186         case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN:
187             return "begin";
188         case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE:
189             return "update";
190         case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END:
191             return "end";
192         default:
193             return "Unknown";
194     }
195 }
196
197 static void
198 input_generator_touch(int idx, int type, int x, int y)
199 {
200     tizen_input_device_manager_generate_touch(data_wl.devicemgr, type, x, y, idx);
201
202     while (data_wl.request_notified == -1)
203         wl_display_dispatch_queue(data_wl.display, data_wl.queue);
204
205     if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
206         if (data_wl.enable_log) {
207             printf("Success to generate touch: %d finger %s on (%d, %d)\n", idx, touch_type_string_get(type), x, y);
208         }
209     } else {
210         printf("Failed to generate touch(%d finger %s on (%d, %d)): %d\n", idx, touch_type_string_get(type), x, y, data_wl.request_notified);
211     }
212
213     data_wl.request_notified = -1;
214 }
215
216 static void
217 touch_generate(int idx, int type, int x, int y)
218 {
219     if (!data_wl.init) {
220         printf("Input genrator is not initialized\n");
221         return;
222     }
223
224     if (type == TOUCH_ALL) {
225         input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 100, 100);
226         input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 200, 200);
227         input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 300, 300);
228
229         input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 110, 110);
230         input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 210, 210);
231         input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 310, 310);
232
233         input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 120, 120);
234         input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 220, 220);
235         input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 320, 320);
236
237         input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 120, 120);
238         input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 220, 220);
239         input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 320, 320);
240     } else {
241         input_generator_touch(idx, type, x, y);
242     }
243 }
244
245 static void
246 stdin_read(void)
247 {
248     int c;
249     char buf[MAX_STR] = {0, }, *tmp, *buf_ptr, key_name[MAX_STR] = {0, };
250     int count = 0;
251     int key_type = KEY_ALL, touch_idx = 0, touch_type = TOUCH_ALL, touch_x = 0, touch_y = 0;
252
253     while ((c = getchar()) != EOF) {
254         if (c == '\n') break;
255         if (count >= MAX_STR) break;
256
257         buf[count] = c;
258         count++;
259     }
260
261     count = 0;
262     tmp = strtok_r(buf, " ", &buf_ptr);
263     if (!tmp) return;
264
265     if (!strncmp(tmp, "init", sizeof("init"))) {
266         while (tmp) {
267             tmp = strtok_r(NULL, " ", &buf_ptr);
268             if (tmp) {
269                 switch (count) {
270                     case 0:
271                         if (!strncmp("keyboard", tmp, MAX_STR-1))
272                             init_input_generator(TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD);
273                         else if (!strncmp("touch", tmp, MAX_STR-1))
274                             init_input_generator(TIZEN_INPUT_DEVICE_MANAGER_CLAS_TOUCHSCREEN);
275                         break;
276                     default:
277                         break;
278                 }
279             }
280             count++;
281         }
282     } else if (!strncmp(tmp, "deinit", sizeof("deinit"))) {
283         deinit_input_generator();
284     } else if (!strncmp(tmp, "key", sizeof("key"))) {
285         while (tmp) {
286             tmp = strtok_r(NULL, " ", &buf_ptr);
287             if (tmp) {
288                 switch (count) {
289                     case 0:
290                         strncpy(key_name, tmp, MAX_STR-1);
291                         break;
292                     case 1:
293                         key_type = atoi(tmp);
294                         break;
295                     default:
296                         break;
297                 }
298             }
299             count++;
300         }
301         key_generate(key_name, key_type);
302     } else if (!strncmp(tmp, "touch", sizeof("touch"))) {
303         while (tmp) {
304             tmp = strtok_r(NULL, " ", &buf_ptr);
305             if (tmp) {
306                 switch (count) {
307                     case 0:
308                         touch_idx = atoi(tmp);
309                         break;
310                     case 1:
311                         touch_type = atoi(tmp);
312                         break;
313                     case 2:
314                         touch_x = atoi(tmp);
315                         break;
316                     case 3:
317                         touch_y = atoi(tmp);
318                         break;
319                     default:
320                         break;
321                 }
322             }
323             count++;
324         }
325         touch_generate(touch_idx, touch_type, touch_x, touch_y);
326     } else if (!strncmp(buf, "q", MAX_STR) || !strncmp(buf, "quit", MAX_STR)) {
327         data_wl.run = 0;
328     } else if (!strncmp(buf, "help", MAX_STR)) {
329         usage();
330     } else if (!strncmp(buf, "log", MAX_STR)) {
331         if (data_wl.enable_log)
332             printf("Disable detailed logs\n");
333         else
334             printf("Enable detailed logs\n");
335
336         data_wl.enable_log = !data_wl.enable_log;
337     } else {
338         printf("Invalid arguments\n");
339         usage();
340     }
341 }
342
343 static void
344 input_device_manager_handle_error(void *data,
345         struct tizen_input_device_manager *tizen_input_device_manager,
346         uint32_t errorcode)
347 {
348     if (data_wl.enable_log)
349         printf("errorcode: %d\n", errorcode);
350     data_wl.request_notified = errorcode;
351 }
352
353 static const struct tizen_input_device_manager_listener _input_device_manager_listener =
354 {
355     .device_add = NULL,
356     .device_remove = NULL,
357     .error = input_device_manager_handle_error,
358     .block_expired = NULL,
359 };
360
361 static void
362 registry_handle_global(void * data, struct wl_registry * registry, uint32_t id,
363         const char * interface, uint32_t version)
364 {
365     if (strcmp(interface, "wl_compositor") == 0) {
366         data_wl.compositor = wl_registry_bind(registry, id,
367                 &wl_compositor_interface, version);
368         if (!data_wl.compositor) {
369             printf("Failed to bind compositor.");
370             return;
371         }
372         if (data_wl.enable_log)
373             printf("Success to bind compositor.");
374     } else if (strcmp(interface, "tizen_input_device_manager") == 0) {
375         data_wl.devicemgr = wl_registry_bind(registry, id,
376                 &tizen_input_device_manager_interface, version);
377         if (!data_wl.devicemgr) {
378             printf("Failed to bind input device manager");
379             return;
380         }
381         if (data_wl.enable_log)
382             printf("Success to bind tizen input device manager.");
383         tizen_input_device_manager_add_listener(data_wl.devicemgr,
384             &_input_device_manager_listener, data_wl.display);
385     }
386 }
387
388 static void
389 registry_handle_global_remove(void * data, struct wl_registry * registry, uint32_t id)
390 {
391     if (data_wl.enable_log)
392         printf("registry is removed. id: %d !\n", id);
393 }
394
395 static const struct wl_registry_listener _registry_listener = {
396     registry_handle_global,
397     registry_handle_global_remove
398 };
399
400 static int
401 wayland_init(void)
402 {
403     memset(&data_wl, 0, sizeof(struct display));
404     data_wl.request_notified = -1;
405
406     data_wl.display = wl_display_connect(NULL);
407     if (!data_wl.display) {
408         printf("Failed to connect wayland display\n");
409         return 0;
410     }
411
412     data_wl.queue = wl_display_create_queue(data_wl.display);
413     if (!data_wl.queue) {
414         printf("Failed to create queue\n");
415         return 0;
416     }
417
418     data_wl.registry = wl_display_get_registry(data_wl.display);
419     if (!data_wl.registry) {
420         printf("Failed to get registry\n");
421         return 0;
422     }
423
424     wl_proxy_set_queue((struct wl_proxy*)data_wl.registry, data_wl.queue);
425     wl_registry_add_listener(data_wl.registry, &_registry_listener, NULL);
426
427     if (wl_display_dispatch_queue(data_wl.display, data_wl.queue) == -1) {
428         printf("Failed to dispatch display\n");
429         return 0;
430     }
431     if (wl_display_roundtrip_queue(data_wl.display, data_wl.queue) == -1) {
432         printf("Failed to roundtrip display\n");
433         return 0;
434     }
435
436     return 1;
437 }
438
439 static void
440 wayland_deinit(void)
441 {
442     if (data_wl.enable_log)
443         printf("Shutdown wayland system\n");
444
445     if (data_wl.init) deinit_input_generator();
446
447     if (data_wl.queue) wl_event_queue_destroy(data_wl.queue);
448     if (data_wl.devicemgr) tizen_input_device_manager_destroy(data_wl.devicemgr);
449     if (data_wl.display) {
450         wl_registry_destroy(data_wl.registry);
451         wl_display_flush(data_wl.display);
452         wl_display_disconnect(data_wl.display);
453     }
454 }
455
456 static int
457 epoll_init(void)
458 {
459     struct epoll_event ep[2];
460
461     data_wl.fd_epoll = epoll_create(SIZE_EPOLL);
462     if (data_wl.fd_epoll <= 0) {
463         printf("Failed to epoll create: %d\n", SIZE_EPOLL);
464         return 0;
465     }
466
467     data_wl.fd_display = wl_display_get_fd(data_wl.display);
468
469     memset(ep, 0, sizeof(struct epoll_event)*2);
470
471     ep[0].events = EPOLLIN | EPOLLERR | EPOLLHUP;
472     ep[0].data.fd = data_wl.fd_display;
473     epoll_ctl(data_wl.fd_epoll, EPOLL_CTL_ADD, data_wl.fd_display, &ep[0]);
474     ep[1].events = EPOLLIN | EPOLLERR | EPOLLHUP;
475     ep[1].data.fd = STDIN_FILENO;
476     epoll_ctl(data_wl.fd_epoll, EPOLL_CTL_ADD, 0, &ep[1]);
477
478     return 1;
479 }
480
481 static void
482 mainloop(void)
483 {
484     struct epoll_event ep[SIZE_EPOLL];
485     int res, count, i;
486
487     res = epoll_init();
488     if (!res) {
489         printf("Failed to init epoll\n");
490         return;
491     }
492
493     data_wl.run = 1;
494     while (data_wl.run) {
495         res = wl_display_dispatch_queue_pending(data_wl.display, data_wl.queue);
496         if (res < 0) {
497             printf("Failed to dispatch pending. result: %d\n", res);
498             data_wl.run = 0;
499             break;
500         }
501         res = wl_display_flush(data_wl.display);
502         if (res < 0) {
503             printf("Failed to flush display. result: %d\n", res);
504             data_wl.run = 0;
505             break;
506         }
507
508         count = epoll_wait(data_wl.fd_epoll, ep, SIZE_EPOLL, -1);
509         for (i = 0; i < count; i++) {
510             if (ep[i].events & EPOLLIN) {
511                 if (ep[i].data.fd == data_wl.fd_display) {
512                     wl_display_dispatch_queue(data_wl.display, data_wl.queue);
513                 } else {
514                     stdin_read();
515                 }
516             }
517             if (ep[i].events & EPOLLERR) {
518                 data_wl.run = 0;
519             }
520             if (ep[i].events & EPOLLHUP) {
521                 data_wl.run = 0;
522             }
523         }
524     }
525 }
526
527 int
528 main(int argc, char **argv)
529 {
530     int res;
531
532     res = wayland_init();
533     if (!res) return 0;
534
535     mainloop();
536
537     wayland_deinit();
538
539     return 0;
540 }