mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-04 15:50:42 -07:00
touch: restore wintouchemu, fall back to it when native touch hooks fail (#834)
## Link to GitHub Issue or related Pull Request, if one exists Fixes #833 ## Description of change Last couple PRs - such as #820 #827 #828 - made the native touch hook & touch injection using `InjectTouchInput` the default path, since it performs much more reliably with both real touch screens and mouse (or any other synthetic source). However, user has reported that WINE lacks `InjectTouchInput` which means this won't work. As a fix, revive the old wintouchemu code. Native touch is still the default, but under following circumstances: 1. if `-touchemuforce` is set, or 2. if any of the required Windows touch APIs are unavailable then we fail over from native touch to wintouchemu code. For Linux, condition #2 would be hit during init, and gracefully switch over. Caveat: the poke code for IIDX and Nost will continue to require native touch, I do not want to maintain two paths for this. This means that iidx poke will stop working on Linux, unfortunately. ## Testing Tested on Windows with `-touchemuforce` set. This is mostly reverting Linux code path back to where we were last release, so this should just work with wine.
This commit is contained in:
@@ -338,9 +338,7 @@ namespace nativetouch::inject {
|
||||
|
||||
// attach mouse injection without replacing the window's existing procedure
|
||||
static void attach_window_impl(HWND window, bool register_touch) {
|
||||
initialize_touch_injection();
|
||||
|
||||
if (!touch_injection_available()) {
|
||||
if (!initialize_touch_injection()) {
|
||||
if (register_touch) {
|
||||
log_warning(
|
||||
"touch::native",
|
||||
@@ -422,7 +420,7 @@ namespace nativetouch::inject {
|
||||
}
|
||||
|
||||
// load and initialize Windows 8 touch injection without a static API dependency
|
||||
void initialize_touch_injection() {
|
||||
bool initialize_touch_injection() {
|
||||
std::call_once(initialization_once, [] {
|
||||
initialize_synthetic_touch();
|
||||
contact_refresh_message =
|
||||
@@ -433,17 +431,26 @@ namespace nativetouch::inject {
|
||||
}
|
||||
|
||||
// load all APIs from user32 without adding static imports
|
||||
//
|
||||
// note that these are expected to be present in Windows 8 and above;
|
||||
// however, on WINE, touch implementation remains in Windows 7 era
|
||||
// and therefore the hooks below will fail, hence the fallback to
|
||||
// legacy wintouchemu code
|
||||
const auto user32 = libutils::load_library("user32.dll");
|
||||
InitializeTouchInjection_ptr = libutils::try_proc<decltype(InitializeTouchInjection_ptr)>(
|
||||
user32, "InitializeTouchInjection");
|
||||
if (InitializeTouchInjection_ptr == nullptr) {
|
||||
log_warning(
|
||||
"touch::native", "InitializeTouchInjection unavailable; mouse touch injection disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
InjectTouchInput_ptr = libutils::try_proc<decltype(InjectTouchInput_ptr)>(
|
||||
user32, "InjectTouchInput");
|
||||
|
||||
if (InitializeTouchInjection_ptr == nullptr ||
|
||||
InjectTouchInput_ptr == nullptr) {
|
||||
if (InjectTouchInput_ptr == nullptr) {
|
||||
clear_touch_injection_functions();
|
||||
log_warning(
|
||||
"touch::native", "touch injection API unavailable; mouse touch injection disabled");
|
||||
"touch::native", "InjectTouchInput unavailable; mouse touch injection disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -457,20 +464,31 @@ namespace nativetouch::inject {
|
||||
|
||||
log_misc("touch::native", "mouse touch injection initialized");
|
||||
});
|
||||
}
|
||||
|
||||
bool touch_injection_available() {
|
||||
return InjectTouchInput_ptr != nullptr;
|
||||
return InitializeTouchInjection_ptr != nullptr && InjectTouchInput_ptr != nullptr;
|
||||
}
|
||||
|
||||
// install injection support for touch windows registered by the game module
|
||||
void hook(HMODULE module) {
|
||||
initialize_touch_injection();
|
||||
bool hook_available(HMODULE module) {
|
||||
if (detour::iat_find("RegisterTouchWindow", module) == nullptr) {
|
||||
log_warning("touch::native", "RegisterTouchWindow unavailable");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hook(HMODULE module) {
|
||||
if (!initialize_touch_injection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisterTouchWindow_orig = detour::iat_try(
|
||||
"RegisterTouchWindow", RegisterTouchWindowHook, module);
|
||||
if (RegisterTouchWindow_orig != nullptr) {
|
||||
log_misc("touch::native", "RegisterTouchWindow hooked");
|
||||
if (RegisterTouchWindow_orig == nullptr) {
|
||||
log_warning("touch::native", "failed to hook RegisterTouchWindow");
|
||||
return false;
|
||||
}
|
||||
|
||||
log_misc("touch::native", "RegisterTouchWindow hooked");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user