24#include <linux/input.h>
26#include <winpr/assert.h>
27#include <winpr/cast.h>
29#include <freerdp/config.h>
30#include <freerdp/locale/keyboard.h>
36static BOOL scale_signed_coordinates(rdpContext* context, int32_t* x, int32_t* y,
42 WINPR_ASSERT(context);
45 WINPR_ASSERT(*x >= 0);
46 WINPR_ASSERT(*y >= 0);
50 rc = wlf_scale_coordinates(context, &ux, &uy, fromLocalToRDP);
51 WINPR_ASSERT(ux < INT32_MAX);
52 WINPR_ASSERT(uy < INT32_MAX);
58BOOL wlf_handle_pointer_enter(freerdp* instance,
const UwacPointerEnterLeaveEvent* ev)
62 rdpClientContext* cctx = NULL;
70 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
73 cctx = (rdpClientContext*)instance->context;
74 return freerdp_client_send_button_event(cctx, FALSE, PTR_FLAGS_MOVE,
75 WINPR_ASSERTING_INT_CAST(
int, x),
76 WINPR_ASSERTING_INT_CAST(
int, y));
79BOOL wlf_handle_pointer_motion(freerdp* instance,
const UwacPointerMotionEvent* ev)
81 rdpClientContext* cctx = NULL;
86 cctx = (rdpClientContext*)instance->context;
92 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
95 return freerdp_client_send_button_event(cctx, FALSE, PTR_FLAGS_MOVE,
96 WINPR_ASSERTING_INT_CAST(int32_t, x),
97 WINPR_ASSERTING_INT_CAST(int32_t, y));
100BOOL wlf_handle_pointer_buttons(freerdp* instance,
const UwacPointerButtonEvent* ev)
102 rdpClientContext* cctx = NULL;
106 if (!instance || !ev)
109 cctx = (rdpClientContext*)instance->context;
115 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
118 if (ev->state == WL_POINTER_BUTTON_STATE_PRESSED)
120 flags |= PTR_FLAGS_DOWN;
121 xflags |= PTR_XFLAGS_DOWN;
127 flags |= PTR_FLAGS_BUTTON1;
131 flags |= PTR_FLAGS_BUTTON2;
135 flags |= PTR_FLAGS_BUTTON3;
139 xflags |= PTR_XFLAGS_BUTTON1;
143 xflags |= PTR_XFLAGS_BUTTON2;
150 const INT32 cx = WINPR_ASSERTING_INT_CAST(int32_t, x);
151 const INT32 cy = WINPR_ASSERTING_INT_CAST(int32_t, y);
153 if ((flags & ~PTR_FLAGS_DOWN) != 0)
154 return freerdp_client_send_button_event(cctx, FALSE, flags, cx, cy);
156 if ((xflags & ~PTR_XFLAGS_DOWN) != 0)
157 return freerdp_client_send_extended_button_event(cctx, FALSE, xflags, cx, cy);
162BOOL wlf_handle_pointer_axis(freerdp* instance,
const UwacPointerAxisEvent* ev)
165 if (!instance || !instance->context || !ev)
169 return ArrayList_Append(context->events, ev);
172BOOL wlf_handle_pointer_axis_discrete(freerdp* instance,
const UwacPointerAxisEvent* ev)
175 if (!instance || !instance->context || !ev)
179 return ArrayList_Append(context->events, ev);
182static BOOL wlf_handle_wheel(freerdp* instance, uint32_t x, uint32_t y, uint32_t axis,
185 rdpClientContext* cctx = NULL;
187 int32_t direction = 0;
188 uint32_t avalue = (uint32_t)abs(value);
190 WINPR_ASSERT(instance);
192 cctx = (rdpClientContext*)instance->context;
195 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
201 case WL_POINTER_AXIS_VERTICAL_SCROLL:
202 flags |= PTR_FLAGS_WHEEL;
204 flags |= PTR_FLAGS_WHEEL_NEGATIVE;
207 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
208 flags |= PTR_FLAGS_HWHEEL;
210 flags |= PTR_FLAGS_WHEEL_NEGATIVE;
225 const UINT16 cval = (avalue > 0xFF) ? 0xFF : (UINT16)avalue;
226 UINT16 cflags = flags | cval;
228 if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
229 cflags = (flags & 0xFF00) | (0x100 - cval);
230 if (!freerdp_client_send_wheel_event(cctx, cflags))
238BOOL wlf_handle_pointer_frame(freerdp* instance,
const UwacPointerFrameEvent* ev)
243 enum wl_pointer_axis_source source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
245 if (!instance || !ev || !instance->context)
250 for (
size_t x = 0; x < ArrayList_Count(context->events); x++)
252 UwacEvent* cev = ArrayList_GetItem(context->events, x);
255 if (cev->type == UWAC_EVENT_POINTER_SOURCE)
258 source = cev->mouse_source.axis_source;
265 for (
size_t x = 0; x < ArrayList_Count(context->events); x++)
267 UwacEvent* cev = ArrayList_GetItem(context->events, x);
274 case WL_POINTER_AXIS_SOURCE_WHEEL:
275#if defined(WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION)
276 case WL_POINTER_AXIS_SOURCE_WHEEL_TILT:
278 if (cev->type == UWAC_EVENT_POINTER_AXIS_DISCRETE)
281 int32_t val = cev->mouse_axis.value * 0x78;
283 if (!wlf_handle_wheel(instance, cev->mouse_axis.x, cev->mouse_axis.y,
284 cev->mouse_axis.axis, val))
289 case WL_POINTER_AXIS_SOURCE_FINGER:
290 case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
291 if (cev->type == UWAC_EVENT_POINTER_AXIS)
293 double dval = wl_fixed_to_double(cev->mouse_axis.value);
294 int32_t val = (int32_t)(dval * 0x78 / 10.0);
295 if (!wlf_handle_wheel(instance, cev->mouse_axis.x, cev->mouse_axis.y,
296 cev->mouse_axis.axis, val))
305 ArrayList_Clear(context->events);
309BOOL wlf_handle_pointer_source(freerdp* instance,
const UwacPointerSourceEvent* ev)
312 if (!instance || !instance->context || !ev)
316 return ArrayList_Append(context->events, ev);
319BOOL wlf_handle_key(freerdp* instance,
const UwacKeyEvent* ev)
321 if (!instance || !ev)
324 WINPR_ASSERT(instance->context);
327 ev->raw_key == KEY_RIGHTCTRL)
328 wlf_handle_ungrab_key(instance, ev);
330 rdpInput* input = instance->context->input;
332 const DWORD vc = GetVirtualKeyCodeFromKeycode(ev->raw_key, WINPR_KEYCODE_TYPE_EVDEV);
333 const DWORD sc = GetVirtualScanCodeFromVirtualKeyCode(vc, WINPR_KBD_TYPE_IBM_ENHANCED);
334 const DWORD rdp_scancode = freerdp_keyboard_remap_key(ctx->remap_table, sc);
336 if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
339 return freerdp_input_send_keyboard_event_ex(input, ev->pressed, ev->repeated, rdp_scancode);
342BOOL wlf_handle_ungrab_key(freerdp* instance,
const UwacKeyEvent* ev)
345 if (!instance || !instance->context || !ev)
350 return UwacSeatInhibitShortcuts(context->seat,
false) == UWAC_SUCCESS;
353BOOL wlf_keyboard_enter(freerdp* instance,
const UwacKeyboardEnterLeaveEvent* ev)
355 if (!instance || !ev)
358 ((
wlfContext*)instance->context)->focusing = TRUE;
362BOOL wlf_keyboard_modifiers(freerdp* instance,
const UwacKeyboardModifiersEvent* ev)
364 rdpInput* input = NULL;
365 UINT16 syncFlags = 0;
368 if (!instance || !ev)
374 input = instance->context->input;
379 if (ev->modifiers & UWAC_MOD_CAPS_MASK)
380 syncFlags |= KBD_SYNC_CAPS_LOCK;
381 if (ev->modifiers & UWAC_MOD_NUM_MASK)
382 syncFlags |= KBD_SYNC_NUM_LOCK;
387 ((
wlfContext*)instance->context)->focusing = FALSE;
389 return freerdp_input_send_focus_in_event(input, syncFlags) &&
390 freerdp_client_send_button_event(&wlf->common, FALSE, PTR_FLAGS_MOVE, 0, 0);
393BOOL wlf_handle_touch_up(freerdp* instance,
const UwacTouchUp* ev)
398 WINPR_ASSERT(instance);
407 if (!scale_signed_coordinates(instance->context, &x, &y, TRUE))
410 return freerdp_client_handle_touch(&wlf->common, FREERDP_TOUCH_UP, ev->id, 0, x, y);
413BOOL wlf_handle_touch_down(freerdp* instance,
const UwacTouchDown* ev)
418 WINPR_ASSERT(instance);
427 if (!scale_signed_coordinates(instance->context, &x, &y, TRUE))
430 return freerdp_client_handle_touch(&wlf->common, FREERDP_TOUCH_DOWN, ev->id, 0, x, y);
433BOOL wlf_handle_touch_motion(freerdp* instance,
const UwacTouchMotion* ev)
438 WINPR_ASSERT(instance);
447 if (!scale_signed_coordinates(instance->context, &x, &y, TRUE))
450 return freerdp_client_handle_touch(&wlf->common, FREERDP_TOUCH_MOTION, 0,
451 WINPR_ASSERTING_INT_CAST(uint32_t, ev->id), x, y);
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.