backend-wayland: create cursor and show it when pointer enters 81/283381/1
authorduna.oh <duna.oh@samsung.com>
Mon, 17 Oct 2022 08:38:32 +0000 (17:38 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 25 Oct 2022 10:55:00 +0000 (19:55 +0900)
get wl_cursor from default cursor theme.

name: "left_ptr"
image_count: 1
image[0]->width: 10, height: 16, hotspot_x: 1, hotspot_y: 1

Change-Id: I7438282d007647aeab3fd9bcb0c5eaf5dc5f155b

src/backend/wayland/backend.c
src/backend/wayland/backend.h
src/backend/wayland/meson.build
src/backend/wayland/output.c
src/backend/wayland/seat.c

index fd663f4..300cb36 100644 (file)
@@ -19,6 +19,7 @@ static bool wl_backend_server_init(struct ds_wl_backend *wl_backend,
 static void wl_backend_server_finish(struct ds_wl_backend_server *server);
 static int wl_backend_handle_dispatch_events(int fd, uint32_t mask,
         void *data);
+static void create_cursor(struct ds_wl_backend *wl_backend);
 
 WL_EXPORT struct ds_backend *
 ds_wl_backend_create(struct wl_display *display, const char *server_name)
@@ -253,6 +254,8 @@ wl_backend_server_init(struct ds_wl_backend *wl_backend, struct ds_wl_backend_se
         goto err_bind;
     }
 
+    create_cursor(wl_backend);
+
     return true;
 
 err_bind:
@@ -272,6 +275,7 @@ err_reg:
 static void
 wl_backend_server_finish(struct ds_wl_backend_server *server)
 {
+    wl_cursor_theme_destroy(server->backend->cursor_theme);
     xdg_wm_base_destroy(server->xdg_wm_base);
     wl_compositor_destroy(server->compositor);
     wl_registry_destroy(server->registry);
@@ -313,3 +317,22 @@ wl_backend_handle_dispatch_events(int fd, uint32_t mask, void *data)
 
     return count;
 }
+
+static void
+create_cursor(struct ds_wl_backend *wl_backend)
+{
+    struct ds_wl_backend_server *server = &wl_backend->server;
+
+    wl_backend->cursor_theme = wl_cursor_theme_load(NULL, 32, server->shm);
+    if (!wl_backend->cursor_theme) {
+        ds_err("Failed to load cursor theme");
+        return;
+    }
+
+    wl_backend->cursor = wl_cursor_theme_get_cursor(wl_backend->cursor_theme, "left_ptr");
+    if (!wl_backend->cursor) {
+        ds_err("Failed to create default cursor (name: left_ptr)\n");
+        return;
+    }
+    ds_inf("Succeeded to create default cursor (name: left_ptr)\n");
+}
\ No newline at end of file
index 12c8a27..a732e97 100644 (file)
@@ -8,6 +8,8 @@
 #include "libds/interfaces/keyboard.h"
 #include "libds/interfaces/touch.h"
 
+#include <wayland-cursor.h>
+
 struct ds_wl_backend_server
 {
     struct ds_wl_backend *backend;
@@ -34,6 +36,9 @@ struct ds_wl_backend
     struct ds_wl_backend_server server;
 
     size_t requested_outputs;
+
+    struct wl_cursor_theme *cursor_theme;
+    struct wl_cursor *cursor;
 };
 
 struct ds_wl_buffer
index 88574a4..17174d6 100644 (file)
@@ -24,4 +24,5 @@ endforeach
 
 libds_deps += [
   dependency('wayland-client', required: true),
+  dependency('wayland-cursor', required: true),
 ]
index a5b7c12..50fd7c8 100644 (file)
@@ -92,7 +92,11 @@ create_wl_output(struct ds_wl_backend *backend)
 
     wl_signal_emit(&backend->base.events.new_output, &output->base);
 
-    ds_dbg("Wayland output(%p) created", output);
+    output->cursor.surface = wl_compositor_create_surface(backend->server.compositor);
+    if (!output->cursor.surface)
+        ds_log_errno(DS_ERR, "Could not create cursor surface");
+
+    ds_inf("Wayland output(%p) created", output);
 
     return output;
 
@@ -134,10 +138,26 @@ output_leave_pointer(struct ds_wl_output *output)
 static void output_update_cursor(struct ds_wl_output *output)
 {
     struct ds_wl_pointer *pointer = output->cursor.pointer;
+    struct wl_buffer *buffer;
+    struct wl_cursor_image *image;
+
+    if (!output->backend->cursor)
+        return;
+
+    image = output->backend->cursor->images[0];
+    buffer = wl_cursor_image_get_buffer(image);
+    if (!buffer)
+        return;
+
+    output->cursor.hotspot_x = image->hotspot_x;
+    output->cursor.hotspot_y = image->hotspot_y;
 
     wl_pointer_set_cursor(pointer->wl_pointer, output->cursor.enter_serial,
             output->cursor.surface, output->cursor.hotspot_x,
             output->cursor.hotspot_y);
+    wl_surface_attach(output->cursor.surface, buffer, 0, 0);
+    wl_surface_damage(output->cursor.surface, 0, 0, image->width, image->height);
+    wl_surface_commit(output->cursor.surface);
 }
 
 static struct ds_wl_output *
@@ -170,6 +190,9 @@ wl_output_iface_destroy(struct ds_output *ds_output)
     if (output->surface)
         wl_surface_destroy(output->surface);
 
+    if (output->cursor.surface)
+        wl_surface_destroy(output->cursor.surface);
+
     wl_display_flush(output->backend->server.display);
 
     free(output);
index bec12ad..34fe78e 100644 (file)
@@ -120,6 +120,7 @@ seat_add_callback_handle_done(void *data, struct wl_callback *callback,
         uint32_t callback_data)
 {
     struct ds_wl_seat *seat = data;
+    struct ds_wl_backend_server *server;
 
     wl_callback_destroy(seat->initial_info_cb);
     seat->initial_info_cb = NULL;