20 #include <freerdp/config.h>
22 #include "sdl_touch.hpp"
23 #include "sdl_freerdp.hpp"
25 #include <winpr/wtypes.h>
26 #include <winpr/assert.h>
28 #include <freerdp/freerdp.h>
29 #include <freerdp/gdi/gdi.h>
33 BOOL sdl_scale_coordinates(
SdlContext* sdl, Uint32 windowId, INT32* px, INT32* py,
34 BOOL fromLocalToRDP, BOOL applyOffset)
36 rdpGdi* gdi =
nullptr;
40 if (!sdl || !px || !py || !sdl->context()->gdi)
43 WINPR_ASSERT(sdl->context()->gdi);
44 WINPR_ASSERT(sdl->context()->settings);
46 gdi = sdl->context()->gdi;
55 for (
const auto& it : sdl->windows)
57 auto& window = it.second;
58 const auto id = window.id();
64 auto size = window.rect();
66 sx = size.w /
static_cast<double>(gdi->width);
67 sy = size.h /
static_cast<double>(gdi->height);
68 offset_x = window.offsetX();
69 offset_y = window.offsetY();
77 *px =
static_cast<INT32
>(*px * sx);
78 *py =
static_cast<INT32
>(*py * sy);
82 *px =
static_cast<INT32
>(*px / sx);
83 *py =
static_cast<INT32
>(*py / sy);
95 static BOOL sdl_get_touch_scaled(
SdlContext* sdl,
const SDL_TouchFingerEvent* ev, INT32* px,
96 INT32* py, BOOL local)
105 #if SDL_VERSION_ATLEAST(2, 0, 12)
106 SDL_Window* window = SDL_GetWindowFromID(ev->windowID);
108 SDL_Window* window = SDL_GetMouseFocus();
114 windowID = SDL_GetWindowID(window);
115 SDL_Surface* surface = SDL_GetWindowSurface(window);
120 *px =
static_cast<INT32
>(ev->x *
static_cast<float>(surface->w));
121 *py =
static_cast<INT32
>(ev->y *
static_cast<float>(surface->h));
122 return sdl_scale_coordinates(sdl, windowID, px, py, local, TRUE);
125 static BOOL send_mouse_wheel(
SdlContext* sdl, UINT16 flags, INT32 avalue)
130 flags |= PTR_FLAGS_WHEEL_NEGATIVE;
136 const UINT16 cval = (avalue > 0xFF) ? 0xFF :
static_cast<UINT16
>(avalue);
137 UINT16 cflags = flags | cval;
139 if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
140 cflags = (flags & 0xFF00) | (0x100 - cval);
141 if (!freerdp_client_send_wheel_event(sdl->common(), cflags))
149 static UINT32 sdl_scale_pressure(
const float pressure)
151 const float val = pressure * 0x400;
156 return static_cast<UINT32
>(val);
159 BOOL sdl_handle_touch_up(
SdlContext* sdl,
const SDL_TouchFingerEvent* ev)
166 if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
168 return freerdp_client_handle_touch(sdl->common(), FREERDP_TOUCH_UP | FREERDP_TOUCH_HAS_PRESSURE,
169 static_cast<INT32
>(ev->fingerId),
170 sdl_scale_pressure(ev->pressure), x, y);
173 BOOL sdl_handle_touch_down(
SdlContext* sdl,
const SDL_TouchFingerEvent* ev)
180 if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
182 return freerdp_client_handle_touch(
183 sdl->common(), FREERDP_TOUCH_DOWN | FREERDP_TOUCH_HAS_PRESSURE,
184 static_cast<INT32
>(ev->fingerId), sdl_scale_pressure(ev->pressure), x, y);
187 BOOL sdl_handle_touch_motion(
SdlContext* sdl,
const SDL_TouchFingerEvent* ev)
194 if (!sdl_get_touch_scaled(sdl, ev, &x, &y, TRUE))
196 return freerdp_client_handle_touch(
197 sdl->common(), FREERDP_TOUCH_MOTION | FREERDP_TOUCH_HAS_PRESSURE,
198 static_cast<INT32
>(ev->fingerId), sdl_scale_pressure(ev->pressure), x, y);
201 BOOL sdl_handle_mouse_motion(
SdlContext* sdl,
const SDL_MouseMotionEvent* ev)
206 sdl->input.mouse_focus(ev->windowID);
207 const BOOL relative = freerdp_client_use_relative_mouse_events(sdl->common());
208 INT32 x = relative ? ev->xrel : ev->x;
209 INT32 y = relative ? ev->yrel : ev->y;
210 sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
211 return freerdp_client_send_button_event(sdl->common(), relative, PTR_FLAGS_MOVE, x, y);
214 BOOL sdl_handle_mouse_wheel(
SdlContext* sdl,
const SDL_MouseWheelEvent* ev)
219 const BOOL flipped = (ev->direction == SDL_MOUSEWHEEL_FLIPPED);
220 const INT32 x = ev->x * (flipped ? -1 : 1) * 0x78;
221 const INT32 y = ev->y * (flipped ? -1 : 1) * 0x78;
226 flags |= PTR_FLAGS_WHEEL;
227 send_mouse_wheel(sdl, flags, y);
232 flags |= PTR_FLAGS_HWHEEL;
233 send_mouse_wheel(sdl, flags, x);
238 BOOL sdl_handle_mouse_button(
SdlContext* sdl,
const SDL_MouseButtonEvent* ev)
246 if (ev->state == SDL_PRESSED)
248 flags |= PTR_FLAGS_DOWN;
249 xflags |= PTR_XFLAGS_DOWN;
255 flags |= PTR_FLAGS_BUTTON1;
258 flags |= PTR_FLAGS_BUTTON3;
261 flags |= PTR_FLAGS_BUTTON2;
264 xflags |= PTR_XFLAGS_BUTTON1;
267 xflags |= PTR_XFLAGS_BUTTON2;
273 const BOOL relative = freerdp_client_use_relative_mouse_events(sdl->common());
274 INT32 x = relative ? 0 : ev->x;
275 INT32 y = relative ? 0 : ev->y;
276 sdl_scale_coordinates(sdl, ev->windowID, &x, &y, TRUE, TRUE);
277 if ((flags & (~PTR_FLAGS_DOWN)) != 0)
278 return freerdp_client_send_button_event(sdl->common(), relative, flags, x, y);
279 else if ((xflags & (~PTR_XFLAGS_DOWN)) != 0)
280 return freerdp_client_send_extended_button_event(sdl->common(), relative, xflags, x, y);
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.