7 #include <wayland-client.h>
8 #include <xkbcommon/xkbcommon.h>
9 //#include <linux/input.h>
11 #include <input-method-client-protocol.h>
12 #include <text-client-protocol.h>
13 #include <tizen-extension-client-protocol.h>
19 KEYBOARD_STATE_DEFAULT,
20 KEYBOARD_STATE_UPPERCASE,
21 KEYBOARD_STATE_SYMBOLS
41 struct wl_display *display;
42 struct wl_registry *registry;
43 struct wl_compositor *compositor;
45 struct tizen_input_device_manager *devicemgr;
46 enum tizen_input_device_manager_clas clas;
47 struct wl_event_queue *queue;
58 struct zwp_input_method_manager_v1 *input_method_mgr;
59 struct zwp_input_method_v1 *input_method;
60 struct zwp_input_method_context_v1 *context;
63 uint32_t preedit_style;
65 xkb_mod_mask_t shift_mask;
68 uint32_t content_hint;
69 int32_t content_purpose;
70 char *preferred_language;
71 char *surrounding_text;
72 uint32_t surrounding_cursor;
73 enum keyboard_state state; //struct keyboard *keyboard;
75 //struct zwp_input_panel_surface_v1 *ips;
79 const struct key *keys;
86 uint32_t text_direction;
105 enum key_type key_type;
114 static const struct key normal_keys[] = {
115 { keytype_default, "q", "Q", "1", 1},
116 { keytype_default, "w", "W", "2", 1},
117 { keytype_default, "e", "E", "3", 1},
118 { keytype_default, "r", "R", "4", 1},
119 { keytype_default, "t", "T", "5", 1},
120 { keytype_default, "y", "Y", "6", 1},
121 { keytype_default, "u", "U", "7", 1},
122 { keytype_default, "i", "I", "8", 1},
123 { keytype_default, "o", "O", "9", 1},
124 { keytype_default, "p", "P", "0", 1},
125 { keytype_backspace, "<--", "<--", "<--", 2},
127 { keytype_tab, "->|", "->|", "->|", 1},
128 { keytype_default, "a", "A", "-", 1},
129 { keytype_default, "s", "S", "@", 1},
130 { keytype_default, "d", "D", "*", 1},
131 { keytype_default, "f", "F", "^", 1},
132 { keytype_default, "g", "G", ":", 1},
133 { keytype_default, "h", "H", ";", 1},
134 { keytype_default, "j", "J", "(", 1},
135 { keytype_default, "k", "K", ")", 1},
136 { keytype_default, "l", "L", "~", 1},
137 { keytype_enter, "Enter", "Enter", "Enter", 2},
139 { keytype_switch, "ABC", "abc", "ABC", 2},
140 { keytype_default, "z", "Z", "/", 1},
141 { keytype_default, "x", "X", "\'", 1},
142 { keytype_default, "c", "C", "\"", 1},
143 { keytype_default, "v", "V", "+", 1},
144 { keytype_default, "b", "B", "=", 1},
145 { keytype_default, "n", "N", "?", 1},
146 { keytype_default, "m", "M", "!", 1},
147 { keytype_default, ",", ",", "\\", 1},
148 { keytype_default, ".", ".", "|", 1},
149 { keytype_switch, "ABC", "abc", "ABC", 1},
151 { keytype_symbols, "?123", "?123", "abc", 1},
152 { keytype_space, "", "", "", 5},
153 { keytype_arrow_up, "/\\", "/\\", "/\\", 1},
154 { keytype_arrow_left, "<", "<", "<", 1},
155 { keytype_arrow_right, ">", ">", ">", 1},
156 { keytype_arrow_down, "\\/", "\\/", "\\/", 1},
157 { keytype_style, "", "", "", 2}
160 static const struct key numeric_keys[] = {
161 { keytype_default, "1", "1", "1", 1},
162 { keytype_default, "2", "2", "2", 1},
163 { keytype_default, "3", "3", "3", 1},
164 { keytype_default, "4", "4", "4", 1},
165 { keytype_default, "5", "5", "5", 1},
166 { keytype_default, "6", "6", "6", 1},
167 { keytype_default, "7", "7", "7", 1},
168 { keytype_default, "8", "8", "8", 1},
169 { keytype_default, "9", "9", "9", 1},
170 { keytype_default, "0", "0", "0", 1},
171 { keytype_backspace, "<--", "<--", "<--", 2},
173 { keytype_space, "", "", "", 4},
174 { keytype_enter, "Enter", "Enter", "Enter", 2},
175 { keytype_arrow_up, "/\\", "/\\", "/\\", 1},
176 { keytype_arrow_left, "<", "<", "<", 1},
177 { keytype_arrow_right, ">", ">", ">", 1},
178 { keytype_arrow_down, "\\/", "\\/", "\\/", 1},
179 { keytype_style, "", "", "", 2}
182 static const struct layout normal_layout = {
184 sizeof(normal_keys) / sizeof(*normal_keys),
188 WL_TEXT_INPUT_TEXT_DIRECTION_LTR
191 static const struct layout numeric_layout = {
193 sizeof(numeric_keys) / sizeof(*numeric_keys),
197 WL_TEXT_INPUT_TEXT_DIRECTION_LTR
200 struct display data_wl;
203 request_key(uint32_t time, const struct key *key, enum wl_keyboard_key_state state);
205 static const struct layout *
206 get_current_layout(void);
211 printf(" Supported commands: init (Initialize input generator)\n");
212 printf(" : deinit (Deinitialize input generator)\n");
213 printf(" : key (Generate key events)\n");
214 printf(" : touch (Generate touch events)\n");
215 printf(" : help (Print this help text)\n");
216 printf(" : q/quit (Quit program)\n");
217 printf(" : log (Print detailed logs)\n");
218 printf("init {device type}\n");
219 printf(" : device type:\n");
220 printf(" - default: all\n");
221 printf(" - keyboard / touch / mouse\n");
222 printf(" - all: all of devices\n");
223 printf(" : ex> init keyboard / init\n");
226 printf(" : ex> deinit\n");
228 printf("key [keyname] {pressed}\n");
229 printf(" : pressed:\n");
230 printf(" - default: down&up pair\n");
231 printf(" - key down: 1\n");
232 printf(" - key up: 0\n");
233 printf(" : ex> key XF86Back 1\n");
235 printf("touch {index} {type} {x} {y}\n");
236 printf(" : index:\n");
237 printf(" - default: first finger(0)\n");
238 printf(" : type:\n");
239 printf(" - default: generate sample touch events\n");
240 printf(" - touch down: 0\n");
241 printf(" - touch move: 1\n");
242 printf(" - touch up: 2\n");
244 printf(" - default: 0\n");
245 printf(" : ex> touch\n");
246 printf(" : ex> touch 0 0 400 400\n");
247 printf(" : touch 0 1 410 410\n");
248 printf(" : touch 0 2 0 0\n");
249 printf("mouse {button} {type} {x} {y}\n");
250 printf(" : button:\n");
251 printf(" - default: left button(1)\n");
252 printf(" : type:\n");
253 printf(" - default: generate sample mouse events\n");
254 printf(" - button down: 0\n");
255 printf(" - mouse move: 1\n");
256 printf(" - button up: 2\n");
258 printf(" - default: 0\n");
259 printf(" - relative motion\n");
260 printf(" : ex> mouse\n");
261 printf(" : ex> mouse 1 0 0 0\n");
262 printf(" : mouse 1 1 10 10\n");
263 printf(" : mouse 1 1 -10 -10\n");
264 printf(" : mouse 1 2 0 0\n");
265 printf("ime {key_idx} {type}\n");
266 printf(" : key_index\n");
267 printf(" : - keys = [q,w,e,r,t,,,]\n");
268 printf(" : type:\n");
269 printf(" : - default: down & up\n");
270 printf(" : - down: 1\n");
271 printf(" : - up: 0\n");
276 init_input_generator(enum tizen_input_device_manager_clas clas)
279 printf("Already init input generator\n");
283 tizen_input_device_manager_init_generator(data_wl.devicemgr, clas);
285 while (data_wl.request_notified == -1)
286 wl_display_dispatch_queue(data_wl.display, data_wl.queue);
288 if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
290 printf("Success to init input generator\n");
292 printf("Failed to init input generator: %d\n", data_wl.request_notified);
296 data_wl.request_notified = -1;
300 deinit_input_generator(void)
303 printf("input generator is not initialized\n");
307 tizen_input_device_manager_deinit_generator(data_wl.devicemgr, data_wl.clas);
309 while (data_wl.request_notified == -1)
310 wl_display_dispatch_queue(data_wl.display, data_wl.queue);
312 if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
314 printf("Success to deinit input generator\n");
316 printf("Failed to deinit input generator: %d\n", data_wl.request_notified);
319 data_wl.request_notified = -1;
323 input_generator_key(char *name, int type)
325 tizen_input_device_manager_generate_key(data_wl.devicemgr, name, !!type);
327 while (data_wl.request_notified == -1)
328 wl_display_dispatch_queue(data_wl.display, data_wl.queue);
330 if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
331 if (data_wl.enable_log) {
332 printf("Success to generate key: %s key %s\n", name, type?"down":"up");
335 printf("Failed to generate %s key %s: %d\n", name, type?"down":"up", data_wl.request_notified);
338 data_wl.request_notified = -1;
342 key_generate(char *name, int type)
344 printf("name: %s, type: %d\n", name, type);
347 printf("Input generator is not initialized\n");
352 printf("Type which key is generated\n");
356 if (type == KEY_ALL) {
357 input_generator_key(name, 1);
358 input_generator_key(name, 0);
360 input_generator_key(name, !!type);
365 type_string_get(int type)
368 case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN:
370 case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE:
372 case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END:
380 input_generator_touch(int idx, int type, int x, int y)
382 tizen_input_device_manager_generate_touch(data_wl.devicemgr, type, x, y, idx);
384 while (data_wl.request_notified == -1)
385 wl_display_dispatch_queue(data_wl.display, data_wl.queue);
387 if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
388 if (data_wl.enable_log) {
389 printf("Success to generate touch: %d finger %s on (%d, %d)\n", idx, type_string_get(type), x, y);
392 printf("Failed to generate touch(%d finger %s on (%d, %d)): %d\n", idx, type_string_get(type), x, y, data_wl.request_notified);
395 data_wl.request_notified = -1;
399 touch_generate(int idx, int type, int x, int y)
402 printf("Input generator is not initialized\n");
406 if (type == POINTER_ALL) {
407 input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 300, 300);
408 input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 400, 400);
409 input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 500, 500);
411 input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 310, 310);
412 input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 410, 410);
413 input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 510, 510);
415 input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 320, 320);
416 input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 420, 420);
417 input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 520, 520);
419 input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 320, 320);
420 input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 420, 420);
421 input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 520, 520);
423 input_generator_touch(idx, type, x, y);
428 input_generator_mouse(int type, int x, int y, int button)
430 tizen_input_device_manager_generate_pointer(data_wl.devicemgr, type, x, y, button);
432 while (data_wl.request_notified == -1)
433 wl_display_dispatch_queue(data_wl.display, data_wl.queue);
435 if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) {
436 if (data_wl.enable_log) {
437 printf("Success to generate mouse: %s on (%d, %d)\n", type_string_get(type), x, y);
440 printf("Failed to generate mouse(%s on (%d, %d)): %d\n", type_string_get(type), x, y, data_wl.request_notified);
443 data_wl.request_notified = -1;
447 mouse_generate(int btn, int type, int x, int y)
450 printf("Input generator is not initialized\n");
454 if (type == POINTER_ALL) {
455 input_generator_mouse(TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, -1, -1, 1);
456 input_generator_mouse(TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 10, 10, 1);
457 input_generator_mouse(TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 10, 10, 1);
458 input_generator_mouse(TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 10, 10, 1);
459 input_generator_mouse(TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, -1, -1, 1);
462 input_generator_mouse(type, x, y, btn);
470 char buf[MAX_STR] = {0, }, *tmp, *buf_ptr, key_name[MAX_STR] = {0, };
472 int key_type = KEY_ALL, idx = 0, type = POINTER_ALL, x = 0, y = 0;
473 static uint32_t time = 12345;
474 const struct layout *layout;
476 while ((c = getchar()) != EOF) {
477 if (c == '\n') break;
478 if (count >= MAX_STR) break;
485 tmp = strtok_r(buf, " ", &buf_ptr);
488 if (!strncmp(tmp, "init", sizeof("init"))) {
490 tmp = strtok_r(NULL, " ", &buf_ptr);
494 if (!strncmp("keyboard", tmp, MAX_STR-1))
495 init_input_generator(TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD);
496 else if (!strncmp("touch", tmp, MAX_STR-1))
497 init_input_generator(TIZEN_INPUT_DEVICE_MANAGER_CLAS_TOUCHSCREEN);
498 else if (!strncmp("mouse", tmp, MAX_STR-1))
499 init_input_generator(TIZEN_INPUT_DEVICE_MANAGER_CLAS_MOUSE);
507 } else if (!strncmp(tmp, "deinit", sizeof("deinit"))) {
508 deinit_input_generator();
509 } else if (!strncmp(tmp, "key", sizeof("key"))) {
511 tmp = strtok_r(NULL, " ", &buf_ptr);
515 strncpy(key_name, tmp, MAX_STR-1);
518 key_type = atoi(tmp);
526 key_generate(key_name, key_type);
527 } else if (!strncmp(tmp, "touch", sizeof("touch"))) {
529 tmp = strtok_r(NULL, " ", &buf_ptr);
550 touch_generate(idx, type, x, y);
551 } else if (!strncmp(tmp, "mouse", sizeof("mouse"))) {
553 tmp = strtok_r(NULL, " ", &buf_ptr);
574 mouse_generate(idx, type, x, y);
575 } else if (!strncmp(tmp, "ime", MAX_STR)) {
577 tmp = strtok_r(NULL, " ", &buf_ptr);
584 key_type = atoi(tmp);
592 if (data_wl.enable_log)
593 printf("request key() key_idx:%u, key_type:%u\n", idx, key_type);
595 layout = get_current_layout();
596 if (key_type == KEY_ALL) {
597 request_key(time++, &layout->keys[idx], WL_KEYBOARD_KEY_STATE_PRESSED);
598 request_key(time++, &layout->keys[idx], WL_KEYBOARD_KEY_STATE_RELEASED);
601 request_key(time++, &layout->keys[idx], key_type);
602 } else if (!strncmp(buf, "q", MAX_STR) || !strncmp(buf, "quit", MAX_STR)) {
604 } else if (!strncmp(buf, "help", MAX_STR)) {
606 } else if (!strncmp(buf, "log", MAX_STR)) {
607 if (data_wl.enable_log)
608 printf("Disable detailed logs\n");
610 printf("Enable detailed logs\n");
612 data_wl.enable_log = !data_wl.enable_log;
614 printf("Invalid arguments\n");
620 input_device_manager_handle_error(void *data,
621 struct tizen_input_device_manager *tizen_input_device_manager,
624 if (data_wl.enable_log)
625 printf("errorcode: %d\n", errorcode);
626 data_wl.request_notified = errorcode;
629 static const struct tizen_input_device_manager_listener _input_device_manager_listener =
632 .device_remove = NULL,
633 .error = input_device_manager_handle_error,
634 .block_expired = NULL,
637 static const struct layout *
638 get_current_layout(void)
640 switch (data_wl.content_purpose) {
641 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
642 case WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER:
643 return &numeric_layout;
645 return &normal_layout;
650 prev_utf8_char(const char *s, const char *p)
652 for (--p; p >= s; --p) {
653 if ((*p & 0xc0) != 0x80)
660 delete_before_cursor(void)
662 const char *start, *end;
664 if (!data_wl.surrounding_text) {
665 printf("delete_before_cursor: No surrounding text available\n");
669 start = prev_utf8_char(data_wl.surrounding_text,
670 data_wl.surrounding_text + data_wl.surrounding_cursor);
672 printf("delete_before_cursor: No previous character to delete\n");
676 end = data_wl.surrounding_text + data_wl.surrounding_cursor;
678 zwp_input_method_context_v1_delete_surrounding_text(data_wl.context,
679 (start - data_wl.surrounding_text) - data_wl.surrounding_cursor,
681 zwp_input_method_context_v1_commit_string(data_wl.context,
685 /* Update surrounding text */
686 data_wl.surrounding_cursor = start - data_wl.surrounding_text;
687 data_wl.surrounding_text[data_wl.surrounding_cursor] = '\0';
689 memmove(data_wl.surrounding_text + data_wl.surrounding_cursor, end, strlen(end));
693 append(char *s1, const char *s2)
700 s = realloc(s1, len1 + len2 + 1);
702 printf("alloc fail");
705 memcpy(s + len1, s2, len2);
706 s[len1 + len2] = '\0';
712 request_preedit(int32_t cursor)
714 printf("request_preedit() preedit_string:%s\n", data_wl.preedit_string);
715 uint32_t index = strlen(data_wl.preedit_string);
717 if (!data_wl.context) return;
719 if (data_wl.preedit_style)
720 zwp_input_method_context_v1_preedit_styling(data_wl.context,
722 strlen(data_wl.preedit_string),
723 data_wl.preedit_style);
726 zwp_input_method_context_v1_preedit_cursor(data_wl.context,
728 zwp_input_method_context_v1_preedit_string(data_wl.context,
730 data_wl.preedit_string,
731 data_wl.preedit_string);
735 insert_text(const char *text, uint32_t offset, const char *insert)
737 int tlen = strlen(text), ilen = strlen(insert);
738 char *new_text = NULL;
740 new_text = malloc(tlen + ilen + 1);
741 if (new_text == NULL) {
742 printf("alloc fail");
746 memcpy(new_text, text, offset);
747 memcpy(new_text + offset, insert, ilen);
748 memcpy(new_text + offset + ilen, text + offset, tlen - offset);
749 new_text[tlen + ilen] = '\0';
755 request_commit_string(void)
757 char *surrounding_text;
759 printf("request_commit_string()\n");
761 if (!data_wl.preedit_string ||
762 strlen(data_wl.preedit_string) == 0)
764 printf("request_commit_string() preedit_string:%s\n", data_wl.preedit_string);
766 if (!data_wl.context) return;
768 zwp_input_method_context_v1_cursor_position(data_wl.context,
770 zwp_input_method_context_v1_commit_string(data_wl.context,
772 data_wl.preedit_string);
774 if (data_wl.surrounding_text) {
775 surrounding_text = insert_text(data_wl.surrounding_text,
776 data_wl.surrounding_cursor,
777 data_wl.preedit_string);
778 free(data_wl.surrounding_text);
779 data_wl.surrounding_text = surrounding_text;
780 data_wl.surrounding_cursor += strlen(data_wl.preedit_string);
782 data_wl.surrounding_text = strdup(data_wl.preedit_string);
783 data_wl.surrounding_cursor = strlen(data_wl.preedit_string);
786 free(data_wl.preedit_string);
787 data_wl.preedit_string = strdup("");
791 request_key(uint32_t time, const struct key *key, enum wl_keyboard_key_state state)
793 const char *label = NULL;
794 static uint32_t serial = 9999;
796 switch(data_wl.state) {
797 case KEYBOARD_STATE_DEFAULT :
800 case KEYBOARD_STATE_UPPERCASE :
801 label = key->uppercase;
803 case KEYBOARD_STATE_SYMBOLS :
811 xkb_mod_mask_t mod_mask = data_wl.state == KEYBOARD_STATE_DEFAULT ? 0 : data_wl.keysym.shift_mask;
812 uint32_t key_state = (state == WL_KEYBOARD_KEY_STATE_PRESSED) ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED;
814 printf("request_key() data_wl.state:%d, key->key_type:%d, pressed:%u, label:%s\n", data_wl.state, key->key_type, key_state, label);
815 switch (key->key_type) {
816 case keytype_default:
817 if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
820 printf("request_key() keytype_default. append label(%s) to preedit_string(%s)\n", label, data_wl.preedit_string);
821 data_wl.preedit_string =
822 append(data_wl.preedit_string,
826 case keytype_backspace:
827 if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
830 if (strlen(data_wl.preedit_string) == 0) {
831 delete_before_cursor();
833 data_wl.preedit_string[strlen(data_wl.preedit_string) - 1] = '\0';
838 request_commit_string();
840 if (!data_wl.context) break;
841 zwp_input_method_context_v1_keysym(data_wl.context,
844 XKB_KEY_Return, key_state, mod_mask);
847 if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
849 data_wl.preedit_string =
850 append(data_wl.preedit_string, " ");
851 request_commit_string();
854 if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
856 switch(data_wl.state) {
857 case KEYBOARD_STATE_DEFAULT:
858 data_wl.state = KEYBOARD_STATE_UPPERCASE;
860 case KEYBOARD_STATE_UPPERCASE:
861 data_wl.state = KEYBOARD_STATE_DEFAULT;
863 case KEYBOARD_STATE_SYMBOLS:
864 data_wl.state = KEYBOARD_STATE_UPPERCASE;
868 case keytype_symbols:
869 if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
871 switch(data_wl.state) {
872 case KEYBOARD_STATE_DEFAULT:
873 data_wl.state = KEYBOARD_STATE_SYMBOLS;
875 case KEYBOARD_STATE_UPPERCASE:
876 data_wl.state = KEYBOARD_STATE_SYMBOLS;
878 case KEYBOARD_STATE_SYMBOLS:
879 data_wl.state = KEYBOARD_STATE_DEFAULT;
884 request_commit_string();
885 if (!data_wl.context) break;
886 zwp_input_method_context_v1_keysym(data_wl.context,
889 XKB_KEY_Tab, key_state, mod_mask);
891 case keytype_arrow_up:
892 request_commit_string();
893 if (!data_wl.context) break;
894 zwp_input_method_context_v1_keysym(data_wl.context,
897 XKB_KEY_Up, key_state, mod_mask);
899 case keytype_arrow_left:
900 request_commit_string();
901 if (!data_wl.context) break;
902 zwp_input_method_context_v1_keysym(data_wl.context,
905 XKB_KEY_Left, key_state, mod_mask);
907 case keytype_arrow_right:
908 request_commit_string();
909 if (!data_wl.context) break;
910 zwp_input_method_context_v1_keysym(data_wl.context,
913 XKB_KEY_Right, key_state, mod_mask);
915 case keytype_arrow_down:
916 request_commit_string();
917 if (!data_wl.context) break;
918 zwp_input_method_context_v1_keysym(data_wl.context,
921 XKB_KEY_Down, key_state, mod_mask);
924 if (state != WL_KEYBOARD_KEY_STATE_PRESSED)
926 data_wl.preedit_style = (data_wl.preedit_style + 1) % 8; /* TODO */
933 im_context_cb_surrounding_text (void *data, struct zwp_input_method_context_v1 *im_ctx, const char *text, uint32_t cursor, uint32_t anchor)
935 printf("im_context_cb_surrounding_text\n");
936 free(data_wl.surrounding_text);
937 data_wl.surrounding_text = strdup(text);
939 data_wl.surrounding_cursor = cursor;
943 im_context_cb_reset (void *data, struct zwp_input_method_context_v1 *im_ctx)
945 printf("im_context_cb_reset\n");
947 if (strlen(data_wl.preedit_string)) {
948 free(data_wl.preedit_string);
949 data_wl.preedit_string = strdup("");
954 im_context_cb_content_type (void *data, struct zwp_input_method_context_v1 *im_ctx, uint32_t hint, uint32_t purpose)
956 printf("im_context_cb_content_type\n");
958 data_wl.content_hint = hint;
959 data_wl.content_purpose = purpose;
963 im_context_cb_invoke_action (void *data, struct zwp_input_method_context_v1 *im_ctx, uint32_t button, uint32_t index)
965 printf("im_context_cb_invoke_action\n");
967 //if (button != BTN_LEFT)
970 request_preedit(index);
974 im_context_cb_commit_state (void *data, struct zwp_input_method_context_v1 *context, uint32_t serial)
976 printf("im_context_cb_commit_state\n");
978 const struct layout *layout;
980 data_wl.serial = serial;
982 layout = get_current_layout();
984 if (data_wl.surrounding_text)
985 printf("Surrounding text updated: %s\n", data_wl.surrounding_text);
987 if (!context) return;
988 zwp_input_method_context_v1_language(context,
991 zwp_input_method_context_v1_text_direction(context,
993 layout->text_direction);
997 im_context_cb_preferred_language (void *data, struct zwp_input_method_context_v1 *context, const char *language)
999 printf("im_context_cb_preferred_language\n");
1001 if (data_wl.preferred_language)
1002 free(data_wl.preferred_language);
1004 data_wl.preferred_language = NULL;
1007 data_wl.preferred_language = strdup(language);
1010 static const struct zwp_input_method_context_v1_listener input_method_context_cb_listener = {
1011 .surrounding_text = im_context_cb_surrounding_text,
1012 .reset = im_context_cb_reset,
1013 .content_type = im_context_cb_content_type,
1014 .invoke_action = im_context_cb_invoke_action,
1015 .commit_state = im_context_cb_commit_state,
1016 .preferred_language = im_context_cb_preferred_language,
1018 .return_key_type = NULL,
1019 .return_key_disabled = NULL,
1020 .input_panel_data = NULL,
1021 .bidi_direction = NULL,
1022 .cursor_position = NULL,
1023 .process_input_device_event = NULL,
1024 .filter_key_event = NULL,
1025 .capital_mode = NULL,
1026 .prediction_hint = NULL,
1028 .finalized_content = NULL,
1029 .prediction_hint_data = NULL,
1030 .input_panel_enabled = NULL,
1034 keysym_modifiers_add(struct wl_array *modifiers_map,
1037 size_t len = strlen(name) + 1;
1040 p = wl_array_add(modifiers_map, len);
1045 strncpy(p, name, len);
1048 static xkb_mod_index_t
1049 keysym_modifiers_get_index(struct wl_array *modifiers_map,
1052 xkb_mod_index_t index = 0;
1053 char *p = modifiers_map->data;
1055 while ((const char *)p < (const char *)(modifiers_map->data + modifiers_map->size)) {
1056 if (strcmp(p, name) == 0)
1063 return XKB_MOD_INVALID;
1066 static xkb_mod_mask_t
1067 keysym_modifiers_get_mask(struct wl_array *modifiers_map,
1070 xkb_mod_index_t index = keysym_modifiers_get_index(modifiers_map, name);
1072 if (index == XKB_MOD_INVALID)
1073 return XKB_MOD_INVALID;
1079 im_cb_activate (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *context)
1081 printf("im_cb_activate\n");
1083 struct wl_array modifiers_map;
1084 const struct layout *layout;
1086 if (data_wl.context)
1087 zwp_input_method_context_v1_destroy(data_wl.context);
1089 if (data_wl.preedit_string)
1090 free(data_wl.preedit_string);
1092 data_wl.preedit_style = 0;
1093 data_wl.preedit_string = strdup("");
1094 data_wl.content_hint = 0;
1095 data_wl.content_purpose = 0;
1096 free(data_wl.preferred_language);
1097 data_wl.preferred_language = NULL;
1098 free(data_wl.surrounding_text);
1099 data_wl.surrounding_text = NULL;
1103 data_wl.context = context;
1104 zwp_input_method_context_v1_add_listener(context,
1105 &input_method_context_cb_listener,
1108 wl_array_init(&modifiers_map);
1109 keysym_modifiers_add(&modifiers_map, "Shift");
1110 keysym_modifiers_add(&modifiers_map, "Control");
1111 keysym_modifiers_add(&modifiers_map, "Mod1");
1112 zwp_input_method_context_v1_modifiers_map(context, &modifiers_map);
1113 data_wl.keysym.shift_mask = keysym_modifiers_get_mask(&modifiers_map, "Shift");
1114 wl_array_release(&modifiers_map);
1116 layout = get_current_layout();
1118 zwp_input_method_context_v1_language(context,
1121 zwp_input_method_context_v1_text_direction(context,
1123 layout->text_direction);
1126 im_cb_deactivate (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx)
1128 printf("im_cb_deactivate\n");
1130 if (!data_wl.context)
1133 zwp_input_method_context_v1_destroy(data_wl.context);
1134 data_wl.context = NULL;
1138 im_cb_destroy (void *data, struct zwp_input_method_v1 *input_method, struct zwp_input_method_context_v1 *im_ctx)
1140 printf("im_cb_destroy\n");
1141 zwp_input_method_v1_destroy(data_wl.input_method);
1142 data_wl.input_method = NULL;
1145 static const struct zwp_input_method_v1_listener input_method_cb_listener = {
1146 .activate = im_cb_activate,
1147 .deactivate = im_cb_deactivate,
1149 .destroy = im_cb_destroy,
1150 .show_input_panel = NULL,
1151 .hide_input_panel = NULL,
1152 .open_connection = NULL,
1153 .close_connection = NULL,
1154 .set_text_input_id = NULL,
1158 registry_handle_global(void * data, struct wl_registry * registry, uint32_t id,
1159 const char * interface, uint32_t version)
1161 if (strcmp(interface, "wl_compositor") == 0) {
1162 data_wl.compositor = wl_registry_bind(registry, id,
1163 &wl_compositor_interface, version);
1164 if (!data_wl.compositor) {
1165 printf("Failed to bind compositor.\n");
1168 if (data_wl.enable_log)
1169 printf("Success to bind compositor.\n");
1170 } else if (strcmp(interface, "tizen_input_device_manager") == 0) {
1171 data_wl.devicemgr = wl_registry_bind(registry, id,
1172 &tizen_input_device_manager_interface, version);
1173 if (!data_wl.devicemgr) {
1174 printf("Failed to bind input device manager");
1177 if (data_wl.enable_log)
1178 printf("Success to bind tizen input device manager.");
1179 tizen_input_device_manager_add_listener(data_wl.devicemgr,
1180 &_input_device_manager_listener, data_wl.display);
1181 } else if (!strcmp(interface, "zwp_input_method_manager_v1")) {
1182 data_wl.input_method_mgr = wl_registry_bind(registry, id,
1183 &zwp_input_method_manager_v1_interface, version);
1184 } else if (!strcmp(interface, "zwp_input_method_v1")) {
1185 data_wl.input_method = wl_registry_bind(registry, id,
1186 &zwp_input_method_v1_interface, version);
1187 zwp_input_method_v1_add_listener(data_wl.input_method,
1188 &input_method_cb_listener,
1191 //TODO: delte this code. this job should be done in cb_activate
1192 data_wl.preedit_string = strdup("");
1193 data_wl.content_hint = 0;
1194 data_wl.content_purpose = 0;
1195 free(data_wl.preferred_language);
1196 data_wl.preferred_language = NULL;
1197 free(data_wl.surrounding_text);
1198 data_wl.surrounding_text = NULL;
1204 registry_handle_global_remove(void * data, struct wl_registry * registry, uint32_t id)
1206 if (data_wl.enable_log)
1207 printf("registry is removed. id: %d !\n", id);
1210 static const struct wl_registry_listener _registry_listener = {
1211 registry_handle_global,
1212 registry_handle_global_remove
1218 memset(&data_wl, 0, sizeof(struct display));
1219 data_wl.request_notified = -1;
1221 data_wl.display = wl_display_connect(NULL);
1222 if (!data_wl.display) {
1223 printf("Failed to connect wayland display\n");
1227 data_wl.queue = wl_display_create_queue(data_wl.display);
1228 if (!data_wl.queue) {
1229 printf("Failed to create queue\n");
1233 data_wl.registry = wl_display_get_registry(data_wl.display);
1234 if (!data_wl.registry) {
1235 printf("Failed to get registry\n");
1239 wl_proxy_set_queue((struct wl_proxy*)data_wl.registry, data_wl.queue);
1240 wl_registry_add_listener(data_wl.registry, &_registry_listener, NULL);
1242 if (wl_display_dispatch_queue(data_wl.display, data_wl.queue) == -1) {
1243 printf("Failed to dispatch display\n");
1246 if (wl_display_roundtrip_queue(data_wl.display, data_wl.queue) == -1) {
1247 printf("Failed to roundtrip display\n");
1255 wayland_deinit(void)
1257 if (data_wl.enable_log)
1258 printf("Shutdown wayland system\n");
1260 if (data_wl.init) deinit_input_generator();
1262 if (data_wl.queue) wl_event_queue_destroy(data_wl.queue);
1263 if (data_wl.devicemgr) tizen_input_device_manager_destroy(data_wl.devicemgr);
1264 if (data_wl.display) {
1265 if (data_wl.input_method)
1266 zwp_input_method_v1_destroy(data_wl.input_method);
1267 zwp_input_method_manager_v1_destroy(data_wl.input_method_mgr);
1268 wl_registry_destroy(data_wl.registry);
1269 wl_display_flush(data_wl.display);
1270 wl_display_disconnect(data_wl.display);
1277 struct epoll_event ep[2];
1279 data_wl.fd_epoll = epoll_create(SIZE_EPOLL);
1280 if (data_wl.fd_epoll <= 0) {
1281 printf("Failed to epoll create: %d\n", SIZE_EPOLL);
1285 data_wl.fd_display = wl_display_get_fd(data_wl.display);
1287 memset(ep, 0, sizeof(struct epoll_event)*2);
1289 ep[0].events = EPOLLIN | EPOLLERR | EPOLLHUP;
1290 ep[0].data.fd = data_wl.fd_display;
1291 epoll_ctl(data_wl.fd_epoll, EPOLL_CTL_ADD, data_wl.fd_display, &ep[0]);
1292 ep[1].events = EPOLLIN | EPOLLERR | EPOLLHUP;
1293 ep[1].data.fd = STDIN_FILENO;
1294 epoll_ctl(data_wl.fd_epoll, EPOLL_CTL_ADD, 0, &ep[1]);
1302 struct epoll_event ep[SIZE_EPOLL];
1307 printf("Failed to init epoll\n");
1312 while (data_wl.run) {
1313 res = wl_display_dispatch_queue_pending(data_wl.display, data_wl.queue);
1315 printf("Failed to dispatch pending. result: %d\n", res);
1319 res = wl_display_flush(data_wl.display);
1321 printf("Failed to flush display. result: %d\n", res);
1326 count = epoll_wait(data_wl.fd_epoll, ep, SIZE_EPOLL, -1);
1327 for (i = 0; i < count; i++) {
1328 if (ep[i].events & EPOLLIN) {
1329 if (ep[i].data.fd == data_wl.fd_display) {
1330 wl_display_dispatch_queue(data_wl.display, data_wl.queue);
1335 if (ep[i].events & EPOLLERR) {
1338 if (ep[i].events & EPOLLHUP) {
1346 main(int argc, char **argv)
1350 res = wayland_init();