mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	types/wlr_xcursor_manager: Add caching textures
This commit is contained in:
		
							parent
							
								
									2fcb2b95fc
								
							
						
					
					
						commit
						c5bd304795
					
				
					 5 changed files with 98 additions and 37 deletions
				
			
		| 
						 | 
					@ -59,9 +59,6 @@ struct sample_output {
 | 
				
			||||||
	struct wlr_output *output;
 | 
						struct wlr_output *output;
 | 
				
			||||||
	struct wl_listener frame;
 | 
						struct wl_listener frame;
 | 
				
			||||||
	struct wl_listener destroy;
 | 
						struct wl_listener destroy;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wlr_texture *texture;
 | 
					 | 
				
			||||||
	int32_t hotspot_x, hotspot_y;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sample_keyboard {
 | 
					struct sample_keyboard {
 | 
				
			||||||
| 
						 | 
					@ -97,9 +94,15 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
 | 
						struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
 | 
				
			||||||
	assert(renderer);
 | 
						assert(renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(
 | 
				
			||||||
 | 
							state->xcursor_manager, "left_ptr", wlr_output->scale);
 | 
				
			||||||
 | 
						struct wlr_xcursor_image *cursor = xcursor->images[0];
 | 
				
			||||||
 | 
						struct wlr_texture *tex = wlr_xcursor_manager_get_texture(
 | 
				
			||||||
 | 
							state->xcursor_manager, cursor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool render_software = true;
 | 
						bool render_software = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!sample_output->texture) {
 | 
						if (!tex) {
 | 
				
			||||||
		goto render_output;
 | 
							goto render_output;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +111,7 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	wlr_output_layout_output_coords(state->layout, wlr_output, &x, &y);
 | 
						wlr_output_layout_output_coords(state->layout, wlr_output, &x, &y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int w, h;
 | 
						int w, h;
 | 
				
			||||||
	wlr_texture_get_size(sample_output->texture, &w, &h);
 | 
						wlr_texture_get_size(tex, &w, &h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int buf_w = w, buf_h = h;
 | 
						int buf_w = w, buf_h = h;
 | 
				
			||||||
	if (!wlr_output_cursor_try_set_size(wlr_output, &buf_w, &buf_h)) {
 | 
						if (!wlr_output_cursor_try_set_size(wlr_output, &buf_w, &buf_h)) {
 | 
				
			||||||
| 
						 | 
					@ -131,11 +134,11 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	 * hardware cursor, and to know it's really ours.
 | 
						 * hardware cursor, and to know it's really ours.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	wlr_renderer_clear(renderer, (float[]){ 0.2, 0.2, 0.2, 0.2 });
 | 
						wlr_renderer_clear(renderer, (float[]){ 0.2, 0.2, 0.2, 0.2 });
 | 
				
			||||||
	wlr_render_texture_with_matrix(renderer, sample_output->texture, mat, 1.0f);
 | 
						wlr_render_texture_with_matrix(renderer, tex, mat, 1.0f);
 | 
				
			||||||
	wlr_renderer_end(renderer);
 | 
						wlr_renderer_end(renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_output_cursor_move(wlr_output, x, y,
 | 
						wlr_output_cursor_move(wlr_output, x, y,
 | 
				
			||||||
		sample_output->hotspot_x, sample_output->hotspot_y);
 | 
							cursor->hotspot_x, cursor->hotspot_y);
 | 
				
			||||||
	wlr_output_cursor_enable(wlr_output, true);
 | 
						wlr_output_cursor_enable(wlr_output, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_output_cursor_commit(wlr_output);
 | 
						wlr_output_cursor_commit(wlr_output);
 | 
				
			||||||
| 
						 | 
					@ -147,15 +150,15 @@ render_output:
 | 
				
			||||||
	wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
 | 
						wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
 | 
				
			||||||
	wlr_renderer_clear(renderer, state->clear_color);
 | 
						wlr_renderer_clear(renderer, state->clear_color);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!render_software || !sample_output->texture) {
 | 
						if (!render_software || !tex) {
 | 
				
			||||||
		goto end;
 | 
							goto end;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	x = state->cursor->x - sample_output->hotspot_x;
 | 
						x = state->cursor->x - cursor->hotspot_x;
 | 
				
			||||||
	y = state->cursor->y - sample_output->hotspot_y;
 | 
						y = state->cursor->y - cursor->hotspot_y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_output_layout_output_coords(state->layout, wlr_output, &x, &y);
 | 
						wlr_output_layout_output_coords(state->layout, wlr_output, &x, &y);
 | 
				
			||||||
	wlr_render_texture(renderer, sample_output->texture,
 | 
						wlr_render_texture(renderer, tex,
 | 
				
			||||||
		wlr_output->transform_matrix, x, y, 1.0f);
 | 
							wlr_output->transform_matrix, x, y, 1.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
end:
 | 
					end:
 | 
				
			||||||
| 
						 | 
					@ -305,7 +308,6 @@ void new_output_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wlr_output *output = data;
 | 
						struct wlr_output *output = data;
 | 
				
			||||||
	struct sample_state *sample = wl_container_of(listener, sample, new_output);
 | 
						struct sample_state *sample = wl_container_of(listener, sample, new_output);
 | 
				
			||||||
	struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
 | 
						struct sample_output *sample_output = calloc(1, sizeof(struct sample_output));
 | 
				
			||||||
	struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!wl_list_empty(&output->modes)) {
 | 
						if (!wl_list_empty(&output->modes)) {
 | 
				
			||||||
		struct wlr_output_mode *mode = wl_container_of(output->modes.prev, mode, link);
 | 
							struct wlr_output_mode *mode = wl_container_of(output->modes.prev, mode, link);
 | 
				
			||||||
| 
						 | 
					@ -320,24 +322,6 @@ void new_output_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	wlr_output_layout_add_auto(sample->layout, sample_output->output);
 | 
						wlr_output_layout_add_auto(sample->layout, sample_output->output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_xcursor_manager_load(sample->xcursor_manager, output->scale);
 | 
						wlr_xcursor_manager_load(sample->xcursor_manager, output->scale);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wlr_xcursor *xcursor;
 | 
					 | 
				
			||||||
	struct wlr_xcursor_image *img;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	xcursor = wlr_xcursor_manager_get_xcursor(sample->xcursor_manager,
 | 
					 | 
				
			||||||
			"left_ptr", output->scale);
 | 
					 | 
				
			||||||
	if (!xcursor) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Animation not supported */
 | 
					 | 
				
			||||||
	img = xcursor->images[0];
 | 
					 | 
				
			||||||
	sample_output->hotspot_x = img->hotspot_x;
 | 
					 | 
				
			||||||
	sample_output->hotspot_y = img->hotspot_y;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	sample_output->texture = wlr_texture_from_pixels(renderer,
 | 
					 | 
				
			||||||
			WL_SHM_FORMAT_ARGB8888, img->width * 4, img->width,
 | 
					 | 
				
			||||||
			img->height, img->buffer);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void keyboard_destroy_notify(struct wl_listener *listener, void *data) {
 | 
					void keyboard_destroy_notify(struct wl_listener *listener, void *data) {
 | 
				
			||||||
| 
						 | 
					@ -459,7 +443,8 @@ int main(int argc, char *argv[]) {
 | 
				
			||||||
		&state.tablet_tool_axis);
 | 
							&state.tablet_tool_axis);
 | 
				
			||||||
	state.tablet_tool_axis.notify = handle_tablet_tool_axis;
 | 
						state.tablet_tool_axis.notify = handle_tablet_tool_axis;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	state.xcursor_manager = wlr_xcursor_manager_create("default", 24);
 | 
						struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr);
 | 
				
			||||||
 | 
						state.xcursor_manager = wlr_xcursor_manager_create("default", 24, renderer);
 | 
				
			||||||
	if (!state.xcursor_manager) {
 | 
						if (!state.xcursor_manager) {
 | 
				
			||||||
		wlr_log(WLR_ERROR, "Failed to load left_ptr cursor");
 | 
							wlr_log(WLR_ERROR, "Failed to load left_ptr cursor");
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,6 +13,8 @@
 | 
				
			||||||
#include <wlr/types/wlr_cursor.h>
 | 
					#include <wlr/types/wlr_cursor.h>
 | 
				
			||||||
#include <wlr/xcursor.h>
 | 
					#include <wlr/xcursor.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * An XCursor theme at a particular scale factor of the base size.
 | 
					 * An XCursor theme at a particular scale factor of the base size.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -32,6 +34,9 @@ struct wlr_xcursor_manager {
 | 
				
			||||||
	char *name;
 | 
						char *name;
 | 
				
			||||||
	uint32_t size;
 | 
						uint32_t size;
 | 
				
			||||||
	struct wl_list scaled_themes; // wlr_xcursor_manager_theme::link
 | 
						struct wl_list scaled_themes; // wlr_xcursor_manager_theme::link
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_renderer *renderer;
 | 
				
			||||||
 | 
						struct wl_listener renderer_destroy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -39,7 +44,7 @@ struct wlr_xcursor_manager {
 | 
				
			||||||
 * (for use when scale=1).
 | 
					 * (for use when scale=1).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
 | 
					struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
 | 
				
			||||||
	uint32_t size);
 | 
						uint32_t size, struct wlr_renderer *renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager);
 | 
					void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,4 +62,20 @@ int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager,
 | 
				
			||||||
struct wlr_xcursor *wlr_xcursor_manager_get_xcursor(
 | 
					struct wlr_xcursor *wlr_xcursor_manager_get_xcursor(
 | 
				
			||||||
	struct wlr_xcursor_manager *manager, const char *name, float scale);
 | 
						struct wlr_xcursor_manager *manager, const char *name, float scale);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Retrieves the cached texture of this xcursor image from the
 | 
				
			||||||
 | 
					 * wlr_xcursor_manager.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The wlr_xcursor_manager must have been created with a wlr_renderer and the
 | 
				
			||||||
 | 
					 * wlr_xcursor_image must have come from a wlr_xcursor returned from
 | 
				
			||||||
 | 
					 * wlr_xcursor_manager_get_xcursor.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The returned texture is owned by the xcursor manager. You should not save or
 | 
				
			||||||
 | 
					 * destroy it.
 | 
				
			||||||
 | 
					 * The manager makes use of the wlr_xcursor_image.userdata field. You must not
 | 
				
			||||||
 | 
					 * modify this field yourself.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					struct wlr_texture *wlr_xcursor_manager_get_texture(
 | 
				
			||||||
 | 
						struct wlr_xcursor_manager *manager, struct wlr_xcursor_image *image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,6 +52,7 @@ struct wlr_xcursor_image {
 | 
				
			||||||
	uint32_t hotspot_y;	/* hot spot y (must be inside image) */
 | 
						uint32_t hotspot_y;	/* hot spot y (must be inside image) */
 | 
				
			||||||
	uint32_t delay;		/* animation delay to next frame (ms) */
 | 
						uint32_t delay;		/* animation delay to next frame (ms) */
 | 
				
			||||||
	uint8_t *buffer;
 | 
						uint8_t *buffer;
 | 
				
			||||||
 | 
						void *userdata;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_xcursor {
 | 
					struct wlr_xcursor {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,34 @@
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <wlr/types/wlr_xcursor_manager.h>
 | 
					#include <wlr/types/wlr_xcursor_manager.h>
 | 
				
			||||||
 | 
					#include <wlr/render/wlr_renderer.h>
 | 
				
			||||||
 | 
					#include <wlr/render/wlr_texture.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void manager_free_textures(struct wlr_xcursor_manager *manager) {
 | 
				
			||||||
 | 
						struct wlr_xcursor_manager_theme *iter;
 | 
				
			||||||
 | 
						wl_list_for_each(iter, &manager->scaled_themes, link) {
 | 
				
			||||||
 | 
							struct wlr_xcursor_theme *theme = iter->theme;
 | 
				
			||||||
 | 
							for (unsigned i = 0; i < theme->cursor_count; ++i) {
 | 
				
			||||||
 | 
								struct wlr_xcursor *xcursor = theme->cursors[i];
 | 
				
			||||||
 | 
								for (unsigned j = 0; j < xcursor->image_count; ++j) {
 | 
				
			||||||
 | 
									struct wlr_xcursor_image *img = xcursor->images[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									wlr_texture_destroy(img->userdata);
 | 
				
			||||||
 | 
									img->userdata = NULL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void handle_renderer_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct wlr_xcursor_manager *manager =
 | 
				
			||||||
 | 
							wl_container_of(listener, manager, renderer_destroy);
 | 
				
			||||||
 | 
						manager->renderer = NULL;
 | 
				
			||||||
 | 
						manager_free_textures(manager);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
 | 
					struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
 | 
				
			||||||
		uint32_t size) {
 | 
							uint32_t size, struct wlr_renderer *renderer) {
 | 
				
			||||||
	struct wlr_xcursor_manager *manager =
 | 
						struct wlr_xcursor_manager *manager =
 | 
				
			||||||
		calloc(1, sizeof(struct wlr_xcursor_manager));
 | 
							calloc(1, sizeof(struct wlr_xcursor_manager));
 | 
				
			||||||
	if (manager == NULL) {
 | 
						if (manager == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -15,6 +40,11 @@ struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	manager->size = size;
 | 
						manager->size = size;
 | 
				
			||||||
	wl_list_init(&manager->scaled_themes);
 | 
						wl_list_init(&manager->scaled_themes);
 | 
				
			||||||
 | 
						if (renderer) {
 | 
				
			||||||
 | 
							manager->renderer = renderer;
 | 
				
			||||||
 | 
							manager->renderer_destroy.notify = handle_renderer_destroy;
 | 
				
			||||||
 | 
							wl_signal_add(&renderer->events.destroy, &manager->renderer_destroy);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return manager;
 | 
						return manager;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,12 +52,20 @@ void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager) {
 | 
				
			||||||
	if (manager == NULL) {
 | 
						if (manager == NULL) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (manager->renderer) {
 | 
				
			||||||
 | 
							manager_free_textures(manager);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_xcursor_manager_theme *theme, *tmp;
 | 
						struct wlr_xcursor_manager_theme *theme, *tmp;
 | 
				
			||||||
	wl_list_for_each_safe(theme, tmp, &manager->scaled_themes, link) {
 | 
						wl_list_for_each_safe(theme, tmp, &manager->scaled_themes, link) {
 | 
				
			||||||
		wl_list_remove(&theme->link);
 | 
					 | 
				
			||||||
		wlr_xcursor_theme_destroy(theme->theme);
 | 
							wlr_xcursor_theme_destroy(theme->theme);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wl_list_remove(&theme->link);
 | 
				
			||||||
		free(theme);
 | 
							free(theme);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (manager->renderer) {
 | 
				
			||||||
 | 
							wl_list_remove(&manager->renderer_destroy.link);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	free(manager->name);
 | 
						free(manager->name);
 | 
				
			||||||
	free(manager);
 | 
						free(manager);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -65,3 +103,19 @@ struct wlr_xcursor *wlr_xcursor_manager_get_xcursor(
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return NULL;
 | 
						return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_texture *wlr_xcursor_manager_get_texture(
 | 
				
			||||||
 | 
							struct wlr_xcursor_manager *manager,
 | 
				
			||||||
 | 
							struct wlr_xcursor_image *image) {
 | 
				
			||||||
 | 
						if (!manager->renderer) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!image->userdata) {
 | 
				
			||||||
 | 
							image->userdata = wlr_texture_from_pixels(manager->renderer,
 | 
				
			||||||
 | 
								WL_SHM_FORMAT_ARGB8888, image->width * 4, image->width,
 | 
				
			||||||
 | 
								image->height, image->buffer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return image->userdata;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ static struct wlr_xcursor *xcursor_create_from_data(
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor->image_count = 1;
 | 
						cursor->image_count = 1;
 | 
				
			||||||
	cursor->images = malloc(sizeof(*cursor->images));
 | 
						cursor->images = calloc(1, sizeof(*cursor->images));
 | 
				
			||||||
	if (!cursor->images) {
 | 
						if (!cursor->images) {
 | 
				
			||||||
		goto err_free_cursor;
 | 
							goto err_free_cursor;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -137,7 +137,7 @@ static struct wlr_xcursor *xcursor_create_from_xcursor_images(
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor->images = malloc(images->nimage * sizeof(cursor->images[0]));
 | 
						cursor->images = calloc(images->nimage, sizeof(cursor->images[0]));
 | 
				
			||||||
	if (!cursor->images) {
 | 
						if (!cursor->images) {
 | 
				
			||||||
		free(cursor);
 | 
							free(cursor);
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
| 
						 | 
					@ -147,7 +147,7 @@ static struct wlr_xcursor *xcursor_create_from_xcursor_images(
 | 
				
			||||||
	cursor->total_delay = 0;
 | 
						cursor->total_delay = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < images->nimage; i++) {
 | 
						for (i = 0; i < images->nimage; i++) {
 | 
				
			||||||
		image = malloc(sizeof(*image));
 | 
							image = calloc(1, sizeof(*image));
 | 
				
			||||||
		if (image == NULL) {
 | 
							if (image == NULL) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue