From: SooChan Lim Date: Wed, 26 Mar 2025 01:40:15 +0000 (+0900) Subject: e_keyrouter_event: move keyrouter_event code X-Git-Tag: accepted/tizen/unified/20250401.113859~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8a4c20f67a991b09faa55df27e3f845d40b26820;p=platform%2Fupstream%2Fenlightenment.git e_keyrouter_event: move keyrouter_event code move the keyrouter_event code to e_keyrouter_events.c file. Change-Id: I1a7bec997452d3f0b47e54a3c1d1a4ec9e958c71 --- diff --git a/src/bin/Makefile.mk b/src/bin/Makefile.mk index c19cd1033f..43d62853ce 100644 --- a/src/bin/Makefile.mk +++ b/src/bin/Makefile.mk @@ -256,7 +256,7 @@ src/bin/inputmgr/e_devicemgr_conf.c \ src/bin/inputmgr/e_devicemgr_block.c \ src/bin/inputmgr/e_devicemgr_input.c \ src/bin/inputmgr/e_devicemgr_inputgen.c \ -src/bin/inputmgr/e_keyrouter_events.c \ +src/bin/inputmgr/e_keyrouter_event.c \ src/bin/inputmgr/e_keyrouter_list.c \ src/bin/inputmgr/e_keyrouter_conf.c \ src/bin/inputmgr/e_keyrouter.c \ diff --git a/src/bin/inputmgr/e_input_backend.c b/src/bin/inputmgr/e_input_backend.c index a12033a3c8..aece0074b9 100644 --- a/src/bin/inputmgr/e_input_backend.c +++ b/src/bin/inputmgr/e_input_backend.c @@ -6,6 +6,7 @@ #include "e_input_device_intern.h" #include "e_input_event_intern.h" #include "e_keyrouter_intern.h" +#include "e_keyrouter_event_intern.h" #include "e_comp_wl_intern.h" #include "e_config_intern.h" #include "e_device_intern.h" @@ -1370,7 +1371,7 @@ input_thread_start(void *data, Ecore_Thread *th) g_source_set_callback(pipe_source, (GSourceFunc)_pipe_recv_handler, input, NULL); g_source_attach(pipe_source, context); - e_keyrouter_input_handler_add(); + e_keyrouter_event_handler_add(); e_input_thread_input_id_set(gettid()); e_input_thread_main_id_set(getpid()); diff --git a/src/bin/inputmgr/e_keyrouter.c b/src/bin/inputmgr/e_keyrouter.c index fd6ab6514a..450145a6fd 100644 --- a/src/bin/inputmgr/e_keyrouter.c +++ b/src/bin/inputmgr/e_keyrouter.c @@ -10,6 +10,7 @@ #include "e_comp_input_intern.h" #include "e_keyrouter_wl_intern.h" #include "e_keyrouter_hardkeys_intern.h" +#include "e_keyrouter_event_intern.h" #include #include @@ -289,125 +290,6 @@ _e_keyrouter_keygrab_print(void *data EINA_UNUSED, const char *log_path) _e_keyrouter_input_thread_keygrab_print((void *)log_path); } -static Eina_Bool -_e_keyrouter_cb_key_down(void *data, int type, void *event) -{ - Ecore_Event_Key *ev; - - EINA_SAFETY_ON_NULL_RETURN_VAL(event, FALSE); - - ev = (Ecore_Event_Key *)event; - - TRACE_INPUT_BEGIN(_e_keyrouter_cb_key_down:KEY_PRESS(%d), ev->keycode); - TRACE_INPUT_END(); - - return e_keyrouter_event_process(event, (E_Device *)ev->dev, type); -} - -static Eina_Bool -_e_keyrouter_cb_key_up(void *data, int type, void *event) -{ - Ecore_Event_Key *ev; - - EINA_SAFETY_ON_NULL_RETURN_VAL(event, FALSE); - - ev = (Ecore_Event_Key *)event; - - TRACE_INPUT_BEGIN(_e_keyrouter_cb_key_down:KEY_RELEASE(%d), ev->keycode); - TRACE_INPUT_END(); - - return e_keyrouter_event_process(event, (E_Device *)ev->dev, type); -} - -static Eina_Bool -_e_keyrouter_client_cb_stack(void *data, int type, void *event) -{ - E_Event_Client *ev = event; - E_Client *ec = ev->ec; - - (void) data; - (void) type; - (void) event; - (void) ev; - (void) ec; - - //KLDBG("ec: %p, visible: %d, focused: %d, take_focus: %d, want_focus: %d, bordername: %s, input_only: %d", - // ec, ec->visible, ec->focused, ec->take_focus, ec->want_focus, ec->bordername, ec->input_only); - - krt->isWindowStackChanged = EINA_TRUE; - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool -_e_keyrouter_client_cb_remove(void *data, int type, void *event) -{ - E_Event_Client *ev = event; - E_Client *ec = ev->ec; - - (void) data; - (void) type; - (void) ev; - (void) ec; - - /* FIXME: Remove this callback or do something others. - * It was moved to _e_keyrouter_wl_surface_cb_destroy() where it had here. - */ - - return ECORE_CALLBACK_PASS_ON; -} - -static void -_e_keyrouter_init_handlers(void) -{ - E_LIST_HANDLER_APPEND(krt->handlers, E_EVENT_CLIENT_STACK, _e_keyrouter_client_cb_stack, NULL); - E_LIST_HANDLER_APPEND(krt->handlers, E_EVENT_CLIENT_REMOVE, _e_keyrouter_client_cb_remove, NULL); - - if (!e_input_thread_mode_get()) - { - E_LIST_HANDLER_APPEND(krt->handlers, ECORE_EVENT_KEY_DOWN, _e_keyrouter_cb_key_down, NULL); - E_LIST_HANDLER_APPEND(krt->handlers, ECORE_EVENT_KEY_UP, _e_keyrouter_cb_key_up, NULL); - } - else - { - e_keyrouter_input_handler_add(); - } - - e_info_server_hook_set("keyrouter", _e_keyrouter_info_print, NULL); - e_info_server_hook_set("keygrab", _e_keyrouter_keygrab_print, NULL); -} - -static void -_e_keyrouter_deinit_handlers(void) -{ - Ecore_Event_Handler *h = NULL; - E_Input_Event_Source *input_event_source = NULL; - - if (!krt || !krt->handlers) return; - - EINA_LIST_FREE(krt->handlers, h) - ecore_event_handler_del(h); - - if (e_input_thread_mode_get()) - { - input_event_source = e_input_event_source_get(); - if (input_event_source) - { - if (krt->_key_down_handler) - e_input_event_handler_del(input_event_source, krt->_key_down_handler); - - if (krt->_key_up_handler) - e_input_event_handler_del(input_event_source, krt->_key_up_handler); - } - - krt->_key_down_handler = NULL; - krt->_key_up_handler = NULL; - } - - e_info_server_hook_set("keyrouter", NULL, NULL); - e_info_server_hook_set("keygrab", NULL, NULL); -} - static Eina_Bool _e_keyrouter_query_tizen_key_table(void) { @@ -478,25 +360,6 @@ _e_keyrouter_max_keycode_get(void) return krt->max_tizen_hwkeys; } -EINTERN void -e_keyrouter_input_handler_add(void) -{ - EINA_SAFETY_ON_NULL_RETURN(krt); - - E_Input_Event_Source *input_event_source = e_input_event_source_get(); - if (!input_event_source) - { - KLERR("Failed to get input_event_source"); - return; - } - - if (!krt->_key_down_handler) - krt->_key_down_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_KEY_DOWN, _e_keyrouter_cb_key_down, NULL); - - if (!krt->_key_up_handler) - krt->_key_up_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_KEY_UP, _e_keyrouter_cb_key_up, NULL); -} - EINTERN int e_keyrouter_init(void) { @@ -532,7 +395,10 @@ e_keyrouter_init(void) //ecore handler add for power callback registration // if (!krt->pictureoff_disabled) // ecore_idle_enterer_add(_e_keyrouter_cb_idler, NULL); - _e_keyrouter_init_handlers(); + e_keyrouter_event_init(); + + e_info_server_hook_set("keyrouter", _e_keyrouter_info_print, NULL); + e_info_server_hook_set("keygrab", _e_keyrouter_keygrab_print, NULL); e_keyrouter.keygrab_list_get = _e_keyrouter_keygrab_list_get; e_keyrouter.max_keycode_get = _e_keyrouter_max_keycode_get; @@ -547,7 +413,7 @@ err: E_FREE(kconfig); } - _e_keyrouter_deinit_handlers(); + e_keyrouter_event_deinit(); eina_log_domain_unregister(_keyrouter_log_dom); _keyrouter_log_dom = -1; if (krt) E_FREE(krt); @@ -565,7 +431,10 @@ e_keyrouter_shutdown(void) e_keyrouter_conf_deinit(kconfig); E_FREE(kconfig); - _e_keyrouter_deinit_handlers(); + e_info_server_hook_set("keyrouter", NULL, NULL); + e_info_server_hook_set("keygrab", NULL, NULL); + + e_keyrouter_event_deinit(); g_rec_mutex_lock(&krt->grab_key_mutex); e_keyrouter_hardkeys_destroy(krt->HardKeys); @@ -755,83 +624,3 @@ E_API int (*e_keyrouter_info_max_keycode_get(void))(void) { return e_keyrouter.max_keycode_get; } - - -/////////////////////////////////////////////////////////////////////// -// This is for getting/setting internal value of E_Keyrouter_Event_Data -E_API E_Keyrouter_Event_Data * -e_keyrouter_event_data_create(void) -{ - return E_NEW(E_Keyrouter_Event_Data, 1); -} - -E_API void -e_keyrouter_event_data_destroy(E_Keyrouter_Event_Data *event_data) -{ - if (event_data) E_FREE(event_data); -} - -E_API struct wl_client * -e_keyrouter_event_data_client_get(const E_Keyrouter_Event_Data *event_data) -{ - if (!event_data) return NULL; - return event_data->client; -} - -E_API void -e_keyrouter_event_data_client_set(E_Keyrouter_Event_Data *event_data, struct wl_client *client) -{ - if (event_data) event_data->client = client; -} - -E_API struct wl_resource * -e_keyrouter_event_data_surface_get(const E_Keyrouter_Event_Data *event_data) -{ - if (!event_data) return NULL; - return event_data->surface; -} - -E_API void -e_keyrouter_event_data_surface_set(E_Keyrouter_Event_Data *event_data, struct wl_resource *surface) -{ - if (event_data) event_data->surface = surface; -} - -EINTERN int -e_keyrouter_event_data_mode_get(const E_Keyrouter_Event_Data *event_data) -{ - if (!event_data) return 0; - return event_data->mode; -} - -EINTERN void -e_keyrouter_event_data_mode_set(E_Keyrouter_Event_Data *event_data, int mode) -{ - if (event_data) event_data->mode = mode; -} - -EINTERN Eina_Bool -e_keyrouter_event_data_ignored_get(const E_Keyrouter_Event_Data *event_data) -{ - if (!event_data) return EINA_FALSE; - return event_data->ignored; -} - -E_API void -e_keyrouter_event_data_ignored_set(E_Keyrouter_Event_Data *event_data, Eina_Bool ignored) -{ - if (event_data) event_data->ignored = ignored; -} - -E_API void * -e_keyrouter_event_data_data_get(const E_Keyrouter_Event_Data *event_data) -{ - if (!event_data) return NULL; - return event_data->data; -} - -E_API void -e_keyrouter_event_data_data_set(E_Keyrouter_Event_Data *event_data, void *data) -{ - if (event_data) event_data->data = data; -} diff --git a/src/bin/inputmgr/e_keyrouter_event.c b/src/bin/inputmgr/e_keyrouter_event.c new file mode 100644 index 0000000000..ebda2d7243 --- /dev/null +++ b/src/bin/inputmgr/e_keyrouter_event.c @@ -0,0 +1,904 @@ +#include "e_keyrouter_event_intern.h" +#include "e_input_intern.h" +#include "e_comp_wl_input_intern.h" +#include "e_comp_wl_intern.h" +#include "e_comp_intern.h" +#include "e_utils_intern.h" +#include "e_screensaver_intern.h" +#include "e_config_intern.h" +#include "e_client_intern.h" +#include "e_keyrouter_wl_intern.h" +#include "e_keyrouter_hardkeys_intern.h" +#include "e_zone_intern.h" + +#include + +static void _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev); +static void _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev); +static void _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *dev); +static void _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, E_Device *dev, Eina_Bool focused, unsigned int mode); + +static Eina_Bool _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface, Ecore_Event_Key *ev, E_Device *dev, struct wl_resource **delivered_surface); + +static Eina_Bool _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx); + +typedef enum +{ + KEY_EVENT_LOG_TYPE_UNKNOWN, + KEY_EVENT_LOG_TYPE_KEY_DOWN, + KEY_EVENT_LOG_TYPE_KEY_UP, + KEY_EVENT_LOG_TYPE_KEY_CANCEL, + KEY_EVENT_LOG_TYPE_PICTURE_OFF, + KEY_EVENT_LOG_TYPE_RELEASE_HOOK, + KEY_EVENT_LOG_TYPE_RELEASE_PAIR, + KEY_EVENT_LOG_TYPE_RELEASE_SKIP, +} KEY_EVENT_LOG_TYPE; + +static const char * +_e_keyrouter_event_type_to_string(int type) +{ + switch (type) + { + case KEY_EVENT_LOG_TYPE_KEY_DOWN: + return "KEY_DOWN"; + case KEY_EVENT_LOG_TYPE_KEY_UP: + return "KEY_UP"; + case KEY_EVENT_LOG_TYPE_KEY_CANCEL: + return "KEY_CANCEL"; + case KEY_EVENT_LOG_TYPE_PICTURE_OFF: + return "PICTURE_OFF"; + case KEY_EVENT_LOG_TYPE_RELEASE_HOOK: + return "RELEASE_HOOK"; + case KEY_EVENT_LOG_TYPE_RELEASE_PAIR: + return "RELEASE_PAIR"; + case KEY_EVENT_LOG_TYPE_RELEASE_SKIP: + return "RELEASE_SKIP"; + default: + break; + } + + return "UNKNOWN"; +} + +static void +_e_keyrouter_log_key_event(int type, const char *mode_str, + uint32_t keycode, + Eina_Bool focused, + int client_status, + struct wl_resource *surface, + struct wl_client *client) +{ + int pid = e_keyrouter_util_get_pid(client, surface); + char *cmd = e_keyrouter_util_cmd_get_from_pid(pid); + char *pname = e_keyrouter_util_process_name_get_from_cmd(cmd); + char *keyname = e_comp_wl_input_keymap_keycode_to_keyname(keycode); + + KLINF("%s: %s(%s:%d)(F:%d,S:%d) => wl_surface(%p) wl_client(%p) (pid:%d) (pname:%s)", + mode_str, + _e_keyrouter_event_type_to_string(type), + keyname ?: "Unknown", + keycode, + focused, + client_status, + surface, + client, + pid, + pname ?: "Unknown"); + + if (keyname) E_FREE(keyname); + if (pname) E_FREE(pname); + if (cmd) E_FREE(cmd); +} + +static Eina_Bool +_e_keyrouter_event_routed_key_check(Ecore_Event_Key *ev, int type) +{ + Eina_List *l, *l_next; + int *keycode_data; + + if ((ev->modifiers != 0) && (type == ECORE_EVENT_KEY_DOWN)) + { + KLDBG("Modifier key delivered to Focus window : Key %s(%d)", + ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode); + + keycode_data = E_NEW(int, 1); + if (keycode_data) + { + *keycode_data = ev->keycode; + krt->ignore_list = eina_list_append(krt->ignore_list, keycode_data); + } + + return EINA_FALSE; + } + + EINA_LIST_FOREACH_SAFE(krt->ignore_list, l, l_next, keycode_data) + { + if (*keycode_data == ev->keycode) + { + KLDBG("Find ignore key, propagate event (%d)\n", ev->keycode); + E_FREE(keycode_data); + krt->ignore_list = eina_list_remove_list(krt->ignore_list, l); + + return EINA_FALSE; + } + } + + if (krt->max_tizen_hwkeys < ev->keycode) + { + KLWRN("The key(%d) is too larger to process keyrouting: Invalid keycode", + ev->keycode); + + return EINA_FALSE; + } + + g_rec_mutex_lock(&krt->grab_key_mutex); + if (!e_keyrouter_hardkeys_keycode_available(krt->HardKeys, ev->keycode)) + { + g_rec_mutex_unlock(&krt->grab_key_mutex); + return EINA_FALSE; + } + g_rec_mutex_unlock(&krt->grab_key_mutex); + + return EINA_TRUE; +} + +/* Function for checking the existing grab for a key and sending key event(s) */ +static Eina_Bool +_e_keyrouter_event_process(void *event, E_Device *dev, int type) +{ + Eina_Bool res = EINA_FALSE; + Ecore_Event_Key *ev = event; + E_Keyrouter_Event_Data *key_data; + + KLDBG("[%s] keyname: %s, key: %s, keycode: %d", + (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", + ev->keyname, ev->key, ev->keycode); + + e_screensaver_notidle(); + + key_data = (E_Keyrouter_Event_Data *)ev->data; + if (!key_data) + { + KLWRN("%s key (%d) %s is not handled by keyrouter\n", + ev->keyname, ev->keycode, + (type == ECORE_EVENT_KEY_DOWN) ? "press" : "release"); + + goto focus_deliver; + } + + if (key_data->client || key_data->surface) + { + e_keyrouter_wl_key_send(ev, dev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE); + return EINA_TRUE; + } + + if (!_e_keyrouter_event_routed_key_check(event, type)) + { + goto focus_deliver; + } + + res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_BEFORE_KEYROUTING, type, ev); + if (!res) goto finish; + if (key_data->ignored) goto finish; + + if (key_data->client || key_data->surface) + { + e_keyrouter_wl_key_send(ev, dev, + (type == ECORE_EVENT_KEY_DOWN) ? EINA_TRUE : EINA_FALSE, + key_data->client, key_data->surface, EINA_FALSE); + goto finish; + } + + KLDBG("[%s] keyname: %s, key: %s, keycode: %d", + (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", + ev->keyname, ev->key, ev->keycode); + + if (e_config->key_input_ttrace_enable) + { + TRACE_INPUT_BEGIN(_e_keyrouter_send_key_events); + ELOGF("INPUT", "_e_keyrouter_send_key_events|B|", NULL); + } + + _e_keyrouter_send_key_events(type, ev, dev); + + if (e_config->key_input_ttrace_enable) + { + TRACE_INPUT_END(); + ELOGF("INPUT", "_e_keyrouter_send_key_events|E|", NULL); + } + + return EINA_FALSE; + +focus_deliver: + if (e_config->key_input_ttrace_enable) + { + TRACE_INPUT_BEGIN(e_comp_wl_key_process); + ELOGF("INPUT", "e_comp_wl_key_process|B|", NULL); + } + + res = e_comp_wl_key_process(event, dev, type); + + if (e_config->key_input_ttrace_enable) + { + TRACE_INPUT_END(); + ELOGF("INPUT", "e_comp_wl_key_process|E|", NULL); + } +finish: + return res; +} + +/* Function for sending key events to wl_client(s) */ +static void +_e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev) +{ + E_Keyrouter_Key_List_NodePtr key_node_data; + Eina_List *l = NULL, *pic_off_ptr_list = NULL; + int keycode = 0; + + keycode = ev->keycode; + + if (krt->isPictureOffEnabled == 1) + { + g_rec_mutex_lock(&krt->grab_key_mutex); + pic_off_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_PICTURE_OFF); + EINA_LIST_FOREACH(pic_off_ptr_list, l, key_node_data) + { + if (key_node_data) + { + _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED); + + _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_PICTURE_OFF, "SHARED", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + } + } + g_rec_mutex_unlock(&krt->grab_key_mutex); + return; + } + + if (ECORE_EVENT_KEY_DOWN == type) + { + _e_keyrouter_send_key_events_press(type, ev, dev); + } + else + { + _e_keyrouter_send_key_events_release(type, ev, dev); + } +} + +static void +_e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *dev) +{ + E_Keyrouter_Key_List_NodePtr key_node_data; + Eina_Bool res_hook = EINA_TRUE; + E_Keyrouter_Event_Data *key_data = NULL; + Eina_List *press_ptr_list = NULL; + + /* Deliver release clean up pressed key list */ + g_rec_mutex_lock(&krt->grab_key_mutex); + press_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED); + EINA_LIST_FREE(press_ptr_list, key_node_data) + { + if (key_node_data->focused == EINA_TRUE) + { + res_hook = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev); + key_data = (E_Keyrouter_Event_Data *)ev->data; + + if (res_hook) + { + if (key_data->ignored) + { + E_FREE(key_node_data); + continue; + } + if (key_data->surface || key_data->client) + { + _e_keyrouter_send_key_event(type, key_data->surface, key_data->client, ev, dev, + EINA_FALSE, TIZEN_KEYROUTER_MODE_PRESSED); + + _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_RELEASE_HOOK, "PRESSED", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + + E_FREE(key_node_data); + + continue; + } + } + } + + if (!res_hook) + { + E_FREE(key_node_data); + continue; + } + + if (key_node_data->status == E_KRT_CSTAT_ALIVE) + { + _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, + key_node_data->focused, TIZEN_KEYROUTER_MODE_PRESSED); + + _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_RELEASE_PAIR, "PRESSED", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + } + else + { + _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_RELEASE_SKIP, "NONE", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + } + + E_FREE(key_node_data); + } + e_keyrouter_hardkeys_list_set(krt->HardKeys, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, NULL); + g_rec_mutex_unlock(&krt->grab_key_mutex); +} + +static void +_e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev) +{ + unsigned int keycode = ev->keycode; + struct wl_resource *surface_focus = NULL; + E_Client *ec_focus = NULL; + struct wl_resource *delivered_surface = NULL; + Eina_Bool res; + int ret = 0; + int key_event_log_type; + const char *seat_name = NULL; + E_Seat *seat; + E_Zone *zone = NULL; + + E_Keyrouter_Key_List_NodePtr key_node_data; + Eina_List *l = NULL, *shared_ptr_list = NULL; + + seat_name = e_device_seatname_get(dev); + if ((seat_name) && (seat = e_seat_find(seat_name))) + zone = e_seat_zone_get(seat); + if (!zone) + zone = e_comp_default_zone_get(e_comp_get()); + + ec_focus = e_zone_focused_client_get(zone); + ELOGF("KRT", "Key Process. seat:%s zone_id:%d", ec_focus, seat_name, e_zone_id_get(zone)); + surface_focus = e_comp_wl_client_surface_get(ec_focus); + + g_rec_mutex_lock(&krt->grab_key_mutex); + if (!e_keyrouter_hardkeys_grabbed(krt->HardKeys, ev->keycode)) + { + g_rec_mutex_unlock(&krt->grab_key_mutex); + _e_keyrouter_send_key_events_focus(type, surface_focus, ev, dev, &delivered_surface); + return; + } + g_rec_mutex_unlock(&krt->grab_key_mutex); + + if (type == ECORE_EVENT_KEY_DOWN) + key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_DOWN; + else + key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_UP; + + g_rec_mutex_lock(&krt->grab_key_mutex); + Eina_List *excl_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_EXCLUSIVE); + EINA_LIST_FOREACH(excl_ptr_list, l, key_node_data) + { + if (key_node_data) + { + _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, + key_node_data->focused, TIZEN_KEYROUTER_MODE_EXCLUSIVE); + + _e_keyrouter_log_key_event(key_event_log_type, "EXCLUSIVE", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + + g_rec_mutex_unlock(&krt->grab_key_mutex); + + return; + } + } + g_rec_mutex_unlock(&krt->grab_key_mutex); + + g_rec_mutex_lock(&krt->grab_key_mutex); + Eina_List *or_excl_ptr = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE); + EINA_LIST_FOREACH(or_excl_ptr, l, key_node_data) + { + if (key_node_data) + { + _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, + key_node_data->focused, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE); + + _e_keyrouter_log_key_event(key_event_log_type, "OVERRIDABLE_EXCLUSIVE", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + + g_rec_mutex_unlock(&krt->grab_key_mutex); + + return; + } + } + g_rec_mutex_unlock(&krt->grab_key_mutex); + + // Top position grab must need a focus surface. + if (surface_focus) + { + g_rec_mutex_lock(&krt->grab_key_mutex); + Eina_List *top_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_TOPMOST); + EINA_LIST_FOREACH(top_ptr_list, l, key_node_data) + { + if (key_node_data) + { + if ((EINA_FALSE == krt->isWindowStackChanged) && (surface_focus == key_node_data->surface)) + { + _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev, dev, key_node_data->focused, + TIZEN_KEYROUTER_MODE_TOPMOST); + + _e_keyrouter_log_key_event(key_event_log_type, "TOPMOST (TOP_POSITION)", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + + g_rec_mutex_unlock(&krt->grab_key_mutex); + + return; + } + krt->isWindowStackChanged = EINA_FALSE; + + if (_e_keyrouter_check_top_visible_window(ec_focus, keycode)) + { + E_Keyrouter_Key_List_NodePtr top_key_node_data = eina_list_data_get(top_ptr_list); + + _e_keyrouter_send_key_event(type, top_key_node_data->surface, NULL, ev, dev, top_key_node_data->focused, + TIZEN_KEYROUTER_MODE_TOPMOST); + + _e_keyrouter_log_key_event(key_event_log_type, "TOPMOST (TOP_POSITION)", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + + g_rec_mutex_unlock(&krt->grab_key_mutex); + + return; + } + break; + } + } + g_rec_mutex_unlock(&krt->grab_key_mutex); + + goto need_shared; + } + + g_rec_mutex_lock(&krt->grab_key_mutex); + shared_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_SHARED); + g_rec_mutex_unlock(&krt->grab_key_mutex); + + if (shared_ptr_list) + { +need_shared: + res = _e_keyrouter_send_key_events_focus(type, surface_focus, ev, dev, &delivered_surface); + if (delivered_surface) + { + ret = e_keyrouter_wl_add_surface_destroy_listener(delivered_surface); + if (ret != TIZEN_KEYROUTER_ERROR_NONE) + { + KLWRN("Failed to add wl_surface to destroy listener (res: %d)", res); + } + } + if (res) + { + g_rec_mutex_lock(&krt->grab_key_mutex); + shared_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_SHARED); + EINA_LIST_FOREACH(shared_ptr_list, l, key_node_data) + { + if (key_node_data) + { + if (delivered_surface && key_node_data->surface == delivered_surface) + { + // Check for already delivered surface + // do not deliver double events in this case. + continue; + } + else + { + _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED); + + _e_keyrouter_log_key_event(key_event_log_type, "SHARED", + ev->keycode, + key_node_data->focused, + key_node_data->status, + key_node_data->surface, + key_node_data->wc); + } + } + } + + g_rec_mutex_unlock(&krt->grab_key_mutex); + + } + } +} + +static Eina_Bool +_e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus, Ecore_Event_Key *ev, E_Device *dev, struct wl_resource **delivered_surface) +{ + E_Keyrouter_Event_Data *key_data; + Eina_Bool res = EINA_TRUE; + int key_event_log_type; + struct wl_client *wc = NULL; + + res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev); + key_data = (E_Keyrouter_Event_Data *)ev->data; + + if (type == ECORE_EVENT_KEY_DOWN) + key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_DOWN; + else + key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_UP; + + if (surface_focus) + wc = wl_resource_get_client(surface_focus); + + if (res) + { + if (key_data->ignored) + { + e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE); + return EINA_TRUE; + } + else if (key_data->surface) + { + *delivered_surface = key_data->surface; + e_keyrouter_prepend_to_keylist(key_data->surface, key_data->client, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE); + res = e_keyrouter_wl_key_send(ev, dev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE); + + _e_keyrouter_log_key_event(key_event_log_type, "FOCUS HOOK", + ev->keycode, + EINA_TRUE, + E_KRT_CSTAT_ALIVE, + surface_focus, + wc); + + return EINA_TRUE; + } + } + else + { + e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE); + return EINA_FALSE; + } + + _e_keyrouter_send_key_event(type, surface_focus, NULL,ev, dev, EINA_TRUE, TIZEN_KEYROUTER_MODE_SHARED); + + _e_keyrouter_log_key_event(key_event_log_type, "FOCUS HOOK", + ev->keycode, + EINA_TRUE, + E_KRT_CSTAT_ALIVE, + surface_focus, + wc); + + *delivered_surface = surface_focus; + + return res; +} + +static Eina_Bool +_e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx) +{ + E_Client *ec_top = NULL; + Eina_List *l = NULL, *l_next = NULL, *top_ptr_list = NULL; + E_Keyrouter_Key_List_NodePtr key_node_data = NULL; + + ec_top = e_client_top_get(); + + while (ec_top) + { + if (e_client_visibility_get(ec_top) != E_VISIBILITY_UNOBSCURED) + { + if (ec_top == ec_focus) + { + KLDBG("Top e_client (%p) is invisible(%d) but focus client", ec_top, ec_top->visible); + return EINA_FALSE; + } + ec_top = e_client_below_get(ec_top); + continue; + } + + /* TODO: Check this client is located inside a display boundary */ + g_rec_mutex_lock(&krt->grab_key_mutex); + top_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, arr_idx, TIZEN_KEYROUTER_MODE_TOPMOST); + EINA_LIST_FOREACH_SAFE(top_ptr_list, l, l_next, key_node_data) + { + if (key_node_data) + { + if (ec_top == e_client_from_surface_resource(key_node_data->surface)) + { + top_ptr_list = eina_list_promote_list(top_ptr_list, l); + e_keyrouter_hardkeys_list_set(krt->HardKeys, arr_idx, TIZEN_KEYROUTER_MODE_TOPMOST, top_ptr_list); + KLDBG("Move a client(e_client: %p, wl_surface: %p) to first index of list(key: %d)", + ec_top, key_node_data->surface, arr_idx); + g_rec_mutex_unlock(&krt->grab_key_mutex); + return EINA_TRUE; + } + } + } + + g_rec_mutex_unlock(&krt->grab_key_mutex); + + if (ec_top == ec_focus) + { + KLDBG("The e_client(%p) is a focus client", ec_top); + return EINA_FALSE; + } + + ec_top = e_client_below_get(ec_top); + } + return EINA_FALSE; +} + +/* Function for sending key event to wl_client(s) */ +static void +_e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, E_Device *dev, Eina_Bool focused, unsigned int mode) +{ + struct wl_client *wc_send; + Eina_Bool pressed = EINA_FALSE; + + if (surface == NULL) wc_send = wc; + else wc_send = wl_resource_get_client(surface); + + if (!wc_send) + { + KLWRN("wl_surface: %p or wl_client: %p returns null wayland client", surface, wc); + return; + } + + if (ECORE_EVENT_KEY_DOWN == type) + { + pressed = EINA_TRUE; + e_keyrouter_prepend_to_keylist(surface, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, focused); + } + + if (e_config->key_input_ttrace_enable) + { + TRACE_INPUT_BEGIN(e_keyrouter_wl_key_send); + ELOGF("INPUT", "e_keyrouter_wl_key_send|B|", NULL); + } + + e_keyrouter_wl_key_send(ev, dev, pressed, wc_send, surface, focused); + + if (e_config->key_input_ttrace_enable) + { + TRACE_INPUT_END(); + ELOGF("INPUT", "e_keyrouter_wl_key_send|E|", NULL); + } + + return; +} + +static Eina_Bool +_e_keyrouter_cb_key_down(void *data, int type, void *event) +{ + Ecore_Event_Key *ev; + + EINA_SAFETY_ON_NULL_RETURN_VAL(event, FALSE); + + ev = (Ecore_Event_Key *)event; + + TRACE_INPUT_BEGIN(_e_keyrouter_cb_key_down:KEY_PRESS(%d), ev->keycode); + TRACE_INPUT_END(); + + return _e_keyrouter_event_process(event, (E_Device *)ev->dev, type); +} + +static Eina_Bool +_e_keyrouter_cb_key_up(void *data, int type, void *event) +{ + Ecore_Event_Key *ev; + + EINA_SAFETY_ON_NULL_RETURN_VAL(event, FALSE); + + ev = (Ecore_Event_Key *)event; + + TRACE_INPUT_BEGIN(_e_keyrouter_cb_key_down:KEY_RELEASE(%d), ev->keycode); + TRACE_INPUT_END(); + + return _e_keyrouter_event_process(event, (E_Device *)ev->dev, type); +} + +static Eina_Bool +_e_keyrouter_client_cb_stack(void *data, int type, void *event) +{ + E_Event_Client *ev = event; + E_Client *ec = ev->ec; + + (void) data; + (void) type; + (void) event; + (void) ev; + (void) ec; + + //KLDBG("ec: %p, visible: %d, focused: %d, take_focus: %d, want_focus: %d, bordername: %s, input_only: %d", + // ec, ec->visible, ec->focused, ec->take_focus, ec->want_focus, ec->bordername, ec->input_only); + + krt->isWindowStackChanged = EINA_TRUE; + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_keyrouter_client_cb_remove(void *data, int type, void *event) +{ + E_Event_Client *ev = event; + E_Client *ec = ev->ec; + + (void) data; + (void) type; + (void) ev; + (void) ec; + + /* FIXME: Remove this callback or do something others. + * It was moved to _e_keyrouter_wl_surface_cb_destroy() where it had here. + */ + + return ECORE_CALLBACK_PASS_ON; +} + +EINTERN void +e_keyrouter_event_init(void) +{ + E_LIST_HANDLER_APPEND(krt->handlers, E_EVENT_CLIENT_STACK, _e_keyrouter_client_cb_stack, NULL); + E_LIST_HANDLER_APPEND(krt->handlers, E_EVENT_CLIENT_REMOVE, _e_keyrouter_client_cb_remove, NULL); + + if (!e_input_thread_mode_get()) + { + E_LIST_HANDLER_APPEND(krt->handlers, ECORE_EVENT_KEY_DOWN, _e_keyrouter_cb_key_down, NULL); + E_LIST_HANDLER_APPEND(krt->handlers, ECORE_EVENT_KEY_UP, _e_keyrouter_cb_key_up, NULL); + } + else + { + e_keyrouter_event_handler_add(); + } +} + +EINTERN void +e_keyrouter_event_deinit(void) +{ + Ecore_Event_Handler *h = NULL; + E_Input_Event_Source *input_event_source = NULL; + + if (!krt || !krt->handlers) return; + + EINA_LIST_FREE(krt->handlers, h) + ecore_event_handler_del(h); + + if (e_input_thread_mode_get()) + { + input_event_source = e_input_event_source_get(); + if (input_event_source) + { + if (krt->_key_down_handler) + e_input_event_handler_del(input_event_source, krt->_key_down_handler); + + if (krt->_key_up_handler) + e_input_event_handler_del(input_event_source, krt->_key_up_handler); + } + + krt->_key_down_handler = NULL; + krt->_key_up_handler = NULL; + } +} + +EINTERN void +e_keyrouter_event_handler_add(void) +{ + EINA_SAFETY_ON_NULL_RETURN(krt); + + E_Input_Event_Source *input_event_source = e_input_event_source_get(); + if (!input_event_source) + { + KLERR("Failed to get input_event_source"); + return; + } + + if (!krt->_key_down_handler) + krt->_key_down_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_KEY_DOWN, _e_keyrouter_cb_key_down, NULL); + + if (!krt->_key_up_handler) + krt->_key_up_handler = e_input_event_handler_add(input_event_source, ECORE_EVENT_KEY_UP, _e_keyrouter_cb_key_up, NULL); +} + +/////////////////////////////////////////////////////////////////////// +// This is for getting/setting internal value of E_Keyrouter_Event_Data +E_API E_Keyrouter_Event_Data * +e_keyrouter_event_data_create(void) +{ + return E_NEW(E_Keyrouter_Event_Data, 1); +} + +E_API void +e_keyrouter_event_data_destroy(E_Keyrouter_Event_Data *event_data) +{ + if (event_data) E_FREE(event_data); +} + +E_API struct wl_client * +e_keyrouter_event_data_client_get(const E_Keyrouter_Event_Data *event_data) +{ + if (!event_data) return NULL; + return event_data->client; +} + +E_API void +e_keyrouter_event_data_client_set(E_Keyrouter_Event_Data *event_data, struct wl_client *client) +{ + if (event_data) event_data->client = client; +} + +E_API struct wl_resource * +e_keyrouter_event_data_surface_get(const E_Keyrouter_Event_Data *event_data) +{ + if (!event_data) return NULL; + return event_data->surface; +} + +E_API void +e_keyrouter_event_data_surface_set(E_Keyrouter_Event_Data *event_data, struct wl_resource *surface) +{ + if (event_data) event_data->surface = surface; +} + +EINTERN int +e_keyrouter_event_data_mode_get(const E_Keyrouter_Event_Data *event_data) +{ + if (!event_data) return 0; + return event_data->mode; +} + +EINTERN void +e_keyrouter_event_data_mode_set(E_Keyrouter_Event_Data *event_data, int mode) +{ + if (event_data) event_data->mode = mode; +} + +EINTERN Eina_Bool +e_keyrouter_event_data_ignored_get(const E_Keyrouter_Event_Data *event_data) +{ + if (!event_data) return EINA_FALSE; + return event_data->ignored; +} + +E_API void +e_keyrouter_event_data_ignored_set(E_Keyrouter_Event_Data *event_data, Eina_Bool ignored) +{ + if (event_data) event_data->ignored = ignored; +} + +E_API void * +e_keyrouter_event_data_data_get(const E_Keyrouter_Event_Data *event_data) +{ + if (!event_data) return NULL; + return event_data->data; +} + +E_API void +e_keyrouter_event_data_data_set(E_Keyrouter_Event_Data *event_data, void *data) +{ + if (event_data) event_data->data = data; +} diff --git a/src/bin/inputmgr/e_keyrouter_event_intern.h b/src/bin/inputmgr/e_keyrouter_event_intern.h new file mode 100644 index 0000000000..8c9b4dbe40 --- /dev/null +++ b/src/bin/inputmgr/e_keyrouter_event_intern.h @@ -0,0 +1,17 @@ +#ifndef E_KEYROUTER_EVENT_INTERN_H +#define E_KEYROUTER_EVENT_INTERN_H + +#include "e_intern.h" +#include "e_keyrouter_intern.h" + +EINTERN void e_keyrouter_event_init(void); +EINTERN void e_keyrouter_event_deinit(void); + +EINTERN void e_keyrouter_event_handler_add(void); + +EINTERN int e_keyrouter_event_data_mode_get(const E_Keyrouter_Event_Data *event_data); +EINTERN void e_keyrouter_event_data_mode_set(E_Keyrouter_Event_Data *event_data, int mode); +EINTERN Eina_Bool e_keyrouter_event_data_ignored_get(const E_Keyrouter_Event_Data *event_data); + +#endif + diff --git a/src/bin/inputmgr/e_keyrouter_events.c b/src/bin/inputmgr/e_keyrouter_events.c deleted file mode 100644 index 2635bc9504..0000000000 --- a/src/bin/inputmgr/e_keyrouter_events.c +++ /dev/null @@ -1,693 +0,0 @@ -#include "e_keyrouter_intern.h" -#include "e_input_intern.h" -#include "e_comp_wl_input_intern.h" -#include "e_comp_wl_intern.h" -#include "e_comp_intern.h" -#include "e_utils_intern.h" -#include "e_screensaver_intern.h" -#include "e_config_intern.h" -#include "e_client_intern.h" -#include "e_keyrouter_wl_intern.h" -#include "e_keyrouter_hardkeys_intern.h" -#include "e_zone_intern.h" - -#include - -static void _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev); -static void _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev); -static void _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *dev); -static void _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, E_Device *dev, Eina_Bool focused, unsigned int mode); - -static Eina_Bool _e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface, Ecore_Event_Key *ev, E_Device *dev, struct wl_resource **delivered_surface); - -static Eina_Bool _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx); - -typedef enum -{ - KEY_EVENT_LOG_TYPE_UNKNOWN, - KEY_EVENT_LOG_TYPE_KEY_DOWN, - KEY_EVENT_LOG_TYPE_KEY_UP, - KEY_EVENT_LOG_TYPE_KEY_CANCEL, - KEY_EVENT_LOG_TYPE_PICTURE_OFF, - KEY_EVENT_LOG_TYPE_RELEASE_HOOK, - KEY_EVENT_LOG_TYPE_RELEASE_PAIR, - KEY_EVENT_LOG_TYPE_RELEASE_SKIP, -} KEY_EVENT_LOG_TYPE; - -static const char * -_e_keyrouter_event_type_to_string(int type) -{ - switch (type) - { - case KEY_EVENT_LOG_TYPE_KEY_DOWN: - return "KEY_DOWN"; - case KEY_EVENT_LOG_TYPE_KEY_UP: - return "KEY_UP"; - case KEY_EVENT_LOG_TYPE_KEY_CANCEL: - return "KEY_CANCEL"; - case KEY_EVENT_LOG_TYPE_PICTURE_OFF: - return "PICTURE_OFF"; - case KEY_EVENT_LOG_TYPE_RELEASE_HOOK: - return "RELEASE_HOOK"; - case KEY_EVENT_LOG_TYPE_RELEASE_PAIR: - return "RELEASE_PAIR"; - case KEY_EVENT_LOG_TYPE_RELEASE_SKIP: - return "RELEASE_SKIP"; - default: - break; - } - - return "UNKNOWN"; -} - -static void -_e_keyrouter_log_key_event(int type, const char *mode_str, - uint32_t keycode, - Eina_Bool focused, - int client_status, - struct wl_resource *surface, - struct wl_client *client) -{ - int pid = e_keyrouter_util_get_pid(client, surface); - char *cmd = e_keyrouter_util_cmd_get_from_pid(pid); - char *pname = e_keyrouter_util_process_name_get_from_cmd(cmd); - char *keyname = e_comp_wl_input_keymap_keycode_to_keyname(keycode); - - KLINF("%s: %s(%s:%d)(F:%d,S:%d) => wl_surface(%p) wl_client(%p) (pid:%d) (pname:%s)", - mode_str, - _e_keyrouter_event_type_to_string(type), - keyname ?: "Unknown", - keycode, - focused, - client_status, - surface, - client, - pid, - pname ?: "Unknown"); - - if (keyname) E_FREE(keyname); - if (pname) E_FREE(pname); - if (cmd) E_FREE(cmd); -} - -static Eina_Bool -_e_keyrouter_event_routed_key_check(Ecore_Event_Key *ev, int type) -{ - Eina_List *l, *l_next; - int *keycode_data; - - if ((ev->modifiers != 0) && (type == ECORE_EVENT_KEY_DOWN)) - { - KLDBG("Modifier key delivered to Focus window : Key %s(%d)", - ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keycode); - - keycode_data = E_NEW(int, 1); - if (keycode_data) - { - *keycode_data = ev->keycode; - krt->ignore_list = eina_list_append(krt->ignore_list, keycode_data); - } - - return EINA_FALSE; - } - - EINA_LIST_FOREACH_SAFE(krt->ignore_list, l, l_next, keycode_data) - { - if (*keycode_data == ev->keycode) - { - KLDBG("Find ignore key, propagate event (%d)\n", ev->keycode); - E_FREE(keycode_data); - krt->ignore_list = eina_list_remove_list(krt->ignore_list, l); - - return EINA_FALSE; - } - } - - if (krt->max_tizen_hwkeys < ev->keycode) - { - KLWRN("The key(%d) is too larger to process keyrouting: Invalid keycode", - ev->keycode); - - return EINA_FALSE; - } - - g_rec_mutex_lock(&krt->grab_key_mutex); - if (!e_keyrouter_hardkeys_keycode_available(krt->HardKeys, ev->keycode)) - { - g_rec_mutex_unlock(&krt->grab_key_mutex); - return EINA_FALSE; - } - g_rec_mutex_unlock(&krt->grab_key_mutex); - - return EINA_TRUE; -} - -/* Function for checking the existing grab for a key and sending key event(s) */ -Eina_Bool -e_keyrouter_event_process(void *event, E_Device *dev, int type) -{ - Eina_Bool res = EINA_FALSE; - Ecore_Event_Key *ev = event; - E_Keyrouter_Event_Data *key_data; - - KLDBG("[%s] keyname: %s, key: %s, keycode: %d", - (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", - ev->keyname, ev->key, ev->keycode); - - e_screensaver_notidle(); - - key_data = (E_Keyrouter_Event_Data *)ev->data; - if (!key_data) - { - KLWRN("%s key (%d) %s is not handled by keyrouter\n", - ev->keyname, ev->keycode, - (type == ECORE_EVENT_KEY_DOWN) ? "press" : "release"); - - goto focus_deliver; - } - - if (key_data->client || key_data->surface) - { - e_keyrouter_wl_key_send(ev, dev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE); - return EINA_TRUE; - } - - if (!_e_keyrouter_event_routed_key_check(event, type)) - { - goto focus_deliver; - } - - res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_BEFORE_KEYROUTING, type, ev); - if (!res) goto finish; - if (key_data->ignored) goto finish; - - if (key_data->client || key_data->surface) - { - e_keyrouter_wl_key_send(ev, dev, - (type == ECORE_EVENT_KEY_DOWN) ? EINA_TRUE : EINA_FALSE, - key_data->client, key_data->surface, EINA_FALSE); - goto finish; - } - - KLDBG("[%s] keyname: %s, key: %s, keycode: %d", - (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", - ev->keyname, ev->key, ev->keycode); - - if (e_config->key_input_ttrace_enable) - { - TRACE_INPUT_BEGIN(_e_keyrouter_send_key_events); - ELOGF("INPUT", "_e_keyrouter_send_key_events|B|", NULL); - } - - _e_keyrouter_send_key_events(type, ev, dev); - - if (e_config->key_input_ttrace_enable) - { - TRACE_INPUT_END(); - ELOGF("INPUT", "_e_keyrouter_send_key_events|E|", NULL); - } - - return EINA_FALSE; - -focus_deliver: - if (e_config->key_input_ttrace_enable) - { - TRACE_INPUT_BEGIN(e_comp_wl_key_process); - ELOGF("INPUT", "e_comp_wl_key_process|B|", NULL); - } - - res = e_comp_wl_key_process(event, dev, type); - - if (e_config->key_input_ttrace_enable) - { - TRACE_INPUT_END(); - ELOGF("INPUT", "e_comp_wl_key_process|E|", NULL); - } -finish: - return res; -} - -/* Function for sending key events to wl_client(s) */ -static void -_e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev, E_Device *dev) -{ - E_Keyrouter_Key_List_NodePtr key_node_data; - Eina_List *l = NULL, *pic_off_ptr_list = NULL; - int keycode = 0; - - keycode = ev->keycode; - - if (krt->isPictureOffEnabled == 1) - { - g_rec_mutex_lock(&krt->grab_key_mutex); - pic_off_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_PICTURE_OFF); - EINA_LIST_FOREACH(pic_off_ptr_list, l, key_node_data) - { - if (key_node_data) - { - _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED); - - _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_PICTURE_OFF, "SHARED", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - } - } - g_rec_mutex_unlock(&krt->grab_key_mutex); - return; - } - - if (ECORE_EVENT_KEY_DOWN == type) - { - _e_keyrouter_send_key_events_press(type, ev, dev); - } - else - { - _e_keyrouter_send_key_events_release(type, ev, dev); - } -} - -static void -_e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev, E_Device *dev) -{ - E_Keyrouter_Key_List_NodePtr key_node_data; - Eina_Bool res_hook = EINA_TRUE; - E_Keyrouter_Event_Data *key_data = NULL; - Eina_List *press_ptr_list = NULL; - - /* Deliver release clean up pressed key list */ - g_rec_mutex_lock(&krt->grab_key_mutex); - press_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED); - EINA_LIST_FREE(press_ptr_list, key_node_data) - { - if (key_node_data->focused == EINA_TRUE) - { - res_hook = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev); - key_data = (E_Keyrouter_Event_Data *)ev->data; - - if (res_hook) - { - if (key_data->ignored) - { - E_FREE(key_node_data); - continue; - } - if (key_data->surface || key_data->client) - { - _e_keyrouter_send_key_event(type, key_data->surface, key_data->client, ev, dev, - EINA_FALSE, TIZEN_KEYROUTER_MODE_PRESSED); - - _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_RELEASE_HOOK, "PRESSED", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - - E_FREE(key_node_data); - - continue; - } - } - } - - if (!res_hook) - { - E_FREE(key_node_data); - continue; - } - - if (key_node_data->status == E_KRT_CSTAT_ALIVE) - { - _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, - key_node_data->focused, TIZEN_KEYROUTER_MODE_PRESSED); - - _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_RELEASE_PAIR, "PRESSED", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - } - else - { - _e_keyrouter_log_key_event(KEY_EVENT_LOG_TYPE_RELEASE_SKIP, "NONE", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - } - - E_FREE(key_node_data); - } - e_keyrouter_hardkeys_list_set(krt->HardKeys, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, NULL); - g_rec_mutex_unlock(&krt->grab_key_mutex); -} - -static void -_e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev, E_Device *dev) -{ - unsigned int keycode = ev->keycode; - struct wl_resource *surface_focus = NULL; - E_Client *ec_focus = NULL; - struct wl_resource *delivered_surface = NULL; - Eina_Bool res; - int ret = 0; - int key_event_log_type; - const char *seat_name = NULL; - E_Seat *seat; - E_Zone *zone = NULL; - - E_Keyrouter_Key_List_NodePtr key_node_data; - Eina_List *l = NULL, *shared_ptr_list = NULL; - - seat_name = e_device_seatname_get(dev); - if ((seat_name) && (seat = e_seat_find(seat_name))) - zone = e_seat_zone_get(seat); - if (!zone) - zone = e_comp_default_zone_get(e_comp_get()); - - ec_focus = e_zone_focused_client_get(zone); - ELOGF("KRT", "Key Process. seat:%s zone_id:%d", ec_focus, seat_name, e_zone_id_get(zone)); - surface_focus = e_comp_wl_client_surface_get(ec_focus); - - g_rec_mutex_lock(&krt->grab_key_mutex); - if (!e_keyrouter_hardkeys_grabbed(krt->HardKeys, ev->keycode)) - { - g_rec_mutex_unlock(&krt->grab_key_mutex); - _e_keyrouter_send_key_events_focus(type, surface_focus, ev, dev, &delivered_surface); - return; - } - g_rec_mutex_unlock(&krt->grab_key_mutex); - - if (type == ECORE_EVENT_KEY_DOWN) - key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_DOWN; - else - key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_UP; - - g_rec_mutex_lock(&krt->grab_key_mutex); - Eina_List *excl_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_EXCLUSIVE); - EINA_LIST_FOREACH(excl_ptr_list, l, key_node_data) - { - if (key_node_data) - { - _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, - key_node_data->focused, TIZEN_KEYROUTER_MODE_EXCLUSIVE); - - _e_keyrouter_log_key_event(key_event_log_type, "EXCLUSIVE", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - - g_rec_mutex_unlock(&krt->grab_key_mutex); - - return; - } - } - g_rec_mutex_unlock(&krt->grab_key_mutex); - - g_rec_mutex_lock(&krt->grab_key_mutex); - Eina_List *or_excl_ptr = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE); - EINA_LIST_FOREACH(or_excl_ptr, l, key_node_data) - { - if (key_node_data) - { - _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, - key_node_data->focused, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE); - - _e_keyrouter_log_key_event(key_event_log_type, "OVERRIDABLE_EXCLUSIVE", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - - g_rec_mutex_unlock(&krt->grab_key_mutex); - - return; - } - } - g_rec_mutex_unlock(&krt->grab_key_mutex); - - // Top position grab must need a focus surface. - if (surface_focus) - { - g_rec_mutex_lock(&krt->grab_key_mutex); - Eina_List *top_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_TOPMOST); - EINA_LIST_FOREACH(top_ptr_list, l, key_node_data) - { - if (key_node_data) - { - if ((EINA_FALSE == krt->isWindowStackChanged) && (surface_focus == key_node_data->surface)) - { - _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev, dev, key_node_data->focused, - TIZEN_KEYROUTER_MODE_TOPMOST); - - _e_keyrouter_log_key_event(key_event_log_type, "TOPMOST (TOP_POSITION)", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - - g_rec_mutex_unlock(&krt->grab_key_mutex); - - return; - } - krt->isWindowStackChanged = EINA_FALSE; - - if (_e_keyrouter_check_top_visible_window(ec_focus, keycode)) - { - E_Keyrouter_Key_List_NodePtr top_key_node_data = eina_list_data_get(top_ptr_list); - - _e_keyrouter_send_key_event(type, top_key_node_data->surface, NULL, ev, dev, top_key_node_data->focused, - TIZEN_KEYROUTER_MODE_TOPMOST); - - _e_keyrouter_log_key_event(key_event_log_type, "TOPMOST (TOP_POSITION)", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - - g_rec_mutex_unlock(&krt->grab_key_mutex); - - return; - } - break; - } - } - g_rec_mutex_unlock(&krt->grab_key_mutex); - - goto need_shared; - } - - g_rec_mutex_lock(&krt->grab_key_mutex); - shared_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_SHARED); - g_rec_mutex_unlock(&krt->grab_key_mutex); - - if (shared_ptr_list) - { -need_shared: - res = _e_keyrouter_send_key_events_focus(type, surface_focus, ev, dev, &delivered_surface); - if (delivered_surface) - { - ret = e_keyrouter_wl_add_surface_destroy_listener(delivered_surface); - if (ret != TIZEN_KEYROUTER_ERROR_NONE) - { - KLWRN("Failed to add wl_surface to destroy listener (res: %d)", res); - } - } - if (res) - { - g_rec_mutex_lock(&krt->grab_key_mutex); - shared_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, keycode, TIZEN_KEYROUTER_MODE_SHARED); - EINA_LIST_FOREACH(shared_ptr_list, l, key_node_data) - { - if (key_node_data) - { - if (delivered_surface && key_node_data->surface == delivered_surface) - { - // Check for already delivered surface - // do not deliver double events in this case. - continue; - } - else - { - _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev, dev, key_node_data->focused, TIZEN_KEYROUTER_MODE_SHARED); - - _e_keyrouter_log_key_event(key_event_log_type, "SHARED", - ev->keycode, - key_node_data->focused, - key_node_data->status, - key_node_data->surface, - key_node_data->wc); - } - } - } - - g_rec_mutex_unlock(&krt->grab_key_mutex); - - } - } -} - -static Eina_Bool -_e_keyrouter_send_key_events_focus(int type, struct wl_resource *surface_focus, Ecore_Event_Key *ev, E_Device *dev, struct wl_resource **delivered_surface) -{ - E_Keyrouter_Event_Data *key_data; - Eina_Bool res = EINA_TRUE; - int key_event_log_type; - struct wl_client *wc = NULL; - - res = e_keyrouter_intercept_hook_call(E_KEYROUTER_INTERCEPT_HOOK_DELIVER_FOCUS, type, ev); - key_data = (E_Keyrouter_Event_Data *)ev->data; - - if (type == ECORE_EVENT_KEY_DOWN) - key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_DOWN; - else - key_event_log_type = KEY_EVENT_LOG_TYPE_KEY_UP; - - if (surface_focus) - wc = wl_resource_get_client(surface_focus); - - if (res) - { - if (key_data->ignored) - { - e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE); - return EINA_TRUE; - } - else if (key_data->surface) - { - *delivered_surface = key_data->surface; - e_keyrouter_prepend_to_keylist(key_data->surface, key_data->client, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE); - res = e_keyrouter_wl_key_send(ev, dev, (type==ECORE_EVENT_KEY_DOWN)?EINA_TRUE:EINA_FALSE, key_data->client, key_data->surface, EINA_FALSE); - - _e_keyrouter_log_key_event(key_event_log_type, "FOCUS HOOK", - ev->keycode, - EINA_TRUE, - E_KRT_CSTAT_ALIVE, - surface_focus, - wc); - - return EINA_TRUE; - } - } - else - { - e_keyrouter_prepend_to_keylist(NULL, NULL, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, EINA_TRUE); - return EINA_FALSE; - } - - _e_keyrouter_send_key_event(type, surface_focus, NULL,ev, dev, EINA_TRUE, TIZEN_KEYROUTER_MODE_SHARED); - - _e_keyrouter_log_key_event(key_event_log_type, "FOCUS HOOK", - ev->keycode, - EINA_TRUE, - E_KRT_CSTAT_ALIVE, - surface_focus, - wc); - - *delivered_surface = surface_focus; - - return res; -} - -static Eina_Bool -_e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx) -{ - E_Client *ec_top = NULL; - Eina_List *l = NULL, *l_next = NULL, *top_ptr_list = NULL; - E_Keyrouter_Key_List_NodePtr key_node_data = NULL; - - ec_top = e_client_top_get(); - - while (ec_top) - { - if (e_client_visibility_get(ec_top) != E_VISIBILITY_UNOBSCURED) - { - if (ec_top == ec_focus) - { - KLDBG("Top e_client (%p) is invisible(%d) but focus client", ec_top, ec_top->visible); - return EINA_FALSE; - } - ec_top = e_client_below_get(ec_top); - continue; - } - - /* TODO: Check this client is located inside a display boundary */ - g_rec_mutex_lock(&krt->grab_key_mutex); - top_ptr_list = e_keyrouter_hardkeys_list_get(krt->HardKeys, arr_idx, TIZEN_KEYROUTER_MODE_TOPMOST); - EINA_LIST_FOREACH_SAFE(top_ptr_list, l, l_next, key_node_data) - { - if (key_node_data) - { - if (ec_top == e_client_from_surface_resource(key_node_data->surface)) - { - top_ptr_list = eina_list_promote_list(top_ptr_list, l); - e_keyrouter_hardkeys_list_set(krt->HardKeys, arr_idx, TIZEN_KEYROUTER_MODE_TOPMOST, top_ptr_list); - KLDBG("Move a client(e_client: %p, wl_surface: %p) to first index of list(key: %d)", - ec_top, key_node_data->surface, arr_idx); - g_rec_mutex_unlock(&krt->grab_key_mutex); - return EINA_TRUE; - } - } - } - - g_rec_mutex_unlock(&krt->grab_key_mutex); - - if (ec_top == ec_focus) - { - KLDBG("The e_client(%p) is a focus client", ec_top); - return EINA_FALSE; - } - - ec_top = e_client_below_get(ec_top); - } - return EINA_FALSE; -} - -/* Function for sending key event to wl_client(s) */ -static void -_e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev, E_Device *dev, Eina_Bool focused, unsigned int mode) -{ - struct wl_client *wc_send; - Eina_Bool pressed = EINA_FALSE; - - if (surface == NULL) wc_send = wc; - else wc_send = wl_resource_get_client(surface); - - if (!wc_send) - { - KLWRN("wl_surface: %p or wl_client: %p returns null wayland client", surface, wc); - return; - } - - if (ECORE_EVENT_KEY_DOWN == type) - { - pressed = EINA_TRUE; - e_keyrouter_prepend_to_keylist(surface, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED, focused); - } - - if (e_config->key_input_ttrace_enable) - { - TRACE_INPUT_BEGIN(e_keyrouter_wl_key_send); - ELOGF("INPUT", "e_keyrouter_wl_key_send|B|", NULL); - } - - e_keyrouter_wl_key_send(ev, dev, pressed, wc_send, surface, focused); - - if (e_config->key_input_ttrace_enable) - { - TRACE_INPUT_END(); - ELOGF("INPUT", "e_keyrouter_wl_key_send|E|", NULL); - } - - return; -} diff --git a/src/bin/inputmgr/e_keyrouter_intern.h b/src/bin/inputmgr/e_keyrouter_intern.h index 69eccf00fa..f9fb6ab551 100644 --- a/src/bin/inputmgr/e_keyrouter_intern.h +++ b/src/bin/inputmgr/e_keyrouter_intern.h @@ -120,8 +120,6 @@ extern E_API E_KeyrouterPtr krt; EINTERN int e_keyrouter_init(void); EINTERN int e_keyrouter_shutdown(void); -EINTERN void e_keyrouter_input_handler_add(void); - EINTERN int e_keyrouter_prepend_to_keylist(struct wl_resource *surface, struct wl_client *wc, uint32_t key, uint32_t mode, Eina_Bool focused); EINTERN void e_keyrouter_remove_surface_from_list(struct wl_resource *surface); EINTERN void e_keyrouter_remove_client_from_list(struct wl_client *wc); @@ -139,11 +137,4 @@ EINTERN void e_keyrouter_conf_deinit(E_Keyrouter_Config_Data *kconfig); EINTERN int e_keyrouter_keygrab_set(struct wl_client *client, struct wl_resource *surface, int key, int mode); EINTERN int e_keyrouter_keygrab_unset(struct wl_client *client, struct wl_resource *surface, int key); -EINTERN Eina_Bool e_keyrouter_event_process(void *event, E_Device *dev, int type); - -EINTERN int e_keyrouter_event_data_mode_get(const E_Keyrouter_Event_Data *event_data); -EINTERN void e_keyrouter_event_data_mode_set(E_Keyrouter_Event_Data *event_data, int mode); -EINTERN Eina_Bool e_keyrouter_event_data_ignored_get(const E_Keyrouter_Event_Data *event_data); - - #endif