Add a pid in logs
[platform/core/uifw/e-mod-tizen-keyrouter.git] / src / e_mod_keyrouter_events.c
1 #define E_COMP_WL
2 #include "e_mod_main_wl.h"
3 #include <string.h>
4
5 static Eina_Bool _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev);
6 static Eina_Bool _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev);
7 static Eina_Bool _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev);
8 static void _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev);
9
10 static Eina_Bool _e_keyrouter_send_key_events_register(int type, Ecore_Event_Key *ev);
11
12 static Eina_Bool _e_keyrouter_is_key_grabbed(int key);
13 static Eina_Bool _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx);
14
15 static Eina_Bool
16 _e_keyrouter_is_key_grabbed(int key)
17 {
18    if (!krt->HardKeys[key].keycode)
19      {
20         return EINA_FALSE;
21      }
22    if (krt->HardKeys[key].excl_ptr ||
23         krt->HardKeys[key].or_excl_ptr ||
24         krt->HardKeys[key].top_ptr ||
25         krt->HardKeys[key].shared_ptr ||
26         krt->HardKeys[key].registered_ptr)
27      {
28         return EINA_TRUE;
29      }
30
31    return EINA_FALSE;
32 }
33
34 /* Function for checking the existing grab for a key and sending key event(s) */
35 Eina_Bool
36 e_keyrouter_process_key_event(void *event, int type)
37 {
38    Eina_Bool res = EINA_TRUE;
39    Ecore_Event_Key *ev = event;
40
41    if (!ev) goto finish;
42
43    KLDBG("[%s] keyname: %s, key: %s, keycode: %d\n", (type == ECORE_EVENT_KEY_DOWN) ? "KEY_PRESS" : "KEY_RELEASE", ev->keyname, ev->key, ev->keycode);
44
45    if (krt->max_tizen_hwkeys < ev->keycode)
46      {
47         KLWRN("The key(%d) is too larger to process keyrouting: Invalid keycode\n", ev->keycode);
48         goto finish;
49      }
50
51    if ((ECORE_EVENT_KEY_DOWN == type) && (!_e_keyrouter_is_key_grabbed(ev->keycode)))
52      {
53         KLDBG("The press key(%d) isn't a grabbable key or has not been grabbed yet !\n", ev->keycode);
54         goto finish;
55      }
56
57    if ((ECORE_EVENT_KEY_UP == type) && (!krt->HardKeys[ev->keycode].press_ptr))
58      {
59         KLDBG("The release key(%d) isn't a grabbable key or has not been grabbed yet !\n", ev->keycode);
60         goto finish;
61      }
62
63    //KLDBG("The key(%d) is going to be sent to the proper wl client(s) !\n", ev->keycode);
64
65   if (_e_keyrouter_send_key_events(type, ev))
66     res = EINA_FALSE;
67
68 finish:
69    return res;
70 }
71
72 /* Function for sending key events to wl_client(s) */
73 static Eina_Bool
74 _e_keyrouter_send_key_events(int type, Ecore_Event_Key *ev)
75 {
76    Eina_Bool res;
77    if (ECORE_EVENT_KEY_DOWN == type)
78      {
79         res = _e_keyrouter_send_key_events_press(type, ev);
80      }
81   else
82      {
83         res = _e_keyrouter_send_key_events_release(type, ev);
84      }
85   return res;
86 }
87
88 static Eina_Bool
89 _e_keyrouter_send_key_events_release(int type, Ecore_Event_Key *ev)
90 {
91    E_Keyrouter_Key_List_NodePtr key_node_data;
92
93    /* Deliver release  clean up pressed key list */
94    EINA_LIST_FREE(krt->HardKeys[ev->keycode].press_ptr, key_node_data)
95      {
96         if (key_node_data)
97           {
98              _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
99              KLINF("Release Pair : Key %s(%s:%d) ===> E_Client (%p) WL_Client (%p) (pid: %d)\n",
100                       ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
101                       key_node_data->surface, key_node_data->wc, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
102              E_FREE(key_node_data);
103           }
104      }
105    krt->HardKeys[ev->keycode].press_ptr = NULL;
106
107    return EINA_TRUE;
108 }
109
110 static Eina_Bool
111 _e_keyrouter_send_key_events_press(int type, Ecore_Event_Key *ev)
112 {
113    unsigned int keycode = ev->keycode;
114    struct wl_resource *surface_focus = NULL;
115    E_Client *ec_focus = NULL;
116
117    E_Keyrouter_Key_List_NodePtr key_node_data;
118    Eina_List *l = NULL;
119
120    EINA_LIST_FOREACH(krt->HardKeys[keycode].excl_ptr, l, key_node_data)
121      {
122         if (key_node_data)
123           {
124              _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
125              KLINF("EXCLUSIVE Mode : Key %s(%s:%d) ===> Surface (%p) WL_Client (%p) (pid: %d)\n",
126                       ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
127                       key_node_data->surface, key_node_data->wc, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
128
129              return EINA_TRUE;
130           }
131      }
132
133    EINA_LIST_FOREACH(krt->HardKeys[keycode].or_excl_ptr, l, key_node_data)
134      {
135         if (key_node_data)
136           {
137              _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
138              KLINF("OVERRIDABLE_EXCLUSIVE Mode : Key %s(%s:%d) ===> Surface (%p) WL_Client (%p) (pid: %d)\n",
139                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
140                      key_node_data->surface, key_node_data->wc, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
141
142              return EINA_TRUE;
143           }
144      }
145
146    ec_focus = e_client_focused_get();
147    surface_focus = e_keyrouter_util_get_surface_from_eclient(ec_focus);
148
149    // Top position grab must need a focus surface.
150    if (surface_focus)
151      {
152         EINA_LIST_FOREACH(krt->HardKeys[keycode].top_ptr, l, key_node_data)
153           {
154              if (key_node_data)
155                {
156                   if ((EINA_FALSE == krt->isWindowStackChanged) && (surface_focus == key_node_data->surface))
157                     {
158                        _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev);
159                        KLINF("TOPMOST (TOP_POSITION) Mode : Key %s (%s:%d) ===> Surface (%p) (pid: %d)\n",
160                                 ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
161                                 key_node_data->surface, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
162
163                        return EINA_TRUE;
164                     }
165                   krt->isWindowStackChanged = EINA_FALSE;
166
167                   if (_e_keyrouter_check_top_visible_window(ec_focus, keycode))
168                     {
169                        _e_keyrouter_send_key_event(type, key_node_data->surface, NULL, ev);
170                        KLINF("TOPMOST (TOP_POSITION) Mode : Key %s (%s:%d) ===> Surface (%p) (pid: %d)\n",
171                              ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
172                              key_node_data->surface, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
173
174                        return EINA_TRUE;
175                     }
176                   break;
177                }
178           }
179      }
180
181    if (krt->HardKeys[keycode].shared_ptr)
182      {
183         _e_keyrouter_send_key_event(type, surface_focus, NULL, ev);
184         KLINF("SHARED [Focus client] : Key %s (%s:%d) ===> Surface (%p) (pid: %d)\n",
185                  ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up "), ev->keyname, ev->keycode,
186                  surface_focus, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
187
188         EINA_LIST_FOREACH(krt->HardKeys[keycode].shared_ptr, l, key_node_data)
189           {
190              if (key_node_data)
191                {
192                   if (key_node_data->surface)
193                     {
194                        if (key_node_data->surface != surface_focus)
195                          {
196                             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
197                             KLINF("SHARED Mode : Key %s(%s:%d) ===> Surface (%p) WL_Client (%p) (pid: %d)\n",
198                                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
199                                      key_node_data->surface, key_node_data->wc, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
200                          }
201                     }
202                   else
203                     {
204                        if (((surface_focus) && (key_node_data->wc != wl_resource_get_client(surface_focus))) ||
205                            (!surface_focus))
206                          {
207                             _e_keyrouter_send_key_event(type, key_node_data->surface, key_node_data->wc, ev);
208                             KLINF("SHARED Mode : Key %s(%s:%d) ===> Surface (%p) WL_Client (%p) (pid: %d)\n",
209                                      ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
210                                      key_node_data->surface, key_node_data->wc, e_keyrouter_util_get_pid(key_node_data->wc, key_node_data->surface));
211                          }
212                     }
213                }
214           }
215
216         return EINA_TRUE;
217      }
218
219    if (_e_keyrouter_send_key_events_register(type, ev))
220      {
221         return EINA_TRUE;
222      }
223
224    return EINA_FALSE;
225 }
226
227 static Eina_Bool
228 _e_keyrouter_send_key_events_register(int type, Ecore_Event_Key *ev)
229 {
230    unsigned int keycode = ev->keycode;
231
232    if (!krt->HardKeys[keycode].registered_ptr)
233      {
234         KLDBG("This keycode is not registered\n");
235         return EINA_FALSE;
236      }
237
238    _e_keyrouter_send_key_event(type, krt->HardKeys[keycode].registered_ptr->surface, NULL, ev);
239    KLINF("REGISTER Mode : Key %s(%s:%d) ===> Surface (%p) (pid: %d)\n",
240             ((ECORE_EVENT_KEY_DOWN == type) ? "Down" : "Up"), ev->keyname, ev->keycode,
241             krt->HardKeys[keycode].registered_ptr->surface, e_keyrouter_util_get_pid(NULL, krt->HardKeys[keycode].registered_ptr->surface));
242
243    return EINA_TRUE;
244 }
245
246 static Eina_Bool
247 _e_keyrouter_check_top_visible_window(E_Client *ec_focus, int arr_idx)
248 {
249    E_Client *ec_top = NULL;
250    Eina_List *l = NULL, *l_next = NULL;
251    E_Keyrouter_Key_List_NodePtr key_node_data = NULL;
252
253    ec_top = e_client_top_get();
254
255    while (ec_top)
256      {
257         if (!ec_top->visible && ec_top == ec_focus)
258           {
259              KLDBG("Top Client(%p) is invisible(%d) but focus client\n", ec_top, ec_top->visible);
260              return EINA_FALSE;
261           }
262
263         /* TODO: Check this client is located inside a display boundary */
264
265         EINA_LIST_FOREACH_SAFE(krt->HardKeys[arr_idx].top_ptr, l, l_next, key_node_data)
266           {
267              if (key_node_data)
268                {
269                   if (ec_top == wl_resource_get_user_data(key_node_data->surface))
270                     {
271                        krt->HardKeys[arr_idx].top_ptr = eina_list_promote_list(krt->HardKeys[arr_idx].top_ptr, l);
272                        KLDBG("Move a client(%p) to first index of list(key: %d)\n",
273                                 ec_top, arr_idx);
274                        return EINA_TRUE;
275                     }
276                }
277           }
278
279         if (ec_top == ec_focus)
280           {
281              KLDBG("The Client(%p) is a focus client\n", ec_top);
282              return EINA_FALSE;
283           }
284
285         ec_top = e_client_below_get(ec_top);
286      }
287    return EINA_FALSE;
288 }
289
290 static void
291 _e_keyrouter_send_event_device(struct wl_client *wc, uint32_t timestamp, const char *dev_name, uint32_t serial)
292 {
293    const char *last_dev_name;
294    E_Comp_Wl_Input_Device *input_dev;
295    struct wl_resource *dev_res;
296    Eina_List *l, *ll;
297
298    last_dev_name = e_comp_wl->input_device_manager.last_device_name;
299    if (!last_dev_name || (last_dev_name && (strcmp(last_dev_name, dev_name))))
300      {
301         if (last_dev_name)
302           eina_stringshare_del(last_dev_name);
303         last_dev_name = eina_stringshare_add(dev_name);
304         e_comp_wl->input_device_manager.last_device_name = last_dev_name;
305
306         EINA_LIST_FOREACH(e_comp_wl->input_device_manager.device_list, l, input_dev)
307           {
308              if ((strcmp(input_dev->identifier, dev_name)) ||
309                  (input_dev->capability != ECORE_DEVICE_KEYBOARD))
310                continue;
311              e_comp_wl->input_device_manager.last_device_cap = input_dev->capability;
312              EINA_LIST_FOREACH(input_dev->resources, ll, dev_res)
313                {
314                   if (wl_resource_get_client(dev_res) != wc) continue;
315                   tizen_input_device_send_event_device(dev_res, serial, input_dev->identifier, timestamp);
316                }
317           }
318      }
319 }
320
321 /* Function for sending key event to wl_client(s) */
322 static void
323 _e_keyrouter_send_key_event(int type, struct wl_resource *surface, struct wl_client *wc, Ecore_Event_Key *ev)
324 {
325    struct wl_client *wc_send;
326    struct wl_resource *res;
327    const char *dev_name;
328
329    uint evtype;
330    uint serial;
331    Eina_List *l;
332
333    if (surface == NULL)
334      {
335         wc_send = wc;
336      }
337    else
338      {
339         wc_send = wl_resource_get_client(surface);
340      }
341
342    if (!wc_send)
343      {
344         KLWRN("surface: %p or wc: %p returns null wayland client\n", surface, wc);
345         return;
346      }
347
348    if (ECORE_EVENT_KEY_DOWN == type)
349      {
350         e_keyrouter_prepend_to_keylist(surface, wc, ev->keycode, TIZEN_KEYROUTER_MODE_PRESSED);
351         evtype = WL_KEYBOARD_KEY_STATE_PRESSED;
352      }
353    else
354      {
355         evtype = WL_KEYBOARD_KEY_STATE_RELEASED;
356      }
357
358    serial = wl_display_next_serial(e_comp_wl->wl.disp);
359    EINA_LIST_FOREACH(e_comp_wl->kbd.resources, l, res)
360      {
361         if (res)
362           {
363              if (wl_resource_get_client(res) != wc_send) continue;
364
365              if (ev->dev)
366                {
367                   dev_name = ecore_device_identifier_get(ev->dev);
368                   if (dev_name)
369                     _e_keyrouter_send_event_device(wc_send, ev->timestamp, dev_name, serial);
370                }
371              KLDBG("[time: %d] res: %p, serial: %d send a key(%d):%d to wl_client:%p\n", ev->timestamp, res, serial, (ev->keycode)-8, evtype, wc_send);
372              TRACE_INPUT_BEGIN(_e_keyrouter_send_key_event);
373              wl_keyboard_send_key(res, serial, ev->timestamp, ev->keycode-8, evtype);
374              TRACE_INPUT_END();
375           }
376      }
377 }
378
379 struct wl_resource *
380 e_keyrouter_util_get_surface_from_eclient(E_Client *client)
381 {
382    EINA_SAFETY_ON_NULL_RETURN_VAL
383      (client, NULL);
384    EINA_SAFETY_ON_NULL_RETURN_VAL
385      (client->comp_data, NULL);
386
387    return client->comp_data->wl_surface;
388 }
389
390 int
391 e_keyrouter_util_get_pid(struct wl_client *client, struct wl_resource *surface)
392 {
393    pid_t pid = 0;
394    uid_t uid = 0;
395    gid_t gid = 0;
396    struct wl_client *cur_client = NULL;
397
398    if (client) cur_client = client;
399    else cur_client = wl_resource_get_client(surface);
400    EINA_SAFETY_ON_NULL_RETURN_VAL(cur_client, 0);
401
402    wl_client_get_credentials(cur_client, &pid, &uid, &gid);
403
404    return pid;
405 }