diff options
Diffstat (limited to 'cursor')
-rw-r--r-- | cursor/wayland-cursor.c | 67 |
1 files changed, 51 insertions, 16 deletions
diff --git a/cursor/wayland-cursor.c b/cursor/wayland-cursor.c index 25e51c2..3dadbdd 100644 --- a/cursor/wayland-cursor.c +++ b/cursor/wayland-cursor.c @@ -20,6 +20,7 @@ * OF THIS SOFTWARE. */ +#include "config.h" #include "xcursor.h" #include "wayland-cursor.h" #include "wayland-client.h" @@ -28,6 +29,8 @@ #include <string.h> #include <unistd.h> #include <sys/mman.h> +#include <fcntl.h> +#include <errno.h> #include "os-compatibility.h" @@ -79,6 +82,12 @@ shm_pool_resize(struct shm_pool *pool, int size) if (ftruncate(pool->fd, size) < 0) return 0; +#ifdef HAVE_POSIX_FALLOCATE + errno = posix_fallocate(pool->fd, 0, size); + if (errno != 0) + return 0; +#endif + wl_shm_pool_resize(pool->pool, size); munmap(pool->data, pool->size); @@ -199,21 +208,15 @@ wl_cursor_create_from_data(struct cursor_metadata *metadata, cursor->cursor.image_count = 1; cursor->cursor.images = malloc(sizeof *cursor->cursor.images); - if (!cursor->cursor.images) { - free(cursor); - return NULL; - } + if (!cursor->cursor.images) + goto err_free_cursor; cursor->cursor.name = strdup(metadata->name); cursor->total_delay = 0; image = malloc(sizeof *image); - if (!image) { - free(cursor->cursor.name); - free(cursor->cursor.images); - free(cursor); - return NULL; - } + if (!image) + goto err_free_images; cursor->cursor.images[0] = (struct wl_cursor_image *) image; image->theme = theme; @@ -226,10 +229,25 @@ wl_cursor_create_from_data(struct cursor_metadata *metadata, size = metadata->width * metadata->height * sizeof(uint32_t); image->offset = shm_pool_allocate(theme->pool, size); + + if (image->offset < 0) + goto err_free_image; + memcpy(theme->pool->data + image->offset, cursor_data + metadata->offset, size); return &cursor->cursor; + +err_free_image: + free(image); + +err_free_images: + free(cursor->cursor.name); + free(cursor->cursor.images); + +err_free_cursor: + free(cursor); + return NULL; } static void @@ -240,12 +258,17 @@ load_default_theme(struct wl_cursor_theme *theme) free(theme->name); theme->name = strdup("default"); - theme->cursor_count = ARRAY_LENGTH(cursor_metadata);; + theme->cursor_count = ARRAY_LENGTH(cursor_metadata); theme->cursors = malloc(theme->cursor_count * sizeof(*theme->cursors)); - for (i = 0; i < theme->cursor_count; ++i) + for (i = 0; i < theme->cursor_count; ++i) { theme->cursors[i] = wl_cursor_create_from_data(&cursor_metadata[i], theme); + + if (theme->cursors[i] == NULL) + break; + } + theme->cursor_count = i; } static struct wl_cursor * @@ -260,7 +283,6 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images, if (!cursor) return NULL; - cursor->cursor.image_count = images->nimage; cursor->cursor.images = malloc(images->nimage * sizeof cursor->cursor.images[0]); if (!cursor->cursor.images) { @@ -273,7 +295,6 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images, for (i = 0; i < images->nimage; i++) { image = malloc(sizeof *image); - cursor->cursor.images[i] = (struct wl_cursor_image *) image; image->theme = theme; image->buffer = NULL; @@ -283,13 +304,27 @@ wl_cursor_create_from_xcursor_images(XcursorImages *images, image->image.hotspot_x = images->images[i]->xhot; image->image.hotspot_y = images->images[i]->yhot; image->image.delay = images->images[i]->delay; - cursor->total_delay += image->image.delay; - /* copy pixels to shm pool */ size = image->image.width * image->image.height * 4; image->offset = shm_pool_allocate(theme->pool, size); + if (image->offset < 0) { + free(image); + break; + } + + /* copy pixels to shm pool */ memcpy(theme->pool->data + image->offset, images->images[i]->pixels, size); + cursor->total_delay += image->image.delay; + cursor->cursor.images[i] = (struct wl_cursor_image *) image; + } + cursor->cursor.image_count = i; + + if (cursor->cursor.image_count == 0) { + free(cursor->cursor.name); + free(cursor->cursor.images); + free(cursor); + return NULL; } return &cursor->cursor; |