From c74f0675925d0b0df3eaf2afeffc2533851f901a Mon Sep 17 00:00:00 2001 From: jeon Date: Thu, 9 May 2019 21:02:25 +0900 Subject: [PATCH] pepper-devicemgr: support a input block request Change-Id: I7fc0e98ffc5a9013951d4fe16fac04f80b4ea98f --- src/lib/devicemgr/pepper-devicemgr.c | 164 ++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) diff --git a/src/lib/devicemgr/pepper-devicemgr.c b/src/lib/devicemgr/pepper-devicemgr.c index 3f8bd2e..788cc38 100644 --- a/src/lib/devicemgr/pepper-devicemgr.c +++ b/src/lib/devicemgr/pepper-devicemgr.c @@ -53,6 +53,13 @@ struct pepper_devicemgr { pepper_list_t resources; + struct wl_resource *block_resource; + struct wl_event_source *timer; + struct { + pepper_keyboard_grab_t *grab; + void *data; + } old_grab; + devicemgr_t *devicemgr; int ref; #ifdef HAVE_CYNARA @@ -186,6 +193,68 @@ _pepper_devicemgr_handle_keyboard_keymap_update(pepper_event_listener_t *listene pepper_devicemgr->xkb_info = keyboard->xkb_info; } +static pepper_bool_t +_pepper_devicemgr_keyboard_grab_key(pepper_keyboard_t *keyboard, void *data, + uint32_t time, uint32_t key, uint32_t state) +{ + PEPPER_TRACE("blocked key event: key: %d, state: %d\n", key, state); + + return PEPPER_FALSE; +} + +static pepper_bool_t +_pepper_devicemgr_keyboard_grab_modifiers(pepper_keyboard_t *keyboard, void *data, + uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ + /* Nothing to do. */ + return PEPPER_TRUE; +} + +static pepper_bool_t +_pepper_devicemgr_keyboard_grab_cancel(pepper_keyboard_t *keyboard, void *data) +{ + /* Nothing to do. */ + return PEPPER_TRUE; +} + +static const pepper_keyboard_grab_t _pepper_devicemgr_keyboard_grab = { + _pepper_devicemgr_keyboard_grab_key, + _pepper_devicemgr_keyboard_grab_modifiers, + _pepper_devicemgr_keyboard_grab_cancel, +}; + +static void +_pepper_devicemgr_grab_keyboard(pepper_devicemgr_t *pepper_devicemgr) +{ + pepper_keyboard_t *keyboard; + + PEPPER_CHECK(pepper_devicemgr->seat, return, "The seat is not set to pepper_devicemgr\n"); + + keyboard = pepper_seat_get_keyboard(pepper_devicemgr->seat); + PEPPER_CHECK(keyboard, return, "Failed to get keyboard from seat(%s)\n", pepper_seat_get_name(pepper_devicemgr->seat)); + + pepper_devicemgr->old_grab.grab = (pepper_keyboard_grab_t *)pepper_keyboard_get_grab(keyboard); + pepper_devicemgr->old_grab.data = pepper_keyboard_get_grab_data(keyboard); + pepper_keyboard_set_grab(keyboard, &_pepper_devicemgr_keyboard_grab, pepper_devicemgr); +} + +static void +_pepper_devicemgr_ungrab_keyboard(pepper_devicemgr_t *pepper_devicemgr) +{ + pepper_keyboard_t *keyboard; + + PEPPER_CHECK(pepper_devicemgr->seat, return, "The seat is not set to pepper_devicemgr\n"); + + keyboard = pepper_seat_get_keyboard(pepper_devicemgr->seat); + PEPPER_CHECK(keyboard, return, "Failed to get keyboard from seat(%s)\n", pepper_seat_get_name(pepper_devicemgr->seat)); + + pepper_keyboard_set_grab(keyboard, pepper_devicemgr->old_grab.grab, pepper_devicemgr->old_grab.data); + + pepper_devicemgr->old_grab.grab = NULL; + pepper_devicemgr->old_grab.data = NULL; +} + static void _pepper_devicemgr_handle_seat_keyboard_add(pepper_event_listener_t *listener, pepper_object_t *object, uint32_t id, void *info, void *data) { @@ -210,18 +279,100 @@ _pepper_devicemgr_handle_input_device_add(pepper_event_listener_t *listener, pep devicemgr_input_generator_keyboard_set(pepper_devicemgr->devicemgr, device); } +static pepper_bool_t +_pepper_devicemgr_add_timer(pepper_devicemgr_t *pepper_devicemgr, wl_event_loop_timer_func_t func, int time) +{ + struct wl_event_loop *event_loop; + + event_loop = wl_display_get_event_loop(pepper_devicemgr->display); + PEPPER_CHECK(event_loop, return PEPPER_FALSE, "Failed to get event_loop from display: %p\n", pepper_devicemgr->display); + + pepper_devicemgr->timer = wl_event_loop_add_timer(event_loop, func, pepper_devicemgr); + wl_event_source_timer_update(pepper_devicemgr->timer, time); + + return PEPPER_TRUE; +} + +static int +_pepper_devicemgr_block_timer(void *data) +{ + pepper_devicemgr_t *pepper_devicemgr = data; + + _pepper_devicemgr_ungrab_keyboard(pepper_devicemgr); + + wl_event_source_remove(pepper_devicemgr->timer); + pepper_devicemgr->timer = NULL; + + tizen_input_device_manager_send_block_expired(pepper_devicemgr->block_resource); + pepper_devicemgr->block_resource = NULL; + + return 1; +} + static void _pepper_devicemgr_cb_block_events(struct wl_client *client, struct wl_resource *resource, uint32_t serial, uint32_t clas, uint32_t duration) { - tizen_input_device_manager_send_error(resource, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES); + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + pepper_devicemgr_t *pepper_devicemgr; + pepper_bool_t res; + + pepper_devicemgr = wl_resource_get_user_data(resource); + PEPPER_CHECK(pepper_devicemgr, goto finish, "pepper_devicemgr is not set\n"); + PEPPER_CHECK(pepper_devicemgr->devicemgr, goto finish, "devicemgr is not created\n"); + + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + res = _pepper_devicemgr_util_do_privilege_check(pepper_devicemgr, client, "http://tizen.org/privilege/internal/inputdevice.block"); + PEPPER_CHECK(res == PEPPER_TRUE, goto finish, "Current client has no permission to input block\n"); + + PEPPER_CHECK(!pepper_devicemgr->block_resource, goto finish, "currently the input system is already blocked\n"); + + if (clas & TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) { + res = _pepper_devicemgr_add_timer(pepper_devicemgr, _pepper_devicemgr_block_timer, duration); + PEPPER_CHECK(res, goto finish, "Failed to add a timer\n"); + + _pepper_devicemgr_grab_keyboard(pepper_devicemgr); + pepper_devicemgr->block_resource = resource; + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + } + else + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + +finish: + tizen_input_device_manager_send_error(resource, ret); } static void _pepper_devicemgr_cb_unblock_events(struct wl_client *client, struct wl_resource *resource, uint32_t serial) { - tizen_input_device_manager_send_error(resource, TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES); + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + pepper_devicemgr_t *pepper_devicemgr; + pepper_bool_t res; + + pepper_devicemgr = wl_resource_get_user_data(resource); + PEPPER_CHECK(pepper_devicemgr, goto finish, "pepper_devicemgr is not set\n"); + PEPPER_CHECK(pepper_devicemgr->devicemgr, goto finish, "devicemgr is not created\n"); + + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + res = _pepper_devicemgr_util_do_privilege_check(pepper_devicemgr, client, "http://tizen.org/privilege/internal/inputdevice.block"); + PEPPER_CHECK(res == PEPPER_TRUE, goto finish, "Current client has no permission to input block\n"); + + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_BLOCKED_ALREADY; + PEPPER_CHECK(pepper_devicemgr->block_resource == resource, goto finish, "currently the input system is blocked by another resource\n"); + + _pepper_devicemgr_ungrab_keyboard(pepper_devicemgr); + pepper_devicemgr->block_resource = NULL; + + if (pepper_devicemgr->timer) { + wl_event_source_remove(pepper_devicemgr->timer); + pepper_devicemgr->timer = NULL; + } + + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + +finish: + tizen_input_device_manager_send_error(resource, ret); } static int @@ -466,6 +617,15 @@ _pepper_devicemgr_cb_unbind(struct wl_resource *resource) _pepper_devicemgr_deinit_generator(pepper_devicemgr, resource); + if (resource == pepper_devicemgr->block_resource) { + _pepper_devicemgr_ungrab_keyboard(pepper_devicemgr); + pepper_devicemgr->block_resource = NULL; + if (pepper_devicemgr->timer) { + wl_event_source_remove(pepper_devicemgr->timer); + pepper_devicemgr->timer = NULL; + } + } + pepper_list_for_each_safe(rdata, rtmp, &pepper_devicemgr->resources, link) { if (rdata->resource == resource) { pepper_list_remove(&rdata->link); -- 2.7.4