devicemgr: implement pointer_warp 47/278247/1 accepted/tizen/unified/20220720.034120 submit/tizen/20220720.024540
authorduna.oh <duna.oh@samsung.com>
Mon, 11 Jul 2022 16:26:50 +0000 (01:26 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 18 Jul 2022 05:59:21 +0000 (14:59 +0900)
Change-Id: Ia3054efdedc15b04b93f4b3e089fa1491c87f981

clients/simple-tbm.c
examples/tinyds-tdm-libinput.c
include/libds-tizen/input_devicemgr.h
src/input_devicemgr/input_devicemgr.c
src/input_devicemgr/input_devicemgr.h

index c82349f..f68fedb 100644 (file)
@@ -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)) {
index b1974f1..10c02bb 100644 (file)
@@ -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);
 }
index fc1060e..458d581 100644 (file)
@@ -2,6 +2,7 @@
 #define LIBDS_TIZEN_INPUT_DEVICEMGR_H
 
 #include <wayland-server.h>
+#include <libds/surface.h>
 
 #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,
index f690fe7..00c99b0 100644 (file)
@@ -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)
 {
index a4428ee..f773fc1 100644 (file)
@@ -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;