From fc9c4e058e23ef37d0caa155016a3d6f792c2938 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Tue, 12 Jul 2022 01:26:50 +0900 Subject: [PATCH] devicemgr: implement pointer_warp Change-Id: Ia3054efdedc15b04b93f4b3e089fa1491c87f981 --- clients/simple-tbm.c | 19 ++++++- examples/tinyds-tdm-libinput.c | 101 ++++++++++++++++++++++++++++++---- include/libds-tizen/input_devicemgr.h | 13 +++++ src/input_devicemgr/input_devicemgr.c | 61 +++++++++++++++++++- src/input_devicemgr/input_devicemgr.h | 1 + 5 files changed, 182 insertions(+), 13 deletions(-) diff --git a/clients/simple-tbm.c b/clients/simple-tbm.c index c82349f..f68fedb 100644 --- a/clients/simple-tbm.c +++ b/clients/simple-tbm.c @@ -56,6 +56,7 @@ struct display { struct tizen_input_device_manager *devicemgr; int notified; bool blocked; + struct wl_surface *entered_surface; }; struct window { @@ -338,8 +339,21 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = { static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { + struct display *d = data; + static int warp_x = 0, warp_y = 0; + if (state == WL_POINTER_BUTTON_STATE_PRESSED) { fprintf(stderr, "pointer_handle_button: PRESSED\n"); + + warp_x += 10; + warp_y += 10; + tizen_input_device_manager_pointer_warp(d->devicemgr, + d->entered_surface, + wl_fixed_from_int(warp_x), + wl_fixed_from_int(warp_y)); + fprintf(stderr, "requesting pointer_warp: surface:%p sx: %d sy: %d\n", + d->entered_surface, + warp_x, warp_y); } else { fprintf(stderr, "pointer_handle_button: RELEASED\n"); @@ -350,8 +364,11 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) { + struct display *d = data; + fprintf(stderr, "pointer_handle_enter surface_x:%d, surface_y:%d\n", wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); + d->entered_surface = surface; } static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, @@ -508,7 +525,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, } if ((caps & WL_SEAT_CAPABILITY_POINTER)) { struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat); - wl_pointer_add_listener(pointer, &pointer_listener, NULL); + wl_pointer_add_listener(pointer, &pointer_listener, d); fprintf(stderr, "seat_handle_capabilities: pointer\n"); } if ((caps & WL_SEAT_CAPABILITY_TOUCH)) { diff --git a/examples/tinyds-tdm-libinput.c b/examples/tinyds-tdm-libinput.c index b1974f1..10c02bb 100644 --- a/examples/tinyds-tdm-libinput.c +++ b/examples/tinyds-tdm-libinput.c @@ -40,6 +40,7 @@ #define TINYDS_UNUSED __attribute__((unused)) struct tinyds_keyboard; +struct tinyds_pointer; struct tinyds_output { @@ -87,8 +88,11 @@ struct tinyds_server struct wl_listener new_output; struct wl_listener new_input; struct wl_listener new_xdg_surface; + struct wl_listener devicemgr_destroy; + struct wl_listener pointer_warp; - struct tinyds_keyboard *keyboard; + struct wl_list keyboards; + struct wl_list pointers; }; struct tinyds_view @@ -119,6 +123,7 @@ struct tinyds_pointer struct wl_listener motion; //relative struct wl_listener button; struct wl_listener frame; + struct wl_list link; //tinyds_server::pointers }; struct tinyds_keyboard @@ -128,6 +133,7 @@ struct tinyds_keyboard struct wl_listener destroy; struct wl_listener key; + struct wl_list link; //tinyds_server::keyboards }; struct tinyds_touch @@ -169,6 +175,10 @@ static void server_add_pointer(struct tinyds_server *server, static void server_add_touch(struct tinyds_server *server, struct ds_input_device *dev); +static struct tinyds_view * +server_view_at(struct tinyds_server *server, double lx, double ly, + double *sx, double *sy); + int main(void) { @@ -214,16 +224,19 @@ view_handle_xdg_surface_map(struct wl_listener *listener, { struct tinyds_view *view; struct ds_keyboard *keyboard; + struct tinyds_keyboard *kbd; view = wl_container_of(listener, view, xdg_surface_map); view->mapped = true; - if (!view->server->keyboard) return; - keyboard = ds_input_device_get_keyboard(view->server->keyboard->dev); - if (keyboard != NULL) { - ds_seat_keyboard_notify_enter(view->server->seat, - ds_xdg_surface_get_surface(view->xdg_surface), - keyboard->keycodes, keyboard->num_keycodes, - &keyboard->modifiers); + wl_list_for_each(kbd, &view->server->keyboards, link) { + keyboard = ds_input_device_get_keyboard(kbd->dev); + if (keyboard != NULL) { + ds_seat_keyboard_notify_enter(view->server->seat, + ds_xdg_surface_get_surface(view->xdg_surface), + keyboard->keycodes, keyboard->num_keycodes, + &keyboard->modifiers); + return; + } } } @@ -306,6 +319,8 @@ server_new_xdg_surface(struct wl_listener *listener, void *data) view->x = rand() % 1000; view->y = rand() % 500; + + ds_inf("view at (%d, %d)", view->x, view->y); } static void @@ -444,6 +459,55 @@ devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr) devicemgr_remove_keymap_data(&keymap_list, 458); } +static void +devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct tinyds_pointer *pointer; + struct ds_tizen_input_devicemgr_event_pointer_warp *event = data; + double sx = 0.f, sy = 0.f; + struct tinyds_view *view = NULL; + + server = wl_container_of(listener, server, pointer_warp); + + ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface, + event->x, event->y); + + wl_list_for_each(pointer, &server->pointers, link){ + if (!pointer->focused_view) continue; + view = pointer->focused_view; + } + if (!view) return; + + if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) { + ds_inf("Pointer is not on the requested surface"); + return; + } + + server->output_x = view->x + (event->x * server->output->width); + server->output_y = view->y + (event->y * server->output->height); + + server_view_at(server, server->output_x, server->output_y, &sx, &sy); + + ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f", + sx, sy, server->output_x, server->output_y); + + ds_seat_pointer_notify_motion(server->seat, + event->time_msec, sx, sy); +} + +static void +devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_server *server = + wl_container_of(listener, server, devicemgr_destroy); + + wl_list_remove(&server->devicemgr_destroy.link); + wl_list_remove(&server->pointer_warp.link); + + server->devicemgr = NULL; +} + static bool init_server(struct tinyds_server *server, struct wl_display *display) { @@ -468,6 +532,8 @@ init_server(struct tinyds_server *server, struct wl_display *display) ds_backend_add_new_output_listener(server->backend, &server->new_output); + wl_list_init(&server->keyboards); + wl_list_init(&server->pointers); server->new_input.notify = backend_handle_new_input; ds_backend_add_new_input_listener(server->input_backend, &server->new_input); @@ -499,6 +565,15 @@ init_server(struct tinyds_server *server, struct wl_display *display) } devicemgr_set_keymap(server->devicemgr); + + server->devicemgr_destroy.notify = devicemgr_handle_destroy; + ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr, + &server->devicemgr_destroy); + + server->pointer_warp.notify = devicemgr_handle_pointer_warp; + ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr, + &server->pointer_warp); + return true; err: @@ -762,8 +837,7 @@ keyboard_handle_device_destroy(struct wl_listener *listener, void *data) wl_list_remove(&kbd->destroy.link); wl_list_remove(&kbd->key.link); - - kbd->server->keyboard = NULL; + wl_list_remove(&kbd->link); free(kbd); } @@ -852,7 +926,7 @@ server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) kbd->key.notify = keyboard_handle_key; ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); - server->keyboard = kbd; + wl_list_insert(&server->keyboards, &kbd->link); ds_inf("Keyboard(%p) added", kbd); } @@ -1007,6 +1081,7 @@ pointer_handle_device_destroy(struct wl_listener *listener, void *data) wl_list_remove(&pointer->motion.link); wl_list_remove(&pointer->button.link); wl_list_remove(&pointer->frame.link); + wl_list_remove(&pointer->link); free(pointer); } @@ -1123,5 +1198,9 @@ server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev), &pointer->frame); + pointer->focused_view = NULL; + + wl_list_insert(&server->pointers, &pointer->link); + ds_inf("Pointer(%p) added", pointer); } diff --git a/include/libds-tizen/input_devicemgr.h b/include/libds-tizen/input_devicemgr.h index fc1060e..458d581 100644 --- a/include/libds-tizen/input_devicemgr.h +++ b/include/libds-tizen/input_devicemgr.h @@ -2,6 +2,7 @@ #define LIBDS_TIZEN_INPUT_DEVICEMGR_H #include +#include #ifdef __cplusplus extern "C" { @@ -19,6 +20,13 @@ struct ds_tizen_input_devicemgr_keymap_data struct wl_list link; }; +struct ds_tizen_input_devicemgr_event_pointer_warp +{ + uint32_t time_msec; + struct ds_surface *surface; + double x, y; +}; + struct ds_tizen_input_devicemgr * ds_tizen_input_devicemgr_create(struct ds_backend *backend, struct ds_seat *seat); @@ -28,6 +36,11 @@ ds_tizen_input_devicemgr_add_destroy_listener( struct ds_tizen_input_devicemgr *devicemgr, struct wl_listener *listener); +void +ds_tizen_input_devicemgr_add_pointer_warp_listener( + struct ds_tizen_input_devicemgr *devicemgr, + struct wl_listener *listener); + bool ds_tizen_input_devicemgr_set_keymap_list( struct ds_tizen_input_devicemgr *devicemgr, diff --git a/src/input_devicemgr/input_devicemgr.c b/src/input_devicemgr/input_devicemgr.c index f690fe7..00c99b0 100644 --- a/src/input_devicemgr/input_devicemgr.c +++ b/src/input_devicemgr/input_devicemgr.c @@ -64,6 +64,10 @@ device_manager_handle_generate_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t type, uint32_t x, uint32_t y, uint32_t button); static void +device_manager_handle_pointer_warp(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surface, + wl_fixed_t x, wl_fixed_t y); +static void device_manager_handle_destroy(struct wl_client *client, struct wl_resource *resource); @@ -169,6 +173,7 @@ ds_tizen_input_devicemgr_create(struct ds_backend *backend, } wl_signal_init(&tz_devicemgr->events.destroy); + wl_signal_init(&tz_devicemgr->events.pointer_warp); wl_list_init(&tz_devicemgr->clients); wl_list_init(&tz_devicemgr->devices.kbd->key.pressed); wl_list_init(&tz_devicemgr->keymap_list); @@ -205,6 +210,14 @@ ds_tizen_input_devicemgr_add_destroy_listener( wl_signal_add(&tz_devicemgr->events.destroy, listener); } +WL_EXPORT void +ds_tizen_input_devicemgr_add_pointer_warp_listener( + struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_listener *listener) +{ + wl_signal_add(&tz_devicemgr->events.pointer_warp, listener); +} + WL_EXPORT bool ds_tizen_input_devicemgr_set_keymap_list( struct ds_tizen_input_devicemgr *tz_devicemgr, struct wl_list *list) @@ -347,7 +360,7 @@ static const struct tizen_input_device_manager_interface _devicemgr_impl = { .generate_key = device_manager_handle_generate_key, .generate_pointer = device_manager_handle_generate_pointer, .generate_touch = device_manager_handle_generate_touch, - .pointer_warp = NULL, + .pointer_warp = device_manager_handle_pointer_warp, .init_generator_with_name = device_manager_handle_init_generator_with_name, // v2 .destroy = device_manager_handle_destroy, // v3 @@ -767,6 +780,52 @@ finish: } static void +device_manager_handle_pointer_warp(struct wl_client *client, + struct wl_resource *resource, struct wl_resource *surface, + wl_fixed_t x, wl_fixed_t y) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + int32_t new_x, new_y; + double transformed_x = .0, transformed_y = .0; + struct ds_tizen_input_devicemgr_event_pointer_warp ds_event; + struct timeval time; + unsigned int timestamp; + + tz_devicemgr = wl_resource_get_user_data(resource); + + if (!tz_devicemgr->devices.ptr || + !tz_devicemgr->devices.ptr->input_device) { + ds_err("Pointer device is not initialized\n"); + goto finish; + } + + new_x = wl_fixed_to_int(x); + new_y = wl_fixed_to_int(y); + + if (tz_devicemgr->output.width != 0 && tz_devicemgr->output.height != 0) { + transformed_x = new_x / (double)tz_devicemgr->output.width; + transformed_y = new_y / (double)tz_devicemgr->output.height; + } + + gettimeofday(&time, NULL); + timestamp = time.tv_sec * 1000 + time.tv_usec / 1000; + + ds_event.time_msec = timestamp; + ds_event.surface = ds_surface_from_resource(surface); + ds_event.x = transformed_x; + ds_event.y = transformed_y; + ds_inf("Pointer warp. surface:%p, x:%.2f, y:%.2f", ds_event.surface, + ds_event.x, ds_event.y); + + wl_signal_emit(&tz_devicemgr->events.pointer_warp, &ds_event); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + +finish: + tizen_input_device_manager_send_error(resource, ret); +} + +static void device_manager_handle_destroy(struct wl_client *client, struct wl_resource *resource) { diff --git a/src/input_devicemgr/input_devicemgr.h b/src/input_devicemgr/input_devicemgr.h index a4428ee..f773fc1 100644 --- a/src/input_devicemgr/input_devicemgr.h +++ b/src/input_devicemgr/input_devicemgr.h @@ -36,6 +36,7 @@ struct ds_tizen_input_devicemgr { struct { struct wl_signal destroy; + struct wl_signal pointer_warp; //ds_tizen_input_devicemgr_event_pointer_warp } events; struct wl_listener new_input; -- 2.7.4