From e391f89656c85a6cf5f8da6930e760b2b3961252 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 17 Mar 2023 23:27:58 -0500 Subject: [PATCH] feat(event): handle mouse up and down events for windows --- src/event/Input.cpp | 1 + src/event/Input.hpp | 1 + src/event/win/Input.cpp | 150 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/src/event/Input.cpp b/src/event/Input.cpp index abb984f..8a25fca 100644 --- a/src/event/Input.cpp +++ b/src/event/Input.cpp @@ -47,6 +47,7 @@ C2iVector Input::s_currentMouse; uint32_t Input::s_mouseHoldButton; MOUSEMODE Input::s_mouseMode; int32_t Input::s_numlockState; +uint32_t Input::s_osButtonState; OS_MOUSE_MODE Input::s_osMouseMode; int32_t Input::s_simulatedRightButtonClick; uint32_t Input::s_metaKeyState; diff --git a/src/event/Input.hpp b/src/event/Input.hpp index e44adb6..865b02a 100644 --- a/src/event/Input.hpp +++ b/src/event/Input.hpp @@ -16,6 +16,7 @@ namespace Input { extern C2iVector s_currentMouse; extern uint32_t s_mouseHoldButton; extern MOUSEMODE s_mouseMode; + extern uint32_t s_osButtonState; extern OS_MOUSE_MODE s_osMouseMode; extern int32_t s_numlockState; extern int32_t s_simulatedRightButtonClick; diff --git a/src/event/win/Input.cpp b/src/event/win/Input.cpp index ebb5ebf..1317b6e 100644 --- a/src/event/win/Input.cpp +++ b/src/event/win/Input.cpp @@ -14,6 +14,122 @@ void SaveMouse(POINT mousePos, HWND hwnd) { // TODO } +int32_t ConvertButton(uint32_t message, uintptr_t wparam, MOUSEBUTTON* button) { + switch (message) { + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONUP: + case WM_NCLBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: { + *button = MOUSE_BUTTON_LEFT; + return 1; + } + + case WM_NCRBUTTONDOWN: + case WM_NCRBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: { + *button = MOUSE_BUTTON_RIGHT; + return 1; + } + + case WM_NCMBUTTONDOWN: + case WM_NCMBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: { + *button = MOUSE_BUTTON_MIDDLE; + return 1; + } + + case WM_NCXBUTTONDOWN: + case WM_NCXBUTTONUP: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: { + switch (GET_XBUTTON_WPARAM(wparam)) { + case XBUTTON1: { + *button = MOUSE_BUTTON_XBUTTON1; + return 1; + } + case XBUTTON2: { + *button = MOUSE_BUTTON_XBUTTON2; + return 1; + } + default: { + *button = MOUSE_BUTTON_NONE; + return 0; + } + } + } + + default: { + *button = MOUSE_BUTTON_NONE; + return 0; + } + } +} + +bool ProcessMouseEvent(MOUSEBUTTON button, uint32_t message, HWND hwnd, OSINPUT id) { + POINT mousePos; + + if (Input::s_osMouseMode == OS_MOUSE_MODE_RELATIVE) { + // TODO + } else { + GetCursorPos(&mousePos); + ScreenToClient(hwnd, &mousePos); + } + + OsQueuePut(id, button, mousePos.x, mousePos.y, 0); + + return message == WM_XBUTTONDOWN + || message == WM_XBUTTONUP + || message == WM_NCXBUTTONDOWN + || message == WM_NCXBUTTONUP; +} + +int32_t HandleMouseDown(uint32_t message, uintptr_t wparam, bool* xbutton, HWND hwnd) { + MOUSEBUTTON button; + if (!ConvertButton(message, wparam, &button)) { + return 0; + } + + if (Input::s_osButtonState == 0) { + SetCapture(hwnd); + } + + Input::s_osButtonState |= button; + + auto xb = ProcessMouseEvent(button, message, hwnd, OS_INPUT_MOUSE_DOWN); + + if (xbutton) { + *xbutton = xb; + } + + return 1; +} + +int32_t HandleMouseUp(uint32_t message, uintptr_t wparam, bool* xbutton, HWND hwnd) { + MOUSEBUTTON button; + if (!ConvertButton(message, wparam, &button)) { + return 0; + } + + Input::s_osButtonState &= ~button; + + if (Input::s_osButtonState == 0) { + // TODO + ReleaseCapture(); + // TODO + } + + auto xb = ProcessMouseEvent(button, message, hwnd, OS_INPUT_MOUSE_UP); + + if (xbutton) { + *xbutton = xb; + } + + return 1; +} + int32_t OsGuiProcessMessage(void* message) { // TODO return 0; @@ -110,6 +226,40 @@ int32_t OsWindowProc(void* window, uint32_t message, uintptr_t wparam, intptr_t return 0; } + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_XBUTTONDOWN: { + bool xbutton; + if (HandleMouseDown(message, wparam, &xbutton, hwnd)) { + // Normally, a processed button down message should return 0 + // In the case of xbuttons, a processed button down message should return 1 + // See: https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-xbuttondown + return xbutton ? 1 : 0; + } + + break; + } + + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + case WM_XBUTTONUP: { + if (message == WM_LBUTTONUP) { + // TODO + } + + bool xbutton; + if (HandleMouseUp(message, wparam, &xbutton, hwnd)) { + // Normally, a processed button down message should return 0 + // In the case of xbuttons, a processed button down message should return 1 + // See: https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-xbuttondown + return xbutton ? 1 : 0; + } + + break; + } + case WM_MOUSEMOVE: { // TODO