From 93a338245a70a40473f225205f455875230f92aa Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 11 Jul 2012 14:43:16 +0100 Subject: [PATCH] wayland: Switch to new wayland cursors mechanism --- gdk/wayland/gdkcursor-wayland.c | 150 ++++++++++++++----------------- gdk/wayland/gdkdevice-wayland.c | 12 ++- gdk/wayland/gdkdisplay-wayland.h | 2 - gdk/wayland/gdkprivate-wayland.h | 4 +- 4 files changed, 77 insertions(+), 91 deletions(-) diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index cb0f377c99..7cc5f92735 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -34,8 +34,7 @@ #include "gdkwayland.h" #include -#include -#include +#include #define GDK_TYPE_WAYLAND_CURSOR (_gdk_wayland_cursor_get_type ()) #define GDK_WAYLAND_CURSOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursor)) @@ -52,8 +51,8 @@ struct _GdkWaylandCursor GdkCursor cursor; gchar *name; guint serial; - int x, y, width, height, size; - void *map; + int hotspot_x, hotspot_y; + int width, height; struct wl_buffer *buffer; }; @@ -83,12 +82,19 @@ gdk_wayland_cursor_get_image (GdkCursor *cursor) } struct wl_buffer * -_gdk_wayland_cursor_get_buffer (GdkCursor *cursor, int *x, int *y) +_gdk_wayland_cursor_get_buffer (GdkCursor *cursor, + int *x, + int *y, + int *w, + int *h) { GdkWaylandCursor *wayland_cursor = GDK_WAYLAND_CURSOR (cursor); - *x = wayland_cursor->x; - *y = wayland_cursor->y; + *x = wayland_cursor->hotspot_x; + *y = wayland_cursor->hotspot_y; + + *w = wayland_cursor->width; + *h = wayland_cursor->height; return wayland_cursor->buffer; } @@ -109,6 +115,8 @@ _gdk_wayland_cursor_init (GdkWaylandCursor *cursor) { } +/* Use to implement from_pixbuf below */ +#if 0 static void set_pixbuf (GdkWaylandCursor *cursor, GdkPixbuf *pixbuf) { @@ -170,6 +178,7 @@ create_cursor(GdkWaylandDisplay *display, GdkPixbuf *pixbuf, int x, int y) int stride, fd; char *filename; GError *error = NULL; + struct wl_shm_pool *pool; cursor = g_object_new (GDK_TYPE_WAYLAND_CURSOR, "cursor-type", GDK_CURSOR_IS_PIXMAP, @@ -236,109 +245,55 @@ create_cursor(GdkWaylandDisplay *display, GdkPixbuf *pixbuf, int x, int y) close(fd); - return GDK_CURSOR (cursor); + return GDK_CURSOR (cursor); } +#endif +/* TODO: Extend this table */ static const struct { GdkCursorType type; - const char *filename; - int hotspot_x, hotspot_y; -} cursor_definitions[] = { - { GDK_BLANK_CURSOR, NULL, 0, 0 }, - { GDK_HAND1, "hand1.png", 18, 11 }, - { GDK_HAND2, "hand2.png", 14, 8 }, - { GDK_LEFT_PTR, "left_ptr.png", 10, 5 }, - { GDK_SB_H_DOUBLE_ARROW, "sb_h_double_arrow.png", 15, 15 }, - { GDK_SB_V_DOUBLE_ARROW, "sb_v_double_arrow.png", 15, 15 }, - { GDK_XTERM, "xterm.png", 15, 15 }, - { GDK_BOTTOM_RIGHT_CORNER, "bottom_right_corner.png", 28, 28 } + const gchar *cursor_name; +} cursor_mapping[] = { + { GDK_BLANK_CURSOR, NULL }, + { GDK_HAND1, "hand1" }, + { GDK_HAND2, "hand2" }, + { GDK_LEFT_PTR, "left_ptr" }, + { GDK_SB_H_DOUBLE_ARROW, "sb_h_double_arrow" }, + { GDK_SB_V_DOUBLE_ARROW, "sb_v_double_arrow" }, + { GDK_XTERM, "xterm" }, + { GDK_BOTTOM_RIGHT_CORNER, "bottom_right_corner" } }; GdkCursor * _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, GdkCursorType cursor_type) { - GdkWaylandDisplay *wayland_display; - GdkPixbuf *pixbuf = NULL; - GError *error = NULL; int i; - for (i = 0; i < G_N_ELEMENTS (cursor_definitions); i++) + for (i = 0; i < G_N_ELEMENTS (cursor_mapping); i++) { - if (cursor_definitions[i].type == cursor_type) + if (cursor_mapping[i].type == cursor_type) break; } - if (i == G_N_ELEMENTS (cursor_definitions)) + if (i == G_N_ELEMENTS (cursor_mapping)) { g_warning ("Unhandled cursor type %d, falling back to blank\n", cursor_type); i = 0; } - wayland_display = GDK_WAYLAND_DISPLAY (display); - if (!wayland_display->cursors) - wayland_display->cursors = - g_new0 (GdkCursor *, G_N_ELEMENTS(cursor_definitions)); - if (wayland_display->cursors[i]) - return g_object_ref (wayland_display->cursors[i]); - - GDK_NOTE (CURSOR, - g_message ("Creating new cursor for type %d, filename %s", - cursor_type, cursor_definitions[i].filename)); - - if (cursor_type != GDK_BLANK_CURSOR) - { - const gchar * const *directories; - gint j; - - directories = g_get_system_data_dirs(); - - for (j = 0; directories[j] != NULL; j++) - { - gchar *filename; - filename = g_build_filename (directories[j], - "weston", - cursor_definitions[i].filename, - NULL); - if (g_file_test (filename, G_FILE_TEST_EXISTS)) - { - pixbuf = gdk_pixbuf_new_from_file (filename, &error); - - if (error != NULL) - { - g_warning ("Failed to load cursor: %s: %s", - filename, error->message); - g_error_free(error); - return NULL; - } - break; - } - } - - if (!pixbuf) - { - g_warning ("Unable to find cursor for: %s", - cursor_definitions[i].filename); - return NULL; - } - } - - wayland_display->cursors[i] = - create_cursor(wayland_display, pixbuf, - cursor_definitions[i].hotspot_x, - cursor_definitions[i].hotspot_y); - if (pixbuf) - g_object_unref (pixbuf); - - return g_object_ref (wayland_display->cursors[i]); + return _gdk_wayland_display_get_cursor_for_name (display, + cursor_mapping[i].cursor_name); } -GdkCursor* +GdkCursor * _gdk_wayland_display_get_cursor_for_name (GdkDisplay *display, const gchar *name) { GdkWaylandCursor *private; + GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (display); + struct wl_cursor *cursor; g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); @@ -349,9 +304,35 @@ _gdk_wayland_display_get_cursor_for_name (GdkDisplay *display, private->name = g_strdup (name); private->serial = theme_serial; + /* Blank cursor case */ + if (!name) + return GDK_CURSOR (private); + + cursor = wl_cursor_theme_get_cursor (wayland_display->cursor_theme, + name); + + if (!cursor) + { + g_warning (G_STRLOC ": Unable to load %s from the cursor theme", name); + g_object_unref (private); + return NULL; + } + + /* TODO: Do something clever so we can do animated cursors - move the + * wl_pointer_set_cursor to a function here so that we can do the magic to + * iterate through + */ + private->hotspot_x = cursor->images[0]->hotspot_x; + private->hotspot_y = cursor->images[0]->hotspot_y; + private->width = cursor->images[0]->width; + private->height = cursor->images[0]->height; + + private->buffer = wl_cursor_image_get_buffer(cursor->images[0]); + return GDK_CURSOR (private); } +/* TODO: Needs implementing */ GdkCursor * _gdk_wayland_display_get_cursor_for_pixbuf (GdkDisplay *display, GdkPixbuf *pixbuf, @@ -381,9 +362,8 @@ _gdk_wayland_display_get_default_cursor_size (GdkDisplay *display, guint *width, guint *height) { - /* FIXME: wayland settings? */ - *width = 64; - *height = 64; + *width = 32; + *height = 32; } void diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index c818596cc8..074f56fdca 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -80,6 +80,8 @@ struct _GdkWaylandDevice DataOffer *selection_offer; GdkWaylandSelectionOffer *selection_offer_out; + + struct wl_surface *pointer_surface; }; struct _GdkDeviceCore @@ -156,7 +158,7 @@ gdk_device_core_set_window_cursor (GdkDevice *device, { GdkWaylandDevice *wd = GDK_DEVICE_CORE(device)->device; struct wl_buffer *buffer; - int x, y; + int x, y, w, h; if (cursor) g_object_ref (cursor); @@ -169,8 +171,10 @@ gdk_device_core_set_window_cursor (GdkDevice *device, GDK_LEFT_PTR); } - buffer = _gdk_wayland_cursor_get_buffer(cursor, &x, &y); - wl_input_device_attach(wd->device, wd->time, buffer, x, y); + buffer = _gdk_wayland_cursor_get_buffer (cursor, &x, &y, &w, &h); + wl_pointer_set_cursor (wd->wl_pointer, wd->time, wd->pointer_surface, x, y); + wl_surface_attach (wd->pointer_surface, buffer, 0, 0); + wl_surface_damage (wd->pointer_surface, 0, 0, w, h); g_object_unref (cursor); } @@ -1274,6 +1278,8 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, wl_data_device_add_listener (device->data_device, &data_device_listener, device); + device->pointer_surface = + wl_compositor_create_surface (display_wayland->compositor); } static void diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index c614e9c8f3..00f3a399cb 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -92,8 +92,6 @@ struct _GdkWaylandDisplay cairo_device_t *cairo_device; #endif - GdkCursor **cursors; - #ifdef GDK_WAYLAND_USE_EGL PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; PFNEGLCREATEIMAGEKHRPROC create_image; diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 262f74dd82..59cd1734a1 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -68,7 +68,9 @@ gboolean _gdk_wayland_display_supports_cursor_color (GdkDisplay *display); struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkCursor *cursor, int *x, - int *y); + int *y, + int *w, + int *h); GdkDragProtocol _gdk_wayland_window_get_drag_protocol (GdkWindow *window, GdkWindow **target);