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