From 4a4488eb98ebf215ac354c79029fa57771adb1b3 Mon Sep 17 00:00:00 2001 From: Peter Tissen Date: Thu, 23 Jan 2014 18:05:42 +0100 Subject: [PATCH] Enable touch support by default Check for touch support and enable it automatically if available. It's probably possible to hack around Vista with the HID stuff but I don't think Vista that want multitouch is a large enough group to invest the time. --- Windows/TouchInputHandler.cpp | 135 +++++++++++++++++++++------------- Windows/TouchInputHandler.h | 33 +++++++-- Windows/WndMainWindow.cpp | 44 ++++------- Windows/WndMainWindow.h | 2 - 4 files changed, 124 insertions(+), 90 deletions(-) diff --git a/Windows/TouchInputHandler.cpp b/Windows/TouchInputHandler.cpp index 2436fbc1c3..3037d09ed5 100644 --- a/Windows/TouchInputHandler.cpp +++ b/Windows/TouchInputHandler.cpp @@ -9,8 +9,23 @@ extern InputState input_state; -TouchInputHandler::TouchInputHandler() +TouchInputHandler::TouchInputHandler() : + touchInfo(nullptr), + closeTouch(nullptr), + registerTouch(nullptr) { + + touchInfo = (getTouchInputProc) GetProcAddress( + GetModuleHandle(TEXT("User32.dll")), + "GetTouchInputInfo"); + + closeTouch = (closeTouchInputProc) GetProcAddress( + GetModuleHandle(TEXT("User32.dll")), + "CloseTouchInputHandle"); + + registerTouch = (registerTouchProc) GetProcAddress( + GetModuleHandle(TEXT("User32.dll")), + "RegisterTouchWindow"); } @@ -20,67 +35,67 @@ TouchInputHandler::~TouchInputHandler() void TouchInputHandler::handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { -#if ENABLE_TOUCH - UINT inputCount = LOWORD(wParam); - TOUCHINPUT *inputs = new TOUCHINPUT[inputCount]; - if (GetTouchInputInfo((HTOUCHINPUT) lParam, - inputCount, - inputs, - sizeof(TOUCHINPUT))) - { - for (int i = 0; i < inputCount; i++) { - int id = 0; + if (hasTouch()){ + UINT inputCount = LOWORD(wParam); + TOUCHINPUT *inputs = new TOUCHINPUT[inputCount]; + if (touchInfo((HTOUCHINPUT) lParam, + inputCount, + inputs, + sizeof(TOUCHINPUT))) + { + for (int i = 0; i < inputCount; i++) { + int id = 0; - //here we map the windows touch id to the ppsspp internal touch id - //currently we ignore the fact that the mouse uses touch id 0, so that - //the mouse could possibly interfere with the mapping so for safety - //the maximum amount of touch points is MAX_POINTERS-1 - std::map::const_iterator it = touchTranslate.find(inputs[i].dwID); - if (it != touchTranslate.end()) //check if we already mapped this touch id - { - id = it->second; - } - else - { - if (touchTranslate.size() + 1 >= MAX_POINTERS) //check if we're tracking too many points + //here we map the windows touch id to the ppsspp internal touch id + //currently we ignore the fact that the mouse uses touch id 0, so that + //the mouse could possibly interfere with the mapping so for safety + //the maximum amount of touch points is MAX_POINTERS-1 + std::map::const_iterator it = touchTranslate.find(inputs[i].dwID); + if (it != touchTranslate.end()) //check if we already mapped this touch id { - touchUp(touchTranslate.begin()->second, 0, 0); - touchTranslate.erase(touchTranslate.begin()); + id = it->second; + } + else + { + if (touchTranslate.size() + 1 >= MAX_POINTERS) //check if we're tracking too many points + { + touchUp(touchTranslate.begin()->second, 0, 0); + touchTranslate.erase(touchTranslate.begin()); + } + //finding first free internal touch id and map this windows id to an internal id + bool *first_free = std::find(input_state.pointer_down, input_state.pointer_down + MAX_POINTERS, false); + id = (first_free - input_state.pointer_down) / sizeof(bool); + touchTranslate[inputs[i].dwID] = id; } - //finding first free internal touch id and map this windows id to an internal id - bool *first_free = std::find(input_state.pointer_down, input_state.pointer_down + MAX_POINTERS, false); - id = (first_free - input_state.pointer_down) / sizeof(bool); - touchTranslate[inputs[i].dwID] = id; - } - POINT point; - point.x = TOUCH_COORD_TO_PIXEL(inputs[i].x); - point.y = TOUCH_COORD_TO_PIXEL(inputs[i].y); + POINT point; + point.x = TOUCH_COORD_TO_PIXEL(inputs[i].x); + point.y = TOUCH_COORD_TO_PIXEL(inputs[i].y); - if (ScreenToClient(hWnd, &point)){ - if (inputs[i].dwFlags & TOUCHEVENTF_DOWN) - { - touchDown(id, point.x, point.y); - } - if (inputs[i].dwFlags & TOUCHEVENTF_MOVE) - { - touchMove(id, point.x, point.y); - } - if (inputs[i].dwFlags & TOUCHEVENTF_UP) - { - touchUp(id, point.x, point.y); - touchTranslate.erase(touchTranslate.find(inputs[i].dwID)); + if (ScreenToClient(hWnd, &point)){ + if (inputs[i].dwFlags & TOUCHEVENTF_DOWN) + { + touchDown(id, point.x, point.y); + } + if (inputs[i].dwFlags & TOUCHEVENTF_MOVE) + { + touchMove(id, point.x, point.y); + } + if (inputs[i].dwFlags & TOUCHEVENTF_UP) + { + touchUp(id, point.x, point.y); + touchTranslate.erase(touchTranslate.find(inputs[i].dwID)); + } } } + closeTouch((HTOUCHINPUT) lParam); } - CloseTouchInputHandle((HTOUCHINPUT) lParam); + else + { + // GetLastError() and error handling. + } + delete [] inputs; } - else - { - // GetLastError() and error handling. - } - delete[] inputs; -#endif } void TouchInputHandler::touchUp(int id, float x, float y){ @@ -122,4 +137,18 @@ void TouchInputHandler::touchMove(int id, float x, float y){ input_state.pointer_y[id] = y; input_state.lock.unlock(); NativeTouch(touchevent); +} + +void TouchInputHandler::registerTouchWindow(HWND wnd) +{ + if (hasTouch()) + registerTouch(wnd, TWF_WANTPALM); +} + +bool TouchInputHandler::hasTouch(){ + return ( + touchInfo != nullptr && + closeTouch != nullptr && + registerTouch != nullptr + ); } \ No newline at end of file diff --git a/Windows/TouchInputHandler.h b/Windows/TouchInputHandler.h index effdc357fc..1ae16f74ef 100644 --- a/Windows/TouchInputHandler.h +++ b/Windows/TouchInputHandler.h @@ -2,18 +2,39 @@ #include +typedef BOOL(WINAPI *getTouchInputProc)( + HTOUCHINPUT hTouchInput, + UINT cInputs, + PTOUCHINPUT pInputs, + int cbSize + ); + +typedef BOOL(WINAPI *closeTouchInputProc)( + HTOUCHINPUT hTouchInput + ); + +typedef BOOL(WINAPI *registerTouchProc)( + HWND hWnd, + ULONG ulFlags + ); + class TouchInputHandler { -public: - TouchInputHandler(); - - void handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); - ~TouchInputHandler(); private: std::map touchTranslate; + getTouchInputProc touchInfo; + closeTouchInputProc closeTouch; + registerTouchProc registerTouch; + +public: + TouchInputHandler(); + ~TouchInputHandler(); + void handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + void registerTouchWindow(HWND wnd); + bool hasTouch(); +private: void touchUp(int id, float x, float y); void touchDown(int id, float x, float y); void touchMove(int id, float x, float y); - }; diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 11e0c0bc7e..2a0b5c0d42 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -75,10 +75,14 @@ #include "Core/HLE/sceUmd.h" +#include + #ifdef THEMES #include "XPTheme.h" #endif +#define MOUSEEVENTF_FROMTOUCH 0xFF515700 + static const int numCPUs = 1; int verysleepy__useSendMessage = 1; @@ -116,9 +120,7 @@ namespace MainWindow HWND hwndDisplay; HWND hwndGameList; -#if ENABLE_TOUCH TouchInputHandler touchHandler; -#endif static HMENU menu; static HINSTANCE hInst; @@ -326,7 +328,8 @@ namespace MainWindow const int y = 0; const int cx = ::GetSystemMetrics(SM_CXSCREEN); const int cy = ::GetSystemMetrics(SM_CYSCREEN); - ::SetWindowPos(hWnd, HWND_TOPMOST, x, y, cx, cy, SWP_FRAMECHANGED); + ERROR_LOG(CPU,"xres: %d yres: %d",cx,cy); + ::SetWindowPos(hWnd, HWND_TOPMOST, -10, -10, cx, cy, SWP_FRAMECHANGED); // Set full screen indicator. g_Config.bFullScreen = true; @@ -744,6 +747,7 @@ namespace MainWindow } BOOL Show(HINSTANCE hInstance, int nCmdShow) { + SetProcessDPIAware(); hInst = hInstance; // Store instance handle in our global variable. RECT rc = DetermineWindowRectangle(); @@ -792,9 +796,7 @@ namespace MainWindow W32Util::MakeTopMost(hwndMain, g_Config.bTopMost); -#if ENABLE_TOUCH - RegisterTouchWindow(hwndDisplay, TWF_WANTPALM); -#endif + touchHandler.registerTouchWindow(hwndDisplay); WindowsRawInput::Init(); @@ -908,14 +910,9 @@ namespace MainWindow // and as asynchronous touch events for minimal latency. case WM_LBUTTONDOWN: -#if ENABLE_TOUCH - #define MOUSEEVENTF_FROMTOUCH 0xFF515700 - if ((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) { - // Click was generated by Windows Touch, ignore and handle WM_TOUCH instead - } - else -#endif - { + if (!touchHandler.hasTouch() || + (GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) != MOUSEEVENTF_FROMTOUCH ) + { // Hack: Take the opportunity to show the cursor. mouseButtonDown = true; { @@ -939,12 +936,8 @@ namespace MainWindow break; case WM_MOUSEMOVE: -#if ENABLE_TOUCH - if ((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) { - // Click was generated by Windows Touch, ignore and handle WM_TOUCH instead - } - else -#endif + if (!touchHandler.hasTouch() || + (GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) != MOUSEEVENTF_FROMTOUCH) { // Hack: Take the opportunity to show the cursor. mouseButtonDown = (wParam & MK_LBUTTON) != 0; @@ -975,12 +968,8 @@ namespace MainWindow break; case WM_LBUTTONUP: -#if ENABLE_TOUCH - if ((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) { - // Click was generated by Windows Touch, ignore and handle WM_TOUCH instead - } - else -#endif + if (!touchHandler.hasTouch() || + (GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) != MOUSEEVENTF_FROMTOUCH) { // Hack: Take the opportunity to hide the cursor. mouseButtonDown = false; @@ -1002,11 +991,8 @@ namespace MainWindow case WM_TOUCH: { - // TODO: Enabling this section will probably break things on Windows XP. -#if ENABLE_TOUCH touchHandler.handleTouchEvent(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam); -#endif } case WM_PAINT: diff --git a/Windows/WndMainWindow.h b/Windows/WndMainWindow.h index 2e44c95ad2..e11da181c5 100644 --- a/Windows/WndMainWindow.h +++ b/Windows/WndMainWindow.h @@ -5,8 +5,6 @@ #include "Core/System.h" -#define ENABLE_TOUCH 0 - namespace MainWindow { enum {