tinyds: Handle ds_seat 90/278190/1
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 4 May 2022 06:34:19 +0000 (15:34 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 18 Jul 2022 05:58:39 +0000 (14:58 +0900)
tinyds now handles ds_seat, but only for pointer.

Change-Id: I2b48841e8dcbbe0845d5cb2facd46b78b48eafd7

src/examples/tinyds.c

index 64612a6..0e25462 100644 (file)
@@ -21,6 +21,7 @@
 #include <libds/keyboard.h>
 #include <libds/touch.h>
 #include <libds/pointer.h>
+#include <libds/seat.h>
 
 #define TINYDS_UNUSED   __attribute__((unused))
 
@@ -34,6 +35,8 @@ struct tinyds_pointer
     struct ds_input_device *dev;
     struct tinyds_server *server;
 
+    struct tinyds_view *focused_view;
+
     struct wl_listener destroy;
     struct wl_listener motion;
     struct wl_listener motion_absolute;
@@ -84,6 +87,7 @@ struct tinyds_server
     struct ds_backend *backend;
     struct ds_compositor *compositor;
     struct ds_xdg_shell *xdg_shell;
+    struct ds_seat *seat;
 
     struct tinyds_output output;
 
@@ -115,6 +119,8 @@ static bool server_init(struct tinyds_server *server,
 static void server_fini(struct tinyds_server *server);
 static void server_add_view(struct tinyds_server *server,
         struct ds_xdg_surface *xdg_surface);
+static struct tinyds_view *server_view_at(struct tinyds_server *server,
+        double lx, double ly, double *sx, double *sy);
 static bool output_init(struct tinyds_output *output,
         struct tinyds_server *server, struct ds_output *ds_output,
         int width, int height);
@@ -354,11 +360,37 @@ pointer_handle_motion_absolute(struct wl_listener *listener, void *data)
 {
     struct tinyds_pointer *pointer;
     struct ds_event_pointer_motion_absolute *event = data;
+    struct tinyds_view *view;
+    double ox, oy, sx, sy;
 
     pointer = wl_container_of(listener, pointer, motion_absolute);
 
     ds_inf("Pointer(%p) motion absolute: (x %f y %f) time(%d)",
             pointer, event->x, event->y, event->time_msec);
+
+    ox = event->x * OUTPUT_WIDTH;
+    oy = event->y * OUTPUT_HEIGHT;
+    view = server_view_at(pointer->server, ox, oy, &sx, &sy);
+
+    if (pointer->focused_view != view) {
+        if (pointer->focused_view) {
+            ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
+            ds_seat_pointer_notify_clear_focus(pointer->server->seat);
+            pointer->focused_view = NULL;
+        }
+
+        if (view) {
+            ds_inf("Set pointer focus to view(%p)", view);
+            ds_seat_pointer_notify_enter(pointer->server->seat,
+                    ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
+            pointer->focused_view = view;
+        }
+    }
+
+    if (view) {
+        ds_seat_pointer_notify_motion(pointer->server->seat,
+                event->time_msec, sx, sy);
+    }
 }
 
 static void
@@ -383,6 +415,7 @@ pointer_handle_frame(struct wl_listener *listener, void *data)
     pointer = wl_container_of(listener, pointer, frame);
 
     ds_inf("Pointer(%p) frame", pointer);
+    ds_seat_pointer_notify_frame(pointer->server->seat);
 }
 
 static void
@@ -437,6 +470,7 @@ server_handle_new_input(struct wl_listener *listener, void *data)
             break;
         case DS_INPUT_DEVICE_POINTER:
             server_add_pointer(server, dev);
+            ds_seat_set_capabilities(server->seat, WL_SEAT_CAPABILITY_POINTER);
             break;
         default:
             ds_err("Unknown type(%d) of ds_input_device", dev_type);
@@ -534,6 +568,10 @@ server_init(struct tinyds_server *server, struct wl_display *display)
     ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
             &server->new_xdg_surface);
 
+    server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
+    if (!server->seat)
+        goto err;
+
     return true;
 
 err:
@@ -696,6 +734,34 @@ server_add_view(struct tinyds_server *server, struct ds_xdg_surface *xdg_surface
     ds_inf("View(%p) added", view);
 }
 
+static struct tinyds_view *
+server_view_at(struct tinyds_server *server, double lx, double ly,
+        double *sx, double *sy)
+{
+    struct tinyds_view *view;
+    struct ds_surface *surface;
+    struct ds_buffer *buffer;
+    int x, y, w = 0, h = 0;
+
+    wl_list_for_each(view, &server->views, link) {
+        surface = ds_xdg_surface_get_surface(view->xdg_surface);
+        buffer = ds_surface_get_buffer(surface);
+        ds_buffer_get_size(buffer, &w, &h);
+
+        x = view->x;
+        y = view->y;
+
+        if (lx >= x && lx <= w && ly >= y && ly <= h) {
+            *sx = lx - x;
+            *sy = ly - y;
+
+            return view;
+        }
+    }
+
+    return NULL;
+}
+
 static void
 view_destroy(struct tinyds_view *view)
 {