CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Windows/TouchInputHandler.cpp
Views: 1401
1
#include "stdafx.h"
2
#include <Windows.h>
3
#include "Windows/TouchInputHandler.h"
4
5
#include <algorithm>
6
7
#include "Common/System/Display.h"
8
#include "Common/System/NativeApp.h"
9
10
#include "Common/CommonWindows.h"
11
#include "Common/CommonFuncs.h"
12
#include "Common/Input/InputState.h"
13
#include "Common/Log.h"
14
#include "Common/SysError.h"
15
#include "Windows/MainWindow.h"
16
17
TouchInputHandler::TouchInputHandler() {
18
HMODULE user32 = GetModuleHandle(TEXT("User32.dll"));
19
if (!user32)
20
return;
21
touchInfo = (getTouchInputProc)GetProcAddress(user32, "GetTouchInputInfo");
22
closeTouch = (closeTouchInputProc)GetProcAddress(user32, "CloseTouchInputHandle");
23
registerTouch = (registerTouchProc)GetProcAddress(user32, "RegisterTouchWindow");
24
}
25
26
int TouchInputHandler::ToTouchID(int windowsID, bool allowAllocate) {
27
// Find the id for the touch. Avoid 0 (mouse.)
28
for (int localId = 1; localId < (int)ARRAY_SIZE(touchIds); ++localId) {
29
if (touchIds[localId] == windowsID) {
30
return localId;
31
}
32
}
33
34
// Allocate a new one, perhaps?
35
if (allowAllocate) {
36
for (int localId = 1; localId < (int)ARRAY_SIZE(touchIds); ++localId) {
37
if (touchIds[localId] == 0) {
38
touchIds[localId] = windowsID;
39
return localId;
40
}
41
}
42
43
// None were free.
44
// TODO: Better to just ignore this touch instead?
45
touchUp(0, 0, 0);
46
return 0;
47
}
48
49
return -1;
50
}
51
52
bool TouchInputHandler::GetTouchPoint(HWND hWnd, const TOUCHINPUT &input, float &x, float &y) {
53
POINT point;
54
point.x = (LONG)(TOUCH_COORD_TO_PIXEL(input.x));
55
point.y = (LONG)(TOUCH_COORD_TO_PIXEL(input.y));
56
if (ScreenToClient(hWnd, &point)) {
57
x = point.x * g_display.dpi_scale_x;
58
y = point.y * g_display.dpi_scale_y;
59
return true;
60
}
61
62
return false;
63
}
64
65
void TouchInputHandler::handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
66
{
67
if (hasTouch()) {
68
UINT inputCount = LOWORD(wParam);
69
HTOUCHINPUT touchInputData = (HTOUCHINPUT)lParam;
70
TOUCHINPUT *inputs = new TOUCHINPUT[inputCount];
71
if (touchInfo(touchInputData, inputCount, inputs, sizeof(TOUCHINPUT))) {
72
for (UINT i = 0; i < inputCount; i++) {
73
float x, y;
74
if (!GetTouchPoint(hWnd, inputs[i], x, y))
75
continue;
76
77
if (inputs[i].dwFlags & TOUCHEVENTF_DOWN) {
78
touchDown(ToTouchID(inputs[i].dwID), x, y);
79
}
80
if (inputs[i].dwFlags & TOUCHEVENTF_MOVE) {
81
touchMove(ToTouchID(inputs[i].dwID), x, y);
82
}
83
if (inputs[i].dwFlags & TOUCHEVENTF_UP) {
84
int id = ToTouchID(inputs[i].dwID, false);
85
if (id >= 0) {
86
touchUp(id, x, y);
87
touchIds[id] = 0;
88
}
89
}
90
}
91
closeTouch(touchInputData);
92
} else {
93
WARN_LOG(Log::System, "Failed to read input data: %s", GetLastErrorMsg().c_str());
94
}
95
delete [] inputs;
96
}
97
}
98
99
// from http://msdn.microsoft.com/en-us/library/ms812373.aspx
100
// disable the press and hold gesture for the given window
101
void TouchInputHandler::disablePressAndHold(HWND hWnd) {
102
// The atom identifier and Tablet PC atom
103
LPCTSTR tabletAtom = _T("MicrosoftTabletPenServiceProperty");
104
ATOM atomID = GlobalAddAtom(tabletAtom);
105
106
// If getting the ID failed, return false
107
if (atomID != 0) {
108
// Try to disable press and hold gesture by setting the window property.
109
SetProp(hWnd, tabletAtom, (HANDLE)1);
110
}
111
112
GlobalDeleteAtom(atomID);
113
}
114
115
void TouchInputHandler::touchUp(int id, float x, float y){
116
TouchInput touchevent;
117
touchevent.id = id;
118
touchevent.x = x;
119
touchevent.y = y;
120
touchevent.flags = TOUCH_UP;
121
NativeTouch(touchevent);
122
}
123
124
void TouchInputHandler::touchDown(int id, float x, float y){
125
TouchInput touchevent;
126
touchevent.id = id;
127
touchevent.x = x;
128
touchevent.y = y;
129
touchevent.flags = TOUCH_DOWN;
130
NativeTouch(touchevent);
131
}
132
133
void TouchInputHandler::touchMove(int id, float x, float y){
134
TouchInput touchevent;
135
touchevent.id = id;
136
touchevent.x = x;
137
touchevent.y = y;
138
touchevent.flags = TOUCH_MOVE;
139
NativeTouch(touchevent);
140
}
141
142
void TouchInputHandler::registerTouchWindow(HWND wnd)
143
{
144
if (hasTouch())
145
{
146
registerTouch(wnd, TWF_WANTPALM);
147
disablePressAndHold(wnd);
148
}
149
}
150
151
bool TouchInputHandler::hasTouch(){
152
return (
153
touchInfo != nullptr &&
154
closeTouch != nullptr &&
155
registerTouch != nullptr
156
);
157
}
158
159