CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Windows/TouchInputHandler.cpp
Views: 1401
#include "stdafx.h"1#include <Windows.h>2#include "Windows/TouchInputHandler.h"34#include <algorithm>56#include "Common/System/Display.h"7#include "Common/System/NativeApp.h"89#include "Common/CommonWindows.h"10#include "Common/CommonFuncs.h"11#include "Common/Input/InputState.h"12#include "Common/Log.h"13#include "Common/SysError.h"14#include "Windows/MainWindow.h"1516TouchInputHandler::TouchInputHandler() {17HMODULE user32 = GetModuleHandle(TEXT("User32.dll"));18if (!user32)19return;20touchInfo = (getTouchInputProc)GetProcAddress(user32, "GetTouchInputInfo");21closeTouch = (closeTouchInputProc)GetProcAddress(user32, "CloseTouchInputHandle");22registerTouch = (registerTouchProc)GetProcAddress(user32, "RegisterTouchWindow");23}2425int TouchInputHandler::ToTouchID(int windowsID, bool allowAllocate) {26// Find the id for the touch. Avoid 0 (mouse.)27for (int localId = 1; localId < (int)ARRAY_SIZE(touchIds); ++localId) {28if (touchIds[localId] == windowsID) {29return localId;30}31}3233// Allocate a new one, perhaps?34if (allowAllocate) {35for (int localId = 1; localId < (int)ARRAY_SIZE(touchIds); ++localId) {36if (touchIds[localId] == 0) {37touchIds[localId] = windowsID;38return localId;39}40}4142// None were free.43// TODO: Better to just ignore this touch instead?44touchUp(0, 0, 0);45return 0;46}4748return -1;49}5051bool TouchInputHandler::GetTouchPoint(HWND hWnd, const TOUCHINPUT &input, float &x, float &y) {52POINT point;53point.x = (LONG)(TOUCH_COORD_TO_PIXEL(input.x));54point.y = (LONG)(TOUCH_COORD_TO_PIXEL(input.y));55if (ScreenToClient(hWnd, &point)) {56x = point.x * g_display.dpi_scale_x;57y = point.y * g_display.dpi_scale_y;58return true;59}6061return false;62}6364void TouchInputHandler::handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)65{66if (hasTouch()) {67UINT inputCount = LOWORD(wParam);68HTOUCHINPUT touchInputData = (HTOUCHINPUT)lParam;69TOUCHINPUT *inputs = new TOUCHINPUT[inputCount];70if (touchInfo(touchInputData, inputCount, inputs, sizeof(TOUCHINPUT))) {71for (UINT i = 0; i < inputCount; i++) {72float x, y;73if (!GetTouchPoint(hWnd, inputs[i], x, y))74continue;7576if (inputs[i].dwFlags & TOUCHEVENTF_DOWN) {77touchDown(ToTouchID(inputs[i].dwID), x, y);78}79if (inputs[i].dwFlags & TOUCHEVENTF_MOVE) {80touchMove(ToTouchID(inputs[i].dwID), x, y);81}82if (inputs[i].dwFlags & TOUCHEVENTF_UP) {83int id = ToTouchID(inputs[i].dwID, false);84if (id >= 0) {85touchUp(id, x, y);86touchIds[id] = 0;87}88}89}90closeTouch(touchInputData);91} else {92WARN_LOG(Log::System, "Failed to read input data: %s", GetLastErrorMsg().c_str());93}94delete [] inputs;95}96}9798// from http://msdn.microsoft.com/en-us/library/ms812373.aspx99// disable the press and hold gesture for the given window100void TouchInputHandler::disablePressAndHold(HWND hWnd) {101// The atom identifier and Tablet PC atom102LPCTSTR tabletAtom = _T("MicrosoftTabletPenServiceProperty");103ATOM atomID = GlobalAddAtom(tabletAtom);104105// If getting the ID failed, return false106if (atomID != 0) {107// Try to disable press and hold gesture by setting the window property.108SetProp(hWnd, tabletAtom, (HANDLE)1);109}110111GlobalDeleteAtom(atomID);112}113114void TouchInputHandler::touchUp(int id, float x, float y){115TouchInput touchevent;116touchevent.id = id;117touchevent.x = x;118touchevent.y = y;119touchevent.flags = TOUCH_UP;120NativeTouch(touchevent);121}122123void TouchInputHandler::touchDown(int id, float x, float y){124TouchInput touchevent;125touchevent.id = id;126touchevent.x = x;127touchevent.y = y;128touchevent.flags = TOUCH_DOWN;129NativeTouch(touchevent);130}131132void TouchInputHandler::touchMove(int id, float x, float y){133TouchInput touchevent;134touchevent.id = id;135touchevent.x = x;136touchevent.y = y;137touchevent.flags = TOUCH_MOVE;138NativeTouch(touchevent);139}140141void TouchInputHandler::registerTouchWindow(HWND wnd)142{143if (hasTouch())144{145registerTouch(wnd, TWF_WANTPALM);146disablePressAndHold(wnd);147}148}149150bool TouchInputHandler::hasTouch(){151return (152touchInfo != nullptr &&153closeTouch != nullptr &&154registerTouch != nullptr155);156}157158159