From af2132315d7fc8073e88cbeb50123a7250c0636f Mon Sep 17 00:00:00 2001 From: Oskari Alaranta Date: Mon, 1 Jun 2026 20:40:56 +0300 Subject: [PATCH] Implement WarpPointer This allows playing games that capture the cursor --- xbanan/Base.cpp | 30 ++++++++++++++++++++++++++++++ xbanan/Platform.h | 2 ++ xbanan/SDL3/sdl3.cpp | 14 ++++++++++++++ xbanan/banan-os/banan-os.cpp | 8 ++++++++ 4 files changed, 54 insertions(+) diff --git a/xbanan/Base.cpp b/xbanan/Base.cpp index 8b6e7f3..3c84389 100644 --- a/xbanan/Base.cpp +++ b/xbanan/Base.cpp @@ -2013,6 +2013,36 @@ BAN::ErrorOr handle_packet(Client& client_info, BAN::ConstByteSpan packet) break; } + case X_WarpPointer: + { + auto request = decode(packet).value(); + + dprintln("WarpPointer"); + dprintln(" src_wid: {}", request.srcWid); + dprintln(" src_x: {}", request.srcX); + dprintln(" src_y: {}", request.srcY); + dprintln(" src_w: {}", request.srcWidth); + dprintln(" src_h: {}", request.srcHeight); + dprintln(" dst_wid: {}", request.dstWid); + dprintln(" dst_x: {}", request.dstX); + dprintln(" dst_y: {}", request.dstY); + + if (g_platform_ops.warp_pointer == nullptr) + break; + + // TODO: source window :) + + if (request.dstWid == None) + g_platform_ops.warp_pointer(request.dstX, request.dstY, true); + else + { + (void)TRY_REF(get_window(client_info, request.dstWid, X_WarpPointer)); + const auto [win_x, win_y] = get_window_position(request.dstWid); + g_platform_ops.warp_pointer(win_x + request.dstX, win_y + request.dstY, false); + } + + break; + } case X_QueryKeymap: { dprintln("QueryKeymap"); diff --git a/xbanan/Platform.h b/xbanan/Platform.h index b3e1ad2..caca7b9 100644 --- a/xbanan/Platform.h +++ b/xbanan/Platform.h @@ -59,6 +59,8 @@ struct PlatformOps void (*request_reposition)(PlatformWindow*, int32_t x, int32_t y); /* Request new fullscreen state, can be async */ void (*request_fullscreen)(PlatformWindow*, bool fullscreen); + /* Warp pointer */ + void (*warp_pointer)(int32_t x, int32_t y, bool relative); /* Create a system cursor */ BAN::ErrorOr> (*create_system_cursor)(SystemCursorType); /* Create cursor from custom bitmap */ diff --git a/xbanan/SDL3/sdl3.cpp b/xbanan/SDL3/sdl3.cpp index ff2a10c..a55e540 100644 --- a/xbanan/SDL3/sdl3.cpp +++ b/xbanan/SDL3/sdl3.cpp @@ -335,6 +335,19 @@ static void sdl3_request_fullscreen(PlatformWindow* window, bool fullscreen) SDL_SetWindowFullscreen(sdl_window.window, fullscreen); } +static void sdl3_warp_pointer(int32_t x, int32_t y, bool relative) +{ + if (relative) + { + float cx, cy; + SDL_GetGlobalMouseState(&cx, &cy); + x += cx; + x += cy; + } + + SDL_WarpMouseGlobal(x, y); +} + static BAN::ErrorOr> sdl3_create_system_cursor(SystemCursorType type) { static constexpr SDL_SystemCursor cursor_type_map[] { @@ -414,6 +427,7 @@ PlatformOps g_platform_ops = { .request_resize = sdl3_request_resize, .request_reposition = sdl3_request_reposition, .request_fullscreen = sdl3_request_fullscreen, + .warp_pointer = sdl3_warp_pointer, .create_system_cursor = sdl3_create_system_cursor, .create_bitmap_cursor = sdl3_create_bitmap_cursor, .set_cursor = sdl3_set_cursor, diff --git a/xbanan/banan-os/banan-os.cpp b/xbanan/banan-os/banan-os.cpp index 042974e..99d24db 100644 --- a/xbanan/banan-os/banan-os.cpp +++ b/xbanan/banan-os/banan-os.cpp @@ -147,6 +147,13 @@ static void bananos_request_fullscreen(PlatformWindow* window, bool fullscreen) banan_window.window->set_fullscreen(fullscreen); } +static void bananos_warp_pointer(int32_t x, int32_t y, bool relative) +{ + (void)x; + (void)y; + (void)relative; +} + static BAN::ErrorOr> bananos_create_system_cursor(SystemCursorType type) { (void)type; @@ -190,6 +197,7 @@ PlatformOps g_platform_ops = { .request_resize = bananos_request_resize, .request_reposition = bananos_request_reposition, .request_fullscreen = bananos_request_fullscreen, + .warp_pointer = bananos_warp_pointer, .create_system_cursor = bananos_create_system_cursor, .create_bitmap_cursor = bananos_create_bitmap_cursor, .set_cursor = bananos_set_cursor,