[PATCH weston] window: use libwayland-cursor instead of libXcursor

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Tue May 22 05:39:42 PDT 2012


---
 clients/clickdot.c      |    3 +-
 clients/desktop-shell.c |    5 +-
 clients/dnd.c           |   33 +++----
 clients/eventdemo.c     |    5 +-
 clients/flower.c        |    3 +-
 clients/gears.c         |    3 +-
 clients/smoke.c         |    3 +-
 clients/terminal.c      |    3 +-
 clients/window.c        |  232 +++++++----------------------------------------
 clients/window.h        |    6 +-
 configure.ac            |    2 +-
 11 files changed, 65 insertions(+), 233 deletions(-)

diff --git a/clients/clickdot.c b/clients/clickdot.c
index b9669d1..4e1538a 100644
--- a/clients/clickdot.c
+++ b/clients/clickdot.c
@@ -32,6 +32,7 @@
 
 #include <linux/input.h>
 #include <wayland-client.h>
+#include <wayland-cursor.h>
 
 #include "window.h"
 
@@ -218,7 +219,7 @@ motion_handler(struct widget *widget,
 
 	window_schedule_redraw(clickdot->window);
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 static void
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 7554df3..2473f36 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -33,6 +33,7 @@
 #include <linux/input.h>
 
 #include <wayland-client.h>
+#include <wayland-cursor.h>
 #include "window.h"
 #include "../shared/cairo-util.h"
 #include "../shared/config-parser.h"
@@ -240,7 +241,7 @@ panel_launcher_enter_handler(struct widget *widget, struct input *input,
 	launcher->focused = 1;
 	widget_schedule_redraw(widget);
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 static void
@@ -511,7 +512,7 @@ unlock_dialog_widget_enter_handler(struct widget *widget,
 	dialog->button_focused = 1;
 	widget_schedule_redraw(widget);
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 static void
diff --git a/clients/dnd.c b/clients/dnd.c
index b56cd59..b0f0fa9 100644
--- a/clients/dnd.c
+++ b/clients/dnd.c
@@ -32,6 +32,7 @@
 #include <sys/epoll.h>
 
 #include <wayland-client.h>
+#include <wayland-cursor.h>
 
 #include "window.h"
 #include "../shared/cairo-util.h"
@@ -311,25 +312,20 @@ create_drag_cursor(struct dnd_drag *dnd_drag,
 		   struct item *item, int32_t x, int32_t y, double opacity)
 {
 	struct dnd *dnd = dnd_drag->dnd;
-	cairo_surface_t *surface, *pointer;
-	int32_t pointer_width, pointer_height, hotspot_x, hotspot_y;
+	cairo_surface_t *surface;
+	struct wl_cursor_image *pointer;
 	struct rectangle rectangle;
 	cairo_pattern_t *pattern;
 	cairo_t *cr;
 
-	pointer = display_get_pointer_surface(dnd->display,
-					      POINTER_DRAGGING,
-					      &pointer_width,
-					      &pointer_height,
-					      &hotspot_x,
-					      &hotspot_y);
+	pointer = display_get_pointer_image(dnd->display, WL_CURSOR_DRAGGING);
 
-	rectangle.width = item_width + 2 * pointer_width;
-	rectangle.height = item_height + 2 * pointer_height;
+	rectangle.width = item_width + 2 * pointer->width;
+	rectangle.height = item_height + 2 * pointer->height;
 	surface = display_create_surface(dnd->display, NULL, &rectangle, 0);
 
 	cr = cairo_create(surface);
-	cairo_translate(cr, pointer_width, pointer_height);
+	cairo_translate(cr, pointer->width, pointer->height);
 
 	cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
 	cairo_set_source_rgba(cr, 0, 0, 0, 0);
@@ -341,17 +337,12 @@ create_drag_cursor(struct dnd_drag *dnd_drag,
 	cairo_mask(cr, pattern);
 	cairo_pattern_destroy(pattern);
 
-	cairo_set_source_surface(cr, pointer,
-				 x - item->x - hotspot_x,
-				 y - item->y - hotspot_y);
-	cairo_surface_destroy(pointer);
-	cairo_paint(cr);
 	/* FIXME: more cairo-gl brokeness */
 	surface_flush_device(surface);
 	cairo_destroy(cr);
 
-	dnd_drag->hotspot_x = pointer_width + x - item->x;
-	dnd_drag->hotspot_y = pointer_height + y - item->y;
+	dnd_drag->hotspot_x = pointer->width + x - item->x;
+	dnd_drag->hotspot_y = pointer->height + y - item->y;
 	dnd_drag->width = rectangle.width;
 	dnd_drag->height = rectangle.height;
 
@@ -419,7 +410,7 @@ dnd_button_handler(struct widget *widget,
 					  dnd_drag->drag_surface,
 					  serial);
 
-		input_set_pointer_image(input, time, POINTER_DRAGGING);
+		input_set_pointer_image(input, time, WL_CURSOR_DRAGGING);
 
 		dnd_drag->opaque =
 			create_drag_cursor(dnd_drag, item, x, y, 1);
@@ -443,9 +434,9 @@ lookup_cursor(struct dnd *dnd, int x, int y)
 
 	item = dnd_get_item(dnd, x, y);
 	if (item)
-		return POINTER_HAND1;
+		return WL_CURSOR_HAND1;
 	else
-		return POINTER_LEFT_PTR;
+		return WL_CURSOR_LEFT_PTR;
 }
 
 static int
diff --git a/clients/eventdemo.c b/clients/eventdemo.c
index 8e63540..3c4233f 100644
--- a/clients/eventdemo.c
+++ b/clients/eventdemo.c
@@ -35,6 +35,7 @@
 
 #include <cairo.h>
 
+#include <wayland-cursor.h>
 #include "window.h"
 
 /** window title */
@@ -247,9 +248,9 @@ motion_handler(struct widget *widget, struct input *input, uint32_t time,
 
 	if (x > e->x && x < e->x + e->w)
 		if (y > e->y && y < e->y + e->h)
-			return POINTER_HAND1;
+			return WL_CURSOR_HAND1;
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 /**
diff --git a/clients/flower.c b/clients/flower.c
index 2d54b38..84f8e6c 100644
--- a/clients/flower.c
+++ b/clients/flower.c
@@ -32,6 +32,7 @@
 
 #include <linux/input.h>
 #include <wayland-client.h>
+#include <wayland-cursor.h>
 #include "window.h"
 
 struct flower {
@@ -133,7 +134,7 @@ static int
 motion_handler(struct widget *widget, struct input *input,
 	       uint32_t time, float x, float y, void *data)
 {
-	return POINTER_HAND1;
+	return WL_CURSOR_HAND1;
 }
 
 static void
diff --git a/clients/gears.c b/clients/gears.c
index ce8212a..be0f9a4 100644
--- a/clients/gears.c
+++ b/clients/gears.c
@@ -35,6 +35,7 @@
 
 #include <linux/input.h>
 #include <wayland-client.h>
+#include <wayland-cursor.h>
 
 #include "window.h"
 
@@ -243,7 +244,7 @@ motion_handler(struct widget *widget, struct input *input,
 			gears->view.rotx = gears->view.rotx + 360;
 	}
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 static void
diff --git a/clients/smoke.c b/clients/smoke.c
index d730124..6104b7c 100644
--- a/clients/smoke.c
+++ b/clients/smoke.c
@@ -30,6 +30,7 @@
 #include <cairo.h>
 
 #include <wayland-client.h>
+#include <wayland-cursor.h>
 #include "window.h"
 
 struct smoke {
@@ -258,7 +259,7 @@ smoke_motion_handler(struct widget *widget, struct input *input,
 			smoke->b[0].d[k] += 1;
 		}
 
-	return POINTER_HAND1;
+	return WL_CURSOR_HAND1;
 }
 
 static void
diff --git a/clients/terminal.c b/clients/terminal.c
index c7300e6..4932532 100644
--- a/clients/terminal.c
+++ b/clients/terminal.c
@@ -34,6 +34,7 @@
 #include <sys/epoll.h>
 
 #include <wayland-client.h>
+#include <wayland-cursor.h>
 
 #include "window.h"
 
@@ -2245,7 +2246,7 @@ motion_handler(struct widget *widget,
 		widget_schedule_redraw(widget);
 	}
 
-	return POINTER_IBEAM;
+	return WL_CURSOR_IBEAM;
 }
 
 static struct terminal *
diff --git a/clients/window.c b/clients/window.c
index 5c4d28b..e4cfff9 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -55,7 +55,7 @@
 #endif
 
 #include <xkbcommon/xkbcommon.h>
-#include <X11/Xcursor/Xcursor.h>
+#include <wayland-cursor.h>
 
 #include <linux/input.h>
 #include <wayland-client.h>
@@ -63,7 +63,6 @@
 
 #include "window.h"
 
-struct cursor;
 struct shm_pool;
 
 struct display {
@@ -103,8 +102,7 @@ struct display {
 		xkb_mod_mask_t shift_mask;
 	} xkb;
 
-	struct cursor *cursors;
-	struct shm_pool *cursor_shm_pool;
+	struct wl_cursor_theme *cursor_theme;
 
 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
 	PFNEGLCREATEIMAGEKHRPROC create_image;
@@ -268,18 +266,6 @@ struct menu {
 	menu_func_t func;
 };
 
-struct cursor_image {
-	cairo_surface_t *surface;
-	int width, height;
-	int hotspot_x, hotspot_y;
-	int delay;
-};
-
-struct cursor {
-	int n_images;
-	struct cursor_image *images;
-};
-
 struct shm_pool {
 	struct wl_shm_pool *pool;
 	size_t size;
@@ -288,8 +274,8 @@ struct shm_pool {
 };
 
 enum {
-	POINTER_DEFAULT = 100,
-	POINTER_UNSET
+	WL_CURSOR_DEFAULT = 100,
+	WL_CURSOR_UNSET
 };
 
 enum window_location {
@@ -418,14 +404,6 @@ shm_surface_data_destroy(void *p)
 		shm_pool_destroy(data->pool);
 }
 
-static void
-shm_surface_write(cairo_surface_t *surface, unsigned char *data, int count)
-{
-	void *dest = cairo_image_surface_get_data(surface);
-
-	memcpy(dest, data, count);
-}
-
 static struct wl_shm_pool *
 make_shm_pool(struct display *display, int size, void **data)
 {
@@ -635,156 +613,13 @@ display_create_surface(struct display *display,
 	return display_create_shm_surface(display, rectangle, flags, NULL);
 }
 
-static const char *cursors[] = {
-	"bottom_left_corner",
-	"bottom_right_corner",
-	"bottom_side",
-	"grabbing",
-	"left_ptr",
-	"left_side",
-	"right_side",
-	"top_left_corner",
-	"top_right_corner",
-	"top_side",
-	"xterm",
-	"hand1",
-};
-
-static void
-create_cursor_from_images(struct display *display, struct cursor *cursor,
-			  XcursorImages *images)
-{
-	int i;
-	struct rectangle rect;
-	XcursorImage *image;
-
-	cursor->images = malloc(images->nimage * sizeof *cursor->images);
-	cursor->n_images = images->nimage;
-
-	for (i = 0; i < images->nimage; i++) {
-		image = images->images[i];
-
-		rect.width = image->width;
-		rect.height = image->height;
-
-		cursor->images[i].surface =
-			display_create_shm_surface_from_pool(display, &rect, 0,
-							     display->cursor_shm_pool);
-
-		shm_surface_write(cursor->images[i].surface,
-				  (unsigned char *) image->pixels,
-				  image->width * image->height * sizeof image->pixels[0]);
-
-		cursor->images[i].width = image->width;
-		cursor->images[i].height = image->height;
-		cursor->images[i].hotspot_x = image->xhot;
-		cursor->images[i].hotspot_y = image->yhot;
-		cursor->images[i].delay = image->delay;
-	}
-
-}
-
-static size_t
-data_length_for_cursor_images(XcursorImages *images)
-{
-	int i;
-	size_t length = 0;
-	struct rectangle rect;
-
-	for (i = 0; i < images->nimage; i++) {
-		rect.width = images->images[i]->width;
-		rect.height = images->images[i]->height;
-		length += data_length_for_shm_surface(&rect);
-	}
-
-	return length;
-}
-
-static void
-create_cursors(struct display *display)
-{
-	int i, count;
-	size_t pool_size = 0;
-	struct cursor *cursor;
-	XcursorImages **images;
-
-	count = ARRAY_LENGTH(cursors);
-	display->cursors = malloc(count * sizeof *display->cursors);
-	images = malloc(count * sizeof images[0]);
-
-	for (i = 0; i < count; i++) {
-		images[i] = XcursorLibraryLoadImages(cursors[i], NULL, 32);
-		if (!images[i]) {
-			fprintf(stderr, "Error loading cursor: %s\n",
-				cursors[i]);
-			continue;
-		}
-		pool_size += data_length_for_cursor_images(images[i]);
-	}
-
-	display->cursor_shm_pool = shm_pool_create(display, pool_size);
-
-	for (i = 0; i < count; i++) {
-		cursor = &display->cursors[i];
-
-		if (!images[i]) {
-			cursor->n_images = 0;
-			cursor->images = NULL;
-			continue;
-		}
-
-		create_cursor_from_images(display, cursor, images[i]);
-
-		XcursorImagesDestroy(images[i]);
-	}
-
-	free(images);
-}
-
-static void
-destroy_cursor_images(struct cursor *cursor)
-{
-	int i;
-
-	for (i = 0; i < cursor->n_images; i++)
-		if (cursor->images[i].surface)
-			cairo_surface_destroy(cursor->images[i].surface);
-
-	free(cursor->images);
-}
-
-static void
-destroy_cursors(struct display *display)
-{
-	int i, count;
-
-	count = ARRAY_LENGTH(cursors);
-	for (i = 0; i < count; ++i) {
-		destroy_cursor_images(&display->cursors[i]);
-	}
-
-	free(display->cursors);
-	shm_pool_destroy(display->cursor_shm_pool);
-}
-
-cairo_surface_t *
-display_get_pointer_surface(struct display *display, int pointer,
-			    int *width, int *height,
-			    int *hotspot_x, int *hotspot_y)
+struct wl_cursor_image *
+display_get_pointer_image(struct display *display, int pointer)
 {
-	struct cursor *cursor = &display->cursors[pointer];
-	cairo_surface_t *surface = cursor->images[0].surface;
+	struct wl_cursor *cursor =
+		wl_cursor_theme_get_cursor(display->cursor_theme, pointer);
 
-	/* FIXME returning information for the first image. Something better
-	 * is needed for animated cursors */
-
-	*width = cairo_image_surface_get_width(surface);
-	*height = cairo_image_surface_get_height(surface);
-
-	*hotspot_x = cursor->images[0].hotspot_x;
-	*hotspot_y = cursor->images[0].hotspot_y;
-
-	return cairo_surface_reference(surface);
+	return cursor ? cursor->images[0] : NULL;
 }
 
 static void
@@ -1271,7 +1106,7 @@ frame_button_enter_handler(struct widget *widget,
 	widget_schedule_redraw(frame_button->widget);
 	frame_button->state = FRAME_BUTTON_OVER;
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 static void
@@ -1488,25 +1323,25 @@ frame_get_pointer_image_for_location(struct frame *frame, struct input *input)
 	location = frame_get_pointer_location(frame, input->sx, input->sy);
 	switch (location) {
 	case WINDOW_RESIZING_TOP:
-		return POINTER_TOP;
+		return WL_CURSOR_TOP;
 	case WINDOW_RESIZING_BOTTOM:
-		return POINTER_BOTTOM;
+		return WL_CURSOR_BOTTOM;
 	case WINDOW_RESIZING_LEFT:
-		return POINTER_LEFT;
+		return WL_CURSOR_LEFT;
 	case WINDOW_RESIZING_RIGHT:
-		return POINTER_RIGHT;
+		return WL_CURSOR_RIGHT;
 	case WINDOW_RESIZING_TOP_LEFT:
-		return POINTER_TOP_LEFT;
+		return WL_CURSOR_TOP_LEFT;
 	case WINDOW_RESIZING_TOP_RIGHT:
-		return POINTER_TOP_RIGHT;
+		return WL_CURSOR_TOP_RIGHT;
 	case WINDOW_RESIZING_BOTTOM_LEFT:
-		return POINTER_BOTTOM_LEFT;
+		return WL_CURSOR_BOTTOM_LEFT;
 	case WINDOW_RESIZING_BOTTOM_RIGHT:
-		return POINTER_BOTTOM_RIGHT;
+		return WL_CURSOR_BOTTOM_RIGHT;
 	case WINDOW_EXTERIOR:
 	case WINDOW_TITLEBAR:
 	default:
-		return POINTER_LEFT_PTR;
+		return WL_CURSOR_LEFT_PTR;
 	}
 }
 
@@ -1579,7 +1414,7 @@ frame_button_handler(struct widget *widget,
 		case WINDOW_TITLEBAR:
 			if (!window->shell_surface)
 				break;
-			input_set_pointer_image(input, time, POINTER_DRAGGING);
+			input_set_pointer_image(input, time, WL_CURSOR_DRAGGING);
 			input_ungrab(input);
 			wl_shell_surface_move(window->shell_surface,
 					      input_get_seat(input),
@@ -1671,7 +1506,7 @@ input_set_focus_widget(struct input *input, struct widget *focus,
 		       float x, float y)
 {
 	struct widget *old, *widget;
-	int pointer = POINTER_LEFT_PTR;
+	int pointer = WL_CURSOR_LEFT_PTR;
 
 	if (focus == input->focus_widget)
 		return;
@@ -1707,7 +1542,7 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
 	struct input *input = data;
 	struct window *window = input->pointer_focus;
 	struct widget *widget;
-	int cursor = POINTER_LEFT_PTR;
+	int cursor = WL_CURSOR_LEFT_PTR;
 	float sx = wl_fixed_to_double(sx_w);
 	float sy = wl_fixed_to_double(sy_w);
 
@@ -1838,7 +1673,7 @@ input_remove_pointer_focus(struct input *input)
 	input_set_focus_widget(input, NULL, 0, 0);
 
 	input->pointer_focus = NULL;
-	input->current_cursor = POINTER_UNSET;
+	input->current_cursor = WL_CURSOR_UNSET;
 }
 
 static void
@@ -2161,21 +1996,22 @@ input_set_pointer_image(struct input *input, uint32_t time, int pointer)
 {
 	struct display *display = input->display;
 	struct wl_buffer *buffer;
-	struct cursor_image *image;
+	struct wl_cursor *cursor;
+	struct wl_cursor_image *image;
 
 	if (pointer == input->current_cursor)
 		return;
 
-	if (display->cursors[pointer].n_images == 0)
+	cursor = wl_cursor_theme_get_cursor(display->cursor_theme, pointer);
+	if (!cursor)
 		return;
 
-	image = &display->cursors[pointer].images[0];
-
-	if (!image->surface)
+	image = cursor->images[0];
+	buffer = wl_cursor_image_get_buffer(image);
+	if (!buffer)
 		return;
 
 	input->current_cursor = pointer;
-	buffer = display_get_buffer_for_surface(display, image->surface);
 	wl_pointer_attach(input->pointer, time, buffer,
 			  image->hotspot_x, image->hotspot_y);
 }
@@ -2737,7 +2573,7 @@ menu_motion_handler(struct widget *widget,
 	if (widget == menu->widget)
 		menu_set_item(data, y);
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 static int
@@ -2749,7 +2585,7 @@ menu_enter_handler(struct widget *widget,
 	if (widget == menu->widget)
 		menu_set_item(data, y);
 
-	return POINTER_LEFT_PTR;
+	return WL_CURSOR_LEFT_PTR;
 }
 
 static void
@@ -3256,7 +3092,7 @@ display_create(int argc, char *argv[])
 	d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR");
 	d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR");
 
-	create_cursors(d);
+	d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm);
 
 	d->theme = theme_create();
 
@@ -3302,7 +3138,7 @@ display_destroy(struct display *display)
 	fini_xkb(display);
 
 	theme_destroy(display->theme);
-	destroy_cursors(display);
+	wl_cursor_theme_destroy(display->cursor_theme);
 
 #ifdef HAVE_CAIRO_EGL
 	fini_egl(display);
diff --git a/clients/window.h b/clients/window.h
index 162cc34..db232e0 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -123,10 +123,8 @@ struct wl_buffer *
 display_get_buffer_for_surface(struct display *display,
 			       cairo_surface_t *surface);
 
-cairo_surface_t *
-display_get_pointer_surface(struct display *display, int pointer,
-			    int *width, int *height,
-			    int *hotspot_x, int *hotspot_y);
+struct wl_cursor_image *
+display_get_pointer_image(struct display *display, int pointer);
 
 void
 display_defer(struct display *display, struct task *task);
diff --git a/configure.ac b/configure.ac
index ceed18d..d4e596c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -139,7 +139,7 @@ AM_CONDITIONAL(BUILD_CLIENTS, test x$enable_clients = xyes)
 if test x$enable_clients = xyes; then
   AC_DEFINE([BUILD_CLIENTS], [1], [Build the Wayland clients])
 
-  PKG_CHECK_MODULES(CLIENT, [wayland-client wayland-egl egl >= 7.10 cairo >= 1.10.0 xkbcommon xcursor])
+  PKG_CHECK_MODULES(CLIENT, [wayland-client wayland-egl egl >= 7.10 cairo >= 1.10.0 xkbcommon wayland-cursor])
 
   CLIENT_CFLAGS="$CLIENT_CFLAGS $IMAGE_CFLAGS"
   CLIENT_LIBS="$CLIENT_LIBS $IMAGE_LIBS"
-- 
1.7.4.1



More information about the wayland-devel mailing list