]> git.tdb.fi Git - libs/gui.git/blob - source/input/windows/touchscreen.cpp
ce8e5a2f71270c2278e97a6aba799c985d173907
[libs/gui.git] / source / input / windows / touchscreen.cpp
1 #define _WIN32_WINNT 0x0601
2 #include <windows.h>
3 #include <msp/graphics/window_private.h>
4 #include "touchscreen.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace Input {
10
11 bool Touchscreen::is_available()
12 {
13         // Must have at least Windows 7 (WinNT 6.1) for WM_TOUCH
14         OSVERSIONINFOEX version;
15         version.dwOSVersionInfoSize = sizeof(version);
16         version.dwMajorVersion = 6;
17         version.dwMinorVersion = 1;
18         version.wServicePackMajor = 0;
19         version.wServicePackMinor = 0;
20         DWORD mask = VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR|VER_SERVICEPACKMINOR;
21         DWORDLONG cond = VerSetConditionMask(0, mask, VER_GREATER_EQUAL);
22         if(VerifyVersionInfo(&version, mask, cond))
23                 return false;
24
25         if(!GetSystemMetrics(SM_TABLETPC))
26                 return false;
27         if(!(GetSystemMetrics(SM_DIGITIZER)&NID_READY))
28                 return false;
29
30         return true;
31 }
32
33 void Touchscreen::input_event(const Graphics::Window::Event &event)
34 {
35         if(event.msg==WM_TOUCH)
36         {
37                 HTOUCHINPUT handle = reinterpret_cast<HTOUCHINPUT>(event.lparam);
38                 unsigned n_points = LOWORD(event.wparam);
39                 /* If I ever invent a legitimate use case for more touch points than an
40                 average human has fingers, I'll come up with something else here. */
41                 TOUCHINPUT touch_buffer[10];
42                 if(!GetTouchInputInfo(handle, 10, touch_buffer, sizeof(TOUCHINPUT)))
43                         return;
44
45                 for(unsigned i=0; i<n_points; ++i)
46                 {
47                         const TOUCHINPUT &point = touch_buffer[i];
48
49                         POINT screen_pt = { point.x/100, point.y/100 };
50                         POINT client_pt = screen_pt;
51                         ScreenToClient(window.get_private().window, &client_pt);
52                         float x = (point.x/100.0f-screen_pt.x+client_pt.x)*2.0f/window.get_width()-1.0f;
53                         float y = 1.0f-(point.y/100.0f-screen_pt.y+client_pt.y)*2.0f/window.get_height();
54
55                         touch_move(point.dwID, x, y);
56                         if(point.dwFlags&TOUCHEVENTF_DOWN)
57                                 touch_down(point.dwID);
58                         else if(point.dwFlags&TOUCHEVENTF_UP)
59                                 touch_up(point.dwID);
60                 }
61
62                 CloseTouchInputHandle(handle);
63         }
64 }
65
66 } // namespace Input
67 } // namespace Msp