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

Kristian Høgsberg hoegsberg at gmail.com
Thu Jul 12 06:49:25 PDT 2012


On Thu, Jul 12, 2012 at 12:46:11AM +0300, Tiago Vignatti wrote:
> 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)

We already look up render formats in the wm, just add something like this:

@@ -1194,10 +1194,14 @@ wxs_wm_get_resources(struct weston_wm *wm)
                return;
 
        formats = xcb_render_query_pict_formats_formats(formats_reply);
-       for (i = 0; i < formats_reply->length; i++)
+       for (i = 0; i < formats_reply->length; i++) {
                if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT &&
                    formats[i].depth == 24)
-                       wm->render_format = formats[i];
+                       wm->render_format_depth_24 = formats[i];
+               if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT &&
+                   formats[i].depth == 32)
+                       wm->render_format_depth_32 = formats[i];
+       }
 
        free(formats_reply);
 }

to look up the 32 bit argb render format as well.  This way we also
only do it once.

>    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;
> +	}

So all of this will go away in favor of looking it up in get_resources.

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

Also, I don't we need to pull in xcb-image either.  If you look at

  http://cgit.freedesktop.org/xcb/util-image/tree/image/xcb_image.c

you can see that xcb_image_create() just stuffs most of the args into
the xcb_image_t struct so that it can feed them all to xcb_put_image
later when you call xcb_image_put.  I expect you're going to end up
with less code (and less deps) if you drop xcb-image.

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

You should be able to just pass img->pixels directly to xcb_put_image
and avoid the malloc and memcpy alltogether.

> +	xcb_pixmap_t pix = xcb_generate_id(c);

Let's keep variable declarations at the top of the function.

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

As a stylistic nit-pick, please leave a blank line before the final return.

> +}
> +
> +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
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list