From 3c377106a572aef64dc5951f15da74520d4bbc84 Mon Sep 17 00:00:00 2001 From: samstalhandske Date: Fri, 6 Feb 2026 02:44:19 +0100 Subject: [PATCH] 'Event_Mouse_Delta', Raw Input, WM_INPUT --- window.odin | 13 ++++++--- window_windows.odin | 65 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/window.odin b/window.odin index 8946245..e6f45c1 100644 --- a/window.odin +++ b/window.odin @@ -11,6 +11,8 @@ Window :: struct { backend: Backend_Info, event_queue: Event_Queue, + + mouse_delta: [2]i32, } Event_Queue :: queue.Queue(Event) @@ -52,12 +54,16 @@ Event_Keyboard :: struct { Event_Mouse :: union { Event_Mouse_Move, Event_Mouse_Button, + Event_Mouse_Delta, } Event_Mouse_Move :: struct { x, y: u16, } Mouse_Button :: enum { Left, Middle, Right } Event_Mouse_Button :: struct { button: Mouse_Button, state: Event_Input_State } +Event_Mouse_Delta :: struct { + x, y: i32, +} Event_Input :: union { Event_Keyboard, @@ -126,11 +132,12 @@ cursor_visible :: proc(window: ^Window) -> bool { return false } -set_cursor_position :: proc(window: ^Window, pos: [2]u32) { - // fmt.printfln("Set cursor pos: %v:%v", pos.x, pos.y) +lock_cursor :: proc(window: ^Window, lock: bool) { when ODIN_OS == .Windows { - set_cursor_position_windows(window, pos) + lock_cursor_windows(window, lock) } + + show_cursor_window(window, !lock) } get_pointer_to_surface :: proc(window: ^Window) -> rawptr { diff --git a/window_windows.odin b/window_windows.odin index 3ea0bff..d9ad5a7 100644 --- a/window_windows.odin +++ b/window_windows.odin @@ -65,6 +65,33 @@ Backend_Info :: struct { return 0 } // Mouse. + case win.WM_INPUT: { + dwSize: win.UINT = size_of(win.RAWINPUT) + lpb: [size_of(win.RAWINPUT)]u8 + + v := win.GetRawInputData( + win.HRAWINPUT(lparam), + win.RID_INPUT, + &lpb[0], + &dwSize, + size_of(win.RAWINPUTHEADER), + ) + + raw := (^win.RAWINPUT)(&lpb[0]) + + if raw.header.dwType == win.RIM_TYPEMOUSE { + mouse_event: Event_Mouse = Event_Mouse_Delta { + x = i32(raw.data.mouse.lLastX), + y = i32(raw.data.mouse.lLastY), + } + + assert(event_queue != nil) + queue.push_back(event_queue, Event_Input(mouse_event)) + } + + return 0 + } + case win.WM_MOUSEMOVE: { x := win.GET_X_LPARAM(lparam) y := win.GET_Y_LPARAM(lparam) @@ -190,6 +217,19 @@ init_window_windows :: proc(window: ^Window) -> bool { hwnd = hwnd, } + register_raw_mouse_windows :: proc(hwnd: win.HWND) -> bool { + rid := win.RAWINPUTDEVICE { + usUsagePage = 0x01, // Generic Desktop Controls. + usUsage = 0x02, // Mouse. + dwFlags = win.RIDEV_INPUTSINK, + hwndTarget = hwnd, + } + + ok := win.RegisterRawInputDevices(&rid, 1, size_of(win.RAWINPUTDEVICE)) + return ok != win.FALSE + } + assert(register_raw_mouse_windows(hwnd)) + // fmt.printfln("Window size: %vx%v.", actual_window_width, actual_window_height) return true @@ -229,7 +269,7 @@ cursor_visible_windows :: proc(window: ^Window) -> bool { return old_count >= 0 } -set_cursor_position_windows :: proc(window: ^Window, pos: [2]u32) { +set_cursor_position_windows :: proc(window: ^Window, pos: [2]u16) { pt := win.POINT { x = i32(pos.x), y = i32(pos.y) } rect: win.RECT win.GetClientRect(window.backend.hwnd, &rect) @@ -242,6 +282,29 @@ set_cursor_position_windows :: proc(window: ^Window, pos: [2]u32) { win.SetCursorPos(pt.x, pt.y) } +lock_cursor_windows :: proc(window: ^Window, lock: bool) { + assert(window != nil) + + if lock { + rect: win.RECT + win.GetClientRect(window.backend.hwnd, &rect) + + pt := win.POINT{rect.left, rect.top} + win.ClientToScreen(window.backend.hwnd, &pt) + rect.left = pt.x + rect.top = pt.y + + pt = win.POINT{rect.right, rect.bottom} + win.ClientToScreen(window.backend.hwnd, &pt) + rect.right = pt.x + rect.bottom = pt.y + + win.ClipCursor(&rect) + } else { + win.ClipCursor(nil) + } +} + update_windows :: proc(window: ^Window) { assert(window != nil)