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);
134 flags |= PTR_FLAGS_WHEEL;
135 if (!send_mouse_wheel(
sdl, flags, y))
141 flags |= PTR_FLAGS_HWHEEL;
142 if (!send_mouse_wheel(
sdl, flags, x))
148bool SdlTouch::handleEvent(
SdlContext*
sdl,
const SDL_MouseButtonEvent& ev)
155 if (ev.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
157 flags |= PTR_FLAGS_DOWN;
158 xflags |= PTR_XFLAGS_DOWN;
164 flags |= PTR_FLAGS_BUTTON1;
167 flags |= PTR_FLAGS_BUTTON3;
170 flags |= PTR_FLAGS_BUTTON2;
173 xflags |= PTR_XFLAGS_BUTTON1;
176 xflags |= PTR_XFLAGS_BUTTON2;
182 const BOOL relative =
183 freerdp_client_use_relative_mouse_events(
sdl->common()) && !
sdl->hasCursor();
184 auto x =
static_cast<INT32
>(relative ? 0 : ev.x);
185 auto y =
static_cast<INT32
>(relative ? 0 : ev.y);
187 if ((flags & (~PTR_FLAGS_DOWN)) != 0)
188 return freerdp_client_send_button_event(
sdl->common(), relative, flags, x, y);
189 else if ((xflags & (~PTR_XFLAGS_DOWN)) != 0)
190 return freerdp_client_send_extended_button_event(
sdl->common(), relative, xflags, x, y);
195bool SdlTouch::handleEvent(
SdlContext*
sdl,
const SDL_TouchFingerEvent& ev)
199 case SDL_EVENT_FINGER_CANCELED:
200 return SdlTouch::touchCancel(
sdl, ev);
201 case SDL_EVENT_FINGER_UP:
202 return SdlTouch::touchUp(
sdl, ev);
203 case SDL_EVENT_FINGER_DOWN:
204 return SdlTouch::touchDown(
sdl, ev);
205 case SDL_EVENT_FINGER_MOTION:
206 return SdlTouch::touchMotion(
sdl, ev);