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 CLAMP_COORDINATES(x, y) \
56static const DWORD mouseLogLevel = WLOG_TRACE;
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 char* val = getConfigOption(TRUE,
"isActionScriptAllowed");
196 xfc->isActionScriptAllowed = !val || (_stricmp(val,
"true") == 0);
199 if (!xfc->isActionScriptAllowed)
202 xfc->xevents = ArrayList_New(TRUE);
207 wObject* obj = ArrayList_Object(xfc->xevents);
212 return run_action_script(xfc,
"xevent",
nullptr, xf_action_script_append,
nullptr);
215void xf_event_action_script_free(xfContext* xfc)
219 ArrayList_Free(xfc->xevents);
220 xfc->xevents =
nullptr;
224static BOOL action_script_run(xfContext* xfc,
const char* buffer,
size_t size,
void* user,
225 const char* what,
const char* arg)
228 if (!xfc->isActionScriptAllowed)
238 WLog_Print(xfc->log, WLOG_WARN,
"ActionScript xevent: script did not return data");
242 if (winpr_PathFileExists(buffer))
246 winpr_asprintf(&cmd, &cmdlen,
"%s %s %s", buffer, what, arg);
251 FILE* fp = popen(cmd,
"w");
255 WLog_Print(xfc->log, WLOG_ERROR,
"Failed to execute '%s'", buffer);
259 *pstatus = pclose(fp);
262 WLog_Print(xfc->log, WLOG_ERROR,
"Command '%s' returned %d", buffer, *pstatus);
268 WLog_Print(xfc->log, WLOG_WARN,
"ActionScript xevent: No such file '%s'", buffer);
275static BOOL xf_event_execute_action_script(xfContext* xfc,
const XEvent* event)
278 char* name =
nullptr;
280 const char* xeventName =
nullptr;
282 if (!xfc->actionScriptExists || !xfc->xevents || !xfc->window)
285 if (event->type > LASTEvent)
288 xeventName = x11_event_string(event->type);
289 count = ArrayList_Count(xfc->xevents);
291 for (
size_t index = 0; index < count; index++)
293 name = (
char*)ArrayList_GetItem(xfc->xevents, index);
295 if (_stricmp(name, xeventName) == 0)
305 char command[2048] = WINPR_C_ARRAY_INIT;
306 char arg[2048] = WINPR_C_ARRAY_INIT;
307 (void)_snprintf(command,
sizeof(command),
"xevent %s", xeventName);
308 (void)_snprintf(arg,
sizeof(arg),
"%lu", (
unsigned long)xfc->window->handle);
309 return run_action_script(xfc, command, arg, action_script_run,
nullptr);
312void xf_adjust_coordinates_to_screen(xfContext* xfc, UINT32* x, UINT32* y)
314 if (!xfc || !xfc->common.context.settings || !y || !x)
317 rdpSettings* settings = xfc->common.context.settings;
320 if (!xfc->remote_app)
324 if (xf_picture_transform_required(xfc))
328 double xScalingFactor = xfc->scaledWidth / dw;
329 double yScalingFactor = xfc->scaledHeight / dh;
330 tx = (INT64)lround((1.0 * (*x) + xfc->offset_x) * xScalingFactor);
331 ty = (INT64)lround((1.0 * (*y) + xfc->offset_y) * yScalingFactor);
337 CLAMP_COORDINATES(tx, ty);
342void xf_event_adjust_coordinates(xfContext* xfc,
int* x,
int* y)
344 if (!xfc || !xfc->common.context.settings || !y || !x)
347 if (!xfc->remote_app)
350 rdpSettings* settings = xfc->common.context.settings;
351 if (xf_picture_transform_required(xfc))
354 (double)xfc->scaledWidth;
356 (double)xfc->scaledHeight;
357 *x = (int)((*x - xfc->offset_x) * xScalingFactor);
358 *y = (int)((*y - xfc->offset_y) * yScalingFactor);
364 CLAMP_COORDINATES(*x, *y);
367static BOOL xf_event_Expose(xfContext* xfc,
const XExposeEvent* event, BOOL app)
372 rdpSettings* settings = xfc->common.context.settings;
373 WINPR_ASSERT(settings);
378 xfc->exposedArea.x = 0;
379 xfc->exposedArea.y = 0;
380 xfc->exposedArea.w = WINPR_ASSERTING_INT_CAST(
382 xfc->exposedArea.h = WINPR_ASSERTING_INT_CAST(
387 xfc->exposedArea.x =
event->x;
388 xfc->exposedArea.y =
event->y;
389 xfc->exposedArea.w =
event->width;
390 xfc->exposedArea.h =
event->height;
393 xfc->exposedWindow =
event->window;
394 xfc->exposeRequested =
true;
399static BOOL xf_event_VisibilityNotify(xfContext* xfc,
const XVisibilityEvent* event, BOOL app)
402 xfc->unobscured =
event->state == VisibilityUnobscured;
406BOOL xf_generic_MotionNotify_(xfContext* xfc,
int x,
int y, Window window, BOOL app,
407 const char* file,
const char* fkt,
size_t line)
409 Window childWindow = None;
411 if (WLog_IsLevelActive(xfc->log, mouseLogLevel))
412 WLog_PrintTextMessage(xfc->log, mouseLogLevel, line, file, fkt,
413 "%s: x=%d, y=%d, window=0x%08lx, app=%d", __func__, x, y, window,
417 WINPR_ASSERT(xfc->common.context.settings);
422 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
423 xf_rail_return_window(appWindow, FALSE);
428 XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y, &x, &y,
432 xf_event_adjust_coordinates(xfc, &x, &y);
433 freerdp_client_send_button_event(&xfc->common, FALSE, PTR_FLAGS_MOVE, x, y);
435 if (xfc->fullscreen && !app)
438 XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
444BOOL xf_generic_RawMotionNotify_(xfContext* xfc,
int x,
int y, WINPR_ATTR_UNUSED Window window,
445 BOOL app,
const char* file,
const char* fkt,
size_t line)
449 if (WLog_IsLevelActive(xfc->log, mouseLogLevel))
450 WLog_PrintTextMessage(xfc->log, mouseLogLevel, line, file, fkt,
451 "%s: x=%d, y=%d, window=0x%08lx, app=%d", __func__, x, y, window,
456 WLog_Print(xfc->log, WLOG_ERROR,
457 "Relative mouse input is not supported with remoate app mode!");
461 return freerdp_client_send_button_event(&xfc->common, TRUE, PTR_FLAGS_MOVE, x, y);
464static BOOL xf_event_MotionNotify(xfContext* xfc,
const XMotionEvent* event, BOOL app)
469 xf_floatbar_set_root_y(xfc->window->floatbar, event->y);
471 if (xfc->xi_event || xfc->xi_rawevent || (xfc->common.mouse_grabbed && xf_use_rel_mouse(xfc)))
474 return xf_generic_MotionNotify(xfc, event->x, event->y, event->window, app);
477BOOL xf_generic_ButtonEvent_(xfContext* xfc,
int x,
int y,
int button, Window window, BOOL app,
478 BOOL down,
const char* file,
const char* fkt,
size_t line)
481 Window childWindow = None;
483 if (WLog_IsLevelActive(xfc->log, mouseLogLevel))
484 WLog_PrintTextMessage(xfc->log, mouseLogLevel, line, file, fkt,
485 "%s: x=%d, y=%d, button=%d, window=0x%08lx, app=%d, down=%d",
486 __func__, x, y, button, window, app, down);
492 for (
size_t i = 0; i < ARRAYSIZE(xfc->button_map); i++)
496 if (cur->button == (UINT32)button)
505 if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
508 freerdp_client_send_wheel_event(&xfc->common, flags);
512 BOOL extended = FALSE;
514 if (flags & (PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2))
519 flags |= PTR_XFLAGS_DOWN;
521 else if (flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3))
524 flags |= PTR_FLAGS_DOWN;
530 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, window);
531 xf_rail_return_window(appWindow, FALSE);
536 XTranslateCoordinates(xfc->display, window, RootWindowOfScreen(xfc->screen), x, y,
537 &x, &y, &childWindow);
540 xf_event_adjust_coordinates(xfc, &x, &y);
543 freerdp_client_send_extended_button_event(&xfc->common, FALSE, flags, x, y);
545 freerdp_client_send_button_event(&xfc->common, FALSE, flags, x, y);
552static BOOL xf_grab_mouse(xfContext* xfc)
561 XGrabPointer(xfc->display, xfc->window->handle, False,
562 ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask |
563 EnterWindowMask | LeaveWindowMask,
564 GrabModeAsync, GrabModeAsync, xfc->window->handle, None, CurrentTime);
565 xfc->common.mouse_grabbed = TRUE;
570static BOOL xf_grab_kbd(xfContext* xfc)
577 XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync,
582static BOOL xf_event_ButtonPress(xfContext* xfc,
const XButtonEvent* event, BOOL app)
586 if (xfc->xi_event || xfc->xi_rawevent || (xfc->common.mouse_grabbed && xf_use_rel_mouse(xfc)))
588 if (!app && xfc_is_floatbar_window(xfc, event->window))
590 return xf_generic_ButtonEvent(xfc, event->x, event->y,
591 WINPR_ASSERTING_INT_CAST(
int, event->button), event->window, app,
595static BOOL xf_event_ButtonRelease(xfContext* xfc,
const XButtonEvent* event, BOOL app)
599 if (xfc->xi_event || xfc->xi_rawevent || (xfc->common.mouse_grabbed && xf_use_rel_mouse(xfc)))
601 return xf_generic_ButtonEvent(xfc, event->x, event->y,
602 WINPR_ASSERTING_INT_CAST(
int, event->button), event->window, app,
606static BOOL xf_event_KeyPress(xfContext* xfc,
const XKeyEvent* event, BOOL app)
609 char str[256] = WINPR_C_ARRAY_INIT;
612 const XKeyEvent* cev;
617 XLookupString(cnv.ev, str,
sizeof(str), &keysym,
nullptr);
618 xf_keyboard_key_press(xfc, event, keysym);
622static BOOL xf_event_KeyRelease(xfContext* xfc,
const XKeyEvent* event, BOOL app)
625 char str[256] = WINPR_C_ARRAY_INIT;
628 const XKeyEvent* cev;
634 XLookupString(cnv.ev, str,
sizeof(str), &keysym,
nullptr);
635 xf_keyboard_key_release(xfc, event, keysym);
641static BOOL xf_event_KeyReleaseOrIgnore(xfContext* xfc,
const XKeyEvent* event, BOOL app)
646 if ((event->type == KeyRelease) && XEventsQueued(xfc->display, QueuedAfterReading))
648 XEvent nev = WINPR_C_ARRAY_INIT;
649 XPeekEvent(xfc->display, &nev);
651 if ((nev.type == KeyPress) && (nev.xkey.time == event->time) &&
652 (nev.xkey.keycode == event->keycode))
659 return xf_event_KeyRelease(xfc, event, app);
662static BOOL xf_event_FocusIn(xfContext* xfc,
const XFocusInEvent* event, BOOL app)
664 if (event->mode == NotifyGrab)
669 if (xfc->mouse_active && !app)
672 if (!xf_grab_kbd(xfc))
679 xf_keyboard_release_all_keypress(xfc);
682 if (!xf_rail_send_activate(xfc, event->window, TRUE))
686 xf_pointer_update_scale(xfc);
690 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
695 xf_rail_adjust_position(xfc, appWindow);
696 xf_rail_return_window(appWindow, FALSE);
699 xf_keyboard_focus_in(xfc);
703static BOOL xf_event_FocusOut(xfContext* xfc,
const XFocusOutEvent* event, BOOL app)
705 if (event->mode == NotifyUngrab)
708 xfc->focused = FALSE;
710 if (event->mode == NotifyWhileGrabbed)
711 XUngrabKeyboard(xfc->display, CurrentTime);
713 xf_keyboard_release_all_keypress(xfc);
715 return xf_rail_send_activate(xfc, event->window, FALSE);
720static BOOL xf_event_MappingNotify(xfContext* xfc,
const XMappingEvent* event, BOOL app)
724 switch (event->request)
726 case MappingModifier:
727 return xf_keyboard_update_modifier_map(xfc);
728 case MappingKeyboard:
729 WLog_Print(xfc->log, WLOG_TRACE,
"[%d] MappingKeyboard", event->request);
730 return xf_keyboard_init(xfc);
732 WLog_Print(xfc->log, WLOG_TRACE,
"[%d] MappingPointer", event->request);
733 xf_button_map_init(xfc);
736 WLog_Print(xfc->log, WLOG_WARN,
737 "[%d] Unsupported MappingNotify::request, must be one "
738 "of[MappingModifier(%d), MappingKeyboard(%d), MappingPointer(%d)]",
739 event->request, MappingModifier, MappingKeyboard, MappingPointer);
744static BOOL xf_event_ClientMessage(xfContext* xfc,
const XClientMessageEvent* event, BOOL app)
746 if ((event->message_type == xfc->WM_PROTOCOLS) &&
747 ((Atom)event->data.l[0] == xfc->WM_DELETE_WINDOW))
752 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
755 rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
756 xf_rail_return_window(appWindow, FALSE);
761 WLog_Print(xfc->log, WLOG_TRACE,
"Main window closed");
769static BOOL xf_event_EnterNotify(xfContext* xfc,
const XEnterWindowEvent* event, BOOL app)
776 xfc->mouse_active = TRUE;
779 XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
786 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
789 xfc->appWindow = appWindow;
790 xf_rail_return_window(appWindow, FALSE);
796static BOOL xf_event_LeaveNotify(xfContext* xfc,
const XLeaveWindowEvent* event, BOOL app)
798 if (event->mode == NotifyGrab || event->mode == NotifyUngrab)
802 xfc->mouse_active = FALSE;
803 XUngrabKeyboard(xfc->display, CurrentTime);
807 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
810 if (xfc->appWindow == appWindow)
811 xfc->appWindow =
nullptr;
812 xf_rail_return_window(appWindow, FALSE);
817static BOOL xf_event_ConfigureNotify(xfContext* xfc,
const XConfigureEvent* event, BOOL app)
819 Window childWindow = None;
820 xfAppWindow* appWindow =
nullptr;
825 const rdpSettings* settings = xfc->common.context.settings;
826 WINPR_ASSERT(settings);
828 WLog_Print(xfc->log, WLOG_DEBUG,
"x=%" PRId32
", y=%" PRId32
", w=%" PRId32
", h=%" PRId32,
829 event->x, event->y, event->width, event->height);
836 if (xfc->window->left != event->x)
837 xfc->window->left =
event->x;
839 if (xfc->window->top != event->y)
840 xfc->window->top =
event->y;
842 if (xfc->window->width != event->width || xfc->window->height != event->height)
844 xfc->window->width =
event->width;
845 xfc->window->height =
event->height;
853 xfc->scaledWidth = xfc->window->width;
854 xfc->scaledHeight = xfc->window->height;
857 WINPR_ASSERTING_INT_CAST(
859 WINPR_ASSERTING_INT_CAST(
864 xfc->scaledWidth = WINPR_ASSERTING_INT_CAST(
866 xfc->scaledHeight = WINPR_ASSERTING_INT_CAST(
875 const int alignedWidth = (xfc->window->width / 2) * 2;
876 const int alignedHeight = (xfc->window->height / 2) * 2;
878 xf_disp_handle_configureNotify(xfc, alignedWidth, alignedHeight);
883 appWindow = xf_AppWindowFromX11Window(xfc, event->window);
891 XTranslateCoordinates(xfc->display, appWindow->handle, RootWindowOfScreen(xfc->screen),
892 0, 0, &appWindow->x, &appWindow->y, &childWindow);
893 appWindow->width =
event->width;
894 appWindow->height =
event->height;
896 xf_AppWindowResize(xfc, appWindow);
904 if (appWindow->decorations)
907 xf_rail_adjust_position(xfc, appWindow);
911 if ((!event->send_event || appWindow->local_move.state == LMS_NOT_ACTIVE) &&
912 !appWindow->rail_ignore_configure && xfc->focused)
913 xf_rail_adjust_position(xfc, appWindow);
916 xf_rail_return_window(appWindow, FALSE);
918 return xf_pointer_update_scale(xfc);
921static BOOL xf_event_MapNotify(xfContext* xfc,
const XMapEvent* event, BOOL app)
926 if (!gdi_send_suppress_output(xfc->common.context.gdi, FALSE))
931 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
941 appWindow->is_mapped = TRUE;
943 xf_rail_return_window(appWindow, FALSE);
949static BOOL xf_event_UnmapNotify(xfContext* xfc,
const XUnmapEvent* event, BOOL app)
955 xf_keyboard_release_all_keypress(xfc);
958 return gdi_send_suppress_output(xfc->common.context.gdi, TRUE);
961 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->window);
964 appWindow->is_mapped = FALSE;
965 xf_rail_return_window(appWindow, FALSE);
971static BOOL xf_event_PropertyNotify(xfContext* xfc,
const XPropertyEvent* event, BOOL app)
982 if (((event->atom == xfc->NET_WM_STATE) && (event->state != PropertyDelete)) ||
983 ((event->atom == xfc->WM_STATE) && (event->state != PropertyDelete)))
986 BOOL minimized = FALSE;
987 BOOL minimizedChanged = FALSE;
988 unsigned long nitems = 0;
989 unsigned long bytes = 0;
990 unsigned char* prop =
nullptr;
991 xfAppWindow* appWindow =
nullptr;
995 appWindow = xf_AppWindowFromX11Window(xfc, event->window);
1001 if (event->atom == xfc->NET_WM_STATE)
1003 status = xf_GetWindowProperty(xfc, event->window, xfc->NET_WM_STATE, 12, &nitems,
1010 appWindow->maxVert = FALSE;
1011 appWindow->maxHorz = FALSE;
1013 for (
unsigned long i = 0; i < nitems; i++)
1015 if ((Atom)((UINT16**)prop)[i] ==
1016 Logging_XInternAtom(xfc->log, xfc->display,
"_NET_WM_STATE_MAXIMIZED_VERT",
1020 appWindow->maxVert = TRUE;
1023 if ((Atom)((UINT16**)prop)[i] ==
1024 Logging_XInternAtom(xfc->log, xfc->display,
"_NET_WM_STATE_MAXIMIZED_HORZ",
1028 appWindow->maxHorz = TRUE;
1036 if (event->atom == xfc->WM_STATE)
1039 xf_GetWindowProperty(xfc, event->window, xfc->WM_STATE, 1, &nitems, &bytes, &prop);
1044 if (((UINT32)*prop == 3) && !IsGnome())
1048 appWindow->minimized = TRUE;
1054 appWindow->minimized = FALSE;
1057 minimizedChanged = TRUE;
1064 WINPR_ASSERT(appWindow);
1065 if (appWindow->maxVert && appWindow->maxHorz && !appWindow->minimized)
1067 if (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED)
1069 appWindow->rail_state = WINDOW_SHOW_MAXIMIZED;
1070 rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MAXIMIZE);
1073 else if (appWindow->minimized)
1075 if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
1077 appWindow->rail_state = WINDOW_SHOW_MINIMIZED;
1078 rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MINIMIZE);
1083 if (appWindow->rail_state != WINDOW_SHOW && appWindow->rail_state != WINDOW_HIDE)
1085 appWindow->rail_state = WINDOW_SHOW;
1086 rc = xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
1090 else if (minimizedChanged)
1091 rc = gdi_send_suppress_output(xfc->common.context.gdi, minimized);
1094 xf_rail_return_window(appWindow, FALSE);
1100static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow,
const XEvent* event)
1102 if (!xfc->remote_app)
1105 switch (appWindow->local_move.state)
1107 case LMS_NOT_ACTIVE:
1113 if ((event->type == ConfigureNotify) && appWindow->rail_ignore_configure)
1115 appWindow->rail_ignore_configure = FALSE;
1125 switch (event->type)
1127 case ConfigureNotify:
1130 appWindow->local_move.state = LMS_ACTIVE;
1147 case VisibilityNotify:
1148 case PropertyNotify:
1163 switch (event->type)
1165 case ConfigureNotify:
1166 case VisibilityNotify:
1167 case PropertyNotify:
1175 xf_rail_end_local_move(xfc, appWindow);
1181 case LMS_TERMINATING:
1191BOOL xf_event_process(freerdp* instance,
const XEvent* event)
1195 WINPR_ASSERT(instance);
1196 WINPR_ASSERT(event);
1198 xfContext* xfc = (xfContext*)instance->context;
1201 rdpSettings* settings = xfc->common.context.settings;
1202 WINPR_ASSERT(settings);
1204 if (xfc->remote_app)
1206 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
1211 xfc->appWindow = appWindow;
1213 const BOOL rc = xf_event_suppress_events(xfc, appWindow, event);
1214 xf_rail_return_window(appWindow, FALSE);
1222 xfFloatbar* floatbar = xfc->window->floatbar;
1223 if (xf_floatbar_check_event(floatbar, event))
1225 xf_floatbar_event_process(floatbar, event);
1229 if (xf_floatbar_is_locked(floatbar))
1232 switch (event->type)
1250 xf_event_execute_action_script(xfc, event);
1252 if (event->type != MotionNotify)
1254 WLog_Print(xfc->log, WLOG_TRACE,
"%s Event(%d): wnd=0x%08lX", x11_event_string(event->type),
1255 event->type, (
unsigned long)event->xany.window);
1258 switch (event->type)
1261 status = xf_event_Expose(xfc, &event->xexpose, xfc->remote_app);
1264 case VisibilityNotify:
1265 status = xf_event_VisibilityNotify(xfc, &event->xvisibility, xfc->remote_app);
1269 status = xf_event_MotionNotify(xfc, &event->xmotion, xfc->remote_app);
1273 status = xf_event_ButtonPress(xfc, &event->xbutton, xfc->remote_app);
1277 status = xf_event_ButtonRelease(xfc, &event->xbutton, xfc->remote_app);
1281 status = xf_event_KeyPress(xfc, &event->xkey, xfc->remote_app);
1285 status = xf_event_KeyReleaseOrIgnore(xfc, &event->xkey, xfc->remote_app);
1289 status = xf_event_FocusIn(xfc, &event->xfocus, xfc->remote_app);
1293 status = xf_event_FocusOut(xfc, &event->xfocus, xfc->remote_app);
1297 status = xf_event_EnterNotify(xfc, &event->xcrossing, xfc->remote_app);
1301 status = xf_event_LeaveNotify(xfc, &event->xcrossing, xfc->remote_app);
1307 case GraphicsExpose:
1310 case ConfigureNotify:
1311 status = xf_event_ConfigureNotify(xfc, &event->xconfigure, xfc->remote_app);
1315 status = xf_event_MapNotify(xfc, &event->xmap, xfc->remote_app);
1319 status = xf_event_UnmapNotify(xfc, &event->xunmap, xfc->remote_app);
1322 case ReparentNotify:
1326 status = xf_event_MappingNotify(xfc, &event->xmapping, xfc->remote_app);
1330 status = xf_event_ClientMessage(xfc, &event->xclient, xfc->remote_app);
1333 case PropertyNotify:
1334 status = xf_event_PropertyNotify(xfc, &event->xproperty, xfc->remote_app);
1339 xf_disp_handle_xevent(xfc, event);
1344 xfWindow* window = xfc->window;
1345 xfFloatbar* floatbar =
nullptr;
1347 floatbar = window->floatbar;
1349 xf_cliprdr_handle_xevent(xfc, event);
1350 if (!xf_floatbar_check_event(floatbar, event) && !xf_floatbar_is_locked(floatbar))
1352 if (xf_input_handle_event(xfc, event) < 0)
1356 LogDynAndXSync(xfc->log, xfc->display, FALSE);
1360BOOL xf_generic_RawButtonEvent_(xfContext* xfc,
int button, BOOL app, BOOL down,
const char* file,
1361 const char* fkt,
size_t line)
1365 if (WLog_IsLevelActive(xfc->log, mouseLogLevel))
1366 WLog_PrintTextMessage(xfc->log, mouseLogLevel, line, file, fkt,
1367 "%s: button=%d, app=%d, down=%d", __func__, button, app, down);
1369 if (app || (button < 0))
1372 for (
size_t i = 0; i < ARRAYSIZE(xfc->button_map); i++)
1376 if (cur->button == (UINT32)button)
1385 if (flags & (PTR_FLAGS_WHEEL | PTR_FLAGS_HWHEEL))
1388 freerdp_client_send_wheel_event(&xfc->common, flags);
1392 BOOL extended = FALSE;
1394 if (flags & (PTR_XFLAGS_BUTTON1 | PTR_XFLAGS_BUTTON2))
1399 flags |= PTR_XFLAGS_DOWN;
1401 else if (flags & (PTR_FLAGS_BUTTON1 | PTR_FLAGS_BUTTON2 | PTR_FLAGS_BUTTON3))
1404 flags |= PTR_FLAGS_DOWN;
1408 freerdp_client_send_extended_button_event(&xfc->common, TRUE, flags, 0, 0);
1410 freerdp_client_send_button_event(&xfc->common, TRUE, flags, 0, 0);
1417BOOL xf_event_update_screen(freerdp* instance)
1419 WINPR_ASSERT(instance);
1421 xfContext* xfc = (xfContext*)instance->context;
1424 if (!xfc->exposeRequested)
1426 xfc->exposeRequested =
false;
1428 if (!xfc->remote_app)
1430 if (xfc->common.context.gdi->gfx)
1432 xf_OutputExpose(xfc, WINPR_ASSERTING_INT_CAST(uint32_t, xfc->exposedArea.x),
1433 WINPR_ASSERTING_INT_CAST(uint32_t, xfc->exposedArea.y),
1434 WINPR_ASSERTING_INT_CAST(uint32_t, xfc->exposedArea.w),
1435 WINPR_ASSERTING_INT_CAST(uint32_t, xfc->exposedArea.h));
1438 xf_draw_screen(xfc, xfc->exposedArea.x, xfc->exposedArea.y, xfc->exposedArea.w,
1439 xfc->exposedArea.h);
1443 xfAppWindow* appWindow = xf_AppWindowFromX11Window(xfc, xfc->exposedWindow);
1445 xf_UpdateWindowArea(xfc, appWindow, xfc->exposedArea.x, xfc->exposedArea.y,
1446 xfc->exposedArea.w, xfc->exposedArea.h);
1447 xf_rail_return_window(appWindow, FALSE);
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD 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.
OBJECT_FREE_FN fnObjectFree
WINPR_ATTR_NODISCARD OBJECT_NEW_FN fnObjectNew