Wayland: Cursor toggling.

This commit is contained in:
Hans-Kristian Arntzen 2016-12-17 21:34:51 +01:00
parent 313ac63c33
commit c48bb6284e
3 changed files with 70 additions and 5 deletions

View File

@ -580,8 +580,8 @@ endif
ifeq ($(HAVE_WAYLAND), 1) ifeq ($(HAVE_WAYLAND), 1)
OBJ += gfx/drivers_context/wayland_ctx.o OBJ += gfx/drivers_context/wayland_ctx.o
DEFINES += $(WAYLAND_CFLAGS) DEFINES += $(WAYLAND_CFLAGS) $(WAYLAND_CURSOR_CFLAGS)
LIBS += $(WAYLAND_LIBS) LIBS += $(WAYLAND_LIBS) $(WAYLAND_CURSOR_LIBS)
endif endif
#Input #Input

View File

@ -18,6 +18,7 @@
#include <unistd.h> #include <unistd.h>
#include <wayland-client.h> #include <wayland-client.h>
#include <wayland-cursor.h>
#include <string/stdstring.h> #include <string/stdstring.h>
@ -70,6 +71,7 @@ typedef struct gfx_ctx_wayland_data
struct wl_keyboard *wl_keyboard; struct wl_keyboard *wl_keyboard;
struct wl_pointer *wl_pointer; struct wl_pointer *wl_pointer;
struct wl_seat *seat; struct wl_seat *seat;
struct wl_shm *shm;
unsigned swap_interval; unsigned swap_interval;
bool core_hw_context_enable; bool core_hw_context_enable;
@ -89,6 +91,16 @@ typedef struct gfx_ctx_wayland_data
bool focus; bool focus;
bool left, right, middle; bool left, right, middle;
} mouse; } mouse;
struct
{
struct wl_cursor *default_cursor;
struct wl_cursor_theme *theme;
struct wl_surface *surface;
uint32_t serial;
bool visible;
} cursor;
const input_device_driver_t *joypad; const input_device_driver_t *joypad;
bool blocked; bool blocked;
@ -215,6 +227,7 @@ static void keyboard_handle_repeat_info(void *data,
(void)wl_keyboard; (void)wl_keyboard;
(void)rate; (void)rate;
(void)delay; (void)delay;
/* TODO: Seems like we'll need this to get repeat working. We'll have to do it on our own. */
} }
static const struct wl_keyboard_listener keyboard_listener = { static const struct wl_keyboard_listener keyboard_listener = {
@ -226,6 +239,8 @@ static const struct wl_keyboard_listener keyboard_listener = {
keyboard_handle_repeat_info, keyboard_handle_repeat_info,
}; };
static void gfx_ctx_wl_show_mouse(void *data, bool state);
static void pointer_handle_enter(void *data, static void pointer_handle_enter(void *data,
struct wl_pointer *pointer, struct wl_pointer *pointer,
uint32_t serial, uint32_t serial,
@ -243,6 +258,9 @@ static void pointer_handle_enter(void *data,
wl->mouse.x = wl->mouse.last_x; wl->mouse.x = wl->mouse.last_x;
wl->mouse.y = wl->mouse.last_y; wl->mouse.y = wl->mouse.last_y;
wl->mouse.focus = true; wl->mouse.focus = true;
wl->cursor.serial = serial;
gfx_ctx_wl_show_mouse(data, wl->cursor.visible);
} }
static void pointer_handle_leave(void *data, static void pointer_handle_leave(void *data,
@ -492,6 +510,8 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
else if (string_is_equal(interface, "wl_shell")) else if (string_is_equal(interface, "wl_shell"))
wl->shell = (struct wl_shell*) wl->shell = (struct wl_shell*)
wl_registry_bind(reg, id, &wl_shell_interface, 1); wl_registry_bind(reg, id, &wl_shell_interface, 1);
else if (string_is_equal(interface, "wl_shm"))
wl->shm = wl_registry_bind(reg, id, &wl_shm_interface, 1);
else if (string_is_equal(interface, "wl_seat")) else if (string_is_equal(interface, "wl_seat"))
{ {
wl->seat = wl_registry_bind(reg, id, &wl_seat_interface, 4); wl->seat = wl_registry_bind(reg, id, &wl_seat_interface, 4);
@ -560,6 +580,11 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl)
if (wl->wl_pointer) if (wl->wl_pointer)
wl_pointer_destroy(wl->wl_pointer); wl_pointer_destroy(wl->wl_pointer);
if (wl->cursor.theme)
wl_cursor_theme_destroy(wl->cursor.theme);
if (wl->cursor.surface)
wl_surface_destroy(wl->cursor.surface);
if (wl->seat) if (wl->seat)
wl_seat_destroy(wl->seat); wl_seat_destroy(wl->seat);
if (wl->shell) if (wl->shell)
@ -862,6 +887,12 @@ static void *gfx_ctx_wl_init(void *video_driver)
goto error; goto error;
} }
if (!wl->shm)
{
RARCH_ERR("Failed to create shm.\n");
goto error;
}
if (!wl->shell) if (!wl->shell)
{ {
RARCH_ERR("Failed to create shell.\n"); RARCH_ERR("Failed to create shell.\n");
@ -902,6 +933,11 @@ static void *gfx_ctx_wl_init(void *video_driver)
wl->keyboard_focus = true; wl->keyboard_focus = true;
wl->mouse.focus = true; wl->mouse.focus = true;
wl->cursor.surface = wl_compositor_create_surface(wl->compositor);
wl->cursor.theme = wl_cursor_theme_load(NULL, 16, wl->shm);
wl->cursor.default_cursor = wl_cursor_theme_get_cursor(wl->cursor.theme, "left_ptr");
flush_wayland_fd(wl);
return wl; return wl;
error: error:
@ -1123,6 +1159,14 @@ static bool gfx_ctx_wl_set_video_mode(void *data,
break; break;
} }
if (fullscreen)
{
wl->cursor.visible = false;
gfx_ctx_wl_show_mouse(wl, false);
}
else
wl->cursor.visible = true;
return true; return true;
error: error:
@ -1592,6 +1636,26 @@ static void gfx_ctx_wl_set_flags(void *data, uint32_t flags)
wl->core_hw_context_enable = true; wl->core_hw_context_enable = true;
} }
static void gfx_ctx_wl_show_mouse(void *data, bool state)
{
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
if (!wl->wl_pointer)
return;
if (state)
{
struct wl_cursor_image *image = wl->cursor.default_cursor->images[0];
wl_pointer_set_cursor(wl->wl_pointer, wl->cursor.serial, wl->cursor.surface, image->hotspot_x, image->hotspot_y);
wl_surface_attach(wl->cursor.surface, wl_cursor_image_get_buffer(image), 0, 0);
wl_surface_damage(wl->cursor.surface, 0, 0, image->width, image->height);
wl_surface_commit(wl->cursor.surface);
}
else
wl_pointer_set_cursor(wl->wl_pointer, wl->cursor.serial, NULL, 0, 0);
wl->cursor.visible = state;
}
const gfx_ctx_driver_t gfx_ctx_wayland = { const gfx_ctx_driver_t gfx_ctx_wayland = {
gfx_ctx_wl_init, gfx_ctx_wl_init,
gfx_ctx_wl_destroy, gfx_ctx_wl_destroy,
@ -1615,7 +1679,7 @@ const gfx_ctx_driver_t gfx_ctx_wayland = {
gfx_ctx_wl_get_proc_address, gfx_ctx_wl_get_proc_address,
NULL, NULL,
NULL, NULL,
NULL, gfx_ctx_wl_show_mouse,
"wayland", "wayland",
gfx_ctx_wl_get_flags, gfx_ctx_wl_get_flags,
gfx_ctx_wl_set_flags, gfx_ctx_wl_set_flags,
@ -1625,5 +1689,5 @@ const gfx_ctx_driver_t gfx_ctx_wayland = {
#else #else
NULL, NULL,
#endif #endif
NULL NULL,
}; };

View File

@ -395,6 +395,7 @@ check_pkgconf XCB xcb
[ "$HAVE_X11" = "no" ] && HAVE_XEXT=no && HAVE_XF86VM=no && HAVE_XINERAMA=no && HAVE_XSHM=no [ "$HAVE_X11" = "no" ] && HAVE_XEXT=no && HAVE_XF86VM=no && HAVE_XINERAMA=no && HAVE_XSHM=no
check_pkgconf WAYLAND wayland-egl check_pkgconf WAYLAND wayland-egl
check_pkgconf WAYLAND_CURSOR wayland-cursor
check_pkgconf XKBCOMMON xkbcommon 0.3.2 check_pkgconf XKBCOMMON xkbcommon 0.3.2
check_pkgconf DBUS dbus-1 check_pkgconf DBUS dbus-1
@ -483,6 +484,6 @@ fi
# Creates config.mk and config.h. # Creates config.mk and config.h.
add_define_make GLOBAL_CONFIG_DIR "$GLOBAL_CONFIG_DIR" add_define_make GLOBAL_CONFIG_DIR "$GLOBAL_CONFIG_DIR"
VARS=$(eval set | grep ^HAVE_ | sed s/=.*// | sed s/^HAVE_//) VARS="$(eval set | grep ^HAVE_ | sed s/=.*// | sed s/^HAVE_//) WAYLAND_CURSOR"
create_config_make config.mk $VARS create_config_make config.mk $VARS
create_config_header config.h $VARS create_config_header config.h $VARS