mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
Merge branch 'work/jinliu/cursor-scaling' into 'main'
cursor: scale cursors to the requested size on env var "XCURSOR_RESIZED=true" See merge request wayland/wayland!440
This commit is contained in:
commit
72a32cc5f2
1 changed files with 85 additions and 4 deletions
|
|
@ -29,6 +29,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
|
|
@ -438,8 +439,45 @@ xcursor_read_image(FILE *file,
|
|||
return image;
|
||||
}
|
||||
|
||||
static struct xcursor_image *
|
||||
xcursor_resize_image (struct xcursor_image *src, int size)
|
||||
{
|
||||
uint32_t dest_y, dest_x;
|
||||
double scale = (double) size / src->size;
|
||||
struct xcursor_image *dest;
|
||||
|
||||
if (size < 0)
|
||||
return NULL;
|
||||
if (size > XCURSOR_IMAGE_MAX_SIZE)
|
||||
return NULL;
|
||||
|
||||
dest = xcursor_image_create((int) (src->width * scale),
|
||||
(int) (src->height * scale));
|
||||
if (!dest)
|
||||
return NULL;
|
||||
|
||||
dest->size = (uint32_t) size;
|
||||
dest->xhot = (uint32_t) (src->xhot * scale);
|
||||
dest->yhot = (uint32_t) (src->yhot * scale);
|
||||
dest->delay = src->delay;
|
||||
|
||||
for (dest_y = 0; dest_y < dest->height; dest_y++)
|
||||
{
|
||||
uint32_t src_y = (uint32_t) (dest_y / scale);
|
||||
uint32_t *src_row = src->pixels + (src_y * src->width);
|
||||
uint32_t *dest_row = dest->pixels + (dest_y * dest->width);
|
||||
for (dest_x = 0; dest_x < dest->width; dest_x++)
|
||||
{
|
||||
uint32_t src_x = (uint32_t) (dest_x / scale);
|
||||
dest_row[dest_x] = src_row[src_x];
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static struct xcursor_images *
|
||||
xcursor_xc_file_load_images(FILE *file, int size)
|
||||
xcursor_xc_file_load_images(FILE *file, int size, bool resize)
|
||||
{
|
||||
struct xcursor_file_header *file_header;
|
||||
uint32_t best_size;
|
||||
|
|
@ -467,8 +505,15 @@ xcursor_xc_file_load_images(FILE *file, int size)
|
|||
toc = xcursor_find_image_toc(file_header, best_size, n);
|
||||
if (toc < 0)
|
||||
break;
|
||||
images->images[images->nimage] = xcursor_read_image(file, file_header,
|
||||
toc);
|
||||
struct xcursor_image *image = xcursor_read_image(file, file_header, toc);
|
||||
if (!image)
|
||||
break;
|
||||
if (resize && image->size != (uint32_t) size) {
|
||||
struct xcursor_image *resized_image = xcursor_resize_image(image, size);
|
||||
xcursor_image_destroy(image);
|
||||
image = resized_image;
|
||||
}
|
||||
images->images[images->nimage] = image;
|
||||
if (!images->images[images->nimage])
|
||||
break;
|
||||
images->nimage++;
|
||||
|
|
@ -682,6 +727,40 @@ xcursor_theme_inherits(const char *full)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
xcursor_default_parse_bool(const char *v)
|
||||
{
|
||||
char c0;
|
||||
|
||||
c0 = *v;
|
||||
if (isupper ((int)c0))
|
||||
c0 = (char) tolower (c0);
|
||||
if (c0 == 't' || c0 == 'y' || c0 == '1')
|
||||
return 1;
|
||||
if (c0 == 'f' || c0 == 'n' || c0 == '0')
|
||||
return 0;
|
||||
if (c0 == 'o')
|
||||
{
|
||||
char c1 = v[1];
|
||||
if (isupper ((int)c1))
|
||||
c1 = (char) tolower (c1);
|
||||
if (c1 == 'n')
|
||||
return 1;
|
||||
if (c1 == 'f')
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool
|
||||
xcursor_get_resizable(void)
|
||||
{
|
||||
const char *v = getenv("XCURSOR_RESIZED");
|
||||
if (!v)
|
||||
return false;
|
||||
return xcursor_default_parse_bool(v) > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
load_all_cursors_from_dir(const char *path, int size,
|
||||
void (*load_callback)(struct xcursor_images *, void *),
|
||||
|
|
@ -700,6 +779,8 @@ load_all_cursors_from_dir(const char *path, int size,
|
|||
if (!dir)
|
||||
return;
|
||||
|
||||
const bool resize = xcursor_get_resizable();
|
||||
|
||||
for (ent = readdir(dir); ent; ent = readdir(dir)) {
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
if (ent->d_type != DT_UNKNOWN &&
|
||||
|
|
@ -718,7 +799,7 @@ load_all_cursors_from_dir(const char *path, int size,
|
|||
continue;
|
||||
}
|
||||
|
||||
images = xcursor_xc_file_load_images(f, size);
|
||||
images = xcursor_xc_file_load_images(f, size, resize);
|
||||
|
||||
if (images) {
|
||||
images->name = strdup(ent->d_name);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue