2 * Copyright © 2015-2017 Samsung Electronics co., Ltd. All Rights Reserved.
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:
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
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.
24 #include "pepper-keyrouter.h"
25 #include "pepper-internal.h"
26 #include <tizen-extension-server-protocol.h>
27 #include <pepper-utils.h>
32 #define MIN(a,b) ((a)<(b)?(a):(b))
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;
40 struct pepper_keyrouter {
41 struct wl_global *global;
42 struct wl_display *display;
43 pepper_compositor_t *compositor;
45 pepper_keyboard_t *keyboard;
47 pepper_list_t resources;
48 pepper_list_t grabbed_clients;
50 keyrouter_t *keyrouter;
52 pepper_view_t *focus_view;
53 pepper_view_t *top_view;
54 pepper_bool_t pepper_security_init_done;
59 pepper_bool_t enabled;
60 pepper_bool_t no_privilege;
63 struct resources_data {
64 struct wl_resource *resource;
69 struct wl_client *client;
73 struct grab_list_data {
79 struct ungrab_list_data {
85 _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter_t *pepper_keyrouter, struct wl_client *client, uint32_t mode, uint32_t keycode)
87 clients_data_t *cdata;
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;
97 if (pepper_keyrouter->opts) {
98 if (pepper_keyrouter->opts[keycode].no_privilege)
102 pepper_list_for_each(cdata, &pepper_keyrouter->grabbed_clients, link) {
103 if (cdata->client == client) return PEPPER_TRUE;
106 wl_client_get_credentials(client, &pid, &uid, &gid);
108 return pepper_security_privilege_check(pid, uid, "http://tizen.org/privilege/keygrab");
111 static struct wl_client *
112 _pepper_keyrouter_get_client_from_view(pepper_view_t *view)
114 pepper_surface_t *surface = pepper_view_get_surface(view);
115 PEPPER_CHECK(surface, return NULL, "No surfce available for the given view.\n");
117 struct wl_resource *resource = pepper_surface_get_resource(surface);
120 return wl_resource_get_client(resource);
126 _pepper_keyrouter_get_pid(struct wl_client *client)
132 wl_client_get_credentials(client, &pid, &uid, &gid);
138 pepper_keyrouter_set_seat(pepper_keyrouter_t *pepper_keyrouter, pepper_seat_t *seat)
140 PEPPER_CHECK(pepper_keyrouter, return, "Invalid pepper_keyrouter_t\n");
141 pepper_keyrouter->seat = seat;
145 pepper_keyrouter_set_keyboard(pepper_keyrouter_t * pepper_keyrouter, pepper_keyboard_t *keyboard)
147 PEPPER_CHECK(pepper_keyrouter, return, "Invalid pepper_keyrouter_t\n");
148 pepper_keyrouter->keyboard = keyboard;
152 pepper_keyrouter_set_focus_view(pepper_keyrouter_t *pk, pepper_view_t *focus_view)
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");
158 pk->focus_view = focus_view;
161 client = _pepper_keyrouter_get_client_from_view(focus_view);
163 keyrouter_set_focus_client(pk->keyrouter, client);
167 pepper_keyrouter_set_top_view(pepper_keyrouter_t *pk, pepper_view_t *top_view)
169 struct wl_client *client = NULL;
170 PEPPER_CHECK(pk, return, "pepper keyrouter is invalid.\n");
172 pk->top_view = top_view;
175 client = _pepper_keyrouter_get_client_from_view(top_view);
177 keyrouter_set_top_client(pk->keyrouter, client);
181 pepper_keyrouter_debug_keygrab_status_print(pepper_keyrouter_t *pepper_keyrouter)
185 keyrouter_key_info_t *grab_data;
187 PEPPER_CHECK(pepper_keyrouter, return, "pepper_keyrouter is invalid.\n");
188 PEPPER_CHECK(pepper_keyrouter->keyrouter, return, "keyrouter is invalid.\n");
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));
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));
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));
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));
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,
234 struct wl_resource *resource;
235 pepper_keyboard_t *keyboard_info;
237 keyboard_info = pepper_seat_get_keyboard(seat);
238 PEPPER_CHECK(keyboard_info, return, "Current seat has no keyboard\n");
240 wl_resource_for_each(resource, pepper_keyboard_get_resource_list(keyboard_info)) {
241 if (wl_resource_get_client(resource) == client)
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);
250 pepper_keyrouter_key_process(pepper_keyrouter_t *pepper_keyrouter,
251 unsigned int key, unsigned int state, unsigned int time)
253 pepper_list_t delivery_list;
254 pepper_list_t *seat_list;
255 keyrouter_key_info_t *info;
259 pepper_list_init(&delivery_list);
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);
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);
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);
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);
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);
287 PEPPER_TRACE("No focused view exists.\n", __FUNCTION__);
292 _pepper_keyrouter_remove_client_from_list(pepper_keyrouter_t *pepper_keyrouter, struct wl_client *client)
295 for (i = 0; i < KEYROUTER_MAX_KEYS; i++) {
296 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
297 TIZEN_KEYROUTER_MODE_EXCLUSIVE,
299 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
300 TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE,
302 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
303 TIZEN_KEYROUTER_MODE_TOPMOST,
305 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
306 TIZEN_KEYROUTER_MODE_SHARED,
312 _pepper_keyrouter_add_client_to_list(pepper_keyrouter_t *pepper_keyrouter, struct wl_client *client)
314 clients_data_t *cdata;
316 pepper_list_for_each(cdata, &pepper_keyrouter->grabbed_clients, link) {
317 if (cdata->client == client) return TIZEN_KEYROUTER_ERROR_NONE;
320 cdata = (clients_data_t *)calloc(1, sizeof(clients_data_t));
323 PEPPER_ERROR("Failed to allocate memory !\n");
324 return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES;
327 cdata->client = client;
328 pepper_list_init(&cdata->link);
329 pepper_list_insert(&pepper_keyrouter->grabbed_clients, &cdata->link);
331 return TIZEN_KEYROUTER_ERROR_NONE;
335 _pepper_keyrouter_cb_keygrab_set(struct wl_client *client,
336 struct wl_resource *resource,
337 struct wl_resource *surface,
341 int res = TIZEN_KEYROUTER_ERROR_NONE;
342 pepper_keyrouter_t *pepper_keyrouter = NULL;
345 pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
346 PEPPER_CHECK(pepper_keyrouter, goto notify, "Invalid pepper_keyrouter_t\n");
348 ret = _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter, client, mode, key);
350 res = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
354 res = keyrouter_grab_key(pepper_keyrouter->keyrouter, mode, key, (void *)client);
356 if (res == TIZEN_KEYROUTER_ERROR_NONE)
357 res = _pepper_keyrouter_add_client_to_list(pepper_keyrouter, client);
360 tizen_keyrouter_send_keygrab_notify(resource, surface, key, mode, res);
364 _pepper_keyrouter_cb_keygrab_unset(struct wl_client *client,
365 struct wl_resource *resource,
366 struct wl_resource *surface,
369 int res = TIZEN_KEYROUTER_ERROR_NONE;
370 pepper_keyrouter_t *pepper_keyrouter = NULL;
373 pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
374 PEPPER_CHECK(pepper_keyrouter, goto notify, "Invalid pepper_keyrouter_t\n");
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);
381 ret = _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter, client, TIZEN_KEYROUTER_MODE_NONE, key);
383 res = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
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);
401 tizen_keyrouter_send_keygrab_notify(resource, surface, key, TIZEN_KEYROUTER_MODE_NONE, res);
405 _pepper_keyrouter_cb_get_keygrab_status(struct wl_client *client,
406 struct wl_resource *resource,
407 struct wl_resource *surface,
410 tizen_keyrouter_send_keygrab_notify(resource, surface, key, TIZEN_KEYROUTER_MODE_NONE, TIZEN_KEYROUTER_ERROR_NO_PERMISSION);
414 _pepper_keyrouter_array_length(const struct wl_array *array)
419 wl_array_for_each(data, array) {
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)
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;
438 pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
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");
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);
448 grab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
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);
457 return_list = grab_list;
459 tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list);
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)
468 struct wl_array *return_list = NULL;
469 ungrab_list_data_t *ungrab_data = NULL;
470 pepper_keyrouter_t *pepper_keyrouter = NULL;
473 pepper_keyrouter = (pepper_keyrouter_t *)wl_resource_get_user_data(resource);
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");
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);
484 ret = _pepper_keyrouter_util_do_privilege_check(pepper_keyrouter, client, TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key);
486 ungrab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION;
488 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
489 TIZEN_KEYROUTER_MODE_EXCLUSIVE,
490 ungrab_data->key, (void *)client);
492 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
493 TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE,
494 ungrab_data->key, (void *)client);
496 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
497 TIZEN_KEYROUTER_MODE_TOPMOST,
498 ungrab_data->key, (void *)client);
500 keyrouter_ungrab_key(pepper_keyrouter->keyrouter,
501 TIZEN_KEYROUTER_MODE_SHARED,
502 ungrab_data->key, (void *)client);
504 ungrab_data->err = TIZEN_KEYROUTER_ERROR_NONE;
508 return_list = ungrab_list;
510 tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list);
514 _pepper_keyrouter_cb_get_keygrab_list(struct wl_client *client,
515 struct wl_resource *resource,
516 struct wl_resource *surface)
518 tizen_keyrouter_send_getgrab_notify_list(resource, surface, NULL);
522 _pepper_keyrouter_cb_set_register_none_key(struct wl_client *client,
523 struct wl_resource *resource,
524 struct wl_resource *surface,
527 tizen_keyrouter_send_set_register_none_key_notify(resource, NULL, 0);
531 _pepper_keyrouter_cb_get_keyregister_status(struct wl_client *client,
532 struct wl_resource *resource,
535 tizen_keyrouter_send_keyregister_notify(resource, (int)PEPPER_FALSE);
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,
545 tizen_keyrouter_send_set_input_config_notify(resource, (int)PEPPER_FALSE);
549 _pepper_keyrouter_cb_destory(struct wl_client *client,
550 struct wl_resource *resource)
552 wl_resource_destroy(resource);
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
568 /* tizen_keyrouter global object destroy function */
570 _pepper_keyrouter_cb_resource_destory(struct wl_resource *resource)
572 resources_data_t *rdata, *rtmp;
573 clients_data_t *cdata, *ctmp;
575 struct wl_client *client;
576 pepper_keyrouter_t *pepper_keyrouter;
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");
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);
595 list = &pepper_keyrouter->resources;
597 if (pepper_list_empty(list))
600 pepper_list_for_each_safe(rdata, rtmp, list, link) {
601 if (rdata->resource== resource) {
602 pepper_list_remove(&rdata->link);
608 /* tizen_keyrouter global object bind function */
610 _pepper_keyrouter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
612 struct wl_resource *resource;
613 resources_data_t *rdata;
614 pepper_keyrouter_t *pepper_keyrouter;
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");
620 resource = wl_resource_create(client, &tizen_keyrouter_interface, MIN(version, 2), id);
622 PEPPER_ERROR("Failed to create resource ! (version :%d, id:%d)", version, id);
623 wl_client_post_no_memory(client);
627 rdata = (resources_data_t *)calloc(1, sizeof(resources_data_t));
630 PEPPER_ERROR("Failed to allocate memory !\n");
632 wl_resource_destroy(resource);
633 wl_client_post_no_memory(client);
637 rdata->resource = resource;
638 pepper_list_init(&rdata->link);
639 pepper_list_insert(&pepper_keyrouter->resources, &rdata->link);
642 wl_resource_set_implementation(resource, &_pepper_keyrouter_implementation,
643 pepper_keyrouter, _pepper_keyrouter_cb_resource_destory);
647 pepper_keyrouter_event_handler(pepper_event_listener_t *listener,
648 pepper_object_t *object,
649 uint32_t id, void *info, void *data)
651 pepper_input_event_t *event;
652 pepper_keyrouter_t *pepper_keyrouter;
653 pepper_keyboard_t *keyboard = (pepper_keyboard_t *)object;
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");
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);
668 _pepper_keyrouter_options_set(pepper_keyrouter_t *pepper_keyrouter)
672 char *ret, *tmp, *buf_ptr, buf[1024] = {0,};
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") ;
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));
680 while (!feof(file)) {
681 ret = fgets(buf, 1024, file);
684 tmp = strtok_r(buf, " ", &buf_ptr);
685 tmp = strtok_r(NULL, " ", &buf_ptr);
688 if ((0 >= keycode) || (keycode >= KEYROUTER_MAX_KEYS)) {
689 PEPPER_ERROR("Currently %d key is invalid to support\n", keycode);
693 pepper_keyrouter->opts[keycode].enabled = PEPPER_TRUE;
695 if (strstr(buf_ptr, "no_priv") != NULL) {
696 pepper_keyrouter->opts[keycode].no_privilege = PEPPER_TRUE;
704 free(pepper_keyrouter->opts);
705 pepper_keyrouter->opts = NULL;
708 PEPPER_API pepper_keyrouter_t *
709 pepper_keyrouter_create(pepper_compositor_t *compositor)
711 struct wl_display *display = NULL;
712 struct wl_global *global = NULL;
713 pepper_keyrouter_t *pepper_keyrouter;
716 PEPPER_CHECK(compositor, return PEPPER_FALSE, "Invalid compositor\n");
718 display = pepper_compositor_get_display(compositor);
719 PEPPER_CHECK(display, return PEPPER_FALSE, "Failed to get wl_display from compositor\n");
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;
726 _pepper_keyrouter_options_set(pepper_keyrouter);
728 pepper_list_init(&pepper_keyrouter->resources);
729 pepper_list_init(&pepper_keyrouter->grabbed_clients);
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");
734 pepper_keyrouter->global = global;
736 pepper_keyrouter->keyrouter = keyrouter_create();
737 PEPPER_CHECK(pepper_keyrouter->keyrouter, goto failed, "Failed to create keyrouter\n");
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");
742 return pepper_keyrouter;
745 if (pepper_keyrouter) {
746 if (pepper_keyrouter->opts) {
747 free(pepper_keyrouter->opts);
748 pepper_keyrouter->opts = NULL;
751 if (pepper_keyrouter->keyrouter) {
752 keyrouter_destroy(pepper_keyrouter->keyrouter);
753 pepper_keyrouter->keyrouter = NULL;
755 free(pepper_keyrouter);
762 pepper_keyrouter_destroy(pepper_keyrouter_t *pepper_keyrouter)
764 resources_data_t *rdata, *rtmp;
765 clients_data_t *cdata, *ctmp;
767 PEPPER_CHECK(pepper_keyrouter, return, "Pepper keyrouter is not initialized\n");
769 pepper_list_for_each_safe(cdata, ctmp, &pepper_keyrouter->grabbed_clients, link) {
770 pepper_list_remove(&cdata->link);
774 pepper_list_for_each_safe(rdata, rtmp, &pepper_keyrouter->resources, link) {
775 wl_resource_destroy(rdata->resource);
778 if (pepper_keyrouter->opts) {
779 free(pepper_keyrouter->opts);
780 pepper_keyrouter->opts = NULL;
783 if (pepper_keyrouter->keyrouter) {
784 keyrouter_destroy(pepper_keyrouter->keyrouter);
785 pepper_keyrouter->keyrouter = NULL;
788 if (pepper_keyrouter->global)
789 wl_global_destroy(pepper_keyrouter->global);
791 if (pepper_keyrouter->pepper_security_init_done)
792 pepper_security_deinit();
793 pepper_keyrouter->pepper_security_init_done = PEPPER_FALSE;
795 free(pepper_keyrouter);
796 pepper_keyrouter = NULL;