mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Introduce wlr_xcursor_manager
This commit is contained in:
		
							parent
							
								
									2dccb11741
								
							
						
					
					
						commit
						8605243459
					
				
					 13 changed files with 180 additions and 167 deletions
				
			
		| 
						 | 
				
			
			@ -30,7 +30,7 @@ struct roots_cursor {
 | 
			
		|||
	enum roots_cursor_mode mode;
 | 
			
		||||
 | 
			
		||||
	// state from input (review if this is necessary)
 | 
			
		||||
	struct roots_xcursor_theme *xcursor_theme;
 | 
			
		||||
	struct wlr_xcursor_manager *xcursor_manager;
 | 
			
		||||
	struct wlr_seat *wl_seat;
 | 
			
		||||
	struct wl_client *cursor_client;
 | 
			
		||||
	int offs_x, offs_y;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,9 +30,9 @@ struct roots_desktop {
 | 
			
		|||
 | 
			
		||||
	struct roots_server *server;
 | 
			
		||||
	struct roots_config *config;
 | 
			
		||||
	struct roots_xcursor_theme *xcursor_theme;
 | 
			
		||||
 | 
			
		||||
	struct wlr_output_layout *layout;
 | 
			
		||||
	struct wlr_xcursor_manager *xcursor_manager;
 | 
			
		||||
 | 
			
		||||
	struct wlr_compositor *compositor;
 | 
			
		||||
	struct wlr_wl_shell *wl_shell;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,44 +1,14 @@
 | 
			
		|||
#ifndef _ROOTSTON_XCURSOR_H
 | 
			
		||||
#define _ROOTSTON_XCURSOR_H
 | 
			
		||||
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
#include <wlr/xcursor.h>
 | 
			
		||||
#include <wlr/xwayland.h>
 | 
			
		||||
#include <wlr/types/wlr_cursor.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#define ROOTS_XCURSOR_SIZE 16
 | 
			
		||||
 | 
			
		||||
struct roots_xcursor_scaled_theme {
 | 
			
		||||
	uint32_t scale;
 | 
			
		||||
	struct wlr_xcursor_theme *theme;
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
};
 | 
			
		||||
#define ROOTS_XCURSOR_DEFAULT "left_ptr"
 | 
			
		||||
#define ROOTS_XCURSOR_MOVE "grabbing"
 | 
			
		||||
#define ROOTS_XCURSOR_ROTATE "grabbing"
 | 
			
		||||
 | 
			
		||||
struct roots_xcursor_theme {
 | 
			
		||||
	char *name;
 | 
			
		||||
	struct wl_list scaled_themes; // roots_xcursor_scaled_theme::link
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name);
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme);
 | 
			
		||||
 | 
			
		||||
int roots_xcursor_theme_load(struct roots_xcursor_theme *theme,
 | 
			
		||||
	uint32_t scale);
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme,
 | 
			
		||||
	struct wlr_cursor *cursor);
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme,
 | 
			
		||||
	struct wlr_cursor *cursor);
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme,
 | 
			
		||||
	struct wlr_cursor *cursor, uint32_t edges);
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme,
 | 
			
		||||
	struct wlr_cursor *cursor);
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme,
 | 
			
		||||
	struct wlr_xwayland *xwayland);
 | 
			
		||||
const char *roots_xcursor_get_resize_name(uint32_t edges);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,6 @@
 | 
			
		|||
#include <wlr/types/wlr_output_layout.h>
 | 
			
		||||
#include <wlr/types/wlr_input_device.h>
 | 
			
		||||
#include <wlr/types/wlr_box.h>
 | 
			
		||||
#include <wlr/xcursor.h>
 | 
			
		||||
 | 
			
		||||
struct wlr_cursor_state;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								include/wlr/types/wlr_xcursor_manager.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								include/wlr/types/wlr_xcursor_manager.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
#ifndef WLR_TYPES_WLR_XCURSOR_MANAGER_H
 | 
			
		||||
#define WLR_TYPES_WLR_XCURSOR_MANAGER_H
 | 
			
		||||
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
#include <wlr/types/wlr_cursor.h>
 | 
			
		||||
#include <wlr/xcursor.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A scaled XCursor theme.
 | 
			
		||||
 */
 | 
			
		||||
struct wlr_xcursor_manager_theme {
 | 
			
		||||
	uint32_t scale;
 | 
			
		||||
	struct wlr_xcursor_theme *theme;
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Manage multiple XCursor themes with different scales and set `wlr_cursor`
 | 
			
		||||
 * images.
 | 
			
		||||
 *
 | 
			
		||||
 * This manager can be used to display cursor images on multiple outputs having
 | 
			
		||||
 * different scale factors.
 | 
			
		||||
 */
 | 
			
		||||
struct wlr_xcursor_manager {
 | 
			
		||||
	char *name;
 | 
			
		||||
	uint32_t size;
 | 
			
		||||
	struct wl_list scaled_themes; // wlr_xcursor_manager_theme::link
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new XCursor manager. After initialization, scaled themes need to be
 | 
			
		||||
 * loaded with `wlr_xcursor_manager_load`. `size` is the unscaled cursor theme
 | 
			
		||||
 * size.
 | 
			
		||||
 */
 | 
			
		||||
struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
 | 
			
		||||
	uint32_t size);
 | 
			
		||||
 | 
			
		||||
void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager);
 | 
			
		||||
 | 
			
		||||
int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager,
 | 
			
		||||
	uint32_t scale);
 | 
			
		||||
 | 
			
		||||
struct wlr_xcursor *wlr_xcursor_manager_get_xcursor(
 | 
			
		||||
	struct wlr_xcursor_manager *manager, const char *name, uint32_t scale);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set a `wlr_cursor` image. The manager uses all currently loaded scaled
 | 
			
		||||
 * themes.
 | 
			
		||||
 */
 | 
			
		||||
void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager,
 | 
			
		||||
	const char *name, struct wlr_cursor *cursor);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,7 @@
 | 
			
		|||
#elif __FreeBSD__
 | 
			
		||||
#include <dev/evdev/input-event-codes.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <wlr/types/wlr_xcursor_manager.h>
 | 
			
		||||
#include <wlr/util/log.h>
 | 
			
		||||
#include "rootston/xcursor.h"
 | 
			
		||||
#include "rootston/cursor.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -44,8 +45,8 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t
 | 
			
		|||
			set_compositor_cursor = view_client != cursor->cursor_client;
 | 
			
		||||
		}
 | 
			
		||||
		if (set_compositor_cursor) {
 | 
			
		||||
			roots_xcursor_theme_set_default(cursor->xcursor_theme,
 | 
			
		||||
				cursor->cursor);
 | 
			
		||||
			wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager,
 | 
			
		||||
				ROOTS_XCURSOR_DEFAULT, cursor->cursor);
 | 
			
		||||
			cursor->cursor_client = NULL;
 | 
			
		||||
		}
 | 
			
		||||
		if (view) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
#include <wlr/types/wlr_server_decoration.h>
 | 
			
		||||
#include <wlr/types/wlr_output_layout.h>
 | 
			
		||||
#include <wlr/types/wlr_wl_shell.h>
 | 
			
		||||
#include <wlr/types/wlr_xcursor_manager.h>
 | 
			
		||||
#include <wlr/types/wlr_xdg_shell_v6.h>
 | 
			
		||||
#include <wlr/util/log.h>
 | 
			
		||||
#include <server-decoration-protocol.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -324,8 +325,10 @@ struct roots_desktop *desktop_create(struct roots_server *server,
 | 
			
		|||
	desktop->server = server;
 | 
			
		||||
	desktop->config = config;
 | 
			
		||||
 | 
			
		||||
	desktop->xcursor_theme = roots_xcursor_theme_create("default");
 | 
			
		||||
	if (desktop->xcursor_theme == NULL) {
 | 
			
		||||
	desktop->xcursor_manager = wlr_xcursor_manager_create(NULL,
 | 
			
		||||
		ROOTS_XCURSOR_SIZE);
 | 
			
		||||
	if (desktop->xcursor_manager == NULL) {
 | 
			
		||||
		wlr_log(L_ERROR, "Cannot create XCursor manager");
 | 
			
		||||
		wlr_list_free(desktop->views);
 | 
			
		||||
		free(desktop);
 | 
			
		||||
		return NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -353,11 +356,17 @@ struct roots_desktop *desktop_create(struct roots_server *server,
 | 
			
		|||
			&desktop->xwayland_surface);
 | 
			
		||||
		desktop->xwayland_surface.notify = handle_xwayland_surface;
 | 
			
		||||
 | 
			
		||||
		if (roots_xcursor_theme_load(desktop->xcursor_theme, 1)) {
 | 
			
		||||
			wlr_log(L_ERROR, "Cannot load xwayland xcursor theme");
 | 
			
		||||
		if (wlr_xcursor_manager_load(desktop->xcursor_manager, 1)) {
 | 
			
		||||
			wlr_log(L_ERROR, "Cannot load XWayland XCursor theme");
 | 
			
		||||
		}
 | 
			
		||||
		struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(
 | 
			
		||||
			desktop->xcursor_manager, ROOTS_XCURSOR_DEFAULT, 1);
 | 
			
		||||
		if (xcursor != NULL) {
 | 
			
		||||
			struct wlr_xcursor_image *image = xcursor->images[0];
 | 
			
		||||
			wlr_xwayland_set_cursor(desktop->xwayland, image->buffer,
 | 
			
		||||
				image->width, image->width, image->height, image->hotspot_x,
 | 
			
		||||
				image->hotspot_y);
 | 
			
		||||
		}
 | 
			
		||||
		roots_xcursor_theme_xwayland_set_default(desktop->xcursor_theme,
 | 
			
		||||
			desktop->xwayland);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,13 +5,13 @@
 | 
			
		|||
#include <wlr/types/wlr_output_layout.h>
 | 
			
		||||
#include <wlr/types/wlr_compositor.h>
 | 
			
		||||
#include <wlr/types/wlr_wl_shell.h>
 | 
			
		||||
#include <wlr/types/wlr_xcursor_manager.h>
 | 
			
		||||
#include <wlr/types/wlr_xdg_shell_v6.h>
 | 
			
		||||
#include <wlr/render/matrix.h>
 | 
			
		||||
#include <wlr/util/log.h>
 | 
			
		||||
#include "rootston/server.h"
 | 
			
		||||
#include "rootston/desktop.h"
 | 
			
		||||
#include "rootston/config.h"
 | 
			
		||||
#include "rootston/xcursor.h"
 | 
			
		||||
 | 
			
		||||
static inline int64_t timespec_to_msec(const struct timespec *a) {
 | 
			
		||||
	return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
 | 
			
		||||
| 
						 | 
				
			
			@ -243,7 +243,7 @@ void output_add_notify(struct wl_listener *listener, void *data) {
 | 
			
		|||
 | 
			
		||||
	struct roots_seat *seat;
 | 
			
		||||
	wl_list_for_each(seat, &input->seats, link) {
 | 
			
		||||
		if (roots_xcursor_theme_load(seat->cursor->xcursor_theme,
 | 
			
		||||
		if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager,
 | 
			
		||||
				wlr_output->scale)) {
 | 
			
		||||
			wlr_log(L_ERROR, "Cannot load xcursor theme for output '%s' "
 | 
			
		||||
				"with scale %d", wlr_output->name, wlr_output->scale);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include <wlr/types/wlr_xcursor_manager.h>
 | 
			
		||||
#include <wlr/util/log.h>
 | 
			
		||||
 | 
			
		||||
#include "rootston/xcursor.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -187,8 +188,9 @@ static void roots_seat_init_cursor(struct roots_seat *seat) {
 | 
			
		|||
	wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout);
 | 
			
		||||
 | 
			
		||||
	// TODO: be able to configure per-seat cursor themes
 | 
			
		||||
	seat->cursor->xcursor_theme = desktop->xcursor_theme;
 | 
			
		||||
	roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, wlr_cursor);
 | 
			
		||||
	seat->cursor->xcursor_manager = desktop->xcursor_manager;
 | 
			
		||||
	wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager,
 | 
			
		||||
		ROOTS_XCURSOR_DEFAULT, wlr_cursor);
 | 
			
		||||
 | 
			
		||||
	wl_list_init(&seat->cursor->touch_points);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -446,8 +448,8 @@ void roots_seat_remove_device(struct roots_seat *seat,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void roots_seat_configure_xcursor(struct roots_seat *seat) {
 | 
			
		||||
	roots_xcursor_theme_set_default(seat->cursor->xcursor_theme,
 | 
			
		||||
		seat->cursor->cursor);
 | 
			
		||||
	wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager,
 | 
			
		||||
		ROOTS_XCURSOR_DEFAULT, seat->cursor->cursor);
 | 
			
		||||
	wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x,
 | 
			
		||||
		seat->cursor->cursor->y);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -524,8 +526,8 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) {
 | 
			
		|||
	view_maximize(view, false);
 | 
			
		||||
	wlr_seat_pointer_clear_focus(seat->seat);
 | 
			
		||||
 | 
			
		||||
	roots_xcursor_theme_set_move(seat->cursor->xcursor_theme,
 | 
			
		||||
		seat->cursor->cursor);
 | 
			
		||||
	wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager,
 | 
			
		||||
		ROOTS_XCURSOR_MOVE, seat->cursor->cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view,
 | 
			
		||||
| 
						 | 
				
			
			@ -551,8 +553,8 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view,
 | 
			
		|||
	view_maximize(view, false);
 | 
			
		||||
	wlr_seat_pointer_clear_focus(seat->seat);
 | 
			
		||||
 | 
			
		||||
	roots_xcursor_theme_set_resize(seat->cursor->xcursor_theme,
 | 
			
		||||
		seat->cursor->cursor, edges);
 | 
			
		||||
	wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager,
 | 
			
		||||
		roots_xcursor_get_resize_name(edges), seat->cursor->cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) {
 | 
			
		||||
| 
						 | 
				
			
			@ -564,6 +566,6 @@ void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) {
 | 
			
		|||
	view_maximize(view, false);
 | 
			
		||||
	wlr_seat_pointer_clear_focus(seat->seat);
 | 
			
		||||
 | 
			
		||||
	roots_xcursor_theme_set_rotate(seat->cursor->xcursor_theme,
 | 
			
		||||
		seat->cursor->cursor);
 | 
			
		||||
	wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager,
 | 
			
		||||
		ROOTS_XCURSOR_ROTATE, seat->cursor->cursor);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,83 +4,7 @@
 | 
			
		|||
#include "rootston/xcursor.h"
 | 
			
		||||
#include "rootston/input.h"
 | 
			
		||||
 | 
			
		||||
struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name) {
 | 
			
		||||
	struct roots_xcursor_theme *theme =
 | 
			
		||||
		calloc(1, sizeof(struct roots_xcursor_theme));
 | 
			
		||||
	if (theme == NULL) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	theme->name = strdup(name);
 | 
			
		||||
	wl_list_init(&theme->scaled_themes);
 | 
			
		||||
	return theme;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme) {
 | 
			
		||||
	if (theme == NULL) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct roots_xcursor_scaled_theme *scaled_theme, *tmp;
 | 
			
		||||
	wl_list_for_each_safe(scaled_theme, tmp, &theme->scaled_themes, link) {
 | 
			
		||||
		wl_list_remove(&scaled_theme->link);
 | 
			
		||||
		wlr_xcursor_theme_destroy(scaled_theme->theme);
 | 
			
		||||
		free(scaled_theme);
 | 
			
		||||
	}
 | 
			
		||||
	free(theme->name);
 | 
			
		||||
	free(theme);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int roots_xcursor_theme_load(struct roots_xcursor_theme *theme,
 | 
			
		||||
		uint32_t scale) {
 | 
			
		||||
	struct roots_xcursor_scaled_theme *scaled_theme;
 | 
			
		||||
	wl_list_for_each(scaled_theme, &theme->scaled_themes, link) {
 | 
			
		||||
		if (scaled_theme->scale == scale) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scaled_theme = calloc(1, sizeof(struct roots_xcursor_scaled_theme));
 | 
			
		||||
	if (scaled_theme == NULL) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	scaled_theme->scale = scale;
 | 
			
		||||
	scaled_theme->theme = wlr_xcursor_theme_load(NULL,
 | 
			
		||||
		ROOTS_XCURSOR_SIZE * scale);
 | 
			
		||||
	if (scaled_theme->theme == NULL) {
 | 
			
		||||
		free(scaled_theme);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	wl_list_insert(&theme->scaled_themes, &scaled_theme->link);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void roots_xcursor_theme_set(struct roots_xcursor_theme *theme,
 | 
			
		||||
		struct wlr_cursor *cursor, const char *name) {
 | 
			
		||||
	struct roots_xcursor_scaled_theme *scaled_theme;
 | 
			
		||||
	wl_list_for_each(scaled_theme, &theme->scaled_themes, link) {
 | 
			
		||||
		struct wlr_xcursor *xcursor =
 | 
			
		||||
			wlr_xcursor_theme_get_cursor(scaled_theme->theme, name);
 | 
			
		||||
		if (xcursor == NULL) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		struct wlr_xcursor_image *image = xcursor->images[0];
 | 
			
		||||
		wlr_cursor_set_image(cursor, image->buffer, image->width,
 | 
			
		||||
			image->width, image->height, image->hotspot_x, image->hotspot_y,
 | 
			
		||||
			scaled_theme->scale);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme,
 | 
			
		||||
		struct wlr_cursor *cursor) {
 | 
			
		||||
	roots_xcursor_theme_set(theme, cursor, "left_ptr");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme,
 | 
			
		||||
		struct wlr_cursor *cursor) {
 | 
			
		||||
	roots_xcursor_theme_set(theme, cursor, "grabbing");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *get_resize_xcursor_name(uint32_t edges) {
 | 
			
		||||
const char *roots_xcursor_get_resize_name(uint32_t edges) {
 | 
			
		||||
	if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) {
 | 
			
		||||
		if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) {
 | 
			
		||||
			return "ne-resize";
 | 
			
		||||
| 
						 | 
				
			
			@ -102,33 +26,3 @@ static const char *get_resize_xcursor_name(uint32_t edges) {
 | 
			
		|||
	}
 | 
			
		||||
	return "se-resize"; // fallback
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme,
 | 
			
		||||
		struct wlr_cursor *cursor, uint32_t edges) {
 | 
			
		||||
	roots_xcursor_theme_set(theme, cursor, get_resize_xcursor_name(edges));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme,
 | 
			
		||||
	struct wlr_cursor *cursor) {
 | 
			
		||||
	roots_xcursor_theme_set(theme, cursor, "grabbing");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme,
 | 
			
		||||
		struct wlr_xwayland *xwayland) {
 | 
			
		||||
	struct roots_xcursor_scaled_theme *scaled_theme;
 | 
			
		||||
	wl_list_for_each(scaled_theme, &theme->scaled_themes, link) {
 | 
			
		||||
		if (scaled_theme->scale == 1) {
 | 
			
		||||
			struct wlr_xcursor *xcursor =
 | 
			
		||||
				wlr_xcursor_theme_get_cursor(scaled_theme->theme, "left_ptr");
 | 
			
		||||
			if (xcursor == NULL) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			struct wlr_xcursor_image *image = xcursor->images[0];
 | 
			
		||||
			wlr_xwayland_set_cursor(xwayland, image->buffer, image->width,
 | 
			
		||||
				image->width, image->height, image->hotspot_x,
 | 
			
		||||
				image->hotspot_y);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,9 @@ lib_wlr_types = static_library(
 | 
			
		|||
		'wlr_tablet_pad.c',
 | 
			
		||||
		'wlr_tablet_tool.c',
 | 
			
		||||
		'wlr_touch.c',
 | 
			
		||||
		'wlr_xdg_shell_v6.c',
 | 
			
		||||
		'wlr_wl_shell.c',
 | 
			
		||||
		'wlr_xcursor_manager.c',
 | 
			
		||||
		'wlr_xdg_shell_v6.c',
 | 
			
		||||
	),
 | 
			
		||||
	include_directories: wlr_inc,
 | 
			
		||||
	dependencies: [wayland_server, pixman, wlr_protos],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										84
									
								
								types/wlr_xcursor_manager.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								types/wlr_xcursor_manager.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
#define _POSIX_C_SOURCE 200809L
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <wlr/types/wlr_xcursor_manager.h>
 | 
			
		||||
 | 
			
		||||
struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name,
 | 
			
		||||
		uint32_t size) {
 | 
			
		||||
	struct wlr_xcursor_manager *manager =
 | 
			
		||||
		calloc(1, sizeof(struct wlr_xcursor_manager));
 | 
			
		||||
	if (manager == NULL) {
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	if (name != NULL) {
 | 
			
		||||
		manager->name = strdup(name);
 | 
			
		||||
	}
 | 
			
		||||
	manager->size = size;
 | 
			
		||||
	wl_list_init(&manager->scaled_themes);
 | 
			
		||||
	return manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager) {
 | 
			
		||||
	if (manager == NULL) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct wlr_xcursor_manager_theme *theme, *tmp;
 | 
			
		||||
	wl_list_for_each_safe(theme, tmp, &manager->scaled_themes, link) {
 | 
			
		||||
		wl_list_remove(&theme->link);
 | 
			
		||||
		wlr_xcursor_theme_destroy(theme->theme);
 | 
			
		||||
		free(theme);
 | 
			
		||||
	}
 | 
			
		||||
	free(manager->name);
 | 
			
		||||
	free(manager);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager,
 | 
			
		||||
		uint32_t scale) {
 | 
			
		||||
	struct wlr_xcursor_manager_theme *theme;
 | 
			
		||||
	wl_list_for_each(theme, &manager->scaled_themes, link) {
 | 
			
		||||
		if (theme->scale == scale) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	theme = calloc(1, sizeof(struct wlr_xcursor_manager_theme));
 | 
			
		||||
	if (theme == NULL) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	theme->scale = scale;
 | 
			
		||||
	theme->theme = wlr_xcursor_theme_load(NULL, manager->size * scale);
 | 
			
		||||
	if (theme->theme == NULL) {
 | 
			
		||||
		free(theme);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
	wl_list_insert(&manager->scaled_themes, &theme->link);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct wlr_xcursor *wlr_xcursor_manager_get_xcursor(
 | 
			
		||||
		struct wlr_xcursor_manager *manager, const char *name, uint32_t scale) {
 | 
			
		||||
	struct wlr_xcursor_manager_theme *theme;
 | 
			
		||||
	wl_list_for_each(theme, &manager->scaled_themes, link) {
 | 
			
		||||
		if (theme->scale == scale) {
 | 
			
		||||
			return wlr_xcursor_theme_get_cursor(theme->theme, name);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager,
 | 
			
		||||
		const char *name, struct wlr_cursor *cursor) {
 | 
			
		||||
	struct wlr_xcursor_manager_theme *theme;
 | 
			
		||||
	wl_list_for_each(theme, &manager->scaled_themes, link) {
 | 
			
		||||
		struct wlr_xcursor *xcursor =
 | 
			
		||||
			wlr_xcursor_theme_get_cursor(theme->theme, name);
 | 
			
		||||
		if (xcursor == NULL) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		struct wlr_xcursor_image *image = xcursor->images[0];
 | 
			
		||||
		wlr_cursor_set_image(cursor, image->buffer, image->width,
 | 
			
		||||
			image->width, image->height, image->hotspot_x, image->hotspot_y,
 | 
			
		||||
			theme->scale);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue