modality_keyboard: fix not to create MMI_PROVIDER_EVENT_KEY type newly
[platform/core/uifw/mmi-manager.git] / src / modules / modality_keyboard / wayland-input.c
1 /*
2 * Copyright © 2021 Samsung Electronics co., Ltd. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "wayland-input.h"
25 #include "mmi-keyboard-provider.h"
26 #include <mmi-manager-dbg.h>
27 #include <mmi-common.h>
28
29 #include <stdlib.h>
30 #include <sys/mman.h>
31 #include <unistd.h>
32 #include <errno.h>
33
34 #include <Ecore.h>
35 #include <wayland-client.h>
36 #include <xkbcommon/xkbcommon.h>
37 #include <tizen-extension-client-protocol.h>
38
39 struct wl_display *display = NULL;
40 struct wl_registry *registry = NULL;
41 struct wl_seat *seat = NULL;
42 struct wl_keyboard *keyboard = NULL;
43 struct tizen_keyrouter *tz_keyrouter = NULL;
44
45 struct xkb_context *xkb_context;
46 struct xkb_keymap *keymap;
47
48 Ecore_Fd_Handler *fd_hdl;
49
50 typedef struct tizen_keyrouter_notify tizen_keyrouter_notify_t;
51 struct tizen_keyrouter_notify
52 {
53         unsigned int keycode;
54         unsigned int mode;
55         unsigned int error;
56 };
57
58 typedef struct keycode_map keycode_map_t;
59 struct keycode_map
60 {
61         xkb_keysym_t keysym;
62         xkb_keycode_t *keycodes;
63         int nkeycodes;
64 };
65
66 typedef struct keymap_info keymap_info_t;
67 struct keymap_info
68 {
69         const char *keyname;
70         int mode;
71 };
72
73 unsigned int has_keymap = 0;
74 unsigned int set_keymap = 0;
75
76 // wl_registry listener
77 static void handle_global(void *, struct wl_registry *, unsigned int, const char *, unsigned int);
78 static void handle_global_remove(void *, struct wl_registry *, unsigned int);
79
80 // wl_seat listener
81 static void seat_capabilities(void *, struct wl_seat *, enum wl_seat_capability);
82 static void seat_name(void *data, struct wl_seat *seat, const char *name);
83
84 // wl_keyboard listener
85 static void keyboard_keymap(void *, struct wl_keyboard *, unsigned int, int fd, unsigned int);
86 static void keyboard_enter(void *, struct wl_keyboard *, unsigned int, struct wl_surface *, struct wl_array *);
87 static void keyboard_leave(void *, struct wl_keyboard *, unsigned int, struct wl_surface *);
88 static void keyboard_key(void *, struct wl_keyboard *, unsigned int, unsigned int, unsigned int, unsigned int);
89 static void keyboard_modifiers(void *, struct wl_keyboard *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int);
90 static void keyboard_repeat_setup(void *, struct wl_keyboard *, int32_t, int32_t);
91
92 // tizen_keyrouter listener
93 static void keygrab_notify(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, uint32_t key, uint32_t mode, uint32_t error);
94 static void keygrab_notify_list(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, struct wl_array *notify_result);
95 static void getgrab_notify_list(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, struct wl_array *notify_result);
96 static void set_register_none_key(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, uint32_t mode);
97 static void keyregister_notify(void *data, struct tizen_keyrouter *tizen_keyrouter, uint32_t status);
98 static void set_input_config(void *data, struct tizen_keyrouter *tizen_keyrouter, uint32_t status);
99 static void key_cancel(void *data, struct tizen_keyrouter *tizen_keyrouter, uint32_t key);
100
101 static const struct wl_registry_listener registry_listener = {
102         handle_global,
103         handle_global_remove,
104 };
105
106 static const struct wl_seat_listener seat_listener = {
107         seat_capabilities,
108         seat_name,
109 };
110
111 static const struct wl_keyboard_listener keyboard_listener = {
112         keyboard_keymap,
113         keyboard_enter,
114         keyboard_leave,
115         keyboard_key,
116         keyboard_modifiers,
117         keyboard_repeat_setup,
118 };
119
120 static const struct tizen_keyrouter_listener keyrouter_listener = {
121         keygrab_notify,
122         keygrab_notify_list,
123         getgrab_notify_list,
124         set_register_none_key,
125         keyregister_notify,
126         set_input_config,
127         key_cancel,
128 };
129
130 static void
131 handle_global(void *data, struct wl_registry *registry, unsigned int id, const char *interface, unsigned int version)
132 {
133         if (!strcmp("wl_seat", interface))
134         {
135                 seat = wl_registry_bind(registry, id, &wl_seat_interface, 4);
136                 wl_seat_add_listener(seat, &seat_listener, NULL);
137         }
138         else if (!strcmp("tizen_keyrouter", interface))
139         {
140                 tz_keyrouter = wl_registry_bind(registry, id, &tizen_keyrouter_interface, 1);
141                 tizen_keyrouter_add_listener(tz_keyrouter, &keyrouter_listener, NULL);
142         }
143 }
144
145 static void
146 handle_global_remove(void *data, struct wl_registry *registry, unsigned int id)
147 {
148         (void) registry;
149         (void) id;
150 }
151
152 static void
153 seat_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps)
154 {
155         if ((caps & WL_SEAT_CAPABILITY_KEYBOARD))
156         {
157                 if (keyboard)
158                 {
159                         wl_keyboard_release(keyboard);
160                         keyboard = NULL;
161                 }
162
163                 keyboard = wl_seat_get_keyboard(seat);
164                 if(!keyboard)
165                 {
166                         LOGE("Failed to get wl_keyboard from a seat !\n");
167                         return;
168                 }
169                 wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL);
170                 LOGD("seat caps update : keyboard added\n");
171         }
172         else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && (keyboard))
173         {
174                 wl_keyboard_release(keyboard);
175                 keyboard = NULL;
176         }
177 }
178
179 static void
180 seat_name(void *data, struct wl_seat *seat, const char *name)
181 {
182         (void) seat;
183         (void) name;
184 }
185
186 static void
187 keyboard_keymap(void *data, struct wl_keyboard *keyboard, unsigned int format, int fd, unsigned int size)
188 {
189         char *map = NULL;
190
191         LOGD("...WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1=%d, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP=%d\n",
192                                         WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP);
193         LOGD("... format=%d, fd=%d, size=%d\n",  format, fd, size);
194
195         if (!xkb_context)
196         {
197                 LOGE("... This client failed to make xkb context\n");
198                 close(fd);
199                 return;
200         }
201         if (format == WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP)
202         {
203                 has_keymap = 0;
204         }
205         else
206         {
207                 LOGD("wl_keyboard has keymap...\n");
208                 map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
209                 if(map == MAP_FAILED)
210                 {
211                         LOGE("... Failed to mmap from fd(%d) size(%d)\n", fd, size);
212                         close(fd);
213                         return;
214                 }
215
216                 if(keymap) xkb_map_unref(keymap);
217                 keymap = xkb_map_new_from_string(xkb_context, map, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
218                 if(!keymap) {
219                         LOGE("... Failed to get keymap from fd(%d)\n", fd);
220                         munmap(map, size);
221                         close(fd);
222                         return;
223                 }
224
225                 munmap(map, size);
226                 close(fd);
227                 has_keymap = 1;
228         }
229
230         LOGD("has_keymap = %s\n", has_keymap ? "true" : "false");
231         set_keymap = 1;
232 }
233
234 static void
235 keyboard_enter(void *data, struct wl_keyboard *keyboard, unsigned int serial, struct wl_surface *surface, struct wl_array *keys)
236 {
237         (void) keyboard;
238         (void) serial;
239         (void) surface;
240         (void) keys;
241 }
242
243 static void
244 keyboard_leave(void *data, struct wl_keyboard *keyboard, unsigned int serial, struct wl_surface *surface)
245 {
246         (void) keyboard;
247         (void) serial;
248         (void) surface;
249 }
250
251 static unsigned int
252 _covert_kernel_keycode_to_user_keycode(unsigned int kernel_keycode)
253 {
254         LOGD("kernel keycode : %d, user keycode : %d\n", kernel_keycode, kernel_keycode+8);
255         return (kernel_keycode+8);
256 }
257
258 static void
259 _input_event_key_cb_free(void *data EINA_UNUSED, void *event)
260 {
261         mmi_provider_event_key *ev = event;
262         if(ev->keyname)
263                 free(ev->keyname);
264         free(ev);
265 }
266
267 static void
268 _input_add_key_event(unsigned int keycode, unsigned int state, unsigned int timestamp)
269 {
270         const char * name = NULL;
271
272         if((name = xkb_keymap_key_get_name(keymap, keycode)))
273         {
274                 LOGD("key name = %s, keycode = %d\n", name, keycode);
275
276                 mmi_provider_event_key *ev = calloc(1, sizeof(mmi_provider_event_key));
277
278                 if(state)
279                         ev->type = MMI_EVENT_KEY_TYPE_DOWN;
280                 else
281                         ev->type = MMI_EVENT_KEY_TYPE_UP;
282                 ev->timestamp = timestamp;
283                 ev->keycode = keycode;
284                 ev->key_down = state;
285                 ev->keyname = strdup(name);
286
287                 LOGI("type = %s, keyname = %s, key = %d, time = %d", (ev->type)?"MMI_EVENT_KEY_TYPE_DOWN":"MMI_EVENT_KEY_TYPE_UP", ev->keyname, ev->keycode, ev->timestamp);
288                 ecore_event_add(MMI_PROVIDER_EVENT_KEY, ev, _input_event_key_cb_free, NULL);
289         }
290         else
291                 LOGD("No matched keyname from keycode = %d\n", keycode);
292
293         LOGI("MMI_PROVIDER_EVENT_KEY has been added !\n");
294 }
295
296 static void
297 keyboard_key(void *data, struct wl_keyboard *keyboard, unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state)
298 {
299         unsigned int user_keycode = _covert_kernel_keycode_to_user_keycode(keycode);
300
301         LOGD("... serial=%d, time=%d, key=%d, state=%d\n", serial, timestamp, user_keycode, state);
302         if (!has_keymap)
303         {
304                 //TODO : do anything with the given keycode
305                 //           ex> call application callback(s)
306                 LOGD("keycode : %d, state : %d, timestamp : %d\n", user_keycode, state, timestamp);
307         }
308         else
309         {
310                 LOGD("has_keymap | keycode : %d, state : %d, timestamp : %d\n", user_keycode, state, timestamp);
311                 if(_provider_mode == MODALITY_PROVIDER_MODE_PROPAGATE_EVENT)
312                 {
313                         _input_add_key_event(user_keycode, state, timestamp);
314                 }
315         }
316 }
317
318 static void
319 keyboard_modifiers(void *data, struct wl_keyboard *keyboard, unsigned int serial, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group)
320 {
321         (void) keyboard;
322         (void) serial;
323         (void) depressed;
324         (void) latched;
325         (void) locked;
326         (void) group;
327 }
328
329 static void
330 keyboard_repeat_setup(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay)
331 {
332         (void) keyboard;
333         (void) rate;
334         (void) delay;
335 }
336
337 static void
338 keygrab_notify(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, uint32_t key, uint32_t mode, uint32_t error)
339 {
340         LOGD("key : %d, mode : %d, error : %d\n", key, mode, error);
341 }
342
343 static void
344 keygrab_notify_list(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, struct wl_array *notify_result)
345 {
346         tizen_keyrouter_notify_t *tz_keyrouter_notify;
347         struct wl_array array;
348
349         wl_array_init(&array);
350         wl_array_copy(&array, notify_result);
351
352         wl_array_for_each(tz_keyrouter_notify, &array)
353         {
354                 LOGD("... keygrab result ! (keycode : %d, mode : %d, error : %d)\n",
355                                 tz_keyrouter_notify->keycode, tz_keyrouter_notify->mode, tz_keyrouter_notify->error);
356         }
357
358         wl_array_release(&array);
359 }
360
361 static void getgrab_notify_list(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, struct wl_array *notify_result)
362 {
363         (void) tizen_keyrouter;
364         (void) surface;
365         (void) notify_result;
366 }
367
368 static void set_register_none_key(void *data, struct tizen_keyrouter *tizen_keyrouter, struct wl_surface *surface, uint32_t mode)
369 {
370         (void) tizen_keyrouter;
371         (void) surface;
372         (void) mode;
373 }
374
375 static void keyregister_notify(void *data, struct tizen_keyrouter *tizen_keyrouter, uint32_t status)
376 {
377         (void) tizen_keyrouter;
378         (void) status;
379 }
380
381 static void set_input_config(void *data, struct tizen_keyrouter *tizen_keyrouter, uint32_t status)
382 {
383         (void) tizen_keyrouter;
384         (void) status;
385 }
386
387 static void key_cancel(void *data, struct tizen_keyrouter *tizen_keyrouter, uint32_t key)
388 {
389         (void) tizen_keyrouter;
390         (void) key;
391 }
392
393 int _xkb_context_init(void)
394 {
395         xkb_context = xkb_context_new(0);
396         if(!xkb_context)
397         {
398                 LOGE("Failed to get xkb_context!\n");
399                 return 0;
400         }
401         return 1;
402 }
403
404 void _xkb_context_shutdown(void)
405 {
406         if(!xkb_context)
407                 return;
408
409         xkb_context_unref(xkb_context);
410 }
411
412 static void
413 _find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
414 {
415         keycode_map_t *found_keycodes = (keycode_map_t *)data;
416         xkb_keysym_t keysym = found_keycodes->keysym;
417         int nsyms = 0;
418         const xkb_keysym_t *syms_out = NULL;
419         xkb_keycode_t *tmp_keycodes = NULL;
420
421         if(!keymap)
422         {
423                 LOGE("Invalied keymap \n");
424                 return;
425         }
426
427         nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out);
428
429         if (nsyms && syms_out)
430         {
431                 if (*syms_out == keysym)
432                 {
433                         tmp_keycodes = calloc(1, sizeof(int)*(found_keycodes->nkeycodes+1));
434
435                         if (tmp_keycodes)
436                         {
437                                 memcpy(tmp_keycodes, found_keycodes->keycodes, sizeof(int)*found_keycodes->nkeycodes);
438                                 free(found_keycodes->keycodes);
439
440                                 found_keycodes->nkeycodes++;
441                                 found_keycodes->keycodes = tmp_keycodes;
442                                 found_keycodes->keycodes[found_keycodes->nkeycodes-1] = key;
443                         }
444                 }
445         }
446 }
447
448 int _get_keycode_from_keysym(struct xkb_keymap *keymap, xkb_keysym_t keysym, xkb_keycode_t **keycodes)
449 {
450         keycode_map_t found_keycodes = {0,};
451         found_keycodes.keysym = keysym;
452
453         if(!keymap)
454         {
455                 LOGE("Invalied keymap \n");
456                 return 0;
457         }
458
459         xkb_keymap_key_for_each(keymap, _find_keycode, &found_keycodes);
460
461         *keycodes = found_keycodes.keycodes;
462         return found_keycodes.nkeycodes;
463 }
464
465 void _do_keygrab(const char *keyname, uint32_t mode)
466 {
467         xkb_keysym_t keysym = 0x0;
468         int nkeycodes = 0;
469         xkb_keycode_t *keycodes = NULL;
470         int i;
471
472         keysym = xkb_keysym_from_name(keyname, XKB_KEYSYM_NO_FLAGS);
473         nkeycodes = _get_keycode_from_keysym(keymap, keysym, &keycodes);
474         if(!nkeycodes)
475         {
476                 LOGE("Failed do keygrab on %s(%d)\n", keyname, keysym);
477                 free(keycodes);
478                 keycodes = NULL;
479                 return;
480         }
481
482         for(i=0; i<nkeycodes; i++)
483         {
484                 tizen_keyrouter_set_keygrab(tz_keyrouter, NULL, keycodes[i], mode);
485         }
486
487 }
488
489 static keymap_info_t stored_keymap[] = {
490                 { "XF86Back", TIZEN_KEYROUTER_MODE_EXCLUSIVE },
491                 { "XF86Info", TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE}
492 };
493
494 void _keygrab_init(void)
495 {
496         int i;
497         int size = sizeof(stored_keymap)/sizeof(keymap_info_t);
498
499         LOGD("stored keymap size = %d\n", size);
500         for(i=0; i < size; i++)
501         {
502                 LOGD("stored keymap %d = %s, %d\n", i, stored_keymap[i].keyname, stored_keymap[i].mode);
503                 _do_keygrab(stored_keymap[i].keyname, stored_keymap[i].mode);
504         }
505 }
506
507 static Eina_Bool
508 _cb_handle_data(void *data, Ecore_Fd_Handler *hdl)
509 {
510         int ret = 0;
511         if(ecore_main_fd_handler_active_get(hdl, ECORE_FD_ERROR))
512         {
513                 LOGE("Received error on wayland display fd");
514                 goto err;
515         }
516
517         if(ecore_main_fd_handler_active_get(hdl, ECORE_FD_READ))
518         {
519                 ret = wl_display_dispatch(display);
520         }
521         else if(ecore_main_fd_handler_active_get(hdl, ECORE_FD_WRITE))
522         {
523                 ret = wl_display_flush(display);
524                 if(ret == 0){
525                         ecore_main_fd_handler_active_set(hdl, ECORE_FD_READ);
526                 }
527         }
528
529         if((ret < 0) && (errno != EAGAIN) && (errno != EINVAL))
530                 goto err;
531
532         return ECORE_CALLBACK_RENEW;
533
534 err:
535         fd_hdl = NULL;
536         LOGE("Wayland Socket Error : %s\n", eina_error_msg_get(errno));
537         return ECORE_CALLBACK_CANCEL;
538 }
539
540 void _wl_init(void)
541 {
542         int res = 0;
543         const char *socket_name = NULL;
544
545         socket_name = getenv("WAYLAND_DISPLAY");
546         LOGD("socket name = %s\n", socket_name);
547         if(!socket_name)
548         {
549                 LOGD("NO has socket name\n");
550                 socket_name = "wayland-0";
551         }
552         if (!getenv("XDG_RUNTIME_DIR"))
553         {
554                 LOGD("no xdg runtime dir\n");
555                 setenv("XDG_RUNTIME_DIR", "/run", 1);
556         }
557
558         display = wl_display_connect(socket_name);
559         if(!display)
560         {
561                 LOGE("Failed to connect wayland display (socket_name = %s) !\n", socket_name);
562                 return;
563         }
564
565         res = _xkb_context_init();
566         if(!res)
567         {
568                 LOGE("Failed to init xkb\n");
569         }
570
571         registry = wl_display_get_registry(display);
572         if(!registry)
573         {
574                 LOGE("Failed to get registry\n");
575                 return;
576         }
577         wl_registry_add_listener(registry, &registry_listener, NULL);
578
579         fd_hdl = ecore_main_fd_handler_add(wl_display_get_fd(display),
580                                                                 (ECORE_FD_READ | ECORE_FD_WRITE | ECORE_FD_ERROR),
581                                                                 _cb_handle_data, NULL, NULL, NULL);
582
583         if(!fd_hdl)
584         {
585                 LOGE("Failed to add ecore fd(%d, wl.display) handler\n", wl_display_get_fd(display));
586                 wl_registry_destroy(registry);
587                 wl_display_disconnect(display);
588                 registry = NULL;
589                 display = NULL;
590                 return;
591         }
592
593         while(!set_keymap)
594                 wl_display_roundtrip(display);
595 }
596
597 void _wl_shutdown(void)
598 {
599         tizen_keyrouter_destroy(tz_keyrouter);
600         wl_keyboard_release(keyboard);
601         wl_seat_destroy(seat);
602         wl_display_disconnect(display);
603 }
604
605 void _keymap_shutdown(void)
606 {
607         if(keymap) xkb_map_unref(keymap);
608 }
609
610 void wayland_input_init(void)
611 {
612         _wl_init();
613         _keygrab_init();
614 }
615
616 void wayland_input_shutdown(void)
617 {
618         _wl_shutdown();
619         _keymap_shutdown();
620         _xkb_context_shutdown();
621 }