851073aa5e2b70b26225492bc3b8b4b60b52753b
[platform/core/uifw/pepper.git] / src / lib / keyrouter / pepper-keyrouter.c
1 /*
2 * Copyright © 2015-2017 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 "pepper-keyrouter.h"
25 #include "pepper-internal.h"
26 #include <tizen-extension-server-protocol.h>
27 #include <pepper-utils.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <errno.h>
31
32 #define MIN(a,b) ((a)<(b)?(a):(b))
33
34 typedef struct key_options key_options_t;
35 typedef struct resources_data resources_data_t;
36 typedef struct clients_data clients_data_t;
37 typedef struct grab_list_data grab_list_data_t;
38 typedef struct ungrab_list_data ungrab_list_data_t;
39
40 struct pepper_keyrouter {
41         struct wl_global *global;
42         struct wl_display *display;
43         pepper_compositor_t *compositor;
44         pepper_seat_t *seat;
45         pepper_keyboard_t *keyboard;
46
47         pepper_list_t resources;
48         pepper_list_t grabbed_clients;
49
50         keyrouter_t *keyrouter;
51
52         pepper_view_t *focus_view;
53         pepper_view_t *top_view;
54         pepper_bool_t pepper_security_init_done;
55         key_options_t *opts;
56 };
57
58 struct key_options {
59         pepper_bool_t enabled;
60         pepper_bool_t no_privilege;
61 };
62
63 struct resources_data {
64         struct wl_resource *resource;
65         pepper_list_t link;
66 };
67
68 struct clients_data {
69         struct wl_client *client;
70         pepper_list_t link;
71 };
72
73 struct grab_list_data {
74         int key;
75         int mode;
76         int err;
77 };
78
79 struct ungrab_list_data {
80         int key;
81         int err;
82 };
83
84 static pepper_bool_t
85 _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter_t *pepper_keyrouter, struct wl_client *client, uint32_t mode, uint32_t keycode)
86 {
87         clients_data_t *cdata;
88
89         pid_t pid = 0;
90         uid_t uid = 0;
91         gid_t gid = 0;
92
93         /* Top position grab is always allowed. This mode do not need privilege.*/
94         if (mode == TIZEN_KEYROUTER_MODE_TOPMOST) return PEPPER_TRUE;
95         if (!client) return PEPPER_FALSE;
96
97         if (pepper_keyrouter->opts) {
98                 if (pepper_keyrouter->opts[keycode].no_privilege)
99                         return PEPPER_TRUE;
100         }
101
102         pepper_list_for_each(cdata, &pepper_keyrouter->grabbed_clients, link)   {
103                 if (cdata->client == client) return PEPPER_TRUE;
104         }
105
106         wl_client_get_credentials(client, &pid, &uid, &gid);
107
108         return pepper_security_privilege_check(pid, uid, "http://tizen.org/privilege/keygrab");
109 }
110
111 static struct wl_client *
112 _pepper_keyrouter_get_client_from_view(pepper_view_t *view)
113 {
114         pepper_surface_t *surface = pepper_view_get_surface(view);
115         PEPPER_CHECK(surface, return NULL, "No surfce available for the given view.\n");
116
117         struct wl_resource *resource = pepper_surface_get_resource(surface);
118
119         if (resource)
120                 return wl_resource_get_client(resource);
121
122         return NULL;
123 }
124
125 static int
126 _pepper_keyrouter_get_pid(struct wl_client *client)
127 {
128         pid_t pid = 0;
129         uid_t uid = 0;
130         gid_t gid = 0;
131
132         wl_client_get_credentials(client, &pid, &uid, &gid);
133
134         return pid;
135 }
136
137 PEPPER_API void
138 pepper_keyrouter_set_seat(pepper_keyrouter_t *pepper_keyrouter, pepper_seat_t *seat)
139 {
140         PEPPER_CHECK(pepper_keyrouter, return, "Invalid pepper_keyrouter_t\n");
141         pepper_keyrouter->seat = seat;
142 }
143
144 PEPPER_API void
145 pepper_keyrouter_set_keyboard(pepper_keyrouter_t * pepper_keyrouter, pepper_keyboard_t *keyboard)
146 {
147         PEPPER_CHECK(pepper_keyrouter, return, "Invalid pepper_keyrouter_t\n");
148         pepper_keyrouter->keyboard = keyboard;
149 }
150
151 PEPPER_API void
152 pepper_keyrouter_set_focus_view(pepper_keyrouter_t *pk, pepper_view_t *focus_view)
153 {
154         struct wl_client *client = NULL;
155         PEPPER_CHECK(pk, return, "pepper keyrouter is invalid.\n");
156         PEPPER_CHECK(pk->keyboard, return, "No keyboard is available for pepper keyrouter.\n");
157
158         pk->focus_view = focus_view;
159
160         if (focus_view)
161                 client = _pepper_keyrouter_get_client_from_view(focus_view);
162
163         keyrouter_set_focus_client(pk->keyrouter, client);
164 }
165
166 PEPPER_API void
167 pepper_keyrouter_set_top_view(pepper_keyrouter_t *pk, pepper_view_t *top_view)
168 {
169         struct wl_client *client = NULL;
170         PEPPER_CHECK(pk, return, "pepper keyrouter is invalid.\n");
171
172         pk->top_view = top_view;
173
174         if (top_view)
175                 client = _pepper_keyrouter_get_client_from_view(top_view);
176
177         keyrouter_set_top_client(pk->keyrouter, client);
178 }
179
180 PEPPER_API void
181 pepper_keyrouter_debug_keygrab_status_print(pepper_keyrouter_t *pepper_keyrouter)
182 {
183         pepper_list_t *list;
184         int i;
185         keyrouter_key_info_t *grab_data;
186
187         PEPPER_CHECK(pepper_keyrouter, return, "pepper_keyrouter is invalid.\n");
188         PEPPER_CHECK(pepper_keyrouter->keyrouter, return, "keyrouter is invalid.\n");
189
190         for (i = 0; i < KEYROUTER_MAX_KEYS; i++) {
191                 if (keyrouter_is_grabbed_key(pepper_keyrouter->keyrouter, i)) {
192                         PEPPER_TRACE("\t[ Keycode: %d ]\n", i);
193                         list = keyrouter_grabbed_list_get(pepper_keyrouter->keyrouter, TIZEN_KEYROUTER_MODE_EXCLUSIVE, i);
194                         if (list && !pepper_list_empty(list)) {
195                                 PEPPER_TRACE("\t  == Exclusive Grab ==\n");
196                                 pepper_list_for_each(grab_data, list, link) {
197                                         PEPPER_TRACE("\t    client: %p (pid: %d)\n", grab_data->data, _pepper_keyrouter_get_pid(grab_data->data));
198                                 }
199                         }
200
201                         list = keyrouter_grabbed_list_get(pepper_keyrouter->keyrouter, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, i);
202                         if (list && !pepper_list_empty(list)) {
203                                 PEPPER_TRACE("\t  == OR_Exclusive Grab ==\n");
204                                 pepper_list_for_each(grab_data, list, link) {
205                                         PEPPER_TRACE("\t    client: %p (pid: %d)\n", grab_data->data, _pepper_keyrouter_get_pid(grab_data->data));
206                                 }
207                         }
208
209                         list = keyrouter_grabbed_list_get(pepper_keyrouter->keyrouter, TIZEN_KEYROUTER_MODE_TOPMOST, i);
210                         if (list && !pepper_list_empty(list)) {
211                                 PEPPER_TRACE("\t  == Top Position Grab ==\n");
212                                 pepper_list_for_each(grab_data, list, link) {
213                                         PEPPER_TRACE("\t    client: %p (pid: %d)\n", grab_data->data, _pepper_keyrouter_get_pid(grab_data->data));
214                                 }
215                         }
216
217                         list = keyrouter_grabbed_list_get(pepper_keyrouter->keyrouter, TIZEN_KEYROUTER_MODE_SHARED, i);
218                         if (list && !pepper_list_empty(list)) {
219                                 PEPPER_TRACE("\t  == Shared Grab ==\n");
220                                 pepper_list_for_each(grab_data, list, link) {
221                                         PEPPER_TRACE("\t    client: %p (pid: %d)\n", grab_data->data, _pepper_keyrouter_get_pid(grab_data->data));
222                                 }
223                         }
224                 }
225         }
226 }
227
228 static void
229 _pepper_keyrouter_key_send(pepper_keyrouter_t *pepper_keyrouter,
230                               pepper_seat_t *seat, struct wl_client *client,
231                               unsigned int key, unsigned int state,
232                               unsigned int time)
233 {
234         struct wl_resource *resource;
235         pepper_keyboard_t *keyboard_info;
236
237         keyboard_info = pepper_seat_get_keyboard(seat);
238         PEPPER_CHECK(keyboard_info, return, "Current seat has no keyboard\n");
239
240         wl_resource_for_each(resource, pepper_keyboard_get_resource_list(keyboard_info)) {
241                 if (wl_resource_get_client(resource) == client)
242                 {
243                         wl_keyboard_send_key(resource, wl_display_get_serial(pepper_keyrouter->display), time, key, state);
244                         PEPPER_TRACE("[%s] key : %d, state : %d, time : %lu\n", __FUNCTION__, key, state, time);
245                 }
246         }
247 }
248
249 PEPPER_API void
250 pepper_keyrouter_key_process(pepper_keyrouter_t *pepper_keyrouter,
251                                 unsigned int key, unsigned int state, unsigned int time)
252 {
253         pepper_list_t delivery_list;
254         pepper_list_t *seat_list;
255         keyrouter_key_info_t *info;
256         int count = 0;
257         pepper_seat_t *seat;
258
259         pepper_list_init(&delivery_list);
260
261         /* Keygrab list is maintained by keycode + 8 which is used in xkb system */
262         count = keyrouter_key_process(pepper_keyrouter->keyrouter, key + 8, state, &delivery_list);
263
264         if (count > 0) {
265                 pepper_list_for_each(info, &delivery_list, link) {
266                         if (pepper_keyrouter->seat && pepper_object_get_type((pepper_object_t *)pepper_keyrouter->seat) == PEPPER_OBJECT_SEAT) {
267                                 _pepper_keyrouter_key_send(pepper_keyrouter, pepper_keyrouter->seat, (struct wl_client *)info->data, key, state, time);
268                         }
269                         else if (pepper_keyrouter->keyboard && pepper_object_get_type((pepper_object_t *)pepper_keyrouter->keyboard) == PEPPER_OBJECT_KEYBOARD) {
270                                 _pepper_keyrouter_key_send(pepper_keyrouter, pepper_keyboard_get_seat(pepper_keyrouter->keyboard), (struct wl_client *)info->data, key, state, time);
271                         }
272                         else {
273                                 seat_list = (pepper_list_t *)pepper_compositor_get_seat_list(pepper_keyrouter->compositor);
274                                 if (!pepper_list_empty(seat_list)) {
275                                         pepper_list_for_each(seat, seat_list, link) {
276                                                 _pepper_keyrouter_key_send(pepper_keyrouter, seat, (struct wl_client *)info->data, key, state, time);
277                                         }
278                                 }
279                         }
280                 }
281         }
282         else {
283                 /* send key event to focus view if any */
284                 if (pepper_keyrouter->focus_view)
285                         pepper_keyboard_send_key(pepper_keyrouter->keyboard, pepper_keyrouter->focus_view, time, key, state);
286                 else
287                         PEPPER_TRACE("No focused view exists.\n", __FUNCTION__);
288         }
289 }
290
291 static void
292 _pepper_keyrouter_remove_client_from_list(pepper_keyrouter_t *pepper_keyrouter, struct wl_client *client)
293 {
294         int i;
295         for (i = 0; i < KEYROUTER_MAX_KEYS; i++) {
296                 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
297                                    TIZEN_KEYROUTER_MODE_EXCLUSIVE,
298                                    i, (void *)client);
299                 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
300                                    TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE,
301                                    i, (void *)client);
302                 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
303                                    TIZEN_KEYROUTER_MODE_TOPMOST,
304                                    i, (void *)client);
305                 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
306                                    TIZEN_KEYROUTER_MODE_SHARED,
307                                    i, (void *)client);
308         }
309 }
310
311 static int
312 _pepper_keyrouter_add_client_to_list(pepper_keyrouter_t *pepper_keyrouter, struct wl_client *client)
313 {
314         clients_data_t *cdata;
315
316         pepper_list_for_each(cdata, &pepper_keyrouter->grabbed_clients, link) {
317                 if (cdata->client == client) return TIZEN_KEYROUTER_ERROR_NONE;
318         }
319
320         cdata = (clients_data_t *)calloc(1, sizeof(clients_data_t));
321         if (!cdata)
322         {
323                 PEPPER_ERROR("Failed to allocate memory !\n");
324                 return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
325         }
326
327         cdata->client = client;
328         pepper_list_init(&cdata->link);
329         pepper_list_insert(&pepper_keyrouter->grabbed_clients, &cdata->link);
330
331         return TIZEN_KEYROUTER_ERROR_NONE;
332 }
333
334 static void
335 _pepper_keyrouter_cb_keygrab_set(struct wl_client *client,
336                                          struct wl_resource *resource,
337                                          struct wl_resource *surface,
338                                          uint32_t key,
339                                          uint32_t mode)
340 {
341         int res = TIZEN_KEYROUTER_ERROR_NONE;
342         pepper_keyrouter_t *pepper_keyrouter = NULL;
343         pepper_bool_t ret;
344
345         pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
346         PEPPER_CHECK(pepper_keyrouter, goto notify, "Invalid pepper_keyrouter_t\n");
347
348         ret = _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter, client, mode, key);
349         if (!ret) {
350                 res = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
351                 goto notify;
352         }
353
354         res = keyrouter_grab_key(pepper_keyrouter->keyrouter, mode, key, (void *)client);
355
356         if (res == TIZEN_KEYROUTER_ERROR_NONE)
357                 res = _pepper_keyrouter_add_client_to_list(pepper_keyrouter, client);
358
359 notify:
360         tizen_keyrouter_send_keygrab_notify(resource, surface, key, mode, res);
361 }
362
363 static void
364 _pepper_keyrouter_cb_keygrab_unset(struct wl_client *client,
365                                            struct wl_resource *resource,
366                                            struct wl_resource *surface,
367                                            uint32_t key)
368 {
369         int res = TIZEN_KEYROUTER_ERROR_NONE;
370         pepper_keyrouter_t *pepper_keyrouter = NULL;
371         pepper_bool_t ret;
372
373         pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
374         PEPPER_CHECK(pepper_keyrouter, goto notify, "Invalid pepper_keyrouter_t\n");
375
376         /* ungrab TOP POSITION grab first, this grab mode is not check privilege */
377         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
378                                    TIZEN_KEYROUTER_MODE_TOPMOST,
379                                    key, (void *)client);
380
381         ret = _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter, client, TIZEN_KEYROUTER_MODE_NONE, key);
382         if (!ret) {
383                 res = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
384                 goto notify;
385         }
386
387         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
388                                    TIZEN_KEYROUTER_MODE_EXCLUSIVE,
389                                    key, (void *)client);
390         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
391                                    TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE,
392                                    key, (void *)client);
393         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
394                                    TIZEN_KEYROUTER_MODE_TOPMOST,
395                                    key, (void *)client);
396         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
397                                    TIZEN_KEYROUTER_MODE_SHARED,
398                                    key, (void *)client);
399
400 notify:
401         tizen_keyrouter_send_keygrab_notify(resource, surface, key, TIZEN_KEYROUTER_MODE_NONE, res);
402 }
403
404 static void
405 _pepper_keyrouter_cb_get_keygrab_status(struct wl_client *client,
406                                                 struct wl_resource *resource,
407                                                 struct wl_resource *surface,
408                                                 uint32_t key)
409 {
410         tizen_keyrouter_send_keygrab_notify(resource, surface, key, TIZEN_KEYROUTER_MODE_NONE, TIZEN_KEYROUTER_ERROR_NO_PERMISSION);
411 }
412
413 static int
414 _pepper_keyrouter_array_length(const struct wl_array *array)
415 {
416         int *data = NULL;
417         int count = 0;
418
419         wl_array_for_each(data, array) {
420                 count++;
421         }
422
423         return count;
424 }
425
426 static void
427 _pepper_keyrouter_cb_keygrab_set_list(struct wl_client *client,
428                                               struct wl_resource *resource,
429                                               struct wl_resource *surface,
430                                               struct wl_array *grab_list)
431 {
432         struct wl_array *return_list = NULL;
433         grab_list_data_t *grab_data = NULL;
434         int res = TIZEN_KEYROUTER_ERROR_NONE;
435         pepper_keyrouter_t *pepper_keyrouter = NULL;
436         pepper_bool_t ret;
437
438         pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
439
440         PEPPER_CHECK(pepper_keyrouter, goto notify, "Invalid pepper_keyrouter_t\n");
441         PEPPER_CHECK(grab_list, goto notify, "Please send valid grab_list\n");
442         PEPPER_CHECK(((_pepper_keyrouter_array_length(grab_list) %3) == 0), goto notify,
443                      "Invalid keycode and grab mode pair. Check arguments in a list\n");
444
445         wl_array_for_each(grab_data, grab_list) {
446                 ret = _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter, client, grab_data->mode, grab_data->key);
447                 if (!ret) {
448                         grab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
449                 } else {
450                         res = keyrouter_grab_key(pepper_keyrouter->keyrouter, grab_data->mode, grab_data->key, (void *)client);
451                         grab_data->err = res;
452                         if (res == TIZEN_KEYROUTER_ERROR_NONE)
453                                 _pepper_keyrouter_add_client_to_list(pepper_keyrouter, client);
454                 }
455         }
456
457         return_list = grab_list;
458 notify:
459         tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list);
460 }
461
462 static void
463 _pepper_keyrouter_cb_keygrab_unset_list(struct wl_client *client,
464                                                 struct wl_resource *resource,
465                                                 struct wl_resource *surface,
466                                                 struct wl_array *ungrab_list)
467 {
468         struct wl_array *return_list = NULL;
469         ungrab_list_data_t *ungrab_data = NULL;
470         pepper_keyrouter_t *pepper_keyrouter = NULL;
471         pepper_bool_t ret;
472
473         pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
474
475         PEPPER_CHECK(pepper_keyrouter, goto notify, "Invalid pepper_keyrouter_t\n");
476         PEPPER_CHECK(((_pepper_keyrouter_array_length(ungrab_list) %3) == 0), goto notify,
477                      "Invalid keycode and grab mode pair. Check arguments in a list\n");
478
479         wl_array_for_each(ungrab_data, ungrab_list) {
480                 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
481                                             TIZEN_KEYROUTER_MODE_TOPMOST,
482                                             ungrab_data->key, (void *)client);
483
484                 ret = _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter, client, TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key);
485                 if (!ret) {
486                         ungrab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
487                 } else {
488                         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
489                                                     TIZEN_KEYROUTER_MODE_EXCLUSIVE,
490                                                     ungrab_data->key, (void *)client);
491
492                         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
493                                                     TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE,
494                                                     ungrab_data->key, (void *)client);
495
496                         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
497                                                     TIZEN_KEYROUTER_MODE_TOPMOST,
498                                                     ungrab_data->key, (void *)client);
499
500                         keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
501                                                     TIZEN_KEYROUTER_MODE_SHARED,
502                                                     ungrab_data->key, (void *)client);
503
504                         ungrab_data->err = TIZEN_KEYROUTER_ERROR_NONE;
505                 }
506         }
507
508         return_list = ungrab_list;
509 notify:
510         tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list);
511 }
512
513 static void
514 _pepper_keyrouter_cb_get_keygrab_list(struct wl_client *client,
515                                               struct wl_resource *resource,
516                                               struct wl_resource *surface)
517 {
518         tizen_keyrouter_send_getgrab_notify_list(resource, surface, NULL);
519 }
520
521 static void
522 _pepper_keyrouter_cb_set_register_none_key(struct wl_client *client,
523                                                    struct wl_resource *resource,
524                                                    struct wl_resource *surface,
525                                                    uint32_t data)
526 {
527         tizen_keyrouter_send_set_register_none_key_notify(resource, NULL, 0);
528 }
529
530 static void
531 _pepper_keyrouter_cb_get_keyregister_status(struct wl_client *client,
532                                                     struct wl_resource *resource,
533                                                     uint32_t key)
534 {
535         tizen_keyrouter_send_keyregister_notify(resource, (int)PEPPER_FALSE);
536 }
537
538 static void
539 _pepper_keyrouter_cb_set_input_config(struct wl_client *client,
540                                               struct wl_resource *resource,
541                                               struct wl_resource *surface,
542                                               uint32_t config_mode,
543                                               uint32_t value)
544 {
545         tizen_keyrouter_send_set_input_config_notify(resource, (int)PEPPER_FALSE);
546 }
547
548 static void
549 _pepper_keyrouter_cb_destory(struct wl_client *client,
550                                                         struct wl_resource *resource)
551 {
552         wl_resource_destroy(resource);
553 }
554
555 static const struct tizen_keyrouter_interface _pepper_keyrouter_implementation = {
556    _pepper_keyrouter_cb_keygrab_set,
557    _pepper_keyrouter_cb_keygrab_unset,
558    _pepper_keyrouter_cb_get_keygrab_status,
559    _pepper_keyrouter_cb_keygrab_set_list,
560    _pepper_keyrouter_cb_keygrab_unset_list,
561    _pepper_keyrouter_cb_get_keygrab_list,
562    _pepper_keyrouter_cb_set_register_none_key,
563    _pepper_keyrouter_cb_get_keyregister_status,
564    _pepper_keyrouter_cb_set_input_config,
565    _pepper_keyrouter_cb_destory
566 };
567
568 /* tizen_keyrouter global object destroy function */
569 static void
570 _pepper_keyrouter_cb_resource_destory(struct wl_resource *resource)
571 {
572         resources_data_t *rdata, *rtmp;
573         clients_data_t *cdata, *ctmp;
574         pepper_list_t *list;
575         struct wl_client *client;
576         pepper_keyrouter_t *pepper_keyrouter;
577
578         PEPPER_CHECK(resource, return, "Invalid keyrouter resource\n");
579         client = wl_resource_get_client(resource);
580         PEPPER_CHECK(client, return, "Invalid client\n");
581         pepper_keyrouter = wl_resource_get_user_data(resource);
582         PEPPER_CHECK(pepper_keyrouter, return, "Invalid pepper_keyrouter_t\n");
583
584         list = &pepper_keyrouter->grabbed_clients;
585         if (!pepper_list_empty(list)) {
586                 pepper_list_for_each_safe(cdata, ctmp, list, link) {
587                         if (cdata->client == client) {
588                                 _pepper_keyrouter_remove_client_from_list(pepper_keyrouter, client);
589                                 pepper_list_remove(&cdata->link);
590                                 free(cdata);
591                         }
592                 }
593         }
594
595         list = &pepper_keyrouter->resources;
596
597         if (pepper_list_empty(list))
598                 return;
599
600         pepper_list_for_each_safe(rdata, rtmp, list, link) {
601                 if (rdata->resource== resource) {
602                         pepper_list_remove(&rdata->link);
603                         free(rdata);
604                 }
605         }
606 }
607
608 /* tizen_keyrouter global object bind function */
609 static void
610 _pepper_keyrouter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
611 {
612         struct wl_resource *resource;
613         resources_data_t *rdata;
614         pepper_keyrouter_t *pepper_keyrouter;
615
616         pepper_keyrouter = (pepper_keyrouter_t *)data;
617         PEPPER_CHECK(client, return, "Invalid client\n");
618         PEPPER_CHECK(pepper_keyrouter, return, "Invalid pepper_keyrouter_t\n");
619
620         resource = wl_resource_create(client, &tizen_keyrouter_interface, MIN(version, 2), id);
621         if (!resource) {
622                 PEPPER_ERROR("Failed to create resource ! (version :%d, id:%d)", version, id);
623                 wl_client_post_no_memory(client);
624                 return;
625         }
626
627         rdata = (resources_data_t *)calloc(1, sizeof(resources_data_t));
628         if (!rdata)
629         {
630                 PEPPER_ERROR("Failed to allocate memory !\n");
631
632                 wl_resource_destroy(resource);
633                 wl_client_post_no_memory(client);
634                 return;
635         }
636
637         rdata->resource = resource;
638         pepper_list_init(&rdata->link);
639         pepper_list_insert(&pepper_keyrouter->resources, &rdata->link);
640
641
642         wl_resource_set_implementation(resource, &_pepper_keyrouter_implementation,
643                                        pepper_keyrouter, _pepper_keyrouter_cb_resource_destory);
644 }
645
646 PEPPER_API void
647 pepper_keyrouter_event_handler(pepper_event_listener_t *listener,
648                                pepper_object_t *object,
649                                uint32_t id, void *info, void *data)
650 {
651         pepper_input_event_t *event;
652         pepper_keyrouter_t *pepper_keyrouter;
653         pepper_keyboard_t *keyboard = (pepper_keyboard_t *)object;
654
655         PEPPER_CHECK((id == PEPPER_EVENT_KEYBOARD_KEY),
656                      return, "%d event is not handled by keyrouter\n", id);
657         PEPPER_CHECK(info, return, "Invalid event\n");
658         PEPPER_CHECK(data, return, "Invalid data. Please insert pepper_keyrouter\n");
659
660         event = (pepper_input_event_t *)info;
661         pepper_keyrouter = (pepper_keyrouter_t *)data;
662         if (!pepper_keyrouter->keyboard)
663                 pepper_keyrouter_set_keyboard(pepper_keyrouter, keyboard);
664         pepper_keyrouter_key_process(pepper_keyrouter, event->key, event->state, event->time);
665 }
666
667 static void
668 _pepper_keyrouter_options_set(pepper_keyrouter_t *pepper_keyrouter)
669 {
670         FILE *file;
671         int keycode;
672         char *ret, *tmp, *buf_ptr, buf[1024] = {0,};
673
674         pepper_keyrouter->opts = (key_options_t *)calloc(KEYROUTER_MAX_KEYS, sizeof(key_options_t));
675         PEPPER_CHECK(pepper_keyrouter->opts, return, "Failed to alloc memory for options\n") ;
676
677         file = fopen(KEYLAYOUT_DIR, "r");
678         PEPPER_CHECK(file, goto finish, "Failed to open key layout file(%s): (errno: %s)\n", KEYLAYOUT_DIR, strerror(errno));
679
680         while (!feof(file)) {
681                 ret = fgets(buf, 1024, file);
682                 if (!ret) continue;
683
684                 tmp = strtok_r(buf, " ", &buf_ptr);
685                 tmp = strtok_r(NULL, " ", &buf_ptr);
686                 if (!tmp) continue;
687                 keycode = atoi(tmp);
688                 if ((0 >= keycode) || (keycode >= KEYROUTER_MAX_KEYS)) {
689                         PEPPER_ERROR("Currently %d key is invalid to support\n", keycode);
690                         continue;
691                 }
692
693                 pepper_keyrouter->opts[keycode].enabled = PEPPER_TRUE;
694
695                 if (strstr(buf_ptr, "no_priv") != NULL) {
696                         pepper_keyrouter->opts[keycode].no_privilege = PEPPER_TRUE;
697                 }
698     }
699     fclose(file);
700
701     return;
702
703 finish:
704         free(pepper_keyrouter->opts);
705         pepper_keyrouter->opts = NULL;
706 }
707
708 PEPPER_API pepper_keyrouter_t *
709 pepper_keyrouter_create(pepper_compositor_t *compositor)
710 {
711         struct wl_display *display = NULL;
712         struct wl_global *global = NULL;
713         pepper_keyrouter_t *pepper_keyrouter;
714         pepper_bool_t ret;
715
716         PEPPER_CHECK(compositor, return PEPPER_FALSE, "Invalid compositor\n");
717
718         display = pepper_compositor_get_display(compositor);
719         PEPPER_CHECK(display, return PEPPER_FALSE, "Failed to get wl_display from compositor\n");
720
721         pepper_keyrouter = (pepper_keyrouter_t *)calloc(1, sizeof(pepper_keyrouter_t));
722         PEPPER_CHECK(pepper_keyrouter, return PEPPER_FALSE, "Failed to allocate memory for keyrouter\n");
723         pepper_keyrouter->display = display;
724         pepper_keyrouter->compositor = compositor;
725
726         _pepper_keyrouter_options_set(pepper_keyrouter);
727
728         pepper_list_init(&pepper_keyrouter->resources);
729         pepper_list_init(&pepper_keyrouter->grabbed_clients);
730
731         global = wl_global_create(display, &tizen_keyrouter_interface, 2, pepper_keyrouter, _pepper_keyrouter_cb_bind);
732         PEPPER_CHECK(global, goto failed, "Failed to create wl_global for tizen_keyrouter\n");
733
734         pepper_keyrouter->global = global;
735
736         pepper_keyrouter->keyrouter = keyrouter_create();
737         PEPPER_CHECK(pepper_keyrouter->keyrouter, goto failed, "Failed to create keyrouter\n");
738
739         pepper_keyrouter->pepper_security_init_done = ret = pepper_security_init();
740                 if (!ret) PEPPER_TRACE("pepper_security_init() is failed. Keyrouter will work without pepper_security.\n");
741
742         return pepper_keyrouter;
743
744 failed:
745         if (pepper_keyrouter) {
746                 if (pepper_keyrouter->opts) {
747                         free(pepper_keyrouter->opts);
748                         pepper_keyrouter->opts = NULL;
749                 }
750
751                 if (pepper_keyrouter->keyrouter) {
752                         keyrouter_destroy(pepper_keyrouter->keyrouter);
753                         pepper_keyrouter->keyrouter = NULL;
754                 }
755                 free(pepper_keyrouter);
756         }
757
758         return NULL;
759 }
760
761 PEPPER_API void
762 pepper_keyrouter_destroy(pepper_keyrouter_t *pepper_keyrouter)
763 {
764         resources_data_t *rdata, *rtmp;
765         clients_data_t *cdata, *ctmp;
766
767         PEPPER_CHECK(pepper_keyrouter, return, "Pepper keyrouter is not initialized\n");
768
769         pepper_list_for_each_safe(cdata, ctmp, &pepper_keyrouter->grabbed_clients, link) {
770                 pepper_list_remove(&cdata->link);
771                 free(cdata);
772         }
773
774         pepper_list_for_each_safe(rdata, rtmp, &pepper_keyrouter->resources, link) {
775                 wl_resource_destroy(rdata->resource);
776         }
777
778         if (pepper_keyrouter->opts) {
779                 free(pepper_keyrouter->opts);
780                 pepper_keyrouter->opts = NULL;
781         }
782
783         if (pepper_keyrouter->keyrouter) {
784                 keyrouter_destroy(pepper_keyrouter->keyrouter);
785                 pepper_keyrouter->keyrouter = NULL;
786         }
787
788         if (pepper_keyrouter->global)
789                 wl_global_destroy(pepper_keyrouter->global);
790
791         if (pepper_keyrouter->pepper_security_init_done)
792                 pepper_security_deinit();
793         pepper_keyrouter->pepper_security_init_done = PEPPER_FALSE;
794
795         free(pepper_keyrouter);
796         pepper_keyrouter = NULL;
797 }