[gtk/wayland-cursor-scale-for-4-6: 2/2] wayland: Make cursors have the right size
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wayland-cursor-scale-for-4-6: 2/2] wayland: Make cursors have the right size
- Date: Fri, 27 May 2022 10:59:32 +0000 (UTC)
commit c47759bd3dd23a4c9ab9049f20bb56efb622693a
Author: Matthias Clasen <mclasen redhat com>
Date: Thu May 26 22:23:31 2022 -0400
wayland: Make cursors have the right size
The Wayland protocol requires that width and height
of cursor surfaces is an integer multiple of the
surface scale. Make it so.
Fixes: #4746
gdk/wayland/cursor/wayland-cursor.c | 46 +++++++++++++++++++++++++++----------
1 file changed, 34 insertions(+), 12 deletions(-)
---
diff --git a/gdk/wayland/cursor/wayland-cursor.c b/gdk/wayland/cursor/wayland-cursor.c
index 572b056b30..071824d914 100644
--- a/gdk/wayland/cursor/wayland-cursor.c
+++ b/gdk/wayland/cursor/wayland-cursor.c
@@ -203,12 +203,16 @@ static struct wl_cursor *
wl_cursor_create_from_xcursor_images(XcursorImages *images,
struct wl_cursor_theme *theme,
const char *name,
- unsigned int load_size)
+ unsigned int size,
+ unsigned int scale)
{
struct cursor *cursor;
struct cursor_image *image;
- int i, size;
+ int i, nbytes;
+ unsigned int load_size;
+ int width, height;
+ load_size = size * scale;
cursor = malloc(sizeof *cursor);
if (!cursor)
return NULL;
@@ -232,22 +236,37 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
image->theme = theme;
image->buffer = NULL;
- image->image.width = images->images[i]->width;
- image->image.height = images->images[i]->height;
+ /* ensure that width and height are multiples of scale */
+ width = images->images[i]->width;
+ if ((width % scale) != 0)
+ width = (width / scale + 1) * scale;
+
+ height = images->images[i]->height;
+ if ((height % scale) != 0)
+ height = (height / scale + 1) * scale;
+
+ image->image.width = width;
+ image->image.height = height;
image->image.hotspot_x = images->images[i]->xhot;
image->image.hotspot_y = images->images[i]->yhot;
image->image.delay = images->images[i]->delay;
- size = image->image.width * image->image.height * 4;
- image->offset = shm_pool_allocate(theme->pool, size);
+ nbytes = image->image.width * image->image.height * 4;
+ image->offset = shm_pool_allocate(theme->pool, nbytes);
if (image->offset < 0) {
free(image);
break;
}
/* copy pixels to shm pool */
- memcpy(theme->pool->data + image->offset,
- images->images[i]->pixels, size);
+ /* pad at the right and bottom with transparent pixels */
+ memset (theme->pool->data + image->offset, 0, nbytes);
+ for (int y = 0; y < height; y++)
+ {
+ memcpy(theme->pool->data + image->offset + y * width * 4,
+ images->images[i]->pixels + y * images->images[i]->width * 4,
+ images->images[i]->width * 4);
+ }
cursor->total_delay += image->image.delay;
cursor->cursor.images[i] = (struct wl_cursor_image *) image;
}
@@ -264,20 +283,23 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
}
static void
-load_cursor(struct wl_cursor_theme *theme, const char *name, unsigned int size)
+load_cursor(struct wl_cursor_theme *theme,
+ const char *name,
+ unsigned int size,
+ unsigned int scale)
{
XcursorImages *images;
struct wl_cursor *cursor;
char *path;
path = g_strconcat (theme->path, "/", name, NULL);
- images = xcursor_load_images (path, size);
+ images = xcursor_load_images (path, size * scale);
g_free (path);
if (!images)
return;
- cursor = wl_cursor_create_from_xcursor_images(images, theme, name, size);
+ cursor = wl_cursor_create_from_xcursor_images(images, theme, name, size, scale);
if (cursor) {
theme->cursor_count++;
@@ -373,7 +395,7 @@ wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
return theme->cursors[i];
}
- load_cursor (theme, name, size);
+ load_cursor (theme, name, theme->size, scale);
if (i < theme->cursor_count) {
if (size == theme->cursors[i]->size &&
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]