mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-29 06:51:10 +00:00
Merge branch 'wayland-cursor-scale-for-4-6' into 'gtk-4-6'
wayland: Sanity check cursor image size See merge request GNOME/gtk!4762
This commit is contained in:
commit
92b6c59f80
@ -203,12 +203,16 @@ static struct wl_cursor *
|
|||||||
wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
||||||
struct wl_cursor_theme *theme,
|
struct wl_cursor_theme *theme,
|
||||||
const char *name,
|
const char *name,
|
||||||
unsigned int load_size)
|
unsigned int size,
|
||||||
|
unsigned int scale)
|
||||||
{
|
{
|
||||||
struct cursor *cursor;
|
struct cursor *cursor;
|
||||||
struct cursor_image *image;
|
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);
|
cursor = malloc(sizeof *cursor);
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -232,22 +236,37 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
|||||||
image->theme = theme;
|
image->theme = theme;
|
||||||
image->buffer = NULL;
|
image->buffer = NULL;
|
||||||
|
|
||||||
image->image.width = images->images[i]->width;
|
/* ensure that width and height are multiples of scale */
|
||||||
image->image.height = images->images[i]->height;
|
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_x = images->images[i]->xhot;
|
||||||
image->image.hotspot_y = images->images[i]->yhot;
|
image->image.hotspot_y = images->images[i]->yhot;
|
||||||
image->image.delay = images->images[i]->delay;
|
image->image.delay = images->images[i]->delay;
|
||||||
|
|
||||||
size = image->image.width * image->image.height * 4;
|
nbytes = image->image.width * image->image.height * 4;
|
||||||
image->offset = shm_pool_allocate(theme->pool, size);
|
image->offset = shm_pool_allocate(theme->pool, nbytes);
|
||||||
if (image->offset < 0) {
|
if (image->offset < 0) {
|
||||||
free(image);
|
free(image);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy pixels to shm pool */
|
/* copy pixels to shm pool */
|
||||||
memcpy(theme->pool->data + image->offset,
|
/* pad at the right and bottom with transparent pixels */
|
||||||
images->images[i]->pixels, size);
|
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->total_delay += image->image.delay;
|
||||||
cursor->cursor.images[i] = (struct wl_cursor_image *) image;
|
cursor->cursor.images[i] = (struct wl_cursor_image *) image;
|
||||||
}
|
}
|
||||||
@ -264,20 +283,23 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
XcursorImages *images;
|
||||||
struct wl_cursor *cursor;
|
struct wl_cursor *cursor;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
path = g_strconcat (theme->path, "/", name, NULL);
|
path = g_strconcat (theme->path, "/", name, NULL);
|
||||||
images = xcursor_load_images (path, size);
|
images = xcursor_load_images (path, size * scale);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
|
|
||||||
if (!images)
|
if (!images)
|
||||||
return;
|
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) {
|
if (cursor) {
|
||||||
theme->cursor_count++;
|
theme->cursor_count++;
|
||||||
@ -373,7 +395,7 @@ wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
|
|||||||
return theme->cursors[i];
|
return theme->cursors[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
load_cursor (theme, name, size);
|
load_cursor (theme, name, theme->size, scale);
|
||||||
|
|
||||||
if (i < theme->cursor_count) {
|
if (i < theme->cursor_count) {
|
||||||
if (size == theme->cursors[i]->size &&
|
if (size == theme->cursors[i]->size &&
|
||||||
|
@ -178,6 +178,7 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
|||||||
if (c)
|
if (c)
|
||||||
{
|
{
|
||||||
struct wl_cursor_image *image;
|
struct wl_cursor_image *image;
|
||||||
|
int cursor_scale;
|
||||||
|
|
||||||
if (image_index >= c->image_count)
|
if (image_index >= c->image_count)
|
||||||
{
|
{
|
||||||
@ -189,12 +190,22 @@ _gdk_wayland_cursor_get_buffer (GdkWaylandDisplay *display,
|
|||||||
|
|
||||||
image = c->images[image_index];
|
image = c->images[image_index];
|
||||||
|
|
||||||
*hotspot_x = image->hotspot_x / desired_scale;
|
cursor_scale = desired_scale;
|
||||||
*hotspot_y = image->hotspot_y / desired_scale;
|
if ((image->width % cursor_scale != 0) ||
|
||||||
|
(image->height % cursor_scale != 0))
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC " cursor image size (%dx%d) not an integer"
|
||||||
|
"multiple of scale (%d)", image->width, image->height,
|
||||||
|
cursor_scale);
|
||||||
|
cursor_scale = 1;
|
||||||
|
}
|
||||||
|
|
||||||
*width = image->width / desired_scale;
|
*hotspot_x = image->hotspot_x / cursor_scale;
|
||||||
*height = image->height / desired_scale;
|
*hotspot_y = image->hotspot_y / cursor_scale;
|
||||||
*scale = desired_scale;
|
|
||||||
|
*width = image->width / cursor_scale;
|
||||||
|
*height = image->height / cursor_scale;
|
||||||
|
*scale = cursor_scale;
|
||||||
|
|
||||||
return wl_cursor_image_get_buffer (image);
|
return wl_cursor_image_get_buffer (image);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user