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>
31 #if defined(CHANNEL_RDPEI_CLIENT)
32 #include <freerdp/client/rdpei.h>
34 #include <uwac/uwac.h>
36 #include "wlfreerdp.h"
37 #include "wlf_input.h"
39 static BOOL scale_signed_coordinates(rdpContext* context, int32_t* x, int32_t* y,
45 WINPR_ASSERT(context);
48 WINPR_ASSERT(*x >= 0);
49 WINPR_ASSERT(*y >= 0);
53 rc = wlf_scale_coordinates(context, &ux, &uy, fromLocalToRDP);
54 WINPR_ASSERT(ux < INT32_MAX);
55 WINPR_ASSERT(uy < INT32_MAX);
61 BOOL wlf_handle_pointer_enter(freerdp* instance,
const UwacPointerEnterLeaveEvent* ev)
65 rdpClientContext* cctx = NULL;
73 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
76 cctx = (rdpClientContext*)instance->context;
77 return freerdp_client_send_button_event(cctx, FALSE, PTR_FLAGS_MOVE,
78 WINPR_ASSERTING_INT_CAST(
int, x),
79 WINPR_ASSERTING_INT_CAST(
int, y));
82 BOOL wlf_handle_pointer_motion(freerdp* instance,
const UwacPointerMotionEvent* ev)
84 rdpClientContext* cctx = NULL;
89 cctx = (rdpClientContext*)instance->context;
95 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
98 return freerdp_client_send_button_event(cctx, FALSE, PTR_FLAGS_MOVE,
99 WINPR_ASSERTING_INT_CAST(int32_t, x),
100 WINPR_ASSERTING_INT_CAST(int32_t, y));
103 BOOL wlf_handle_pointer_buttons(freerdp* instance,
const UwacPointerButtonEvent* ev)
105 rdpClientContext* cctx = NULL;
109 if (!instance || !ev)
112 cctx = (rdpClientContext*)instance->context;
118 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
121 if (ev->state == WL_POINTER_BUTTON_STATE_PRESSED)
123 flags |= PTR_FLAGS_DOWN;
124 xflags |= PTR_XFLAGS_DOWN;
130 flags |= PTR_FLAGS_BUTTON1;
134 flags |= PTR_FLAGS_BUTTON2;
138 flags |= PTR_FLAGS_BUTTON3;
142 xflags |= PTR_XFLAGS_BUTTON1;
146 xflags |= PTR_XFLAGS_BUTTON2;
153 const INT32 cx = WINPR_ASSERTING_INT_CAST(int32_t, x);
154 const INT32 cy = WINPR_ASSERTING_INT_CAST(int32_t, y);
156 if ((flags & ~PTR_FLAGS_DOWN) != 0)
157 return freerdp_client_send_button_event(cctx, FALSE, flags, cx, cy);
159 if ((xflags & ~PTR_XFLAGS_DOWN) != 0)
160 return freerdp_client_send_extended_button_event(cctx, FALSE, xflags, cx, cy);
165 BOOL wlf_handle_pointer_axis(freerdp* instance,
const UwacPointerAxisEvent* ev)
168 if (!instance || !instance->context || !ev)
172 return ArrayList_Append(context->events, ev);
175 BOOL wlf_handle_pointer_axis_discrete(freerdp* instance,
const UwacPointerAxisEvent* ev)
178 if (!instance || !instance->context || !ev)
182 return ArrayList_Append(context->events, ev);
185 static BOOL wlf_handle_wheel(freerdp* instance, uint32_t x, uint32_t y, uint32_t axis,
188 rdpClientContext* cctx = NULL;
190 int32_t direction = 0;
191 uint32_t avalue = (uint32_t)abs(value);
193 WINPR_ASSERT(instance);
195 cctx = (rdpClientContext*)instance->context;
198 if (!wlf_scale_coordinates(instance->context, &x, &y, TRUE))
204 case WL_POINTER_AXIS_VERTICAL_SCROLL:
205 flags |= PTR_FLAGS_WHEEL;
207 flags |= PTR_FLAGS_WHEEL_NEGATIVE;
210 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
211 flags |= PTR_FLAGS_HWHEEL;
213 flags |= PTR_FLAGS_WHEEL_NEGATIVE;
228 const UINT16 cval = (avalue > 0xFF) ? 0xFF : (UINT16)avalue;
229 UINT16 cflags = flags | cval;
231 if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
232 cflags = (flags & 0xFF00) | (0x100 - cval);
233 if (!freerdp_client_send_wheel_event(cctx, cflags))
241 BOOL wlf_handle_pointer_frame(freerdp* instance,
const UwacPointerFrameEvent* ev)
246 enum wl_pointer_axis_source source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
248 if (!instance || !ev || !instance->context)
253 for (
size_t x = 0; x < ArrayList_Count(context->events); x++)
255 UwacEvent* cev = ArrayList_GetItem(context->events, x);
258 if (cev->type == UWAC_EVENT_POINTER_SOURCE)
261 source = cev->mouse_source.axis_source;
268 for (
size_t x = 0; x < ArrayList_Count(context->events); x++)
270 UwacEvent* cev = ArrayList_GetItem(context->events, x);
277 case WL_POINTER_AXIS_SOURCE_WHEEL:
278 #if defined(WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION)
279 case WL_POINTER_AXIS_SOURCE_WHEEL_TILT:
281 if (cev->type == UWAC_EVENT_POINTER_AXIS_DISCRETE)
284 int32_t val = cev->mouse_axis.value * 0x78;
286 if (!wlf_handle_wheel(instance, cev->mouse_axis.x, cev->mouse_axis.y,
287 cev->mouse_axis.axis, val))
292 case WL_POINTER_AXIS_SOURCE_FINGER:
293 case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
294 if (cev->type == UWAC_EVENT_POINTER_AXIS)
296 double dval = wl_fixed_to_double(cev->mouse_axis.value);
297 int32_t val = (int32_t)(dval * 0x78 / 10.0);
298 if (!wlf_handle_wheel(instance, cev->mouse_axis.x, cev->mouse_axis.y,
299 cev->mouse_axis.axis, val))
308 ArrayList_Clear(context->events);
312 BOOL wlf_handle_pointer_source(freerdp* instance,
const UwacPointerSourceEvent* ev)
315 if (!instance || !instance->context || !ev)
319 return ArrayList_Append(context->events, ev);
322 BOOL wlf_handle_key(freerdp* instance,
const UwacKeyEvent* ev)
324 if (!instance || !ev)
327 WINPR_ASSERT(instance->context);
330 ev->raw_key == KEY_RIGHTCTRL)
331 wlf_handle_ungrab_key(instance, ev);
333 rdpInput* input = instance->context->input;
335 const DWORD vc = GetVirtualKeyCodeFromKeycode(ev->raw_key, WINPR_KEYCODE_TYPE_EVDEV);
336 const DWORD sc = GetVirtualScanCodeFromVirtualKeyCode(vc, WINPR_KBD_TYPE_IBM_ENHANCED);
337 const DWORD rdp_scancode = freerdp_keyboard_remap_key(ctx->remap_table, sc);
339 if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
342 return freerdp_input_send_keyboard_event_ex(input, ev->pressed, ev->repeated, rdp_scancode);
345 BOOL wlf_handle_ungrab_key(freerdp* instance,
const UwacKeyEvent* ev)
348 if (!instance || !instance->context || !ev)
353 return UwacSeatInhibitShortcuts(context->seat,
false) == UWAC_SUCCESS;
356 BOOL wlf_keyboard_enter(freerdp* instance,
const UwacKeyboardEnterLeaveEvent* ev)
358 if (!instance || !ev)
361 ((
wlfContext*)instance->context)->focusing = TRUE;
365 BOOL wlf_keyboard_modifiers(freerdp* instance,
const UwacKeyboardModifiersEvent* ev)
367 rdpInput* input = NULL;
368 UINT16 syncFlags = 0;
371 if (!instance || !ev)
377 input = instance->context->input;
382 if (ev->modifiers & UWAC_MOD_CAPS_MASK)
383 syncFlags |= KBD_SYNC_CAPS_LOCK;
384 if (ev->modifiers & UWAC_MOD_NUM_MASK)
385 syncFlags |= KBD_SYNC_NUM_LOCK;
390 ((
wlfContext*)instance->context)->focusing = FALSE;
392 return freerdp_input_send_focus_in_event(input, syncFlags) &&
393 freerdp_client_send_button_event(&wlf->common, FALSE, PTR_FLAGS_MOVE, 0, 0);
396 BOOL wlf_handle_touch_up(freerdp* instance,
const UwacTouchUp* ev)
401 WINPR_ASSERT(instance);
410 if (!scale_signed_coordinates(instance->context, &x, &y, TRUE))
413 return freerdp_client_handle_touch(&wlf->common, FREERDP_TOUCH_UP, ev->id, 0, x, y);
416 BOOL wlf_handle_touch_down(freerdp* instance,
const UwacTouchDown* ev)
421 WINPR_ASSERT(instance);
430 if (!scale_signed_coordinates(instance->context, &x, &y, TRUE))
433 return freerdp_client_handle_touch(&wlf->common, FREERDP_TOUCH_DOWN, ev->id, 0, x, y);
436 BOOL wlf_handle_touch_motion(freerdp* instance,
const UwacTouchMotion* ev)
441 WINPR_ASSERT(instance);
450 if (!scale_signed_coordinates(instance->context, &x, &y, TRUE))
453 return freerdp_client_handle_touch(&wlf->common, FREERDP_TOUCH_MOTION, 0,
454 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.