[PATCH weston 2/6] xwayland: add simple xcb-cursor hook based on libXcursor

Tiago Vignatti tiago.vignatti at intel.com
Wed Jul 11 14:46:11 PDT 2012


It's in fact based on the core of libXcursor, which doesn't bring any Xlib
dependency.

Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
---
 configure.ac              |    2 +-
 src/xwayland/Makefile.am  |    1 +
 src/xwayland/xcb-cursor.c |  140 +++++++++++++++++++++++++++++++++++++++++++++
 src/xwayland/xwayland.h   |    2 +
 4 files changed, 144 insertions(+), 1 deletion(-)
 create mode 100644 src/xwayland/xcb-cursor.c

diff --git a/configure.ac b/configure.ac
index 6945652..ee35cac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -42,7 +42,7 @@ AC_ARG_ENABLE(xwayland, [  --enable-xwayland],,
 	      enable_xwayland=yes)
 AM_CONDITIONAL(ENABLE_XWAYLAND, test x$enable_xwayland = xyes)
 if test x$enable_xwayland = xyes; then
-  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-xfixes cairo-xcb)
+  PKG_CHECK_MODULES([XWAYLAND], xcb xcb-image xcb-render xcb-renderutil xcb-xfixes xcursor cairo-xcb)
   AC_DEFINE([BUILD_XWAYLAND], [1], [Build the X server launcher])
 
   AC_ARG_WITH(xserver-path, AS_HELP_STRING([--with-xserver-path=PATH],
diff --git a/src/xwayland/Makefile.am b/src/xwayland/Makefile.am
index 6772f8d..2268c07 100644
--- a/src/xwayland/Makefile.am
+++ b/src/xwayland/Makefile.am
@@ -18,6 +18,7 @@ xwayland_la_SOURCES =				\
 	window-manager.c			\
 	selection.c				\
 	launcher.c				\
+	xcb-cursor.c				\
 	xserver-protocol.c			\
 	xserver-server-protocol.h		\
 	hash.c					\
diff --git a/src/xwayland/xcb-cursor.c b/src/xwayland/xcb-cursor.c
new file mode 100644
index 0000000..700f7f7
--- /dev/null
+++ b/src/xwayland/xcb-cursor.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author: Tiago Vignatti
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xcursor/Xcursor.h>
+#include <xcb/xcb.h>
+#include <xcb/render.h>
+#include <xcb/xcb_image.h>
+#include <xcb/xcb_renderutil.h>
+
+xcb_cursor_t
+xcb_cursor_library_load_cursor(xcb_connection_t *c, const char *file);
+
+static xcb_cursor_t
+xcb_cursor_image_load_cursor(xcb_connection_t *c, const XcursorImage *img)
+{
+	xcb_screen_iterator_t s = xcb_setup_roots_iterator(xcb_get_setup(c));
+	xcb_screen_t *screen = s.data;
+	xcb_generic_error_t *error;
+	xcb_render_query_pict_formats_cookie_t formats_cookie;
+	xcb_render_query_pict_formats_reply_t *formats_reply;
+	xcb_render_pictforminfo_t *fmt;
+	xcb_image_t *xi;
+
+	formats_cookie = xcb_render_query_pict_formats(c);
+	formats_reply =
+		xcb_render_query_pict_formats_reply(c, formats_cookie, &error);
+	if (!formats_reply || error) {
+		fprintf(stderr, "query_pict_formats failed\n");
+		free(formats_reply);
+		free(error);
+		return XCB_NONE;
+	}
+	fmt = xcb_render_util_find_standard_format(formats_reply,
+						   XCB_PICT_STANDARD_ARGB_32);
+	if (!fmt) {
+		fprintf(stderr, "Failed to find format PICT_STANDARD_ARGB_32");
+		free(formats_reply);
+		return XCB_NONE;
+	}
+
+	xi = xcb_image_create(img->width, img->height,
+			      XCB_IMAGE_FORMAT_Z_PIXMAP, 32, 32, 32, 32,
+			      xcb_get_setup(c)->image_byte_order,
+			      xcb_get_setup(c)->bitmap_format_bit_order,
+			      0, 0, 0);
+	if (!xi) {
+		free(formats_reply);
+		return XCB_NONE;
+	}
+
+	xi->data = (uint8_t *) malloc(xi->stride * img->height);
+	if (!xi->data) {
+		xcb_image_destroy(xi);
+		free(formats_reply);
+		return XCB_NONE;
+	}
+
+	memcpy(xi->data, (char *) img->pixels, xi->stride * img->height);
+
+	xcb_pixmap_t pix = xcb_generate_id(c);
+	xcb_create_pixmap(c, 32, pix, screen->root, img->width, img->height);
+
+	xcb_render_picture_t pic = xcb_generate_id(c);
+	xcb_render_create_picture(c, pic, pix, fmt->id, 0, 0);
+
+	xcb_gcontext_t gc = xcb_generate_id(c);
+	xcb_create_gc(c, gc, pix, 0, 0);
+	xcb_image_put(c, pix, gc, xi, 0, 0, 0);
+	xcb_free_gc(c, gc);
+
+	xcb_cursor_t cursor = xcb_generate_id(c);
+	xcb_render_create_cursor(c, cursor, pic, img->xhot, img->yhot);
+
+	free(xi->data);
+	xcb_image_destroy(xi);
+	xcb_render_free_picture(c, pic);
+	xcb_free_pixmap(c, pix);
+	free(formats_reply);
+	return cursor;
+}
+
+static xcb_cursor_t
+xcb_cursor_images_load_cursor(xcb_connection_t *c, const XcursorImages *images)
+{
+	/* TODO: treat animated cursors as well */
+	if (images->nimage != 1)
+		return -1;
+
+	return xcb_cursor_image_load_cursor(c, images->images[0]);
+}
+
+xcb_cursor_t
+xcb_cursor_library_load_cursor(xcb_connection_t *c, const char *file)
+{
+	xcb_cursor_t cursor;
+	XcursorImages *images;
+	char *v = NULL;
+	int size = 0;
+
+	if (!file)
+		return 0;
+
+	v = getenv ("XCURSOR_SIZE");
+	if (v)
+		size = atoi(v);
+
+	if (!size)
+		size = 32;
+
+	images = XcursorLibraryLoadImages (file, NULL, size);
+	cursor = xcb_cursor_images_load_cursor (c, images);
+	XcursorImagesDestroy (images);
+
+	return cursor;
+}
diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h
index 438b7be..1a022d0 100644
--- a/src/xwayland/xwayland.h
+++ b/src/xwayland/xwayland.h
@@ -149,3 +149,5 @@ weston_wm_create(struct weston_xserver *wxs);
 void
 weston_wm_destroy(struct weston_wm *wm);
 
+xcb_cursor_t
+xcb_cursor_library_load_cursor(xcb_connection_t *c, const char *file);
-- 
1.7.9.5



More information about the wayland-devel mailing list