wayland: Switch to new wayland cursors mechanism

This commit is contained in:
Rob Bradford 2012-07-11 14:43:16 +01:00
parent 33b9f8e1b8
commit 93a338245a
4 changed files with 77 additions and 91 deletions

View File

@ -34,8 +34,7 @@
#include "gdkwayland.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <sys/mman.h>
#include <errno.h>
#include <wayland-cursor.h>
#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

View File

@ -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

View File

@ -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;

View File

@ -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);