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

Signed-off-by: Tiago Vignatti <[email protected]>
---
v2: no file split; removed a bunch of xcb dependencies; style nit-picking
fixed.

 configure.ac                  |    2 +-
 src/xwayland/window-manager.c |   77 +++++++++++++++++++++++++++++++++++++++--
 src/xwayland/xwayland.h       |    3 +-
 3 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6945652..6c27cd4 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-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/window-manager.c b/src/xwayland/window-manager.c
index b922e9b..738e8a2 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -31,6 +31,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <signal.h>
+#include <X11/Xcursor/Xcursor.h>
 
 #include "xwayland.h"
 
@@ -140,6 +141,77 @@ get_atom_name(xcb_connection_t *c, xcb_atom_t atom)
        return buffer;
 }
 
+static xcb_cursor_t
+xcb_cursor_image_load_cursor(struct weston_wm *wm, const XcursorImage *img)
+{
+       xcb_connection_t *c = wm->conn;
+       xcb_screen_iterator_t s = xcb_setup_roots_iterator(xcb_get_setup(c));
+       xcb_screen_t *screen = s.data;
+       xcb_gcontext_t gc;
+       xcb_pixmap_t pix;
+       xcb_render_picture_t pic;
+       xcb_cursor_t cursor;
+       int stride = img->width * 4;
+
+       pix = xcb_generate_id(c);
+       xcb_create_pixmap(c, 32, pix, screen->root, img->width, img->height);
+
+       pic = xcb_generate_id(c);
+       xcb_render_create_picture(c, pic, pix, wm->render_format_depth_32.id,
+                                 0, 0);
+
+       gc = xcb_generate_id(c);
+       xcb_create_gc(c, gc, pix, 0, 0);
+
+       xcb_put_image(c, XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc,
+                     img->width, img->height, 0, 0, 0, 32,
+                     stride * img->height, (uint8_t *) img->pixels);
+       xcb_free_gc(c, gc);
+
+       cursor = xcb_generate_id(c);
+       xcb_render_create_cursor(c, cursor, pic, img->xhot, img->yhot);
+
+       xcb_render_free_picture(c, pic);
+       xcb_free_pixmap(c, pix);
+
+       return cursor;
+}
+
+static xcb_cursor_t
+xcb_cursor_images_load_cursor(struct weston_wm *wm, const XcursorImages 
*images)
+{
+       /* TODO: treat animated cursors as well */
+       if (images->nimage != 1)
+               return -1;
+
+       return xcb_cursor_image_load_cursor(wm, images->images[0]);
+}
+
+static xcb_cursor_t
+xcb_cursor_library_load_cursor(struct weston_wm *wm, 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 (wm, images);
+       XcursorImagesDestroy (images);
+
+       return cursor;
+}
+
 void
 dump_property(struct weston_wm *wm,
              xcb_atom_t property, xcb_get_property_reply_t *reply)
@@ -528,7 +600,7 @@ weston_wm_handle_map_request(struct weston_wm *wm, 
xcb_generic_event_t *event)
                cairo_xcb_surface_create_with_xrender_format(wm->conn,
                                                             wm->screen,
                                                             window->frame_id,
-                                                            &wm->render_format,
+                                                            
&wm->render_format_depth_24,
                                                             width, height);
 
        hash_table_insert(wm->window_hash, window->frame_id, window);
@@ -1085,7 +1157,8 @@ wxs_wm_get_resources(struct weston_wm *wm)
 
        free(xfixes_reply);
 
-       wm->render_format = *(find_depth(wm->conn, 24));
+       wm->render_format_depth_24 = *(find_depth(wm->conn, 24));
+       wm->render_format_depth_32 = *(find_depth(wm->conn, 32));
 }
 
 static void
diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h
index 438b7be..c912214 100644
--- a/src/xwayland/xwayland.h
+++ b/src/xwayland/xwayland.h
@@ -58,7 +58,8 @@ struct weston_wm {
        xcb_window_t wm_window;
        struct weston_wm_window *focus_window;
        struct theme *theme;
-       xcb_render_pictforminfo_t render_format;
+       xcb_render_pictforminfo_t render_format_depth_24;
+       xcb_render_pictforminfo_t render_format_depth_32;
        struct wl_listener activate_listener;
 
        xcb_window_t selection_window;
-- 
1.7.9.5

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to