21 #include <freerdp/config.h>
24 #include <X11/Xutil.h>
29 #include <winpr/assert.h>
30 #include <winpr/path.h>
32 #include <freerdp/log.h>
33 #include <freerdp/locale/keyboard.h>
36 #include "xf_window.h"
37 #include "xf_cliprdr.h"
41 #include "xf_graphics.h"
46 #define TAG CLIENT_TAG("x11")
48 #define CLAMP_COORDINATES(x, y) \
57 const char* x11_event_string(
int event)
71 return "ButtonRelease";
74 return "MotionNotify";
89 return "KeymapNotify";
95 return "GraphicsExpose";
100 case VisibilityNotify:
101 return "VisibilityNotify";
104 return "CreateNotify";
107 return "DestroyNotify";
110 return "UnmapNotify";
119 return "ReparentNotify";
121 case ConfigureNotify:
122 return "ConfigureNotify";
124 case ConfigureRequest:
125 return "ConfigureRequest";
128 return "GravityNotify";
131 return "ResizeRequest";
133 case CirculateNotify:
134 return "CirculateNotify";
136 case CirculateRequest:
137 return "CirculateRequest";
140 return "PropertyNotify";
143 return "SelectionClear";
145 case SelectionRequest:
146 return "SelectionRequest";
148 case SelectionNotify:
149 return "SelectionNotify";
152 return "ColormapNotify";
155 return "ClientMessage";
158 return "MappingNotify";
161 return "GenericEvent";
168 #ifdef WITH_DEBUG_X11
169 #define DEBUG_X11(...) WLog_DBG(TAG, __VA_ARGS__)
171 #define DEBUG_X11(...) \
177 static BOOL xf_action_script_append(xfContext* xfc,
const char* buffer,
size_t size,
void* user,
178 const char* what,
const char* arg)
184 if (buffer || (size == 0))
187 if (!ArrayList_Append(xfc->xevents, buffer))
189 ArrayList_Clear(xfc->xevents);
195 BOOL xf_event_action_script_init(xfContext* xfc)
198 const rdpSettings* settings = NULL;
202 settings = xfc->common.context.settings;
203 WINPR_ASSERT(settings);
205 xfc->xevents = ArrayList_New(TRUE);
210 obj = ArrayList_Object(xfc->xevents);
212 obj->fnObjectNew = winpr_ObjectStringClone;
213 obj->fnObjectFree = winpr_ObjectStringFree;
215 if (!run_action_script(xfc,
"xevent", NULL, xf_action_script_append, NULL))
221 void xf_event_action_script_free(xfContext* xfc)
225 ArrayList_Free(xfc->xevents);
230 static BOOL action_script_run(xfContext* xfc,
const char* buffer,
size_t size,
void* user,
231 const char* what,
const char* arg)
241 WLog_WARN(TAG,
"ActionScript xevent: script did not return data");
245 if (winpr_PathFileExists(buffer))
249 winpr_asprintf(&cmd, &cmdlen,
"%s %s %s", buffer, what, arg);
253 FILE* fp = popen(cmd,
"w");
257 WLog_ERR(TAG,
"Failed to execute '%s'", buffer);
261 *pstatus = pclose(fp);
264 WLog_ERR(TAG,
"Command '%s' returned %d", buffer, *pstatus);
270 WLog_WARN(TAG,
"ActionScript xevent: No such file '%s'", buffer);
277 static BOOL xf_event_execute_action_script(xfContext* xfc,
const XEvent* event)
282 const char* xeventName = NULL;
284 if (!xfc->actionScriptExists || !xfc->xevents || !xfc->window)
287 if (event->type > LASTEvent)
290 xeventName = x11_event_string(event->type);
291 count = ArrayList_Count(xfc->xevents);
293 for (
size_t index = 0; index < count; index++)
295 name = (
char*)ArrayList_GetItem(xfc->xevents, index);
297 if (_stricmp(name, xeventName) == 0)
307 char command[2048] = { 0 };
308 char arg[2048] = { 0 };
309 (void)_snprintf(command,
sizeof(command),
"xevent %s", xeventName);
310 (void)_snprintf(arg,
sizeof(arg),
"%lu", (
unsigned long)xfc->window->handle);
311 if (!run_action_script(xfc, command, arg, action_script_run, NULL))
316 void xf_adjust_coordinates_to_screen(xfContext* xfc, UINT32* x, UINT32* y)
318 if (!xfc || !xfc->common.context.settings || !y || !x)
321 rdpSettings* settings = xfc->common.context.settings;
324 if (!xfc->remote_app)
328 if (xf_picture_transform_required(xfc))
332 double xScalingFactor = xfc->scaledWidth / dw;
333 double yScalingFactor = xfc->scaledHeight / dh;
334 tx = (INT64)lround((1.0 * (*x) + xfc->offset_x) * xScalingFactor);
335 ty = (INT64)lround((1.0 * (*y) + xfc->offset_y) * yScalingFactor);
341 CLAMP_COORDINATES(tx, ty);
346 void xf_event_adjust_coordinates(xfContext* xfc,
int* x,
int* y)
348 if (!xfc || !xfc->common.context.settings || !y || !x)
351 if (!xfc->remote_app)
354 rdpSettings* settings = xfc->common.context.settings;
355 if (xf_picture_transform_required(xfc))
358 (double)xfc->scaledWidth;
360 (double)xfc->scaledHeight;
361 *x = (
int)((*x - xfc->offset_x) * xScalingFactor);
362 *y = (int)((*y - xfc->offset_y) * yScalingFactor);
368 CLAMP_COORDINATES(*x, *y);
371 static BOOL xf_event_Expose(xfContext* xfc,
const XExposeEvent* event, BOOL app)
377 rdpSettings* settings = NULL;
382 settings = xfc->common.context.settings;
383 WINPR_ASSERT(settings);
390 w = WINPR_ASSERTING_INT_CAST(
int,
392 h = WINPR_ASSERTING_INT_CAST(
int,
405 if (xfc->common.context.gdi->gfx)
408 xfc, WINPR_ASSERTING_INT_CAST(uint32_t, x), WINPR_ASSERTING_INT_CAST(uint32_t, y),
409 WINPR_ASSERTING_INT_CAST(uint32_t, w), WINPR_ASSERTING_INT_CAST(uint32_t, h));
412 xf_draw_screen(xfc, x, y, w, h);
416 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
419 xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
426 static BOOL xf_event_VisibilityNotify(xfContext* xfc,
const XVisibilityEvent* event, BOOL app)
429 xfc->unobscured =
event->state == VisibilityUnobscured;
433 BOOL xf_generic_MotionNotify(xfContext* xfc,
int x,
int y,
int state, Window window, BOOL app)
435 Window childWindow = None;
438 WINPR_ASSERT(xfc->common.context.settings);
442 if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
449 if (!xf_AppWindowFromX11Window(xfc, window))
453 XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y, &x, &y,
457 xf_event_adjust_coordinates(xfc, &x, &y);
458 freerdp_client_send_button_event(&xfc->common, FALSE, PTR_FLAGS_MOVE, x, y);
460 if (xfc->fullscreen && !app)
462 XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
468 BOOL xf_generic_RawMotionNotify(xfContext* xfc,
int x,
int y, Window window, BOOL app)
474 WLog_ERR(TAG,
"Relative mouse input is not supported with remoate app mode!");
478 return freerdp_client_send_button_event(&xfc->common, TRUE, PTR_FLAGS_MOVE, x, y);
481 static BOOL xf_event_MotionNotify(xfContext* xfc,
const XMotionEvent* event, BOOL app)
486 xf_floatbar_set_root_y(xfc->window->floatbar, event->y);
489 (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common)))
492 return xf_generic_MotionNotify(xfc, event->x, event->y,
493 WINPR_ASSERTING_INT_CAST(
int, event->state), event->window, app);
496 BOOL xf_generic_ButtonEvent(xfContext* xfc,
int x,
int y,
int button, Window window, BOOL app,
500 Window childWindow = None;
506 for (
size_t i = 0; i < ARRAYSIZE(xfc->button_map); i++)
510 if (cur->button == (UINT32)button)
519 if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
522 freerdp_client_send_wheel_event(&xfc->common, flags);
526 BOOL extended = FALSE;
528 if (flags & (PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2))
533 flags |= PTR_XFLAGS_DOWN;
535 else if (flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3))
538 flags |= PTR_FLAGS_DOWN;
544 if (!xf_AppWindowFromX11Window(xfc, window))
548 XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y,
549 &x, &y, &childWindow);
552 xf_event_adjust_coordinates(xfc, &x, &y);
555 freerdp_client_send_extended_button_event(&xfc->common, FALSE, flags, x, y);
557 freerdp_client_send_button_event(&xfc->common, FALSE, flags, x, y);
564 static BOOL xf_grab_mouse(xfContext* xfc)
573 XGrabPointer(xfc->display, xfc->window->handle, False,
574 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask |
575 EnterWindowMask | LeaveWindowMask,
576 GrabModeAsync, GrabModeAsync, xfc->window->handle, None, CurrentTime);
577 xfc->common.mouse_grabbed = TRUE;
582 static BOOL xf_grab_kbd(xfContext* xfc)
589 XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync,
594 static BOOL xf_event_ButtonPress(xfContext* xfc,
const XButtonEvent* event, BOOL app)
599 (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common)))
601 return xf_generic_ButtonEvent(xfc, event->x, event->y,
602 WINPR_ASSERTING_INT_CAST(
int, event->button), event->window, app,
606 static BOOL xf_event_ButtonRelease(xfContext* xfc,
const XButtonEvent* event, BOOL app)
611 (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common)))
613 return xf_generic_ButtonEvent(xfc, event->x, event->y,
614 WINPR_ASSERTING_INT_CAST(
int, event->button), event->window, app,
618 static BOOL xf_event_KeyPress(xfContext* xfc,
const XKeyEvent* event, BOOL app)
621 char str[256] = { 0 };
624 const XKeyEvent* cev;
629 XLookupString(cnv.ev, str,
sizeof(str), &keysym, NULL);
630 xf_keyboard_key_press(xfc, event, keysym);
634 static BOOL xf_event_KeyRelease(xfContext* xfc,
const XKeyEvent* event, BOOL app)
637 char str[256] = { 0 };
640 const XKeyEvent* cev;
646 XLookupString(cnv.ev, str,
sizeof(str), &keysym, NULL);
647 xf_keyboard_key_release(xfc, event, keysym);
653 static BOOL xf_event_KeyReleaseOrIgnore(xfContext* xfc,
const XKeyEvent* event, BOOL app)
658 if ((event->type == KeyRelease) && XEventsQueued(xfc->display, QueuedAfterReading))
661 XPeekEvent(xfc->display, &nev);
663 if ((nev.type == KeyPress) && (nev.xkey.time == event->time) &&
664 (nev.xkey.keycode == event->keycode))
671 return xf_event_KeyRelease(xfc, event, app);
674 static BOOL xf_event_FocusIn(xfContext* xfc,
const XFocusInEvent* event, BOOL app)
676 if (event->mode == NotifyGrab)
681 if (xfc->mouse_active && !app)
684 if (!xf_grab_kbd(xfc))
691 xf_keyboard_release_all_keypress(xfc);
693 xf_rail_send_activate(xfc, event->window, TRUE);
695 xf_pointer_update_scale(xfc);
699 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
704 xf_rail_adjust_position(xfc, appWindow);
707 xf_keyboard_focus_in(xfc);
711 static BOOL xf_event_FocusOut(xfContext* xfc,
const XFocusOutEvent* event, BOOL app)
713 if (event->mode == NotifyUngrab)
716 xfc->focused = FALSE;
718 if (event->mode == NotifyWhileGrabbed)
719 XUngrabKeyboard(xfc->display, CurrentTime);
721 xf_keyboard_release_all_keypress(xfc);
723 xf_rail_send_activate(xfc, event->window, FALSE);
728 static BOOL xf_event_MappingNotify(xfContext* xfc,
const XMappingEvent* event, BOOL app)
732 if (event->request == MappingModifier)
733 return xf_keyboard_update_modifier_map(xfc);
738 static BOOL xf_event_ClientMessage(xfContext* xfc,
const XClientMessageEvent* event, BOOL app)
740 if ((event->message_type == xfc->WM_PROTOCOLS) &&
741 ((Atom)event->data.l[0] == xfc->WM_DELETE_WINDOW))
745 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
748 return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
754 DEBUG_X11(
"Main window closed");
762 static BOOL xf_event_EnterNotify(xfContext* xfc,
const XEnterWindowEvent* event, BOOL app)
769 xfc->mouse_active = TRUE;
772 XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
779 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
782 xfc->appWindow = appWindow;
788 static BOOL xf_event_LeaveNotify(xfContext* xfc,
const XLeaveWindowEvent* event, BOOL app)
790 if (event->mode == NotifyGrab || event->mode == NotifyUngrab)
794 xfc->mouse_active = FALSE;
795 XUngrabKeyboard(xfc->display, CurrentTime);
799 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
802 if (xfc->appWindow == appWindow)
803 xfc->appWindow = NULL;
808 static BOOL xf_event_ConfigureNotify(xfContext* xfc,
const XConfigureEvent* event, BOOL app)
810 Window childWindow = None;
811 xfAppWindow* appWindow = NULL;
816 const rdpSettings* settings = xfc->common.context.settings;
817 WINPR_ASSERT(settings);
819 WLog_DBG(TAG,
"x=%" PRId32
", y=%" PRId32
", w=%" PRId32
", h=%" PRId32, event->x, event->y,
820 event->width, event->height);
827 if (xfc->window->left != event->x)
828 xfc->window->left =
event->x;
830 if (xfc->window->top != event->y)
831 xfc->window->top =
event->y;
833 if (xfc->window->width != event->width || xfc->window->height != event->height)
835 xfc->window->width =
event->width;
836 xfc->window->height =
event->height;
844 xfc->scaledWidth = xfc->window->width;
845 xfc->scaledHeight = xfc->window->height;
848 WINPR_ASSERTING_INT_CAST(
850 WINPR_ASSERTING_INT_CAST(
855 xfc->scaledWidth = WINPR_ASSERTING_INT_CAST(
857 xfc->scaledHeight = WINPR_ASSERTING_INT_CAST(
866 int alignedWidth = 0;
867 int alignedHeight = 0;
868 alignedWidth = (xfc->window->width / 2) * 2;
869 alignedHeight = (xfc->window->height / 2) * 2;
871 xf_disp_handle_configureNotify(xfc, alignedWidth, alignedHeight);
876 appWindow = xf_AppWindowFromX11Window(xfc, event->window);
884 XTranslateCoordinates(xfc->display, appWindow->handle, RootWindowOfScreen(xfc->screen),
885 0, 0, &appWindow->x, &appWindow->y, &childWindow);
886 appWindow->width =
event->width;
887 appWindow->height =
event->height;
889 xf_AppWindowResize(xfc, appWindow);
897 if (appWindow->decorations)
900 xf_rail_adjust_position(xfc, appWindow);
904 if ((!event->send_event || appWindow->local_move.state == LMS_NOT_ACTIVE) &&
905 !appWindow->rail_ignore_configure && xfc->focused)
906 xf_rail_adjust_position(xfc, appWindow);
910 return xf_pointer_update_scale(xfc);
913 static BOOL xf_event_MapNotify(xfContext* xfc,
const XMapEvent* event, BOOL app)
917 gdi_send_suppress_output(xfc->common.context.gdi, FALSE);
920 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
930 appWindow->is_mapped = TRUE;
937 static BOOL xf_event_UnmapNotify(xfContext* xfc,
const XUnmapEvent* event, BOOL app)
943 xf_keyboard_release_all_keypress(xfc);
946 gdi_send_suppress_output(xfc->common.context.gdi, TRUE);
949 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
952 appWindow->is_mapped = FALSE;
958 static BOOL xf_event_PropertyNotify(xfContext* xfc,
const XPropertyEvent* event, BOOL app)
968 if (((event->atom == xfc->_NET_WM_STATE) && (event->state != PropertyDelete)) ||
969 ((event->atom == xfc->WM_STATE) && (event->state != PropertyDelete)))
972 BOOL minimized = FALSE;
973 BOOL minimizedChanged = FALSE;
974 unsigned long nitems = 0;
975 unsigned long bytes = 0;
976 unsigned char* prop = NULL;
977 xfAppWindow* appWindow = NULL;
981 appWindow = xf_AppWindowFromX11Window(xfc, event->window);
987 if (event->atom == xfc->_NET_WM_STATE)
989 status = xf_GetWindowProperty(xfc, event->window, xfc->_NET_WM_STATE, 12, &nitems,
996 appWindow->maxVert = FALSE;
997 appWindow->maxHorz = FALSE;
999 for (
unsigned long i = 0; i < nitems; i++)
1001 if ((Atom)((UINT16**)prop)[i] ==
1002 Logging_XInternAtom(xfc->log, xfc->display,
"_NET_WM_STATE_MAXIMIZED_VERT",
1006 appWindow->maxVert = TRUE;
1009 if ((Atom)((UINT16**)prop)[i] ==
1010 Logging_XInternAtom(xfc->log, xfc->display,
"_NET_WM_STATE_MAXIMIZED_HORZ",
1014 appWindow->maxHorz = TRUE;
1022 if (event->atom == xfc->WM_STATE)
1025 xf_GetWindowProperty(xfc, event->window, xfc->WM_STATE, 1, &nitems, &bytes, &prop);
1030 if (((UINT32)*prop == 3) && !IsGnome())
1034 appWindow->minimized = TRUE;
1040 appWindow->minimized = FALSE;
1043 minimizedChanged = TRUE;
1050 WINPR_ASSERT(appWindow);
1051 if (appWindow->maxVert && appWindow->maxHorz && !appWindow->minimized)
1053 if (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED)
1055 appWindow->rail_state = WINDOW_SHOW_MAXIMIZED;
1056 return xf_rail_send_client_system_command(xfc, appWindow->windowId,
1060 else if (appWindow->minimized)
1062 if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
1064 appWindow->rail_state = WINDOW_SHOW_MINIMIZED;
1065 return xf_rail_send_client_system_command(xfc, appWindow->windowId,
1071 if (appWindow->rail_state != WINDOW_SHOW && appWindow->rail_state != WINDOW_HIDE)
1073 appWindow->rail_state = WINDOW_SHOW;
1074 return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
1078 else if (minimizedChanged)
1079 gdi_send_suppress_output(xfc->common.context.gdi, minimized);
1085 static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow,
const XEvent* event)
1087 if (!xfc->remote_app)
1090 switch (appWindow->local_move.state)
1092 case LMS_NOT_ACTIVE:
1098 if ((event->type == ConfigureNotify) && appWindow->rail_ignore_configure)
1100 appWindow->rail_ignore_configure = FALSE;
1110 switch (event->type)
1112 case ConfigureNotify:
1115 appWindow->local_move.state = LMS_ACTIVE;
1132 case VisibilityNotify:
1133 case PropertyNotify:
1148 switch (event->type)
1150 case ConfigureNotify:
1151 case VisibilityNotify:
1152 case PropertyNotify:
1160 xf_rail_end_local_move(xfc, appWindow);
1166 case LMS_TERMINATING:
1176 BOOL xf_event_process(freerdp* instance,
const XEvent* event)
1180 WINPR_ASSERT(instance);
1181 WINPR_ASSERT(event);
1183 xfContext* xfc = (xfContext*)instance->context;
1186 rdpSettings* settings = xfc->common.context.settings;
1187 WINPR_ASSERT(settings);
1189 if (xfc->remote_app)
1191 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
1196 xfc->appWindow = appWindow;
1198 if (xf_event_suppress_events(xfc, appWindow, event))
1205 xfFloatbar* floatbar = xfc->window->floatbar;
1206 if (xf_floatbar_check_event(floatbar, event))
1208 xf_floatbar_event_process(floatbar, event);
1212 if (xf_floatbar_is_locked(floatbar))
1216 xf_event_execute_action_script(xfc, event);
1218 if (event->type != MotionNotify)
1220 DEBUG_X11(
"%s Event(%d): wnd=0x%08lX", x11_event_string(event->type), event->type,
1221 (
unsigned long)event->xany.window);
1224 switch (event->type)
1227 status = xf_event_Expose(xfc, &event->xexpose, xfc->remote_app);
1230 case VisibilityNotify:
1231 status = xf_event_VisibilityNotify(xfc, &event->xvisibility, xfc->remote_app);
1235 status = xf_event_MotionNotify(xfc, &event->xmotion, xfc->remote_app);
1239 status = xf_event_ButtonPress(xfc, &event->xbutton, xfc->remote_app);
1243 status = xf_event_ButtonRelease(xfc, &event->xbutton, xfc->remote_app);
1247 status = xf_event_KeyPress(xfc, &event->xkey, xfc->remote_app);
1251 status = xf_event_KeyReleaseOrIgnore(xfc, &event->xkey, xfc->remote_app);
1255 status = xf_event_FocusIn(xfc, &event->xfocus, xfc->remote_app);
1259 status = xf_event_FocusOut(xfc, &event->xfocus, xfc->remote_app);
1263 status = xf_event_EnterNotify(xfc, &event->xcrossing, xfc->remote_app);
1267 status = xf_event_LeaveNotify(xfc, &event->xcrossing, xfc->remote_app);
1273 case GraphicsExpose:
1276 case ConfigureNotify:
1277 status = xf_event_ConfigureNotify(xfc, &event->xconfigure, xfc->remote_app);
1281 status = xf_event_MapNotify(xfc, &event->xmap, xfc->remote_app);
1285 status = xf_event_UnmapNotify(xfc, &event->xunmap, xfc->remote_app);
1288 case ReparentNotify:
1292 status = xf_event_MappingNotify(xfc, &event->xmapping, xfc->remote_app);
1296 status = xf_event_ClientMessage(xfc, &event->xclient, xfc->remote_app);
1299 case PropertyNotify:
1300 status = xf_event_PropertyNotify(xfc, &event->xproperty, xfc->remote_app);
1305 xf_disp_handle_xevent(xfc, event);
1310 xfWindow* window = xfc->window;
1311 xfFloatbar* floatbar = NULL;
1313 floatbar = window->floatbar;
1315 xf_cliprdr_handle_xevent(xfc, event);
1316 if (!xf_floatbar_check_event(floatbar, event) && !xf_floatbar_is_locked(floatbar))
1317 xf_input_handle_event(xfc, event);
1319 XSync(xfc->display, FALSE);
1323 BOOL xf_generic_RawButtonEvent(xfContext* xfc,
int button, BOOL app, BOOL down)
1327 if (app || (button < 0))
1330 for (
size_t i = 0; i < ARRAYSIZE(xfc->button_map); i++)
1334 if (cur->button == (UINT32)button)
1343 if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
1346 freerdp_client_send_wheel_event(&xfc->common, flags);
1350 BOOL extended = FALSE;
1352 if (flags & (PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2))
1357 flags |= PTR_XFLAGS_DOWN;
1359 else if (flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3))
1362 flags |= PTR_FLAGS_DOWN;
1366 freerdp_client_send_extended_button_event(&xfc->common, TRUE, flags, 0, 0);
1368 freerdp_client_send_button_event(&xfc->common, TRUE, flags, 0, 0);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
This struct contains function pointer to initialize/free objects.