mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 19:00:08 +00:00
wayland: Switch to new wayland cursors mechanism
This commit is contained in:
parent
33b9f8e1b8
commit
93a338245a
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user