summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Hindoe Paaboel Andersen <phomes@gmail.com>2013-03-21 21:05:32 +0100
committerKristian Høgsberg <krh@bitplanet.net>2013-03-21 18:00:23 -0400
commitc5145421af3e641b3070bba2a83d3c2f74a06f53 (patch)
tree13fd050d91468348bba194c310486f628268f04b
parenta2cd9983c3e017238a9e0fa41674171a9adacdc4 (diff)
downloadgtk+-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.c154
-rw-r--r--gdk/wayland/gdkprivate-wayland.h6
-rw-r--r--gdk/wayland/gdkwindow-wayland.c2
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,