21#include <freerdp/config.h>
29#include <winpr/assert.h>
30#include <winpr/path.h>
32#include <freerdp/log.h>
33#include <freerdp/locale/keyboard.h>
37#include "xf_cliprdr.h"
41#include "xf_graphics.h"
47#define TAG CLIENT_TAG("x11")
49#define CLAMP_COORDINATES(x, y) \
58const char* x11_event_string(
int event)
72 return "ButtonRelease";
75 return "MotionNotify";
90 return "KeymapNotify";
96 return "GraphicsExpose";
101 case VisibilityNotify:
102 return "VisibilityNotify";
105 return "CreateNotify";
108 return "DestroyNotify";
111 return "UnmapNotify";
120 return "ReparentNotify";
122 case ConfigureNotify:
123 return "ConfigureNotify";
125 case ConfigureRequest:
126 return "ConfigureRequest";
129 return "GravityNotify";
132 return "ResizeRequest";
134 case CirculateNotify:
135 return "CirculateNotify";
137 case CirculateRequest:
138 return "CirculateRequest";
141 return "PropertyNotify";
144 return "SelectionClear";
146 case SelectionRequest:
147 return "SelectionRequest";
149 case SelectionNotify:
150 return "SelectionNotify";
153 return "ColormapNotify";
156 return "ClientMessage";
159 return "MappingNotify";
162 return "GenericEvent";
169static BOOL xf_action_script_append(xfContext* xfc,
const char* buffer,
size_t size,
170 WINPR_ATTR_UNUSED
void* user,
const char* what,
const char* arg)
176 if (buffer || (size == 0))
179 if (!ArrayList_Append(xfc->xevents, buffer))
181 ArrayList_Clear(xfc->xevents);
187BOOL xf_event_action_script_init(xfContext* xfc)
191 xf_event_action_script_free(xfc);
193 xfc->xevents = ArrayList_New(TRUE);
198 wObject* obj = ArrayList_Object(xfc->xevents);
200 obj->fnObjectNew = winpr_ObjectStringClone;
201 obj->fnObjectFree = winpr_ObjectStringFree;
203 return run_action_script(xfc,
"xevent", NULL, xf_action_script_append, NULL);
206void xf_event_action_script_free(xfContext* xfc)
210 ArrayList_Free(xfc->xevents);
215static BOOL action_script_run(xfContext* xfc,
const char* buffer,
size_t size,
void* user,
216 const char* what,
const char* arg)
226 WLog_WARN(TAG,
"ActionScript xevent: script did not return data");
230 if (winpr_PathFileExists(buffer))
234 winpr_asprintf(&cmd, &cmdlen,
"%s %s %s", buffer, what, arg);
238 FILE* fp = popen(cmd,
"w");
242 WLog_ERR(TAG,
"Failed to execute '%s'", buffer);
246 *pstatus = pclose(fp);
249 WLog_ERR(TAG,
"Command '%s' returned %d", buffer, *pstatus);
255 WLog_WARN(TAG,
"ActionScript xevent: No such file '%s'", buffer);
262static BOOL xf_event_execute_action_script(xfContext* xfc,
const XEvent* event)
267 const char* xeventName = NULL;
269 if (!xfc->actionScriptExists || !xfc->xevents || !xfc->window)
272 if (event->type > LASTEvent)
275 xeventName = x11_event_string(event->type);
276 count = ArrayList_Count(xfc->xevents);
278 for (
size_t index = 0; index < count; index++)
280 name = (
char*)ArrayList_GetItem(xfc->xevents, index);
282 if (_stricmp(name, xeventName) == 0)
292 char command[2048] = { 0 };
293 char arg[2048] = { 0 };
294 (void)_snprintf(command,
sizeof(command),
"xevent %s", xeventName);
295 (void)_snprintf(arg,
sizeof(arg),
"%lu", (
unsigned long)xfc->window->handle);
296 return run_action_script(xfc, command, arg, action_script_run, NULL);
299void xf_adjust_coordinates_to_screen(xfContext* xfc, UINT32* x, UINT32* y)
301 if (!xfc || !xfc->common.context.settings || !y || !x)
304 rdpSettings* settings = xfc->common.context.settings;
307 if (!xfc->remote_app)
311 if (xf_picture_transform_required(xfc))
315 double xScalingFactor = xfc->scaledWidth / dw;
316 double yScalingFactor = xfc->scaledHeight / dh;
317 tx = (INT64)lround((1.0 * (*x) + xfc->offset_x) * xScalingFactor);
318 ty = (INT64)lround((1.0 * (*y) + xfc->offset_y) * yScalingFactor);
324 CLAMP_COORDINATES(tx, ty);
329void xf_event_adjust_coordinates(xfContext* xfc,
int* x,
int* y)
331 if (!xfc || !xfc->common.context.settings || !y || !x)
334 if (!xfc->remote_app)
337 rdpSettings* settings = xfc->common.context.settings;
338 if (xf_picture_transform_required(xfc))
341 (double)xfc->scaledWidth;
343 (double)xfc->scaledHeight;
344 *x = (int)((*x - xfc->offset_x) * xScalingFactor);
345 *y = (int)((*y - xfc->offset_y) * yScalingFactor);
351 CLAMP_COORDINATES(*x, *y);
354static BOOL xf_event_Expose(xfContext* xfc,
const XExposeEvent* event, BOOL app)
360 rdpSettings* settings = NULL;
365 settings = xfc->common.context.settings;
366 WINPR_ASSERT(settings);
373 w = WINPR_ASSERTING_INT_CAST(
int,
375 h = WINPR_ASSERTING_INT_CAST(
int,
388 if (xfc->common.context.gdi->gfx)
391 xfc, WINPR_ASSERTING_INT_CAST(uint32_t, x), WINPR_ASSERTING_INT_CAST(uint32_t, y),
392 WINPR_ASSERTING_INT_CAST(uint32_t, w), WINPR_ASSERTING_INT_CAST(uint32_t, h));
395 xf_draw_screen(xfc, x, y, w, h);
399 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
402 xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
409static BOOL xf_event_VisibilityNotify(xfContext* xfc,
const XVisibilityEvent* event, BOOL app)
412 xfc->unobscured =
event->state == VisibilityUnobscured;
416BOOL xf_generic_MotionNotify(xfContext* xfc,
int x,
int y,
int state, Window window, BOOL app)
418 Window childWindow = None;
421 WINPR_ASSERT(xfc->common.context.settings);
425 if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
432 if (!xf_AppWindowFromX11Window(xfc, window))
436 XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y, &x, &y,
440 xf_event_adjust_coordinates(xfc, &x, &y);
441 freerdp_client_send_button_event(&xfc->common, FALSE, PTR_FLAGS_MOVE, x, y);
443 if (xfc->fullscreen && !app)
446 XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
452BOOL xf_generic_RawMotionNotify(xfContext* xfc,
int x,
int y, WINPR_ATTR_UNUSED Window window,
459 WLog_ERR(TAG,
"Relative mouse input is not supported with remoate app mode!");
463 return freerdp_client_send_button_event(&xfc->common, TRUE, PTR_FLAGS_MOVE, x, y);
466static BOOL xf_event_MotionNotify(xfContext* xfc,
const XMotionEvent* event, BOOL app)
471 xf_floatbar_set_root_y(xfc->window->floatbar, event->y);
474 (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common)))
477 return xf_generic_MotionNotify(xfc, event->x, event->y,
478 WINPR_ASSERTING_INT_CAST(
int, event->state), event->window, app);
481BOOL xf_generic_ButtonEvent(xfContext* xfc,
int x,
int y,
int button, Window window, BOOL app,
485 Window childWindow = None;
491 for (
size_t i = 0; i < ARRAYSIZE(xfc->button_map); i++)
495 if (cur->button == (UINT32)button)
504 if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
507 freerdp_client_send_wheel_event(&xfc->common, flags);
511 BOOL extended = FALSE;
513 if (flags & (PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2))
518 flags |= PTR_XFLAGS_DOWN;
520 else if (flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3))
523 flags |= PTR_FLAGS_DOWN;
529 if (!xf_AppWindowFromX11Window(xfc, window))
533 XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y,
534 &x, &y, &childWindow);
537 xf_event_adjust_coordinates(xfc, &x, &y);
540 freerdp_client_send_extended_button_event(&xfc->common, FALSE, flags, x, y);
542 freerdp_client_send_button_event(&xfc->common, FALSE, flags, x, y);
549static BOOL xf_grab_mouse(xfContext* xfc)
558 XGrabPointer(xfc->display, xfc->window->handle, False,
559 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask |
560 EnterWindowMask | LeaveWindowMask,
561 GrabModeAsync, GrabModeAsync, xfc->window->handle, None, CurrentTime);
562 xfc->common.mouse_grabbed = TRUE;
567static BOOL xf_grab_kbd(xfContext* xfc)
574 XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync,
579static BOOL xf_event_ButtonPress(xfContext* xfc,
const XButtonEvent* event, BOOL app)
584 (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common)))
586 return xf_generic_ButtonEvent(xfc, event->x, event->y,
587 WINPR_ASSERTING_INT_CAST(
int, event->button), event->window, app,
591static BOOL xf_event_ButtonRelease(xfContext* xfc,
const XButtonEvent* event, BOOL app)
596 (xfc->common.mouse_grabbed && freerdp_client_use_relative_mouse_events(&xfc->common)))
598 return xf_generic_ButtonEvent(xfc, event->x, event->y,
599 WINPR_ASSERTING_INT_CAST(
int, event->button), event->window, app,
603static BOOL xf_event_KeyPress(xfContext* xfc,
const XKeyEvent* event, BOOL app)
606 char str[256] = { 0 };
609 const XKeyEvent* cev;
614 XLookupString(cnv.ev, str,
sizeof(str), &keysym, NULL);
615 xf_keyboard_key_press(xfc, event, keysym);
619static BOOL xf_event_KeyRelease(xfContext* xfc,
const XKeyEvent* event, BOOL app)
622 char str[256] = { 0 };
625 const XKeyEvent* cev;
631 XLookupString(cnv.ev, str,
sizeof(str), &keysym, NULL);
632 xf_keyboard_key_release(xfc, event, keysym);
638static BOOL xf_event_KeyReleaseOrIgnore(xfContext* xfc,
const XKeyEvent* event, BOOL app)
643 if ((event->type == KeyRelease) && XEventsQueued(xfc->display, QueuedAfterReading))
646 XPeekEvent(xfc->display, &nev);
648 if ((nev.type == KeyPress) && (nev.xkey.time == event->time) &&
649 (nev.xkey.keycode == event->keycode))
656 return xf_event_KeyRelease(xfc, event, app);
659static BOOL xf_event_FocusIn(xfContext* xfc,
const XFocusInEvent* event, BOOL app)
661 if (event->mode == NotifyGrab)
666 if (xfc->mouse_active && !app)
669 if (!xf_grab_kbd(xfc))
676 xf_keyboard_release_all_keypress(xfc);
678 xf_rail_send_activate(xfc, event->window, TRUE);
680 xf_pointer_update_scale(xfc);
684 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
689 xf_rail_adjust_position(xfc, appWindow);
692 xf_keyboard_focus_in(xfc);
696static BOOL xf_event_FocusOut(xfContext* xfc,
const XFocusOutEvent* event, BOOL app)
698 if (event->mode == NotifyUngrab)
701 xfc->focused = FALSE;
703 if (event->mode == NotifyWhileGrabbed)
704 XUngrabKeyboard(xfc->display, CurrentTime);
706 xf_keyboard_release_all_keypress(xfc);
708 xf_rail_send_activate(xfc, event->window, FALSE);
713static BOOL xf_event_MappingNotify(xfContext* xfc,
const XMappingEvent* event, BOOL app)
717 switch (event->request)
719 case MappingModifier:
720 return xf_keyboard_update_modifier_map(xfc);
721 case MappingKeyboard:
722 WLog_VRB(TAG,
"[%d] MappingKeyboard", event->request);
723 return xf_keyboard_init(xfc);
725 WLog_VRB(TAG,
"[%d] MappingPointer", event->request);
726 xf_button_map_init(xfc);
730 "[%d] Unsupported MappingNotify::request, must be one "
731 "of[MappingModifier(%d), MappingKeyboard(%d), MappingPointer(%d)]",
732 event->request, MappingModifier, MappingKeyboard, MappingPointer);
737static BOOL xf_event_ClientMessage(xfContext* xfc,
const XClientMessageEvent* event, BOOL app)
739 if ((event->message_type == xfc->WM_PROTOCOLS) &&
740 ((Atom)event->data.l[0] == xfc->WM_DELETE_WINDOW))
744 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
747 return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
753 DEBUG_X11(
"Main window closed");
761static BOOL xf_event_EnterNotify(xfContext* xfc,
const XEnterWindowEvent* event, BOOL app)
768 xfc->mouse_active = TRUE;
771 XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
778 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
781 xfc->appWindow = appWindow;
787static BOOL xf_event_LeaveNotify(xfContext* xfc,
const XLeaveWindowEvent* event, BOOL app)
789 if (event->mode == NotifyGrab || event->mode == NotifyUngrab)
793 xfc->mouse_active = FALSE;
794 XUngrabKeyboard(xfc->display, CurrentTime);
798 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
801 if (xfc->appWindow == appWindow)
802 xfc->appWindow = NULL;
807static BOOL xf_event_ConfigureNotify(xfContext* xfc,
const XConfigureEvent* event, BOOL app)
809 Window childWindow = None;
810 xfAppWindow* appWindow = NULL;
815 const rdpSettings* settings = xfc->common.context.settings;
816 WINPR_ASSERT(settings);
818 WLog_DBG(TAG,
"x=%" PRId32
", y=%" PRId32
", w=%" PRId32
", h=%" PRId32, event->x, event->y,
819 event->width, event->height);
826 if (xfc->window->left != event->x)
827 xfc->window->left =
event->x;
829 if (xfc->window->top != event->y)
830 xfc->window->top =
event->y;
832 if (xfc->window->width != event->width || xfc->window->height != event->height)
834 xfc->window->width =
event->width;
835 xfc->window->height =
event->height;
843 xfc->scaledWidth = xfc->window->width;
844 xfc->scaledHeight = xfc->window->height;
847 WINPR_ASSERTING_INT_CAST(
849 WINPR_ASSERTING_INT_CAST(
854 xfc->scaledWidth = WINPR_ASSERTING_INT_CAST(
856 xfc->scaledHeight = WINPR_ASSERTING_INT_CAST(
865 int alignedWidth = 0;
866 int alignedHeight = 0;
867 alignedWidth = (xfc->window->width / 2) * 2;
868 alignedHeight = (xfc->window->height / 2) * 2;
870 xf_disp_handle_configureNotify(xfc, alignedWidth, alignedHeight);
875 appWindow = xf_AppWindowFromX11Window(xfc, event->window);
883 XTranslateCoordinates(xfc->display, appWindow->handle, RootWindowOfScreen(xfc->screen),
884 0, 0, &appWindow->x, &appWindow->y, &childWindow);
885 appWindow->width =
event->width;
886 appWindow->height =
event->height;
888 xf_AppWindowResize(xfc, appWindow);
896 if (appWindow->decorations)
899 xf_rail_adjust_position(xfc, appWindow);
903 if ((!event->send_event || appWindow->local_move.state == LMS_NOT_ACTIVE) &&
904 !appWindow->rail_ignore_configure && xfc->focused)
905 xf_rail_adjust_position(xfc, appWindow);
909 return xf_pointer_update_scale(xfc);
912static BOOL xf_event_MapNotify(xfContext* xfc,
const XMapEvent* event, BOOL app)
916 gdi_send_suppress_output(xfc->common.context.gdi, FALSE);
919 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
929 appWindow->is_mapped = TRUE;
936static BOOL xf_event_UnmapNotify(xfContext* xfc,
const XUnmapEvent* event, BOOL app)
942 xf_keyboard_release_all_keypress(xfc);
945 gdi_send_suppress_output(xfc->common.context.gdi, TRUE);
948 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
951 appWindow->is_mapped = FALSE;
957static BOOL xf_event_PropertyNotify(xfContext* xfc,
const XPropertyEvent* event, BOOL app)
967 if (((event->atom == xfc->NET_WM_STATE) && (event->state != PropertyDelete)) ||
968 ((event->atom == xfc->WM_STATE) && (event->state != PropertyDelete)))
971 BOOL minimized = FALSE;
972 BOOL minimizedChanged = FALSE;
973 unsigned long nitems = 0;
974 unsigned long bytes = 0;
975 unsigned char* prop = NULL;
976 xfAppWindow* appWindow = NULL;
980 appWindow = xf_AppWindowFromX11Window(xfc, event->window);
986 if (event->atom == xfc->NET_WM_STATE)
988 status = xf_GetWindowProperty(xfc, event->window, xfc->NET_WM_STATE, 12, &nitems,
995 appWindow->maxVert = FALSE;
996 appWindow->maxHorz = FALSE;
998 for (
unsigned long i = 0; i < nitems; i++)
1000 if ((Atom)((UINT16**)prop)[i] ==
1001 Logging_XInternAtom(xfc->log, xfc->display,
"_NET_WM_STATE_MAXIMIZED_VERT",
1005 appWindow->maxVert = TRUE;
1008 if ((Atom)((UINT16**)prop)[i] ==
1009 Logging_XInternAtom(xfc->log, xfc->display,
"_NET_WM_STATE_MAXIMIZED_HORZ",
1013 appWindow->maxHorz = TRUE;
1021 if (event->atom == xfc->WM_STATE)
1024 xf_GetWindowProperty(xfc, event->window, xfc->WM_STATE, 1, &nitems, &bytes, &prop);
1029 if (((UINT32)*prop == 3) && !IsGnome())
1033 appWindow->minimized = TRUE;
1039 appWindow->minimized = FALSE;
1042 minimizedChanged = TRUE;
1049 WINPR_ASSERT(appWindow);
1050 if (appWindow->maxVert && appWindow->maxHorz && !appWindow->minimized)
1052 if (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED)
1054 appWindow->rail_state = WINDOW_SHOW_MAXIMIZED;
1055 return xf_rail_send_client_system_command(xfc, appWindow->windowId,
1059 else if (appWindow->minimized)
1061 if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
1063 appWindow->rail_state = WINDOW_SHOW_MINIMIZED;
1064 return xf_rail_send_client_system_command(xfc, appWindow->windowId,
1070 if (appWindow->rail_state != WINDOW_SHOW && appWindow->rail_state != WINDOW_HIDE)
1072 appWindow->rail_state = WINDOW_SHOW;
1073 return xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
1077 else if (minimizedChanged)
1078 gdi_send_suppress_output(xfc->common.context.gdi, minimized);
1084static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow,
const XEvent* event)
1086 if (!xfc->remote_app)
1089 switch (appWindow->local_move.state)
1091 case LMS_NOT_ACTIVE:
1097 if ((event->type == ConfigureNotify) && appWindow->rail_ignore_configure)
1099 appWindow->rail_ignore_configure = FALSE;
1109 switch (event->type)
1111 case ConfigureNotify:
1114 appWindow->local_move.state = LMS_ACTIVE;
1131 case VisibilityNotify:
1132 case PropertyNotify:
1147 switch (event->type)
1149 case ConfigureNotify:
1150 case VisibilityNotify:
1151 case PropertyNotify:
1159 xf_rail_end_local_move(xfc, appWindow);
1165 case LMS_TERMINATING:
1175BOOL xf_event_process(freerdp* instance,
const XEvent* event)
1179 WINPR_ASSERT(instance);
1180 WINPR_ASSERT(event);
1182 xfContext* xfc = (xfContext*)instance->context;
1185 rdpSettings* settings = xfc->common.context.settings;
1186 WINPR_ASSERT(settings);
1188 if (xfc->remote_app)
1190 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
1195 xfc->appWindow = appWindow;
1197 if (xf_event_suppress_events(xfc, appWindow, event))
1204 xfFloatbar* floatbar = xfc->window->floatbar;
1205 if (xf_floatbar_check_event(floatbar, event))
1207 xf_floatbar_event_process(floatbar, event);
1211 if (xf_floatbar_is_locked(floatbar))
1214 switch (event->type)
1232 xf_event_execute_action_script(xfc, event);
1234 if (event->type != MotionNotify)
1236 DEBUG_X11(
"%s Event(%d): wnd=0x%08lX", x11_event_string(event->type), event->type,
1237 (
unsigned long)event->xany.window);
1240 switch (event->type)
1243 status = xf_event_Expose(xfc, &event->xexpose, xfc->remote_app);
1246 case VisibilityNotify:
1247 status = xf_event_VisibilityNotify(xfc, &event->xvisibility, xfc->remote_app);
1251 status = xf_event_MotionNotify(xfc, &event->xmotion, xfc->remote_app);
1255 status = xf_event_ButtonPress(xfc, &event->xbutton, xfc->remote_app);
1259 status = xf_event_ButtonRelease(xfc, &event->xbutton, xfc->remote_app);
1263 status = xf_event_KeyPress(xfc, &event->xkey, xfc->remote_app);
1267 status = xf_event_KeyReleaseOrIgnore(xfc, &event->xkey, xfc->remote_app);
1271 status = xf_event_FocusIn(xfc, &event->xfocus, xfc->remote_app);
1275 status = xf_event_FocusOut(xfc, &event->xfocus, xfc->remote_app);
1279 status = xf_event_EnterNotify(xfc, &event->xcrossing, xfc->remote_app);
1283 status = xf_event_LeaveNotify(xfc, &event->xcrossing, xfc->remote_app);
1289 case GraphicsExpose:
1292 case ConfigureNotify:
1293 status = xf_event_ConfigureNotify(xfc, &event->xconfigure, xfc->remote_app);
1297 status = xf_event_MapNotify(xfc, &event->xmap, xfc->remote_app);
1301 status = xf_event_UnmapNotify(xfc, &event->xunmap, xfc->remote_app);
1304 case ReparentNotify:
1308 status = xf_event_MappingNotify(xfc, &event->xmapping, xfc->remote_app);
1312 status = xf_event_ClientMessage(xfc, &event->xclient, xfc->remote_app);
1315 case PropertyNotify:
1316 status = xf_event_PropertyNotify(xfc, &event->xproperty, xfc->remote_app);
1321 xf_disp_handle_xevent(xfc, event);
1326 xfWindow* window = xfc->window;
1327 xfFloatbar* floatbar = NULL;
1329 floatbar = window->floatbar;
1331 xf_cliprdr_handle_xevent(xfc, event);
1332 if (!xf_floatbar_check_event(floatbar, event) && !xf_floatbar_is_locked(floatbar))
1333 xf_input_handle_event(xfc, event);
1335 XSync(xfc->display, FALSE);
1339BOOL xf_generic_RawButtonEvent(xfContext* xfc,
int button, BOOL app, BOOL down)
1343 if (app || (button < 0))
1346 for (
size_t i = 0; i < ARRAYSIZE(xfc->button_map); i++)
1350 if (cur->button == (UINT32)button)
1359 if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
1362 freerdp_client_send_wheel_event(&xfc->common, flags);
1366 BOOL extended = FALSE;
1368 if (flags & (PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2))
1373 flags |= PTR_XFLAGS_DOWN;
1375 else if (flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3))
1378 flags |= PTR_FLAGS_DOWN;
1382 freerdp_client_send_extended_button_event(&xfc->common, TRUE, flags, 0, 0);
1384 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.