20#include <freerdp/config.h>
22#include "sdl_touch.hpp"
23#include "sdl_context.hpp"
24#include "sdl_prefs.hpp"
26#include <winpr/wtypes.h>
27#include <winpr/assert.h>
29#include <freerdp/freerdp.h>
30#include <freerdp/gdi/gdi.h>
34[[nodiscard]]
static bool send_mouse_wheel(
SdlContext*
sdl, UINT16 flags, INT32 avalue)
39 flags |= PTR_FLAGS_WHEEL_NEGATIVE;
45 const UINT16 cval = (avalue > 0xFF) ? 0xFF : static_cast<UINT16>(avalue);
46 UINT16 cflags = flags | cval;
48 if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
49 cflags = (flags & 0xFF00) | (0x100 - cval);
50 if (!freerdp_client_send_wheel_event(
sdl->common(), cflags))
58[[nodiscard]]
static UINT32 sdl_scale_pressure(
const float pressure)
60 const float val = pressure * 0x400;
65 return static_cast<UINT32
>(val);
68bool SdlTouch::touchUp(
SdlContext*
sdl,
const SDL_TouchFingerEvent& ev)
72 return freerdp_client_handle_touch(
sdl->common(), FREERDP_TOUCH_UP | FREERDP_TOUCH_HAS_PRESSURE,
73 static_cast<INT32
>(ev.fingerID),
74 sdl_scale_pressure(ev.pressure),
static_cast<Sint32
>(ev.x),
75 static_cast<Sint32
>(ev.y));
78bool SdlTouch::touchCancel(
SdlContext*
sdl,
const SDL_TouchFingerEvent& ev)
82 return freerdp_client_handle_touch(
83 sdl->common(), FREERDP_TOUCH_CANCEL | FREERDP_TOUCH_HAS_PRESSURE,
84 static_cast<INT32
>(ev.fingerID), sdl_scale_pressure(ev.pressure),
static_cast<Sint32
>(ev.x),
85 static_cast<Sint32
>(ev.y));
88bool SdlTouch::touchDown(
SdlContext*
sdl,
const SDL_TouchFingerEvent& ev)
92 return freerdp_client_handle_touch(
93 sdl->common(), FREERDP_TOUCH_DOWN | FREERDP_TOUCH_HAS_PRESSURE,
94 static_cast<INT32
>(ev.fingerID), sdl_scale_pressure(ev.pressure),
static_cast<Sint32
>(ev.x),
95 static_cast<Sint32
>(ev.y));
98bool SdlTouch::touchMotion(
SdlContext*
sdl,
const SDL_TouchFingerEvent& ev)
102 return freerdp_client_handle_touch(
103 sdl->common(), FREERDP_TOUCH_MOTION | FREERDP_TOUCH_HAS_PRESSURE,
104 static_cast<INT32
>(ev.fingerID), sdl_scale_pressure(ev.pressure),
static_cast<Sint32
>(ev.x),
105 static_cast<Sint32
>(ev.y));
108bool SdlTouch::handleEvent(
SdlContext*
sdl,
const SDL_MouseMotionEvent& ev)
112 if (!
sdl->getInputChannelContext().mouse_focus(ev.windowID))
115 const BOOL relative =
116 freerdp_client_use_relative_mouse_events(
sdl->common()) && !
sdl->hasCursor();
117 auto x =
static_cast<INT32
>(relative ? ev.xrel : ev.x);
118 auto y =
static_cast<INT32
>(relative ? ev.yrel : ev.y);
119 return freerdp_client_send_button_event(
sdl->common(), relative, PTR_FLAGS_MOVE, x, y);
122bool SdlTouch::handleEvent(
SdlContext*
sdl,
const SDL_MouseWheelEvent& ev)
126 const bool flipped = (ev.direction == SDL_MOUSEWHEEL_FLIPPED) &&
127 !SdlPref::instance()->get_bool(
"UseLocalMouseScrollDirection");
128 const auto x =
static_cast<INT32
>(ev.x * (flipped ? -1.0f : 1.0f) * 120.0f);
129 const auto y =
static_cast<INT32
>(ev.y * (flipped ? -1.0f : 1.0f) * 120.0f);
137 if (!send_mouse_wheel(
sdl, PTR_FLAGS_WHEEL, y))
143 if (!send_mouse_wheel(
sdl, PTR_FLAGS_HWHEEL, x))
149bool SdlTouch::handleEvent(
SdlContext*
sdl,
const SDL_MouseButtonEvent& ev)
156 if (ev.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
158 flags |= PTR_FLAGS_DOWN;
159 xflags |= PTR_XFLAGS_DOWN;
165 flags |= PTR_FLAGS_BUTTON1;
168 flags |= PTR_FLAGS_BUTTON3;
171 flags |= PTR_FLAGS_BUTTON2;
174 xflags |= PTR_XFLAGS_BUTTON1;
177 xflags |= PTR_XFLAGS_BUTTON2;
183 const BOOL relative =
184 freerdp_client_use_relative_mouse_events(
sdl->common()) && !
sdl->hasCursor();
185 auto x =
static_cast<INT32
>(relative ? 0 : ev.x);
186 auto y =
static_cast<INT32
>(relative ? 0 : ev.y);
188 if ((flags & (~PTR_FLAGS_DOWN)) != 0)
189 return freerdp_client_send_button_event(
sdl->common(), relative, flags, x, y);
190 else if ((xflags & (~PTR_XFLAGS_DOWN)) != 0)
191 return freerdp_client_send_extended_button_event(
sdl->common(), relative, xflags, x, y);
196bool SdlTouch::handleEvent(
SdlContext*
sdl,
const SDL_TouchFingerEvent& ev)
200 case SDL_EVENT_FINGER_CANCELED:
201 return SdlTouch::touchCancel(
sdl, ev);
202 case SDL_EVENT_FINGER_UP:
203 return SdlTouch::touchUp(
sdl, ev);
204 case SDL_EVENT_FINGER_DOWN:
205 return SdlTouch::touchDown(
sdl, ev);
206 case SDL_EVENT_FINGER_MOTION:
207 return SdlTouch::touchMotion(
sdl, ev);