Currently only implemented for Windows.
{
}
+void Window::platform_set_touch_input()
+{
+}
+
void Window::platform_show()
{
}
{
}
+void Window::platform_set_touch_input()
+{
+}
+
void Window::platform_show()
{
show_window(priv->window);
{
visible = false;
kbd_autorepeat = true;
+ touch_input = false;
resizing = false;
priv = new Private;
kbd_autorepeat = r;
}
+void Window::set_touch_input(bool t)
+{
+ touch_input = t;
+ platform_set_touch_input();
+}
+
void Window::show()
{
platform_show();
WindowOptions options;
bool visible;
bool kbd_autorepeat;
+ bool touch_input;
bool resizing;
Private *priv;
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; }
+#define _WIN32_WINNT 0x0601
#include <windowsx.h>
#include <msp/core/application.h>
#include <msp/core/systemerror.h>
ev.msg = msg;
ev.wparam = wparam;
ev.lparam = lparam;
+ ev.extra = GetMessageExtraInfo();
if(wnd && wnd->event(ev))
return 0;
}
{
}
+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);
case WM_RBUTTONUP:
case WM_MOUSEWHEEL:
case WM_MOUSEMOVE:
+ case WM_TOUCHMOVE:
signal_input_event.emit(evnt);
break;
case WM_SIZE:
UINT msg;
WPARAM wparam;
LPARAM lparam;
+ LPARAM extra;
};
} // namespace Graphics
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);
--- /dev/null
+#include "touchscreen.h"
+
+namespace Msp {
+namespace Input {
+
+void Touchscreen::input_event(const Graphics::Window::Event &)
+{
+}
+
+} // namespace Input
+} // namespace Msp
--- /dev/null
+#include "touchscreen.h"
+
+namespace Msp {
+namespace Input {
+
+void Touchscreen::input_event(const Graphics::Window::Event &)
+{
+}
+
+} // namespace Input
+} // namespace Msp
--- /dev/null
+#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<active_points.size(); ++i)
+ {
+ if(active_points[i]==id)
+ return i;
+ else if(active_points[i]==UNUSED && i<unused)
+ unused = i;
+ }
+
+ if(unused<active_points.size())
+ active_points[unused] = id;
+ else
+ active_points.push_back(id);
+
+ return unused;
+}
+
+void Touchscreen::touch_down(unsigned id)
+{
+ unsigned i = map_point_id(id);
+ set_button_state(i, true, true);
+}
+
+void Touchscreen::touch_move(unsigned id, float x, float y)
+{
+ unsigned i = map_point_id(id);
+ set_axis_value(i*2, x, true);
+ set_axis_value(i*2+1, y, true);
+}
+
+void Touchscreen::touch_up(unsigned id)
+{
+ unsigned i = map_point_id(id);
+ set_button_state(i, true, false);
+ active_points[i] = UNUSED;
+}
+
+} // namespace Input
+} // namespace Msp
--- /dev/null
+#ifndef MSP_INPUT_TOUCHSCREEN_H_
+#define MSP_INPUT_TOUCHSCREEN_H_
+
+#include <sigc++/trackable.h>
+#include <msp/graphics/window.h>
+#include "device.h"
+
+namespace Msp {
+namespace Input {
+
+class Touchscreen: public Device, public sigc::trackable
+{
+private:
+ enum
+ {
+ UNUSED = static_cast<unsigned>(-1)
+ };
+
+ Graphics::Window &window;
+ std::vector<unsigned> 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
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:
--- /dev/null
+#define _WIN32_WINNT 0x0601
+#include <windows.h>
+#include <msp/graphics/window_private.h>
+#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<HTOUCHINPUT>(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<n_points; ++i)
+ {
+ const TOUCHINPUT &point = touch_buffer[i];
+
+ POINT screen_pt = { point.x/100, point.y/100 };
+ POINT client_pt = screen_pt;
+ ScreenToClient(window.get_private().window, &client_pt);
+ float x = (point.x/100.0f-screen_pt.x+client_pt.x)*2.0f/window.get_width()-1.0f;
+ float y = 1.0f-(point.y/100.0f-screen_pt.y+client_pt.y)*2.0f/window.get_height();
+
+ touch_move(point.dwID, x, y);
+ if(point.dwFlags&TOUCHEVENTF_DOWN)
+ touch_down(point.dwID);
+ else if(point.dwFlags&TOUCHEVENTF_UP)
+ touch_up(point.dwID);
+ }
+
+ CloseTouchInputHandle(handle);
+ }
+}
+
+
+
+} // namespace Input
+} // namespace Msp
--- /dev/null
+#include "touchscreen.h"
+
+namespace Msp {
+namespace Input {
+
+void Touchscreen::input_event(const Graphics::Window::Event &)
+{
+}
+
+} // namespace Input
+} // namespace Msp