From 571ff1a3a96f03a3c1e2e01479077c5d61eadfa0 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Sun, 30 Oct 2022 00:19:09 -0400 Subject: [PATCH] wayland: Prepare cursor implementation for reconnect support Co-authored-by: David Edmundson --- src/video/wayland/SDL_waylandmouse.c | 91 ++++++++++++++++++++++++---- src/video/wayland/SDL_waylandmouse.h | 3 + src/video/wayland/SDL_waylandvideo.c | 6 +- 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c index a5a45e724e..32499fdd7e 100644 --- a/src/video/wayland/SDL_waylandmouse.c +++ b/src/video/wayland/SDL_waylandmouse.c @@ -458,25 +458,35 @@ Wayland_CreateDefaultCursor() return Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); } +static void +Wayland_FreeCursorData(Wayland_CursorData *d) +{ + if (d->buffer) { + if (d->shm_data) { + wl_buffer_destroy(d->buffer); + } + d->buffer = NULL; + } + + if (d->surface) { + wl_surface_destroy(d->surface); + d->surface = NULL; + } +} + static void Wayland_FreeCursor(SDL_Cursor *cursor) { - Wayland_CursorData *d; - - if (!cursor) + if (!cursor) { return; - - d = cursor->driverdata; + } /* Probably not a cursor we own */ - if (!d) + if (!cursor->driverdata) { return; + } - if (d->buffer && d->shm_data) - wl_buffer_destroy(d->buffer); - - if (d->surface) - wl_surface_destroy(d->surface); + Wayland_FreeCursorData((Wayland_CursorData *) cursor->driverdata); /* Not sure what's meant to happen to shm_data */ SDL_free(cursor->driverdata); @@ -589,6 +599,65 @@ Wayland_EmulateMouseWarpChanged(void *userdata, const char *name, const char *ol input->warp_emulation_prohibited = !SDL_GetStringBoolean(hint, !input->warp_emulation_prohibited); } +#if 0 /* TODO RECONNECT: See waylandvideo.c for more information! */ +static void +Wayland_RecreateCursor(SDL_Cursor *cursor, SDL_VideoData *vdata) +{ + Wayland_CursorData *cdata = (Wayland_CursorData *) cursor->driverdata; + + /* Probably not a cursor we own */ + if (cdata == NULL) { + return; + } + + Wayland_FreeCursorData(cdata); + + /* We're not currently freeing this, so... yolo? */ + if (cdata->shm_data != NULL) { + void *old_data_pointer = cdata->shm_data; + int stride = cdata->w * 4; + + create_buffer_from_shm(cdata, cdata->w, cdata->h, WL_SHM_FORMAT_ARGB8888); + + SDL_memcpy(cdata->shm_data, old_data_pointer, stride * cdata->h); + + cdata->surface = wl_compositor_create_surface(vdata->compositor); + wl_surface_set_user_data(cdata->surface, NULL); + } +} + +void +Wayland_RecreateCursors(void) +{ + SDL_Cursor *cursor; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_VideoData *vdata = SDL_GetVideoDevice()->driverdata; + + if (vdata && vdata->cursor_themes) { + SDL_free(vdata->cursor_themes); + vdata->cursor_themes = NULL; + vdata->num_cursor_themes = 0; + } + + if (mouse == NULL) { + return; + } + + for (cursor = mouse->cursors; cursor != NULL; cursor = cursor->next) { + Wayland_RecreateCursor(cursor, vdata); + } + if (mouse->def_cursor) { + Wayland_RecreateCursor(mouse->def_cursor, vdata); + } + if (mouse->cur_cursor) { + Wayland_RecreateCursor(mouse->cur_cursor, vdata); + if (mouse->cursor_shown) { + Wayland_ShowCursor(mouse->cur_cursor); + } + } +} +#endif /* 0 */ + void Wayland_InitMouse(void) { diff --git a/src/video/wayland/SDL_waylandmouse.h b/src/video/wayland/SDL_waylandmouse.h index 76b58b5c23..00a56af435 100644 --- a/src/video/wayland/SDL_waylandmouse.h +++ b/src/video/wayland/SDL_waylandmouse.h @@ -27,5 +27,8 @@ extern void Wayland_InitMouse(void); extern void Wayland_FiniMouse(SDL_VideoData *data); +#if 0 /* TODO RECONNECT: See waylandvideo.c for more information! */ +extern void Wayland_RecreateCursors(void); +#endif /* 0 */ #endif diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 318d96e088..eccdd0bbb3 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -1027,7 +1027,7 @@ Wayland_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float return driverdata->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); } -void +static void Wayland_VideoCleanup(_THIS) { SDL_VideoData *data = _this->driverdata; @@ -1160,8 +1160,6 @@ Wayland_VideoReconnect(_THIS) SDL_GLContext current_ctx = SDL_GL_GetCurrentContext(); SDL_Window *current_window = SDL_GL_GetCurrentWindow(); - Wayland_FiniMouse(data); - SDL_GL_MakeCurrent(NULL, NULL); Wayland_VideoCleanup(_this); @@ -1188,6 +1186,8 @@ Wayland_VideoReconnect(_THIS) window = window->next; } + Wayland_RecreateCursors(); + if (current_window && current_ctx) { SDL_GL_MakeCurrent (current_window, current_ctx); }