diff options
author | Thomas Hindoe Paaboel Andersen <phomes@gmail.com> | 2013-03-21 21:05:32 +0100 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-03-21 18:00:23 -0400 |
commit | c5145421af3e641b3070bba2a83d3c2f74a06f53 (patch) | |
tree | 13fd050d91468348bba194c310486f628268f04b | |
parent | a2cd9983c3e017238a9e0fa41674171a9adacdc4 (diff) | |
download | gtk+-c5145421af3e641b3070bba2a83d3c2f74a06f53.tar.gz |
wayland: complete cursor_for_pixbuf
Finishes the implementation for loading cursors from pixbufs.
Gnome bug #696223
-rw-r--r-- | gdk/wayland/gdkcursor-wayland.c | 154 | ||||
-rw-r--r-- | gdk/wayland/gdkprivate-wayland.h | 6 | ||||
-rw-r--r-- | gdk/wayland/gdkwindow-wayland.c | 2 |
3 files changed, 63 insertions, 99 deletions
diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index 198753e193..76d3708629 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -133,6 +133,8 @@ gdk_wayland_cursor_finalize (GObject *object) GdkWaylandCursor *cursor = GDK_WAYLAND_CURSOR (object); g_free (cursor->name); + if (cursor->cursor.type == GDK_CURSOR_IS_PIXMAP) + wl_buffer_destroy (cursor->buffer); G_OBJECT_CLASS (_gdk_wayland_cursor_parent_class)->finalize (object); } @@ -177,29 +179,27 @@ _gdk_wayland_cursor_init (GdkWaylandCursor *cursor) { } -/* Use to implement from_pixbuf below */ -#if 0 +/* Used to implement from_pixbuf below */ static void -set_pixbuf (GdkWaylandCursor *cursor, GdkPixbuf *pixbuf) +set_pixbuf (gpointer argb_pixels, int width, int height, GdkPixbuf *pixbuf) { int stride, i, n_channels; - unsigned char *pixels, *end, *argb_pixels, *s, *d; + unsigned char *pixels, *end, *s, *d; stride = gdk_pixbuf_get_rowstride(pixbuf); pixels = gdk_pixbuf_get_pixels(pixbuf); n_channels = gdk_pixbuf_get_n_channels(pixbuf); - argb_pixels = cursor->map; #define MULT(_d,c,a,t) \ do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0) if (n_channels == 4) { - for (i = 0; i < cursor->height; i++) + for (i = 0; i < height; i++) { s = pixels + i * stride; - end = s + cursor->width * 4; - d = argb_pixels + i * cursor->width * 4; + end = s + width * 4; + d = argb_pixels + i * width * 4; while (s < end) { unsigned int t; @@ -215,11 +215,11 @@ set_pixbuf (GdkWaylandCursor *cursor, GdkPixbuf *pixbuf) } else if (n_channels == 3) { - for (i = 0; i < cursor->height; i++) + for (i = 0; i < height; i++) { s = pixels + i * stride; - end = s + cursor->width * 3; - d = argb_pixels + i * cursor->width * 4; + end = s + width * 3; + d = argb_pixels + i * width * 4; while (s < end) { d[0] = s[2]; @@ -233,84 +233,6 @@ set_pixbuf (GdkWaylandCursor *cursor, GdkPixbuf *pixbuf) } } -static GdkCursor * -create_cursor(GdkWaylandDisplay *display, GdkPixbuf *pixbuf, int x, int y) -{ - GdkWaylandCursor *cursor; - 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, - "display", display, - NULL); - cursor->name = NULL; - cursor->serial = theme_serial; - cursor->x = x; - cursor->y = y; - if (pixbuf) - { - cursor->width = gdk_pixbuf_get_width (pixbuf); - cursor->height = gdk_pixbuf_get_height (pixbuf); - } - else - { - cursor->width = 1; - cursor->height = 1; - } - - stride = cursor->width * 4; - cursor->size = stride * cursor->height; - - fd = g_file_open_tmp("wayland-shm-XXXXXX", &filename, &error); - if (fd < 0) - { - g_critical (G_STRLOC ": Error opening temporary file for buffer: %s", - error->message); - g_error_free (error); - return NULL; - } - - unlink (filename); - g_free (filename); - - if (ftruncate(fd, cursor->size) < 0) - { - g_critical (G_STRLOC ": Error truncating file for buffer: %s", - g_strerror (errno)); - close(fd); - return NULL; - } - - cursor->map = mmap(NULL, cursor->size, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (cursor->map == MAP_FAILED) - { - g_critical (G_STRLOC ": Error mmap'ing file for buffer: %s", - g_strerror (errno)); - close(fd); - return NULL; - } - - if (pixbuf) - set_pixbuf (cursor, pixbuf); - else - memset (cursor->map, 0, 4); - - cursor->buffer = wl_shm_create_buffer(display->shm, - fd, - cursor->width, - cursor->height, - stride, WL_SHM_FORMAT_ARGB8888); - - close(fd); - - return GDK_CURSOR (cursor); -} -#endif - GdkCursor * _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, GdkCursorType cursor_type) @@ -395,29 +317,65 @@ _gdk_wayland_display_get_cursor_for_name (GdkDisplay *display, return GDK_CURSOR (private); } -/* TODO: Needs implementing */ GdkCursor * _gdk_wayland_display_get_cursor_for_pixbuf (GdkDisplay *display, GdkPixbuf *pixbuf, gint x, gint y) { - GdkWaylandCursor *private; + GdkWaylandCursor *cursor; + GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (display); + int stride; + size_t size; + gpointer data; + struct wl_shm_pool *pool; g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); g_return_val_if_fail (0 <= x && x < gdk_pixbuf_get_width (pixbuf), NULL); g_return_val_if_fail (0 <= y && y < gdk_pixbuf_get_height (pixbuf), NULL); - private = g_object_new (GDK_TYPE_WAYLAND_CURSOR, - "cursor-type", GDK_CURSOR_IS_PIXMAP, - "display", display, - NULL); + cursor = g_object_new (GDK_TYPE_WAYLAND_CURSOR, + "cursor-type", GDK_CURSOR_IS_PIXMAP, + "display", wayland_display, + NULL); + cursor->name = NULL; + cursor->serial = theme_serial; + cursor->hotspot_x = x; + cursor->hotspot_y = y; - private->name = NULL; - private->serial = theme_serial; + if (pixbuf) + { + cursor->width = gdk_pixbuf_get_width (pixbuf); + cursor->height = gdk_pixbuf_get_height (pixbuf); + } + else + { + cursor->width = 1; + cursor->height = 1; + } - return GDK_CURSOR (private); + pool = _create_shm_pool (wayland_display->shm, + cursor->width, + cursor->height, + &size, + &data); + + if (pixbuf) + set_pixbuf (data, cursor->width, cursor->height, pixbuf); + else + memset (data, 0, 4); + + stride = cursor->width * 4; + cursor->buffer = wl_shm_pool_create_buffer (pool, 0, + cursor->width, + cursor->height, + stride, + WL_SHM_FORMAT_ARGB8888); + + wl_shm_pool_destroy (pool); + + return GDK_CURSOR (cursor); } void diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index 480108ec46..efbc87e3f5 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -164,4 +164,10 @@ void _gdk_wayland_window_set_device_grabbed (GdkWindow *window, guint32 _gdk_wayland_display_get_serial (GdkWaylandDisplay *wayland_display); void _gdk_wayland_display_update_serial (GdkWaylandDisplay *wayland_display, guint32 serial); +struct wl_shm_pool * _create_shm_pool (struct wl_shm *shm, + int width, + int height, + size_t *buf_length, + void **data_out); + #endif /* __GDK_PRIVATE_WAYLAND_H__ */ diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 42cce16542..d65f86dcd9 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -387,7 +387,7 @@ gdk_wayland_cairo_surface_destroy (void *p) } -static struct wl_shm_pool * +struct wl_shm_pool * _create_shm_pool (struct wl_shm *shm, int width, int height, |