chore: CRLF to LF
This commit is contained in:
+60
-60
@@ -1,60 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
#include "touch.h"
|
||||
|
||||
// touch states
|
||||
extern std::mutex TOUCH_POINTS_M;
|
||||
extern std::mutex TOUCH_EVENTS_M;
|
||||
extern std::vector<TouchPoint> TOUCH_POINTS;
|
||||
|
||||
enum msg_handler_action {
|
||||
/*
|
||||
* The message was unhandled by the touch handler. This is the default value set when
|
||||
* the touch handler is called.
|
||||
*/
|
||||
ACTION_PASS = 0,
|
||||
|
||||
/*
|
||||
* The message was handled by the touch handler, but `DefWindowProc` should be called
|
||||
* and its return value used instead of the stored one.
|
||||
*/
|
||||
ACTION_RETURN_DEFAULT = 1,
|
||||
|
||||
/*
|
||||
* The message was handled by the touch handler and the stored `return_value` should be
|
||||
* used as the return value.
|
||||
*/
|
||||
ACTION_RETURN_STORED = 2,
|
||||
};
|
||||
|
||||
struct msg_handler_result {
|
||||
msg_handler_action action;
|
||||
LRESULT return_value;
|
||||
};
|
||||
|
||||
class TouchHandler {
|
||||
public:
|
||||
|
||||
TouchHandler(std::string name);
|
||||
virtual ~TouchHandler() = default;
|
||||
|
||||
static bool is_available() {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool window_register(HWND hWnd) {
|
||||
return true;
|
||||
}
|
||||
virtual bool window_unregister(HWND hWnd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) = 0;
|
||||
};
|
||||
|
||||
void add_touch_event(TouchEvent *te);
|
||||
|
||||
void update_card_button();
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
#include "touch.h"
|
||||
|
||||
// touch states
|
||||
extern std::mutex TOUCH_POINTS_M;
|
||||
extern std::mutex TOUCH_EVENTS_M;
|
||||
extern std::vector<TouchPoint> TOUCH_POINTS;
|
||||
|
||||
enum msg_handler_action {
|
||||
/*
|
||||
* The message was unhandled by the touch handler. This is the default value set when
|
||||
* the touch handler is called.
|
||||
*/
|
||||
ACTION_PASS = 0,
|
||||
|
||||
/*
|
||||
* The message was handled by the touch handler, but `DefWindowProc` should be called
|
||||
* and its return value used instead of the stored one.
|
||||
*/
|
||||
ACTION_RETURN_DEFAULT = 1,
|
||||
|
||||
/*
|
||||
* The message was handled by the touch handler and the stored `return_value` should be
|
||||
* used as the return value.
|
||||
*/
|
||||
ACTION_RETURN_STORED = 2,
|
||||
};
|
||||
|
||||
struct msg_handler_result {
|
||||
msg_handler_action action;
|
||||
LRESULT return_value;
|
||||
};
|
||||
|
||||
class TouchHandler {
|
||||
public:
|
||||
|
||||
TouchHandler(std::string name);
|
||||
virtual ~TouchHandler() = default;
|
||||
|
||||
static bool is_available() {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool window_register(HWND hWnd) {
|
||||
return true;
|
||||
}
|
||||
virtual bool window_unregister(HWND hWnd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) = 0;
|
||||
};
|
||||
|
||||
void add_touch_event(TouchEvent *te);
|
||||
|
||||
void update_card_button();
|
||||
|
||||
+297
-297
@@ -1,297 +1,297 @@
|
||||
|
||||
// enable touch functions - set version to windows 7
|
||||
// mingw otherwise doesn't load touch stuff
|
||||
#define _WIN32_WINNT 0x0601
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "win7.h"
|
||||
|
||||
#include "util/libutils.h"
|
||||
#include "util/logging.h"
|
||||
#include "rawinput/touch.h"
|
||||
|
||||
// mingw issue #2205 workaround
|
||||
// https://sourceforge.net/p/mingw/bugs/2205/
|
||||
#undef TOUCHEVENTF_MOVE
|
||||
#define TOUCHEVENTF_MOVE 0x0001
|
||||
#undef TOUCHEVENTF_DOWN
|
||||
#define TOUCHEVENTF_DOWN 0x0002
|
||||
|
||||
// mingw doesn't seem to have these
|
||||
#ifndef WM_TABLET_DEFBASE
|
||||
#define WM_TABLET_DEFBASE 0x02C0
|
||||
#define WM_TABLET_QUERYSYSTEMGESTURESTATUS (WM_TABLET_DEFBASE + 12)
|
||||
#define TABLET_DISABLE_PRESSANDHOLD 0x00000001
|
||||
#define TABLET_DISABLE_PENTAPFEEDBACK 0x00000008
|
||||
#define TABLET_DISABLE_PENBARRELFEEDBACK 0x00000010
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEON 0x00000100
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEOFF 0x00000200
|
||||
#define TABLET_DISABLE_TOUCHSWITCH 0x00008000
|
||||
#define TABLET_DISABLE_FLICKS 0x00010000
|
||||
#define TABLET_DISABLE_SMOOTHSCROLLING 0x00080000
|
||||
#define TABLET_DISABLE_FLICKFALLBACKKEYS 0x00100000
|
||||
#define TABLET_ENABLE_MULTITOUCHDATA 0x01000000
|
||||
#endif
|
||||
|
||||
// general states
|
||||
static HMODULE USER32_INSTANCE = nullptr;
|
||||
static const char *LOG_MODULE_NAME = "touch::win7";
|
||||
|
||||
/* dynamic touch functions
|
||||
* to maintain compatibility with windows XP
|
||||
*/
|
||||
static BOOL (WINAPI *pSetGestureConfig)(HWND, DWORD, UINT, PGESTURECONFIG, UINT);
|
||||
static BOOL (WINAPI *pRegisterTouchWindow)(HWND, ULONG);
|
||||
static BOOL (WINAPI *pGetTouchInputInfo)(HANDLE, UINT, PTOUCHINPUT, int);
|
||||
static BOOL (WINAPI *pCloseTouchInputHandle)(HANDLE);
|
||||
static BOOL (WINAPI *pUnregisterTouchWindow)(HWND hWnd);
|
||||
|
||||
// other
|
||||
static const char ATOM_NAME[] = "MicrosoftTabletPenServiceProperty";
|
||||
|
||||
Win7Handler::Win7Handler() : TouchHandler("win7") {
|
||||
|
||||
// check if already loaded
|
||||
static bool functions_loaded = false;
|
||||
if (functions_loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
// load user32
|
||||
if (USER32_INSTANCE == nullptr) {
|
||||
USER32_INSTANCE = libutils::load_library("user32.dll");
|
||||
}
|
||||
|
||||
// load touch functions
|
||||
pSetGestureConfig = libutils::try_proc<decltype(pSetGestureConfig)>(
|
||||
USER32_INSTANCE, "SetGestureConfig");
|
||||
pRegisterTouchWindow = libutils::try_proc<decltype(pRegisterTouchWindow)>(
|
||||
USER32_INSTANCE, "RegisterTouchWindow");
|
||||
pGetTouchInputInfo = libutils::try_proc<decltype(pGetTouchInputInfo)>(
|
||||
USER32_INSTANCE, "GetTouchInputInfo");
|
||||
pCloseTouchInputHandle = libutils::try_proc<decltype(pCloseTouchInputHandle)>(
|
||||
USER32_INSTANCE, "CloseTouchInputHandle");
|
||||
pUnregisterTouchWindow = libutils::try_proc<decltype(pUnregisterTouchWindow)>(
|
||||
USER32_INSTANCE, "UnregisterTouchWindow");
|
||||
|
||||
functions_loaded = true;
|
||||
}
|
||||
|
||||
bool Win7Handler::is_available() {
|
||||
bool win_touch_available = (GetSystemMetrics(94) & 0x80) == 0x80;
|
||||
|
||||
if (win_touch_available) {
|
||||
log_info(LOG_MODULE_NAME, "WinTouch available");
|
||||
} else {
|
||||
log_info(LOG_MODULE_NAME, "WinTouch unavailable");
|
||||
}
|
||||
|
||||
return win_touch_available;
|
||||
}
|
||||
|
||||
bool Win7Handler::window_register(HWND hWnd) {
|
||||
|
||||
bool result = true;
|
||||
|
||||
// atom settings
|
||||
DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD |
|
||||
TABLET_DISABLE_PENTAPFEEDBACK |
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK |
|
||||
TABLET_DISABLE_FLICKS;
|
||||
|
||||
// get atom ID
|
||||
ATOM atom_id = GlobalAddAtom(ATOM_NAME);
|
||||
|
||||
// disable gestures
|
||||
if (atom_id > 0) {
|
||||
SetProp(hWnd, ATOM_NAME, (HANDLE) ((unsigned long long) dwHwndTabletProperty));
|
||||
}
|
||||
|
||||
// register touch window
|
||||
if ((pRegisterTouchWindow == nullptr) || (pRegisterTouchWindow(hWnd, TWF_WANTPALM) == 0)) {
|
||||
log_warning(LOG_MODULE_NAME, "could not register touch window");
|
||||
|
||||
result = false;
|
||||
}
|
||||
|
||||
// set gesture config
|
||||
if (pSetGestureConfig != nullptr) {
|
||||
GESTURECONFIG gc {};
|
||||
gc.dwID = 0;
|
||||
gc.dwWant = 0;
|
||||
gc.dwBlock = 1;
|
||||
pSetGestureConfig(hWnd, 0, 1, &gc, sizeof(GESTURECONFIG));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Win7Handler::window_unregister(HWND hWnd) {
|
||||
|
||||
// dispose window
|
||||
if (pUnregisterTouchWindow != nullptr) {
|
||||
pUnregisterTouchWindow(hWnd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Win7Handler::handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
// parse touch messages
|
||||
switch (msg) {
|
||||
case WM_TOUCH: {
|
||||
|
||||
// touch input fields
|
||||
UINT cInputs = LOWORD(wParam);
|
||||
auto pInputs = std::make_unique<TOUCHINPUT[]>(cInputs);
|
||||
|
||||
// get touch input
|
||||
if ((pGetTouchInputInfo != nullptr) &&
|
||||
(pGetTouchInputInfo((HANDLE) lParam, cInputs, pInputs.get(), sizeof(TOUCHINPUT)) != 0)) {
|
||||
|
||||
// lock touch points
|
||||
std::lock_guard<std::mutex> lock_points(TOUCH_POINTS_M);
|
||||
std::lock_guard<std::mutex> lock_events(TOUCH_EVENTS_M);
|
||||
|
||||
// iterate all inputs
|
||||
static long prev_x, prev_y;
|
||||
for (UINT i = 0; i < cInputs; i++) {
|
||||
auto &ti = pInputs[i];
|
||||
|
||||
// touch down
|
||||
if (ti.dwFlags & TOUCHEVENTF_DOWN) {
|
||||
|
||||
// convert to window position
|
||||
POINT point {};
|
||||
point.x = ti.x / 100;
|
||||
point.y = ti.y / 100;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// create new touch point
|
||||
TouchPoint tp {
|
||||
.id = ti.dwID,
|
||||
.x = point.x,
|
||||
.y = point.y,
|
||||
.mouse = false,
|
||||
};
|
||||
TOUCH_POINTS.push_back(tp);
|
||||
|
||||
// add touch down event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_DOWN,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
|
||||
// card button
|
||||
update_card_button();
|
||||
}
|
||||
|
||||
// touch move
|
||||
if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0u) {
|
||||
|
||||
// convert to window position
|
||||
POINT point {};
|
||||
point.x = ti.x / 100;
|
||||
point.y = ti.y / 100;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// check prev coordinates
|
||||
if (point.x != prev_x || point.y != prev_y) {
|
||||
|
||||
// update point
|
||||
for (auto &tp : TOUCH_POINTS) {
|
||||
if (tp.id == ti.dwID) {
|
||||
|
||||
// update values
|
||||
tp.x = point.x;
|
||||
tp.y = point.y;
|
||||
|
||||
// add touch move event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_MOVE,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
}
|
||||
|
||||
// touch up
|
||||
if ((ti.dwFlags & TOUCHEVENTF_UP) != 0u) {
|
||||
|
||||
// remove point
|
||||
for (size_t x = 0; x < TOUCH_POINTS.size(); x++) {
|
||||
auto &tp = TOUCH_POINTS[x];
|
||||
|
||||
if (tp.id == ti.dwID) {
|
||||
|
||||
// add touch up event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_UP,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// remove from active touch points
|
||||
TOUCH_POINTS.erase(TOUCH_POINTS.begin() + x);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
if (pCloseTouchInputHandle != nullptr) {
|
||||
pCloseTouchInputHandle((HANDLE) lParam);
|
||||
}
|
||||
|
||||
result.action = ACTION_RETURN_DEFAULT;
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_TABLET_QUERYSYSTEMGESTURESTATUS: {
|
||||
result.action = ACTION_RETURN_STORED;
|
||||
result.return_value = TABLET_DISABLE_PRESSANDHOLD
|
||||
| TABLET_DISABLE_PENTAPFEEDBACK
|
||||
| TABLET_DISABLE_PENBARRELFEEDBACK
|
||||
| TABLET_DISABLE_TOUCHUIFORCEON
|
||||
| TABLET_DISABLE_TOUCHUIFORCEOFF
|
||||
| TABLET_DISABLE_TOUCHSWITCH
|
||||
| TABLET_DISABLE_FLICKS
|
||||
| TABLET_DISABLE_SMOOTHSCROLLING
|
||||
| TABLET_DISABLE_FLICKFALLBACKKEYS
|
||||
| TABLET_ENABLE_MULTITOUCHDATA;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// enable touch functions - set version to windows 7
|
||||
// mingw otherwise doesn't load touch stuff
|
||||
#define _WIN32_WINNT 0x0601
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "win7.h"
|
||||
|
||||
#include "util/libutils.h"
|
||||
#include "util/logging.h"
|
||||
#include "rawinput/touch.h"
|
||||
|
||||
// mingw issue #2205 workaround
|
||||
// https://sourceforge.net/p/mingw/bugs/2205/
|
||||
#undef TOUCHEVENTF_MOVE
|
||||
#define TOUCHEVENTF_MOVE 0x0001
|
||||
#undef TOUCHEVENTF_DOWN
|
||||
#define TOUCHEVENTF_DOWN 0x0002
|
||||
|
||||
// mingw doesn't seem to have these
|
||||
#ifndef WM_TABLET_DEFBASE
|
||||
#define WM_TABLET_DEFBASE 0x02C0
|
||||
#define WM_TABLET_QUERYSYSTEMGESTURESTATUS (WM_TABLET_DEFBASE + 12)
|
||||
#define TABLET_DISABLE_PRESSANDHOLD 0x00000001
|
||||
#define TABLET_DISABLE_PENTAPFEEDBACK 0x00000008
|
||||
#define TABLET_DISABLE_PENBARRELFEEDBACK 0x00000010
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEON 0x00000100
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEOFF 0x00000200
|
||||
#define TABLET_DISABLE_TOUCHSWITCH 0x00008000
|
||||
#define TABLET_DISABLE_FLICKS 0x00010000
|
||||
#define TABLET_DISABLE_SMOOTHSCROLLING 0x00080000
|
||||
#define TABLET_DISABLE_FLICKFALLBACKKEYS 0x00100000
|
||||
#define TABLET_ENABLE_MULTITOUCHDATA 0x01000000
|
||||
#endif
|
||||
|
||||
// general states
|
||||
static HMODULE USER32_INSTANCE = nullptr;
|
||||
static const char *LOG_MODULE_NAME = "touch::win7";
|
||||
|
||||
/* dynamic touch functions
|
||||
* to maintain compatibility with windows XP
|
||||
*/
|
||||
static BOOL (WINAPI *pSetGestureConfig)(HWND, DWORD, UINT, PGESTURECONFIG, UINT);
|
||||
static BOOL (WINAPI *pRegisterTouchWindow)(HWND, ULONG);
|
||||
static BOOL (WINAPI *pGetTouchInputInfo)(HANDLE, UINT, PTOUCHINPUT, int);
|
||||
static BOOL (WINAPI *pCloseTouchInputHandle)(HANDLE);
|
||||
static BOOL (WINAPI *pUnregisterTouchWindow)(HWND hWnd);
|
||||
|
||||
// other
|
||||
static const char ATOM_NAME[] = "MicrosoftTabletPenServiceProperty";
|
||||
|
||||
Win7Handler::Win7Handler() : TouchHandler("win7") {
|
||||
|
||||
// check if already loaded
|
||||
static bool functions_loaded = false;
|
||||
if (functions_loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
// load user32
|
||||
if (USER32_INSTANCE == nullptr) {
|
||||
USER32_INSTANCE = libutils::load_library("user32.dll");
|
||||
}
|
||||
|
||||
// load touch functions
|
||||
pSetGestureConfig = libutils::try_proc<decltype(pSetGestureConfig)>(
|
||||
USER32_INSTANCE, "SetGestureConfig");
|
||||
pRegisterTouchWindow = libutils::try_proc<decltype(pRegisterTouchWindow)>(
|
||||
USER32_INSTANCE, "RegisterTouchWindow");
|
||||
pGetTouchInputInfo = libutils::try_proc<decltype(pGetTouchInputInfo)>(
|
||||
USER32_INSTANCE, "GetTouchInputInfo");
|
||||
pCloseTouchInputHandle = libutils::try_proc<decltype(pCloseTouchInputHandle)>(
|
||||
USER32_INSTANCE, "CloseTouchInputHandle");
|
||||
pUnregisterTouchWindow = libutils::try_proc<decltype(pUnregisterTouchWindow)>(
|
||||
USER32_INSTANCE, "UnregisterTouchWindow");
|
||||
|
||||
functions_loaded = true;
|
||||
}
|
||||
|
||||
bool Win7Handler::is_available() {
|
||||
bool win_touch_available = (GetSystemMetrics(94) & 0x80) == 0x80;
|
||||
|
||||
if (win_touch_available) {
|
||||
log_info(LOG_MODULE_NAME, "WinTouch available");
|
||||
} else {
|
||||
log_info(LOG_MODULE_NAME, "WinTouch unavailable");
|
||||
}
|
||||
|
||||
return win_touch_available;
|
||||
}
|
||||
|
||||
bool Win7Handler::window_register(HWND hWnd) {
|
||||
|
||||
bool result = true;
|
||||
|
||||
// atom settings
|
||||
DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD |
|
||||
TABLET_DISABLE_PENTAPFEEDBACK |
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK |
|
||||
TABLET_DISABLE_FLICKS;
|
||||
|
||||
// get atom ID
|
||||
ATOM atom_id = GlobalAddAtom(ATOM_NAME);
|
||||
|
||||
// disable gestures
|
||||
if (atom_id > 0) {
|
||||
SetProp(hWnd, ATOM_NAME, (HANDLE) ((unsigned long long) dwHwndTabletProperty));
|
||||
}
|
||||
|
||||
// register touch window
|
||||
if ((pRegisterTouchWindow == nullptr) || (pRegisterTouchWindow(hWnd, TWF_WANTPALM) == 0)) {
|
||||
log_warning(LOG_MODULE_NAME, "could not register touch window");
|
||||
|
||||
result = false;
|
||||
}
|
||||
|
||||
// set gesture config
|
||||
if (pSetGestureConfig != nullptr) {
|
||||
GESTURECONFIG gc {};
|
||||
gc.dwID = 0;
|
||||
gc.dwWant = 0;
|
||||
gc.dwBlock = 1;
|
||||
pSetGestureConfig(hWnd, 0, 1, &gc, sizeof(GESTURECONFIG));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Win7Handler::window_unregister(HWND hWnd) {
|
||||
|
||||
// dispose window
|
||||
if (pUnregisterTouchWindow != nullptr) {
|
||||
pUnregisterTouchWindow(hWnd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Win7Handler::handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
// parse touch messages
|
||||
switch (msg) {
|
||||
case WM_TOUCH: {
|
||||
|
||||
// touch input fields
|
||||
UINT cInputs = LOWORD(wParam);
|
||||
auto pInputs = std::make_unique<TOUCHINPUT[]>(cInputs);
|
||||
|
||||
// get touch input
|
||||
if ((pGetTouchInputInfo != nullptr) &&
|
||||
(pGetTouchInputInfo((HANDLE) lParam, cInputs, pInputs.get(), sizeof(TOUCHINPUT)) != 0)) {
|
||||
|
||||
// lock touch points
|
||||
std::lock_guard<std::mutex> lock_points(TOUCH_POINTS_M);
|
||||
std::lock_guard<std::mutex> lock_events(TOUCH_EVENTS_M);
|
||||
|
||||
// iterate all inputs
|
||||
static long prev_x, prev_y;
|
||||
for (UINT i = 0; i < cInputs; i++) {
|
||||
auto &ti = pInputs[i];
|
||||
|
||||
// touch down
|
||||
if (ti.dwFlags & TOUCHEVENTF_DOWN) {
|
||||
|
||||
// convert to window position
|
||||
POINT point {};
|
||||
point.x = ti.x / 100;
|
||||
point.y = ti.y / 100;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// create new touch point
|
||||
TouchPoint tp {
|
||||
.id = ti.dwID,
|
||||
.x = point.x,
|
||||
.y = point.y,
|
||||
.mouse = false,
|
||||
};
|
||||
TOUCH_POINTS.push_back(tp);
|
||||
|
||||
// add touch down event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_DOWN,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
|
||||
// card button
|
||||
update_card_button();
|
||||
}
|
||||
|
||||
// touch move
|
||||
if ((ti.dwFlags & TOUCHEVENTF_MOVE) != 0u) {
|
||||
|
||||
// convert to window position
|
||||
POINT point {};
|
||||
point.x = ti.x / 100;
|
||||
point.y = ti.y / 100;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// check prev coordinates
|
||||
if (point.x != prev_x || point.y != prev_y) {
|
||||
|
||||
// update point
|
||||
for (auto &tp : TOUCH_POINTS) {
|
||||
if (tp.id == ti.dwID) {
|
||||
|
||||
// update values
|
||||
tp.x = point.x;
|
||||
tp.y = point.y;
|
||||
|
||||
// add touch move event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_MOVE,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
}
|
||||
|
||||
// touch up
|
||||
if ((ti.dwFlags & TOUCHEVENTF_UP) != 0u) {
|
||||
|
||||
// remove point
|
||||
for (size_t x = 0; x < TOUCH_POINTS.size(); x++) {
|
||||
auto &tp = TOUCH_POINTS[x];
|
||||
|
||||
if (tp.id == ti.dwID) {
|
||||
|
||||
// add touch up event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_UP,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// remove from active touch points
|
||||
TOUCH_POINTS.erase(TOUCH_POINTS.begin() + x);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clean up
|
||||
if (pCloseTouchInputHandle != nullptr) {
|
||||
pCloseTouchInputHandle((HANDLE) lParam);
|
||||
}
|
||||
|
||||
result.action = ACTION_RETURN_DEFAULT;
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_TABLET_QUERYSYSTEMGESTURESTATUS: {
|
||||
result.action = ACTION_RETURN_STORED;
|
||||
result.return_value = TABLET_DISABLE_PRESSANDHOLD
|
||||
| TABLET_DISABLE_PENTAPFEEDBACK
|
||||
| TABLET_DISABLE_PENBARRELFEEDBACK
|
||||
| TABLET_DISABLE_TOUCHUIFORCEON
|
||||
| TABLET_DISABLE_TOUCHUIFORCEOFF
|
||||
| TABLET_DISABLE_TOUCHSWITCH
|
||||
| TABLET_DISABLE_FLICKS
|
||||
| TABLET_DISABLE_SMOOTHSCROLLING
|
||||
| TABLET_DISABLE_FLICKFALLBACKKEYS
|
||||
| TABLET_ENABLE_MULTITOUCHDATA;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-18
@@ -1,18 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
#include "handler.h"
|
||||
|
||||
class Win7Handler : public TouchHandler {
|
||||
public:
|
||||
|
||||
Win7Handler();
|
||||
|
||||
static bool is_available();
|
||||
|
||||
virtual bool window_register(HWND hWnd) override;
|
||||
virtual bool window_unregister(HWND hWnd) override;
|
||||
virtual void handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) override;
|
||||
};
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
#include "handler.h"
|
||||
|
||||
class Win7Handler : public TouchHandler {
|
||||
public:
|
||||
|
||||
Win7Handler();
|
||||
|
||||
static bool is_available();
|
||||
|
||||
virtual bool window_register(HWND hWnd) override;
|
||||
virtual bool window_unregister(HWND hWnd) override;
|
||||
virtual void handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) override;
|
||||
};
|
||||
|
||||
+316
-316
@@ -1,316 +1,316 @@
|
||||
|
||||
// set version to Windows 8 to enable Windows 8 touch functions
|
||||
#define _WIN32_WINNT 0x0602
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <initguid.h>
|
||||
#include <windowsx.h>
|
||||
#include <propsys.h>
|
||||
|
||||
#include "win8.h"
|
||||
|
||||
#include "util/libutils.h"
|
||||
#include "util/logging.h"
|
||||
#include "rawinput/touch.h"
|
||||
|
||||
// mingw does not seem to have this either
|
||||
DEFINE_GUID(PKEY_EdgeGesture_DisableTouchWhenFullscreen_Format, 0x32CE38B2, 0x2C9A, 0x41B1, 0x9B, 0xC5, 0xB3, 0x78, 0x43, 0x94, 0xAA, 0x44);
|
||||
|
||||
// mingw issue #2205 workaround
|
||||
// https://sourceforge.net/p/mingw/bugs/2205/
|
||||
#undef TOUCHEVENTF_MOVE
|
||||
#define TOUCHEVENTF_MOVE 0x0001
|
||||
#undef TOUCHEVENTF_DOWN
|
||||
#define TOUCHEVENTF_DOWN 0x0002
|
||||
|
||||
// mingw doesn't seem to have these
|
||||
#ifndef WM_TABLET_DEFBASE
|
||||
#define WM_TABLET_DEFBASE 0x02C0
|
||||
#define WM_TABLET_QUERYSYSTEMGESTURESTATUS (WM_TABLET_DEFBASE + 12)
|
||||
#define TABLET_DISABLE_PRESSANDHOLD 0x00000001
|
||||
#define TABLET_DISABLE_PENTAPFEEDBACK 0x00000008
|
||||
#define TABLET_DISABLE_PENBARRELFEEDBACK 0x00000010
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEON 0x00000100
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEOFF 0x00000200
|
||||
#define TABLET_DISABLE_TOUCHSWITCH 0x00008000
|
||||
#define TABLET_DISABLE_FLICKS 0x00010000
|
||||
#define TABLET_DISABLE_SMOOTHSCROLLING 0x00080000
|
||||
#define TABLET_DISABLE_FLICKFALLBACKKEYS 0x00100000
|
||||
#define TABLET_ENABLE_MULTITOUCHDATA 0x01000000
|
||||
#endif
|
||||
|
||||
// general states
|
||||
static HINSTANCE USER32_INSTANCE = nullptr;
|
||||
static HINSTANCE SHELL32_INSTANCE = nullptr;
|
||||
const char *LOG_MODULE_NAME = "touch::win8";
|
||||
|
||||
/*
|
||||
* dynamic touch functions
|
||||
* to maintain compatibility with windows XP
|
||||
*/
|
||||
typedef BOOL (WINAPI *GetPointerFrameInfoHistory_t)(UINT32, UINT32 *, UINT32 *, POINTER_INFO *);
|
||||
typedef BOOL (WINAPI *SkipPointerFrameMessages_t)(UINT32);
|
||||
typedef HRESULT (WINAPI *SHGetPropertyStoreForWindow_t)(HWND, REFIID, void **);
|
||||
static GetPointerFrameInfoHistory_t pGetPointerFrameInfoHistory = nullptr;
|
||||
static SkipPointerFrameMessages_t pSkipPointerFrameMessages = nullptr;
|
||||
static SHGetPropertyStoreForWindow_t pSHGetPropertyStoreForWindow = nullptr;
|
||||
|
||||
// other
|
||||
static const char ATOM_NAME[] = "MicrosoftTabletPenServiceProperty";
|
||||
|
||||
static void load_functions() {
|
||||
|
||||
// check if already loaded
|
||||
static bool functions_loaded = false;
|
||||
if (functions_loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
// load libraries
|
||||
if (USER32_INSTANCE == nullptr) {
|
||||
USER32_INSTANCE = libutils::load_library("user32.dll");
|
||||
}
|
||||
if (SHELL32_INSTANCE == nullptr) {
|
||||
SHELL32_INSTANCE = libutils::try_library("shell32.dll");
|
||||
}
|
||||
|
||||
// load touch functions
|
||||
pGetPointerFrameInfoHistory = libutils::try_proc<GetPointerFrameInfoHistory_t>(
|
||||
USER32_INSTANCE, "GetPointerFrameInfoHistory");
|
||||
pSkipPointerFrameMessages = libutils::try_proc<SkipPointerFrameMessages_t>(
|
||||
USER32_INSTANCE, "SkipPointerFrameMessages");
|
||||
|
||||
if (SHELL32_INSTANCE != nullptr) {
|
||||
pSHGetPropertyStoreForWindow = libutils::try_proc<SHGetPropertyStoreForWindow_t>(
|
||||
SHELL32_INSTANCE, "SHGetPropertyStoreForWindow");
|
||||
}
|
||||
|
||||
functions_loaded = true;
|
||||
}
|
||||
|
||||
Win8Handler::Win8Handler() : TouchHandler("win8") {
|
||||
load_functions();
|
||||
}
|
||||
|
||||
bool Win8Handler::is_available() {
|
||||
bool have_digitizers = (GetSystemMetrics(94) & 0x80) == 0x80;
|
||||
|
||||
load_functions();
|
||||
|
||||
if (pGetPointerFrameInfoHistory != nullptr) {
|
||||
if (have_digitizers) {
|
||||
log_info(LOG_MODULE_NAME, "Pointer API available");
|
||||
} else {
|
||||
log_info(LOG_MODULE_NAME, "Pointer API available, but no touch screens active");
|
||||
}
|
||||
} else {
|
||||
log_info(LOG_MODULE_NAME, "Pointer API unavailable");
|
||||
}
|
||||
|
||||
return have_digitizers && pGetPointerFrameInfoHistory != nullptr;
|
||||
}
|
||||
|
||||
bool Win8Handler::window_register(HWND hWnd) {
|
||||
|
||||
// atom settings
|
||||
DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD |
|
||||
TABLET_DISABLE_PENTAPFEEDBACK |
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK |
|
||||
TABLET_DISABLE_FLICKS;
|
||||
|
||||
// get atom ID
|
||||
ATOM atomID = GlobalAddAtom(ATOM_NAME);
|
||||
|
||||
// disable gestures
|
||||
if (atomID > 0) {
|
||||
SetProp(hWnd, ATOM_NAME, (HANDLE) ((unsigned long long) dwHwndTabletProperty));
|
||||
}
|
||||
|
||||
IPropertyStore *ps = nullptr;
|
||||
HRESULT hr = pSHGetPropertyStoreForWindow(hWnd, IID_IPropertyStore, (void **) &ps);
|
||||
|
||||
if (SUCCEEDED(hr) && ps != nullptr) {
|
||||
PROPERTYKEY PKEY_EdgeGesture_DisableTouchWhenFullscreen = {
|
||||
PKEY_EdgeGesture_DisableTouchWhenFullscreen_Format,
|
||||
2,
|
||||
};
|
||||
|
||||
PROPVARIANT var {};
|
||||
var.vt = VT_BOOL;
|
||||
var.boolVal = VARIANT_TRUE;
|
||||
|
||||
hr = ps->SetValue(PKEY_EdgeGesture_DisableTouchWhenFullscreen, var);
|
||||
|
||||
ps->Release();
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning(LOG_MODULE_NAME, "Failed to disable edge gestures on window");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Win8Handler::window_unregister(HWND hWnd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Win8Handler::handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
// parse touch messages
|
||||
switch (msg) {
|
||||
case WM_POINTERACTIVATE: {
|
||||
result.action = ACTION_RETURN_STORED;
|
||||
result.return_value = PA_ACTIVATE;
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_NCPOINTERUPDATE:
|
||||
case WM_NCPOINTERDOWN:
|
||||
case WM_NCPOINTERUP:
|
||||
case WM_POINTERUPDATE:
|
||||
case WM_POINTERDOWN:
|
||||
case WM_POINTERUP: {
|
||||
|
||||
UINT entries_count = 0, pointer_count = 0;
|
||||
|
||||
if (pGetPointerFrameInfoHistory == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pGetPointerFrameInfoHistory(GET_POINTERID_WPARAM(wParam), &entries_count, &pointer_count, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (entries_count * pointer_count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto pointer_info = std::make_unique<POINTER_INFO[]>(entries_count * pointer_count);
|
||||
|
||||
if (!pGetPointerFrameInfoHistory(GET_POINTERID_WPARAM(wParam), &entries_count, &pointer_count, pointer_info.get())) {
|
||||
break;
|
||||
}
|
||||
|
||||
// lock touch points
|
||||
std::lock_guard<std::mutex> lock_points(TOUCH_POINTS_M);
|
||||
std::lock_guard<std::mutex> lock_events(TOUCH_EVENTS_M);
|
||||
|
||||
// iterate all inputs
|
||||
static long prev_x, prev_y;
|
||||
for (size_t i = 0; i < entries_count * pointer_count; i++) {
|
||||
auto &pi = pointer_info[i];
|
||||
|
||||
if (pi.pointerFlags & POINTER_FLAG_DOWN) {
|
||||
|
||||
// convert to window position
|
||||
POINT point = pi.ptPixelLocation;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// create new touch point
|
||||
TouchPoint tp {
|
||||
.id = pi.pointerId,
|
||||
.x = point.x,
|
||||
.y = point.y,
|
||||
.mouse = false,
|
||||
};
|
||||
TOUCH_POINTS.push_back(tp);
|
||||
|
||||
// add touch down event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_DOWN,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
|
||||
}
|
||||
|
||||
if ((pi.pointerFlags & POINTER_FLAG_UPDATE) != 0) {
|
||||
|
||||
// convert to window position
|
||||
POINT point = pi.ptPixelLocation;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// check prev coordinates
|
||||
if (point.x != prev_x || point.y != prev_y) {
|
||||
|
||||
// update point
|
||||
for (auto &tp : TOUCH_POINTS) {
|
||||
if (tp.id == pi.pointerId) {
|
||||
|
||||
// update values
|
||||
tp.x = point.x;
|
||||
tp.y = point.y;
|
||||
|
||||
// add touch move event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_MOVE,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
|
||||
}
|
||||
|
||||
if ((pi.pointerFlags & POINTER_FLAG_UP) != 0) {
|
||||
|
||||
// remove point
|
||||
for (size_t x = 0; x < TOUCH_POINTS.size(); x++) {
|
||||
auto &tp = TOUCH_POINTS[x];
|
||||
|
||||
if (tp.id == pi.pointerId) {
|
||||
|
||||
// add touch up event
|
||||
TouchEvent te {
|
||||
.id = pi.pointerId,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_UP,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// remove from active touch points
|
||||
TOUCH_POINTS.erase(TOUCH_POINTS.begin() + x);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pSkipPointerFrameMessages != nullptr) {
|
||||
pSkipPointerFrameMessages(GET_POINTERID_WPARAM(wParam));
|
||||
}
|
||||
|
||||
// card button
|
||||
update_card_button();
|
||||
|
||||
result.action = ACTION_RETURN_STORED;
|
||||
result.return_value = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set version to Windows 8 to enable Windows 8 touch functions
|
||||
#define _WIN32_WINNT 0x0602
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <initguid.h>
|
||||
#include <windowsx.h>
|
||||
#include <propsys.h>
|
||||
|
||||
#include "win8.h"
|
||||
|
||||
#include "util/libutils.h"
|
||||
#include "util/logging.h"
|
||||
#include "rawinput/touch.h"
|
||||
|
||||
// mingw does not seem to have this either
|
||||
DEFINE_GUID(PKEY_EdgeGesture_DisableTouchWhenFullscreen_Format, 0x32CE38B2, 0x2C9A, 0x41B1, 0x9B, 0xC5, 0xB3, 0x78, 0x43, 0x94, 0xAA, 0x44);
|
||||
|
||||
// mingw issue #2205 workaround
|
||||
// https://sourceforge.net/p/mingw/bugs/2205/
|
||||
#undef TOUCHEVENTF_MOVE
|
||||
#define TOUCHEVENTF_MOVE 0x0001
|
||||
#undef TOUCHEVENTF_DOWN
|
||||
#define TOUCHEVENTF_DOWN 0x0002
|
||||
|
||||
// mingw doesn't seem to have these
|
||||
#ifndef WM_TABLET_DEFBASE
|
||||
#define WM_TABLET_DEFBASE 0x02C0
|
||||
#define WM_TABLET_QUERYSYSTEMGESTURESTATUS (WM_TABLET_DEFBASE + 12)
|
||||
#define TABLET_DISABLE_PRESSANDHOLD 0x00000001
|
||||
#define TABLET_DISABLE_PENTAPFEEDBACK 0x00000008
|
||||
#define TABLET_DISABLE_PENBARRELFEEDBACK 0x00000010
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEON 0x00000100
|
||||
#define TABLET_DISABLE_TOUCHUIFORCEOFF 0x00000200
|
||||
#define TABLET_DISABLE_TOUCHSWITCH 0x00008000
|
||||
#define TABLET_DISABLE_FLICKS 0x00010000
|
||||
#define TABLET_DISABLE_SMOOTHSCROLLING 0x00080000
|
||||
#define TABLET_DISABLE_FLICKFALLBACKKEYS 0x00100000
|
||||
#define TABLET_ENABLE_MULTITOUCHDATA 0x01000000
|
||||
#endif
|
||||
|
||||
// general states
|
||||
static HINSTANCE USER32_INSTANCE = nullptr;
|
||||
static HINSTANCE SHELL32_INSTANCE = nullptr;
|
||||
const char *LOG_MODULE_NAME = "touch::win8";
|
||||
|
||||
/*
|
||||
* dynamic touch functions
|
||||
* to maintain compatibility with windows XP
|
||||
*/
|
||||
typedef BOOL (WINAPI *GetPointerFrameInfoHistory_t)(UINT32, UINT32 *, UINT32 *, POINTER_INFO *);
|
||||
typedef BOOL (WINAPI *SkipPointerFrameMessages_t)(UINT32);
|
||||
typedef HRESULT (WINAPI *SHGetPropertyStoreForWindow_t)(HWND, REFIID, void **);
|
||||
static GetPointerFrameInfoHistory_t pGetPointerFrameInfoHistory = nullptr;
|
||||
static SkipPointerFrameMessages_t pSkipPointerFrameMessages = nullptr;
|
||||
static SHGetPropertyStoreForWindow_t pSHGetPropertyStoreForWindow = nullptr;
|
||||
|
||||
// other
|
||||
static const char ATOM_NAME[] = "MicrosoftTabletPenServiceProperty";
|
||||
|
||||
static void load_functions() {
|
||||
|
||||
// check if already loaded
|
||||
static bool functions_loaded = false;
|
||||
if (functions_loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
// load libraries
|
||||
if (USER32_INSTANCE == nullptr) {
|
||||
USER32_INSTANCE = libutils::load_library("user32.dll");
|
||||
}
|
||||
if (SHELL32_INSTANCE == nullptr) {
|
||||
SHELL32_INSTANCE = libutils::try_library("shell32.dll");
|
||||
}
|
||||
|
||||
// load touch functions
|
||||
pGetPointerFrameInfoHistory = libutils::try_proc<GetPointerFrameInfoHistory_t>(
|
||||
USER32_INSTANCE, "GetPointerFrameInfoHistory");
|
||||
pSkipPointerFrameMessages = libutils::try_proc<SkipPointerFrameMessages_t>(
|
||||
USER32_INSTANCE, "SkipPointerFrameMessages");
|
||||
|
||||
if (SHELL32_INSTANCE != nullptr) {
|
||||
pSHGetPropertyStoreForWindow = libutils::try_proc<SHGetPropertyStoreForWindow_t>(
|
||||
SHELL32_INSTANCE, "SHGetPropertyStoreForWindow");
|
||||
}
|
||||
|
||||
functions_loaded = true;
|
||||
}
|
||||
|
||||
Win8Handler::Win8Handler() : TouchHandler("win8") {
|
||||
load_functions();
|
||||
}
|
||||
|
||||
bool Win8Handler::is_available() {
|
||||
bool have_digitizers = (GetSystemMetrics(94) & 0x80) == 0x80;
|
||||
|
||||
load_functions();
|
||||
|
||||
if (pGetPointerFrameInfoHistory != nullptr) {
|
||||
if (have_digitizers) {
|
||||
log_info(LOG_MODULE_NAME, "Pointer API available");
|
||||
} else {
|
||||
log_info(LOG_MODULE_NAME, "Pointer API available, but no touch screens active");
|
||||
}
|
||||
} else {
|
||||
log_info(LOG_MODULE_NAME, "Pointer API unavailable");
|
||||
}
|
||||
|
||||
return have_digitizers && pGetPointerFrameInfoHistory != nullptr;
|
||||
}
|
||||
|
||||
bool Win8Handler::window_register(HWND hWnd) {
|
||||
|
||||
// atom settings
|
||||
DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD |
|
||||
TABLET_DISABLE_PENTAPFEEDBACK |
|
||||
TABLET_DISABLE_PENBARRELFEEDBACK |
|
||||
TABLET_DISABLE_FLICKS;
|
||||
|
||||
// get atom ID
|
||||
ATOM atomID = GlobalAddAtom(ATOM_NAME);
|
||||
|
||||
// disable gestures
|
||||
if (atomID > 0) {
|
||||
SetProp(hWnd, ATOM_NAME, (HANDLE) ((unsigned long long) dwHwndTabletProperty));
|
||||
}
|
||||
|
||||
IPropertyStore *ps = nullptr;
|
||||
HRESULT hr = pSHGetPropertyStoreForWindow(hWnd, IID_IPropertyStore, (void **) &ps);
|
||||
|
||||
if (SUCCEEDED(hr) && ps != nullptr) {
|
||||
PROPERTYKEY PKEY_EdgeGesture_DisableTouchWhenFullscreen = {
|
||||
PKEY_EdgeGesture_DisableTouchWhenFullscreen_Format,
|
||||
2,
|
||||
};
|
||||
|
||||
PROPVARIANT var {};
|
||||
var.vt = VT_BOOL;
|
||||
var.boolVal = VARIANT_TRUE;
|
||||
|
||||
hr = ps->SetValue(PKEY_EdgeGesture_DisableTouchWhenFullscreen, var);
|
||||
|
||||
ps->Release();
|
||||
|
||||
if (FAILED(hr)) {
|
||||
log_warning(LOG_MODULE_NAME, "Failed to disable edge gestures on window");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Win8Handler::window_unregister(HWND hWnd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Win8Handler::handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
// parse touch messages
|
||||
switch (msg) {
|
||||
case WM_POINTERACTIVATE: {
|
||||
result.action = ACTION_RETURN_STORED;
|
||||
result.return_value = PA_ACTIVATE;
|
||||
|
||||
break;
|
||||
}
|
||||
case WM_NCPOINTERUPDATE:
|
||||
case WM_NCPOINTERDOWN:
|
||||
case WM_NCPOINTERUP:
|
||||
case WM_POINTERUPDATE:
|
||||
case WM_POINTERDOWN:
|
||||
case WM_POINTERUP: {
|
||||
|
||||
UINT entries_count = 0, pointer_count = 0;
|
||||
|
||||
if (pGetPointerFrameInfoHistory == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pGetPointerFrameInfoHistory(GET_POINTERID_WPARAM(wParam), &entries_count, &pointer_count, NULL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (entries_count * pointer_count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto pointer_info = std::make_unique<POINTER_INFO[]>(entries_count * pointer_count);
|
||||
|
||||
if (!pGetPointerFrameInfoHistory(GET_POINTERID_WPARAM(wParam), &entries_count, &pointer_count, pointer_info.get())) {
|
||||
break;
|
||||
}
|
||||
|
||||
// lock touch points
|
||||
std::lock_guard<std::mutex> lock_points(TOUCH_POINTS_M);
|
||||
std::lock_guard<std::mutex> lock_events(TOUCH_EVENTS_M);
|
||||
|
||||
// iterate all inputs
|
||||
static long prev_x, prev_y;
|
||||
for (size_t i = 0; i < entries_count * pointer_count; i++) {
|
||||
auto &pi = pointer_info[i];
|
||||
|
||||
if (pi.pointerFlags & POINTER_FLAG_DOWN) {
|
||||
|
||||
// convert to window position
|
||||
POINT point = pi.ptPixelLocation;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// create new touch point
|
||||
TouchPoint tp {
|
||||
.id = pi.pointerId,
|
||||
.x = point.x,
|
||||
.y = point.y,
|
||||
.mouse = false,
|
||||
};
|
||||
TOUCH_POINTS.push_back(tp);
|
||||
|
||||
// add touch down event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_DOWN,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
|
||||
}
|
||||
|
||||
if ((pi.pointerFlags & POINTER_FLAG_UPDATE) != 0) {
|
||||
|
||||
// convert to window position
|
||||
POINT point = pi.ptPixelLocation;
|
||||
ScreenToClient(hWnd, &point);
|
||||
|
||||
// check prev coordinates
|
||||
if (point.x != prev_x || point.y != prev_y) {
|
||||
|
||||
// update point
|
||||
for (auto &tp : TOUCH_POINTS) {
|
||||
if (tp.id == pi.pointerId) {
|
||||
|
||||
// update values
|
||||
tp.x = point.x;
|
||||
tp.y = point.y;
|
||||
|
||||
// add touch move event
|
||||
TouchEvent te {
|
||||
.id = tp.id,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_MOVE,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set prev coordinates
|
||||
prev_x = point.x;
|
||||
prev_y = point.y;
|
||||
|
||||
}
|
||||
|
||||
if ((pi.pointerFlags & POINTER_FLAG_UP) != 0) {
|
||||
|
||||
// remove point
|
||||
for (size_t x = 0; x < TOUCH_POINTS.size(); x++) {
|
||||
auto &tp = TOUCH_POINTS[x];
|
||||
|
||||
if (tp.id == pi.pointerId) {
|
||||
|
||||
// add touch up event
|
||||
TouchEvent te {
|
||||
.id = pi.pointerId,
|
||||
.x = tp.x,
|
||||
.y = tp.y,
|
||||
.type = TOUCH_UP,
|
||||
.mouse = tp.mouse,
|
||||
};
|
||||
add_touch_event(&te);
|
||||
|
||||
// remove from active touch points
|
||||
TOUCH_POINTS.erase(TOUCH_POINTS.begin() + x);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pSkipPointerFrameMessages != nullptr) {
|
||||
pSkipPointerFrameMessages(GET_POINTERID_WPARAM(wParam));
|
||||
}
|
||||
|
||||
// card button
|
||||
update_card_button();
|
||||
|
||||
result.action = ACTION_RETURN_STORED;
|
||||
result.return_value = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-18
@@ -1,18 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
#include "handler.h"
|
||||
|
||||
class Win8Handler : public TouchHandler {
|
||||
public:
|
||||
|
||||
Win8Handler();
|
||||
|
||||
static bool is_available();
|
||||
|
||||
virtual bool window_register(HWND hWnd) override;
|
||||
virtual bool window_unregister(HWND hWnd) override;
|
||||
virtual void handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) override;
|
||||
};
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
#include "handler.h"
|
||||
|
||||
class Win8Handler : public TouchHandler {
|
||||
public:
|
||||
|
||||
Win8Handler();
|
||||
|
||||
static bool is_available();
|
||||
|
||||
virtual bool window_register(HWND hWnd) override;
|
||||
virtual bool window_unregister(HWND hWnd) override;
|
||||
virtual void handle_message(msg_handler_result &result, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) override;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user