From f03be9430963aa454e50113a7ee1f4647634d4f2 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 18 Aug 2017 19:48:55 -0400 Subject: rename wlr_cursor to wlr_xcursor This is for the implementation of another type that should be called wlr_cursor. --- examples/pointer.c | 14 +++++++------- include/wlr/xcursor.h | 20 ++++++++++---------- xcursor/wlr_cursor.c | 50 +++++++++++++++++++++++++------------------------- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/examples/pointer.c b/examples/pointer.c index ef815785..1325a579 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -22,7 +22,7 @@ #include "cat.h" struct sample_state { - struct wlr_cursor *cursor; + struct wlr_xcursor *cursor; double cur_x, cur_y; float default_color[4]; float clear_color[4]; @@ -48,7 +48,7 @@ static void handle_pointer_motion(struct pointer_state *pstate, state->cur_x += d_x; state->cur_y += d_y; - struct wlr_cursor_image *image = state->cursor->images[0]; + struct wlr_xcursor_image *image = state->cursor->images[0]; struct output_state *output; wl_list_for_each(output, &pstate->compositor->outputs, link) { @@ -64,7 +64,7 @@ static void handle_pointer_motion_absolute(struct pointer_state *pstate, state->cur_x = x; state->cur_y = y; - struct wlr_cursor_image *image = state->cursor->images[0]; + struct wlr_xcursor_image *image = state->cursor->images[0]; struct output_state *output; wl_list_for_each(output, &pstate->compositor->outputs, link) { @@ -109,7 +109,7 @@ static void handle_pointer_axis(struct pointer_state *pstate, static void handle_output_add(struct output_state *ostate) { struct sample_state *state = ostate->compositor->data; struct wlr_output *wlr_output = ostate->output; - struct wlr_cursor_image *image = state->cursor->images[0]; + struct wlr_xcursor_image *image = state->cursor->images[0]; if (!wlr_output_set_cursor(wlr_output, image->buffer, image->width, image->width, image->height)) { wlr_log(L_DEBUG, "Failed to set hardware cursor"); @@ -134,12 +134,12 @@ int main(int argc, char *argv[]) { compositor.pointer_button_cb = handle_pointer_button; compositor.pointer_axis_cb = handle_pointer_axis; - struct wlr_cursor_theme *theme = wlr_cursor_theme_load("default", 16); + struct wlr_xcursor_theme *theme = wlr_xcursor_theme_load("default", 16); if (!theme) { wlr_log(L_ERROR, "Failed to load cursor theme"); return 1; } - state.cursor = wlr_cursor_theme_get_cursor(theme, "left_ptr"); + state.cursor = wlr_xcursor_theme_get_cursor(theme, "left_ptr"); if (!state.cursor) { wlr_log(L_ERROR, "Failed to load left_ptr cursor"); return 1; @@ -148,5 +148,5 @@ int main(int argc, char *argv[]) { compositor_init(&compositor); compositor_run(&compositor); - wlr_cursor_theme_destroy(theme); + wlr_xcursor_theme_destroy(theme); } diff --git a/include/wlr/xcursor.h b/include/wlr/xcursor.h index 1744fd92..ae07b4fa 100644 --- a/include/wlr/xcursor.h +++ b/include/wlr/xcursor.h @@ -31,7 +31,7 @@ #define _WLR_XCURSOR_H #include -struct wlr_cursor_image { +struct wlr_xcursor_image { uint32_t width; /* actual width */ uint32_t height; /* actual height */ uint32_t hotspot_x; /* hot spot x (must be inside image) */ @@ -40,27 +40,27 @@ struct wlr_cursor_image { uint8_t *buffer; }; -struct wlr_cursor { +struct wlr_xcursor { unsigned int image_count; - struct wlr_cursor_image **images; + struct wlr_xcursor_image **images; char *name; uint32_t total_delay; /* length of the animation in ms */ }; -struct wlr_cursor_theme { +struct wlr_xcursor_theme { unsigned int cursor_count; - struct wlr_cursor **cursors; + struct wlr_xcursor **cursors; char *name; int size; }; -struct wlr_cursor_theme *wlr_cursor_theme_load(const char *name, int size); +struct wlr_xcursor_theme *wlr_xcursor_theme_load(const char *name, int size); -void wlr_cursor_theme_destroy(struct wlr_cursor_theme *theme); +void wlr_xcursor_theme_destroy(struct wlr_xcursor_theme *theme); -struct wlr_cursor *wlr_cursor_theme_get_cursor( - struct wlr_cursor_theme *theme, const char *name); +struct wlr_xcursor *wlr_xcursor_theme_get_cursor( + struct wlr_xcursor_theme *theme, const char *name); -int wlr_cursor_frame(struct wlr_cursor *cursor, uint32_t time); +int wlr_xcursor_frame(struct wlr_xcursor *cursor, uint32_t time); #endif diff --git a/xcursor/wlr_cursor.c b/xcursor/wlr_cursor.c index 85e0d3be..fdebe1af 100644 --- a/xcursor/wlr_cursor.c +++ b/xcursor/wlr_cursor.c @@ -33,7 +33,7 @@ #include #include "xcursor/xcursor.h" -static void wlr_cursor_destroy(struct wlr_cursor *cursor) { +static void wlr_xcursor_destroy(struct wlr_xcursor *cursor) { for (size_t i = 0; i < cursor->image_count; i++) { free(cursor->images[i]->buffer); free(cursor->images[i]); @@ -46,10 +46,10 @@ static void wlr_cursor_destroy(struct wlr_cursor *cursor) { #include "xcursor/cursor_data.h" -static struct wlr_cursor *wlr_cursor_create_from_data( - struct cursor_metadata *metadata, struct wlr_cursor_theme *theme) { - struct wlr_cursor *cursor; - struct wlr_cursor_image *image; +static struct wlr_xcursor *wlr_xcursor_create_from_data( + struct cursor_metadata *metadata, struct wlr_xcursor_theme *theme) { + struct wlr_xcursor *cursor; + struct wlr_xcursor_image *image; int size; cursor = malloc(sizeof(*cursor)); @@ -102,7 +102,7 @@ err_free_cursor: return NULL; } -static void load_default_theme(struct wlr_cursor_theme *theme) { +static void load_default_theme(struct wlr_xcursor_theme *theme) { uint32_t i; free(theme->name); @@ -118,7 +118,7 @@ static void load_default_theme(struct wlr_cursor_theme *theme) { for (i = 0; i < theme->cursor_count; ++i) { theme->cursors[i] = - wlr_cursor_create_from_data(&cursor_metadata[i], theme); + wlr_xcursor_create_from_data(&cursor_metadata[i], theme); if (theme->cursors[i] == NULL) { break; @@ -127,10 +127,10 @@ static void load_default_theme(struct wlr_cursor_theme *theme) { theme->cursor_count = i; } -static struct wlr_cursor *wlr_cursor_create_from_xcursor_images( - XcursorImages *images, struct wlr_cursor_theme *theme) { - struct wlr_cursor *cursor; - struct wlr_cursor_image *image; +static struct wlr_xcursor *wlr_xcursor_create_from_xcursor_images( + XcursorImages *images, struct wlr_xcursor_theme *theme) { + struct wlr_xcursor *cursor; + struct wlr_xcursor_image *image; int i, size; cursor = malloc(sizeof(*cursor)); @@ -186,15 +186,15 @@ static struct wlr_cursor *wlr_cursor_create_from_xcursor_images( } static void load_callback(XcursorImages *images, void *data) { - struct wlr_cursor_theme *theme = data; - struct wlr_cursor *cursor; + struct wlr_xcursor_theme *theme = data; + struct wlr_xcursor *cursor; - if (wlr_cursor_theme_get_cursor(theme, images->name)) { + if (wlr_xcursor_theme_get_cursor(theme, images->name)) { XcursorImagesDestroy(images); return; } - cursor = wlr_cursor_create_from_xcursor_images(images, theme); + cursor = wlr_xcursor_create_from_xcursor_images(images, theme); if (cursor) { theme->cursor_count++; @@ -213,8 +213,8 @@ static void load_callback(XcursorImages *images, void *data) { XcursorImagesDestroy(images); } -struct wlr_cursor_theme *wlr_cursor_theme_load(const char *name, int size) { - struct wlr_cursor_theme *theme; +struct wlr_xcursor_theme *wlr_xcursor_theme_load(const char *name, int size) { + struct wlr_xcursor_theme *theme; theme = malloc(sizeof(*theme)); if (!theme) { @@ -242,8 +242,8 @@ struct wlr_cursor_theme *wlr_cursor_theme_load(const char *name, int size) { wlr_log(L_DEBUG, "Loaded cursor theme '%s', available cursors:", theme->name); for (size_t i = 0; i < theme->cursor_count; ++i) { - struct wlr_cursor *c = theme->cursors[i]; - struct wlr_cursor_image *i = c->images[0]; + struct wlr_xcursor *c = theme->cursors[i]; + struct wlr_xcursor_image *i = c->images[0]; wlr_log(L_DEBUG, "%s (%u images) %dx%d+%d,%d", c->name, c->image_count, i->width, i->height, i->hotspot_x, i->hotspot_y); @@ -256,11 +256,11 @@ out_error_name: return NULL; } -void wlr_cursor_theme_destroy(struct wlr_cursor_theme *theme) { +void wlr_xcursor_theme_destroy(struct wlr_xcursor_theme *theme) { unsigned int i; for (i = 0; i < theme->cursor_count; i++) { - wlr_cursor_destroy(theme->cursors[i]); + wlr_xcursor_destroy(theme->cursors[i]); } free(theme->name); @@ -268,7 +268,7 @@ void wlr_cursor_theme_destroy(struct wlr_cursor_theme *theme) { free(theme); } -struct wlr_cursor *wlr_cursor_theme_get_cursor(struct wlr_cursor_theme *theme, +struct wlr_xcursor *wlr_xcursor_theme_get_cursor(struct wlr_xcursor_theme *theme, const char *name) { unsigned int i; @@ -281,7 +281,7 @@ struct wlr_cursor *wlr_cursor_theme_get_cursor(struct wlr_cursor_theme *theme, return NULL; } -static int wlr_cursor_frame_and_duration(struct wlr_cursor *cursor, +static int wlr_xcursor_frame_and_duration(struct wlr_xcursor *cursor, uint32_t time, uint32_t *duration) { uint32_t t; int i; @@ -323,6 +323,6 @@ static int wlr_cursor_frame_and_duration(struct wlr_cursor *cursor, return i; } -int wlr_cursor_frame(struct wlr_cursor *_cursor, uint32_t time) { - return wlr_cursor_frame_and_duration(_cursor, time, NULL); +int wlr_xcursor_frame(struct wlr_xcursor *_cursor, uint32_t time) { + return wlr_xcursor_frame_and_duration(_cursor, time, NULL); } -- cgit v1.2.3 From f334dcaf40799b82c102c8583f9f91c377321ee4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 18 Aug 2017 19:51:41 -0400 Subject: rename wlr_cursor.c to wlr_xcursor.c --- xcursor/meson.build | 2 +- xcursor/wlr_cursor.c | 328 -------------------------------------------------- xcursor/wlr_xcursor.c | 328 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 329 insertions(+), 329 deletions(-) delete mode 100644 xcursor/wlr_cursor.c create mode 100644 xcursor/wlr_xcursor.c diff --git a/xcursor/meson.build b/xcursor/meson.build index 39094b06..712da35a 100644 --- a/xcursor/meson.build +++ b/xcursor/meson.build @@ -1,5 +1,5 @@ lib_wlr_xcursor = static_library('wlr_xcursor', files( 'xcursor.c', - 'wlr_cursor.c', + 'wlr_xcursor.c', ), include_directories: wlr_inc) diff --git a/xcursor/wlr_cursor.c b/xcursor/wlr_cursor.c deleted file mode 100644 index fdebe1af..00000000 --- a/xcursor/wlr_cursor.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define _XOPEN_SOURCE 500 -#include -#include -#include -#include -#include -#include -#include -#include "xcursor/xcursor.h" - -static void wlr_xcursor_destroy(struct wlr_xcursor *cursor) { - for (size_t i = 0; i < cursor->image_count; i++) { - free(cursor->images[i]->buffer); - free(cursor->images[i]); - } - - free(cursor->images); - free(cursor->name); - free(cursor); -} - -#include "xcursor/cursor_data.h" - -static struct wlr_xcursor *wlr_xcursor_create_from_data( - struct cursor_metadata *metadata, struct wlr_xcursor_theme *theme) { - struct wlr_xcursor *cursor; - struct wlr_xcursor_image *image; - int size; - - cursor = malloc(sizeof(*cursor)); - if (!cursor) { - return NULL; - } - - cursor->image_count = 1; - cursor->images = malloc(sizeof(*cursor->images)); - if (!cursor->images) { - goto err_free_cursor; - } - - cursor->name = strdup(metadata->name); - cursor->total_delay = 0; - - image = malloc(sizeof(*image)); - if (!image) { - goto err_free_images; - } - - cursor->images[0] = image; - image->buffer = NULL; - image->width = metadata->width; - image->height = metadata->height; - image->hotspot_x = metadata->hotspot_x; - image->hotspot_y = metadata->hotspot_y; - image->delay = 0; - - size = metadata->width * metadata->height * sizeof(uint32_t); - image->buffer = malloc(size); - - if (!image->buffer) { - goto err_free_image; - } - - memcpy(image->buffer, cursor_data + metadata->offset, size); - - return cursor; - -err_free_image: - free(image); - -err_free_images: - free(cursor->name); - free(cursor->images); - -err_free_cursor: - free(cursor); - return NULL; -} - -static void load_default_theme(struct wlr_xcursor_theme *theme) { - uint32_t i; - - free(theme->name); - theme->name = strdup("default"); - - theme->cursor_count = sizeof(cursor_metadata) / sizeof(cursor_metadata[0]); - theme->cursors = malloc(theme->cursor_count * sizeof(*theme->cursors)); - - if (theme->cursors == NULL) { - theme->cursor_count = 0; - return; - } - - for (i = 0; i < theme->cursor_count; ++i) { - theme->cursors[i] = - wlr_xcursor_create_from_data(&cursor_metadata[i], theme); - - if (theme->cursors[i] == NULL) { - break; - } - } - theme->cursor_count = i; -} - -static struct wlr_xcursor *wlr_xcursor_create_from_xcursor_images( - XcursorImages *images, struct wlr_xcursor_theme *theme) { - struct wlr_xcursor *cursor; - struct wlr_xcursor_image *image; - int i, size; - - cursor = malloc(sizeof(*cursor)); - if (!cursor) { - return NULL; - } - - cursor->images = malloc(images->nimage * sizeof(cursor->images[0])); - if (!cursor->images) { - free(cursor); - return NULL; - } - - cursor->name = strdup(images->name); - cursor->total_delay = 0; - - for (i = 0; i < images->nimage; i++) { - image = malloc(sizeof(*image)); - if (image == NULL) { - break; - } - - image->buffer = NULL; - - image->width = images->images[i]->width; - image->height = images->images[i]->height; - image->hotspot_x = images->images[i]->xhot; - image->hotspot_y = images->images[i]->yhot; - image->delay = images->images[i]->delay; - - size = image->width * image->height * 4; - image->buffer = malloc(size); - if (!image->buffer) { - free(image); - break; - } - - /* copy pixels to shm pool */ - memcpy(image->buffer, images->images[i]->pixels, size); - cursor->total_delay += image->delay; - cursor->images[i] = image; - } - cursor->image_count = i; - - if (cursor->image_count == 0) { - free(cursor->name); - free(cursor->images); - free(cursor); - return NULL; - } - - return cursor; -} - -static void load_callback(XcursorImages *images, void *data) { - struct wlr_xcursor_theme *theme = data; - struct wlr_xcursor *cursor; - - if (wlr_xcursor_theme_get_cursor(theme, images->name)) { - XcursorImagesDestroy(images); - return; - } - - cursor = wlr_xcursor_create_from_xcursor_images(images, theme); - - if (cursor) { - theme->cursor_count++; - theme->cursors = - realloc(theme->cursors, - theme->cursor_count * sizeof(theme->cursors[0])); - - if (theme->cursors == NULL) { - theme->cursor_count--; - free(cursor); - } else { - theme->cursors[theme->cursor_count - 1] = cursor; - } - } - - XcursorImagesDestroy(images); -} - -struct wlr_xcursor_theme *wlr_xcursor_theme_load(const char *name, int size) { - struct wlr_xcursor_theme *theme; - - theme = malloc(sizeof(*theme)); - if (!theme) { - return NULL; - } - - if (!name) { - name = "default"; - } - - theme->name = strdup(name); - if (!theme->name) { - goto out_error_name; - } - theme->size = size; - theme->cursor_count = 0; - theme->cursors = NULL; - - xcursor_load_theme(name, size, load_callback, theme); - - if (theme->cursor_count == 0) { - load_default_theme(theme); - } - - wlr_log(L_DEBUG, "Loaded cursor theme '%s', available cursors:", - theme->name); - for (size_t i = 0; i < theme->cursor_count; ++i) { - struct wlr_xcursor *c = theme->cursors[i]; - struct wlr_xcursor_image *i = c->images[0]; - wlr_log(L_DEBUG, "%s (%u images) %dx%d+%d,%d", - c->name, c->image_count, - i->width, i->height, i->hotspot_x, i->hotspot_y); - } - - return theme; - -out_error_name: - free(theme); - return NULL; -} - -void wlr_xcursor_theme_destroy(struct wlr_xcursor_theme *theme) { - unsigned int i; - - for (i = 0; i < theme->cursor_count; i++) { - wlr_xcursor_destroy(theme->cursors[i]); - } - - free(theme->name); - free(theme->cursors); - free(theme); -} - -struct wlr_xcursor *wlr_xcursor_theme_get_cursor(struct wlr_xcursor_theme *theme, - const char *name) { - unsigned int i; - - for (i = 0; i < theme->cursor_count; i++) { - if (strcmp(name, theme->cursors[i]->name) == 0) { - return theme->cursors[i]; - } - } - - return NULL; -} - -static int wlr_xcursor_frame_and_duration(struct wlr_xcursor *cursor, - uint32_t time, uint32_t *duration) { - uint32_t t; - int i; - - if (cursor->image_count == 1) { - if (duration) { - *duration = 0; - } - return 0; - } - - i = 0; - t = time % cursor->total_delay; - - /* If there is a 0 delay in the image set then this - * loop breaks on it and we display that cursor until - * time % cursor->total_delay wraps again. - * Since a 0 delay is silly, and we've never actually - * seen one in a cursor file, we haven't bothered to - * "fix" this. - */ - while (t - cursor->images[i]->delay < t) { - t -= cursor->images[i++]->delay; - } - - if (!duration) { - return i; - } - - /* Make sure we don't accidentally tell the caller this is - * a static cursor image. - */ - if (t >= cursor->images[i]->delay) { - *duration = 1; - } else { - *duration = cursor->images[i]->delay - t; - } - - return i; -} - -int wlr_xcursor_frame(struct wlr_xcursor *_cursor, uint32_t time) { - return wlr_xcursor_frame_and_duration(_cursor, time, NULL); -} diff --git a/xcursor/wlr_xcursor.c b/xcursor/wlr_xcursor.c new file mode 100644 index 00000000..fdebe1af --- /dev/null +++ b/xcursor/wlr_xcursor.c @@ -0,0 +1,328 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include +#include +#include +#include "xcursor/xcursor.h" + +static void wlr_xcursor_destroy(struct wlr_xcursor *cursor) { + for (size_t i = 0; i < cursor->image_count; i++) { + free(cursor->images[i]->buffer); + free(cursor->images[i]); + } + + free(cursor->images); + free(cursor->name); + free(cursor); +} + +#include "xcursor/cursor_data.h" + +static struct wlr_xcursor *wlr_xcursor_create_from_data( + struct cursor_metadata *metadata, struct wlr_xcursor_theme *theme) { + struct wlr_xcursor *cursor; + struct wlr_xcursor_image *image; + int size; + + cursor = malloc(sizeof(*cursor)); + if (!cursor) { + return NULL; + } + + cursor->image_count = 1; + cursor->images = malloc(sizeof(*cursor->images)); + if (!cursor->images) { + goto err_free_cursor; + } + + cursor->name = strdup(metadata->name); + cursor->total_delay = 0; + + image = malloc(sizeof(*image)); + if (!image) { + goto err_free_images; + } + + cursor->images[0] = image; + image->buffer = NULL; + image->width = metadata->width; + image->height = metadata->height; + image->hotspot_x = metadata->hotspot_x; + image->hotspot_y = metadata->hotspot_y; + image->delay = 0; + + size = metadata->width * metadata->height * sizeof(uint32_t); + image->buffer = malloc(size); + + if (!image->buffer) { + goto err_free_image; + } + + memcpy(image->buffer, cursor_data + metadata->offset, size); + + return cursor; + +err_free_image: + free(image); + +err_free_images: + free(cursor->name); + free(cursor->images); + +err_free_cursor: + free(cursor); + return NULL; +} + +static void load_default_theme(struct wlr_xcursor_theme *theme) { + uint32_t i; + + free(theme->name); + theme->name = strdup("default"); + + theme->cursor_count = sizeof(cursor_metadata) / sizeof(cursor_metadata[0]); + theme->cursors = malloc(theme->cursor_count * sizeof(*theme->cursors)); + + if (theme->cursors == NULL) { + theme->cursor_count = 0; + return; + } + + for (i = 0; i < theme->cursor_count; ++i) { + theme->cursors[i] = + wlr_xcursor_create_from_data(&cursor_metadata[i], theme); + + if (theme->cursors[i] == NULL) { + break; + } + } + theme->cursor_count = i; +} + +static struct wlr_xcursor *wlr_xcursor_create_from_xcursor_images( + XcursorImages *images, struct wlr_xcursor_theme *theme) { + struct wlr_xcursor *cursor; + struct wlr_xcursor_image *image; + int i, size; + + cursor = malloc(sizeof(*cursor)); + if (!cursor) { + return NULL; + } + + cursor->images = malloc(images->nimage * sizeof(cursor->images[0])); + if (!cursor->images) { + free(cursor); + return NULL; + } + + cursor->name = strdup(images->name); + cursor->total_delay = 0; + + for (i = 0; i < images->nimage; i++) { + image = malloc(sizeof(*image)); + if (image == NULL) { + break; + } + + image->buffer = NULL; + + image->width = images->images[i]->width; + image->height = images->images[i]->height; + image->hotspot_x = images->images[i]->xhot; + image->hotspot_y = images->images[i]->yhot; + image->delay = images->images[i]->delay; + + size = image->width * image->height * 4; + image->buffer = malloc(size); + if (!image->buffer) { + free(image); + break; + } + + /* copy pixels to shm pool */ + memcpy(image->buffer, images->images[i]->pixels, size); + cursor->total_delay += image->delay; + cursor->images[i] = image; + } + cursor->image_count = i; + + if (cursor->image_count == 0) { + free(cursor->name); + free(cursor->images); + free(cursor); + return NULL; + } + + return cursor; +} + +static void load_callback(XcursorImages *images, void *data) { + struct wlr_xcursor_theme *theme = data; + struct wlr_xcursor *cursor; + + if (wlr_xcursor_theme_get_cursor(theme, images->name)) { + XcursorImagesDestroy(images); + return; + } + + cursor = wlr_xcursor_create_from_xcursor_images(images, theme); + + if (cursor) { + theme->cursor_count++; + theme->cursors = + realloc(theme->cursors, + theme->cursor_count * sizeof(theme->cursors[0])); + + if (theme->cursors == NULL) { + theme->cursor_count--; + free(cursor); + } else { + theme->cursors[theme->cursor_count - 1] = cursor; + } + } + + XcursorImagesDestroy(images); +} + +struct wlr_xcursor_theme *wlr_xcursor_theme_load(const char *name, int size) { + struct wlr_xcursor_theme *theme; + + theme = malloc(sizeof(*theme)); + if (!theme) { + return NULL; + } + + if (!name) { + name = "default"; + } + + theme->name = strdup(name); + if (!theme->name) { + goto out_error_name; + } + theme->size = size; + theme->cursor_count = 0; + theme->cursors = NULL; + + xcursor_load_theme(name, size, load_callback, theme); + + if (theme->cursor_count == 0) { + load_default_theme(theme); + } + + wlr_log(L_DEBUG, "Loaded cursor theme '%s', available cursors:", + theme->name); + for (size_t i = 0; i < theme->cursor_count; ++i) { + struct wlr_xcursor *c = theme->cursors[i]; + struct wlr_xcursor_image *i = c->images[0]; + wlr_log(L_DEBUG, "%s (%u images) %dx%d+%d,%d", + c->name, c->image_count, + i->width, i->height, i->hotspot_x, i->hotspot_y); + } + + return theme; + +out_error_name: + free(theme); + return NULL; +} + +void wlr_xcursor_theme_destroy(struct wlr_xcursor_theme *theme) { + unsigned int i; + + for (i = 0; i < theme->cursor_count; i++) { + wlr_xcursor_destroy(theme->cursors[i]); + } + + free(theme->name); + free(theme->cursors); + free(theme); +} + +struct wlr_xcursor *wlr_xcursor_theme_get_cursor(struct wlr_xcursor_theme *theme, + const char *name) { + unsigned int i; + + for (i = 0; i < theme->cursor_count; i++) { + if (strcmp(name, theme->cursors[i]->name) == 0) { + return theme->cursors[i]; + } + } + + return NULL; +} + +static int wlr_xcursor_frame_and_duration(struct wlr_xcursor *cursor, + uint32_t time, uint32_t *duration) { + uint32_t t; + int i; + + if (cursor->image_count == 1) { + if (duration) { + *duration = 0; + } + return 0; + } + + i = 0; + t = time % cursor->total_delay; + + /* If there is a 0 delay in the image set then this + * loop breaks on it and we display that cursor until + * time % cursor->total_delay wraps again. + * Since a 0 delay is silly, and we've never actually + * seen one in a cursor file, we haven't bothered to + * "fix" this. + */ + while (t - cursor->images[i]->delay < t) { + t -= cursor->images[i++]->delay; + } + + if (!duration) { + return i; + } + + /* Make sure we don't accidentally tell the caller this is + * a static cursor image. + */ + if (t >= cursor->images[i]->delay) { + *duration = 1; + } else { + *duration = cursor->images[i]->delay - t; + } + + return i; +} + +int wlr_xcursor_frame(struct wlr_xcursor *_cursor, uint32_t time) { + return wlr_xcursor_frame_and_duration(_cursor, time, NULL); +} -- cgit v1.2.3