From 1d7113259625a91f5f6d2f53365aad22ae744689 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 13 Nov 2014 22:40:25 +0200 Subject: [PATCH] Touchscreen input device Currently only implemented for Windows. --- source/graphics/android/window.cpp | 4 ++ source/graphics/cocoa/window.cpp | 4 ++ source/graphics/window.cpp | 7 ++ source/graphics/window.h | 6 ++ source/graphics/windows/window.cpp | 18 +++++ source/graphics/windows/window_platform.h | 1 + source/graphics/x11/window.cpp | 4 ++ source/input/android/touchscreen.cpp | 11 ++++ source/input/cocoa/touchscreen.cpp | 11 ++++ source/input/touchscreen.cpp | 80 +++++++++++++++++++++++ source/input/touchscreen.h | 40 ++++++++++++ source/input/windows/mouse.cpp | 4 ++ source/input/windows/touchscreen.cpp | 47 +++++++++++++ source/input/x11/touchscreen.cpp | 11 ++++ 14 files changed, 248 insertions(+) create mode 100644 source/input/android/touchscreen.cpp create mode 100644 source/input/cocoa/touchscreen.cpp create mode 100644 source/input/touchscreen.cpp create mode 100644 source/input/touchscreen.h create mode 100644 source/input/windows/touchscreen.cpp create mode 100644 source/input/x11/touchscreen.cpp diff --git a/source/graphics/android/window.cpp b/source/graphics/android/window.cpp index 465d325..3a58420 100644 --- a/source/graphics/android/window.cpp +++ b/source/graphics/android/window.cpp @@ -33,6 +33,10 @@ void Window::warp_pointer(int, int) { } +void Window::platform_set_touch_input() +{ +} + void Window::platform_show() { } diff --git a/source/graphics/cocoa/window.cpp b/source/graphics/cocoa/window.cpp index 321934c..abaefe2 100644 --- a/source/graphics/cocoa/window.cpp +++ b/source/graphics/cocoa/window.cpp @@ -37,6 +37,10 @@ void Window::warp_pointer(int, int) { } +void Window::platform_set_touch_input() +{ +} + void Window::platform_show() { show_window(priv->window); diff --git a/source/graphics/window.cpp b/source/graphics/window.cpp index ebdc578..d2fb37f 100644 --- a/source/graphics/window.cpp +++ b/source/graphics/window.cpp @@ -37,6 +37,7 @@ void Window::init() { visible = false; kbd_autorepeat = true; + touch_input = false; resizing = false; priv = new Private; @@ -85,6 +86,12 @@ void Window::set_keyboard_autorepeat(bool r) kbd_autorepeat = r; } +void Window::set_touch_input(bool t) +{ + touch_input = t; + platform_set_touch_input(); +} + void Window::show() { platform_show(); diff --git a/source/graphics/window.h b/source/graphics/window.h index 55751b3..70b4044 100644 --- a/source/graphics/window.h +++ b/source/graphics/window.h @@ -38,6 +38,7 @@ protected: WindowOptions options; bool visible; bool kbd_autorepeat; + bool touch_input; bool resizing; Private *priv; @@ -60,6 +61,11 @@ public: bool get_keyboard_autorepeat() const { return kbd_autorepeat; } void show_cursor(bool); void warp_pointer(int, int); + void set_touch_input(bool); +private: + void platform_set_touch_input(); +public: + bool get_touch_input() const { return touch_input; } Display &get_display() const { return display; } const WindowOptions &get_options() const { return options; } diff --git a/source/graphics/windows/window.cpp b/source/graphics/windows/window.cpp index e998950..2af6b83 100644 --- a/source/graphics/windows/window.cpp +++ b/source/graphics/windows/window.cpp @@ -1,3 +1,4 @@ +#define _WIN32_WINNT 0x0601 #include #include #include @@ -22,6 +23,7 @@ LRESULT CALLBACK wndproc_(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) ev.msg = msg; ev.wparam = wparam; ev.lparam = lparam; + ev.extra = GetMessageExtraInfo(); if(wnd && wnd->event(ev)) return 0; } @@ -129,6 +131,21 @@ void Window::warp_pointer(int, int) { } +void Window::platform_set_touch_input() +{ + WORD winver = LOWORD(GetVersion); + if(winver<_WIN32_WINNT) + { + touch_input = false; + throw runtime_error("no touch support"); + } + + if(touch_input) + RegisterTouchWindow(priv->window, 3); // TWF_FINETOUCH|TWF_WANTPALM + else + UnregisterTouchWindow(priv->window); +} + void Window::platform_show() { ShowWindow(priv->window, SW_SHOWNORMAL); @@ -153,6 +170,7 @@ bool Window::event(const Event &evnt) case WM_RBUTTONUP: case WM_MOUSEWHEEL: case WM_MOUSEMOVE: + case WM_TOUCHMOVE: signal_input_event.emit(evnt); break; case WM_SIZE: diff --git a/source/graphics/windows/window_platform.h b/source/graphics/windows/window_platform.h index 1ff5cf3..7d53f55 100644 --- a/source/graphics/windows/window_platform.h +++ b/source/graphics/windows/window_platform.h @@ -17,6 +17,7 @@ struct PlatformEvent UINT msg; WPARAM wparam; LPARAM lparam; + LPARAM extra; }; } // namespace Graphics diff --git a/source/graphics/x11/window.cpp b/source/graphics/x11/window.cpp index b7fabd5..1747da9 100644 --- a/source/graphics/x11/window.cpp +++ b/source/graphics/x11/window.cpp @@ -151,6 +151,10 @@ void Window::warp_pointer(int x, int y) XWarpPointer(display.get_private().display, None, priv->window, 0, 0, 0, 0, x, y); } +void Window::platform_set_touch_input() +{ +} + void Window::platform_show() { XMapRaised(display.get_private().display, priv->window); diff --git a/source/input/android/touchscreen.cpp b/source/input/android/touchscreen.cpp new file mode 100644 index 0000000..bfbf7aa --- /dev/null +++ b/source/input/android/touchscreen.cpp @@ -0,0 +1,11 @@ +#include "touchscreen.h" + +namespace Msp { +namespace Input { + +void Touchscreen::input_event(const Graphics::Window::Event &) +{ +} + +} // namespace Input +} // namespace Msp diff --git a/source/input/cocoa/touchscreen.cpp b/source/input/cocoa/touchscreen.cpp new file mode 100644 index 0000000..bfbf7aa --- /dev/null +++ b/source/input/cocoa/touchscreen.cpp @@ -0,0 +1,11 @@ +#include "touchscreen.h" + +namespace Msp { +namespace Input { + +void Touchscreen::input_event(const Graphics::Window::Event &) +{ +} + +} // namespace Input +} // namespace Msp diff --git a/source/input/touchscreen.cpp b/source/input/touchscreen.cpp new file mode 100644 index 0000000..95fd272 --- /dev/null +++ b/source/input/touchscreen.cpp @@ -0,0 +1,80 @@ +#include "touchscreen.h" + +using namespace std; + +namespace Msp { +namespace Input { + +Touchscreen::Touchscreen(Graphics::Window &w): + window(w) +{ + name = "Touchscreen"; + + window.set_touch_input(true); + window.signal_input_event.connect(sigc::mem_fun(this, &Touchscreen::input_event)); +} + +Touchscreen::~Touchscreen() +{ + window.set_touch_input(false); +} + +string Touchscreen::get_button_name(unsigned btn) const +{ + if(btn==0) + return "Primary touch"; + else + return Device::get_button_name(btn); +} + +string Touchscreen::get_axis_name(unsigned axis) const +{ + if(axis==0) + return "Primary touch X"; + else if(axis==1) + return "Primary touch Y"; + else + return Device::get_axis_name(axis); +} + +unsigned Touchscreen::map_point_id(unsigned id) +{ + unsigned unused = active_points.size(); + for(unsigned i=0; i +#include +#include "device.h" + +namespace Msp { +namespace Input { + +class Touchscreen: public Device, public sigc::trackable +{ +private: + enum + { + UNUSED = static_cast(-1) + }; + + Graphics::Window &window; + std::vector active_points; + +public: + Touchscreen(Graphics::Window &); + ~Touchscreen(); + + virtual std::string get_button_name(unsigned) const; + virtual std::string get_axis_name(unsigned) const; +private: + void input_event(const Graphics::Window::Event &); + + unsigned map_point_id(unsigned); + void touch_down(unsigned); + void touch_move(unsigned, float, float); + void touch_up(unsigned); +}; + +} // namespace Input +} // namespace Msp + +#endif diff --git a/source/input/windows/mouse.cpp b/source/input/windows/mouse.cpp index 77f8488..aae5141 100644 --- a/source/input/windows/mouse.cpp +++ b/source/input/windows/mouse.cpp @@ -7,6 +7,10 @@ namespace Input { void Mouse::input_event(const Graphics::Window::Event &event) { + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms703320.aspx + if(window.get_touch_input() && (event.extra&0xFFFFFF00)==0xFF515700) + return; + switch(event.msg) { case WM_LBUTTONDOWN: diff --git a/source/input/windows/touchscreen.cpp b/source/input/windows/touchscreen.cpp new file mode 100644 index 0000000..180f1c0 --- /dev/null +++ b/source/input/windows/touchscreen.cpp @@ -0,0 +1,47 @@ +#define _WIN32_WINNT 0x0601 +#include +#include +#include "touchscreen.h" + +using namespace std; + +namespace Msp { +namespace Input { + +void Touchscreen::input_event(const Graphics::Window::Event &event) +{ + if(event.msg==WM_TOUCHMOVE) + { + HTOUCHINPUT handle = reinterpret_cast(event.lparam); + unsigned n_points = LOWORD(event.wparam); + /* If I ever invent a legitimate use case for more touch points than an + average human has fingers, I'll come up with something else here. */ + TOUCHINPUT touch_buffer[10]; + if(!GetTouchInputInfo(handle, 10, touch_buffer, sizeof(TOUCHINPUT))) + return; + + for(unsigned i=0; i