24#include <freerdp/display.h>
25#include <freerdp/session.h>
26#include <winpr/assert.h>
27#include <winpr/image.h>
28#include <winpr/sysinfo.h>
30#include <freerdp/server/proxy/proxy_log.h>
35#include <freerdp/server/proxy/proxy_context.h>
36#include "proxy_modules.h"
38#define TAG PROXY_TAG("update")
41static BOOL pf_server_refresh_rect(rdpContext* context, BYTE count,
const RECTANGLE_16* areas)
43 pServerContext* ps = (pServerContext*)context;
45 WINPR_ASSERT(ps->pdata);
47 pClientContext* pc = proxy_data_get_client_context(ps->pdata);
50 if (!freerdp_is_active_state(&pc->cctx.context))
53 WINPR_ASSERT(pc->cctx.context.update);
54 WINPR_ASSERT(pc->cctx.context.update->RefreshRect);
55 return pc->cctx.context.update->RefreshRect(&pc->cctx.context, count, areas);
59static BOOL pf_server_suppress_output(rdpContext* context, BYTE allow,
const RECTANGLE_16* area)
61 pServerContext* ps = (pServerContext*)context;
63 WINPR_ASSERT(ps->pdata);
65 pClientContext* pc = proxy_data_get_client_context(ps->pdata);
68 if (!freerdp_is_active_state(&pc->cctx.context))
71 WINPR_ASSERT(pc->cctx.context.update);
72 WINPR_ASSERT(pc->cctx.context.update->SuppressOutput);
73 return pc->cctx.context.update->SuppressOutput(&pc->cctx.context, allow, area);
83static BOOL pf_client_begin_paint(rdpContext* context)
85 pClientContext* pc = (pClientContext*)context;
88 proxyData* pdata = pc->pdata;
91 pServerContext* ps = proxy_data_get_server_context(pdata);
94 WINPR_ASSERT(ps->context.update);
95 WINPR_ASSERT(ps->context.update->BeginPaint);
96 WLog_DBG(TAG,
"called");
97 return ps->context.update->BeginPaint(&ps->context);
106static BOOL pf_client_end_paint(rdpContext* context)
108 pClientContext* pc = (pClientContext*)context;
111 proxyData* pdata = pc->pdata;
114 pServerContext* ps = proxy_data_get_server_context(pdata);
116 WINPR_ASSERT(ps->context.update);
117 WINPR_ASSERT(ps->context.update->EndPaint);
119 WLog_DBG(TAG,
"called");
122 if (!ps->context.update->EndPaint(&ps->context))
125 if (!pf_modules_run_hook(pdata->module, HOOK_TYPE_CLIENT_END_PAINT, pdata, context))
132static BOOL pf_client_bitmap_update(rdpContext* context,
const BITMAP_UPDATE* bitmap)
134 pClientContext* pc = (pClientContext*)context;
137 proxyData* pdata = pc->pdata;
140 pServerContext* ps = proxy_data_get_server_context(pdata);
142 WINPR_ASSERT(ps->context.update);
143 WINPR_ASSERT(ps->context.update->BitmapUpdate);
144 WLog_DBG(TAG,
"called");
145 return ps->context.update->BitmapUpdate(&ps->context, bitmap);
149static BOOL pf_client_desktop_resize(rdpContext* context)
151 pClientContext* pc = (pClientContext*)context;
154 proxyData* pdata = pc->pdata;
157 pServerContext* ps = proxy_data_get_server_context(pdata);
159 WINPR_ASSERT(ps->context.update);
160 WINPR_ASSERT(ps->context.update->DesktopResize);
161 WINPR_ASSERT(context->settings);
162 WINPR_ASSERT(ps->context.settings);
163 WLog_DBG(TAG,
"called");
168 return ps->context.update->DesktopResize(&ps->context);
172static BOOL pf_client_remote_monitors(rdpContext* context, UINT32 count,
175 pClientContext* pc = (pClientContext*)context;
178 proxyData* pdata = pc->pdata;
181 pServerContext* ps = proxy_data_get_server_context(pdata);
183 WLog_DBG(TAG,
"called");
184 return freerdp_display_send_monitor_layout(&ps->context, count, monitors);
188static BOOL pf_client_send_pointer_system(rdpContext* context,
191 pClientContext* pc = (pClientContext*)context;
194 proxyData* pdata = pc->pdata;
197 pServerContext* ps = proxy_data_get_server_context(pdata);
199 WINPR_ASSERT(ps->context.update);
200 WINPR_ASSERT(ps->context.update->pointer);
201 WINPR_ASSERT(ps->context.update->pointer->PointerSystem);
202 WLog_DBG(TAG,
"called");
203 return ps->context.update->pointer->PointerSystem(&ps->context, pointer_system);
207static BOOL pf_client_send_pointer_position(rdpContext* context,
210 pClientContext* pc = (pClientContext*)context;
213 proxyData* pdata = pc->pdata;
216 pServerContext* ps = proxy_data_get_server_context(pdata);
218 WINPR_ASSERT(ps->context.update);
219 WINPR_ASSERT(ps->context.update->pointer);
220 WINPR_ASSERT(ps->context.update->pointer->PointerPosition);
221 WLog_DBG(TAG,
"called");
222 return ps->context.update->pointer->PointerPosition(&ps->context, pointerPosition);
226static BOOL pf_client_send_pointer_color(rdpContext* context,
229 pClientContext* pc = (pClientContext*)context;
232 proxyData* pdata = pc->pdata;
235 pServerContext* ps = proxy_data_get_server_context(pdata);
237 WINPR_ASSERT(ps->context.update);
238 WINPR_ASSERT(ps->context.update->pointer);
239 WINPR_ASSERT(ps->context.update->pointer->PointerColor);
240 WLog_DBG(TAG,
"called");
241 return ps->context.update->pointer->PointerColor(&ps->context, pointer_color);
245static BOOL pf_client_send_pointer_large(rdpContext* context,
248 pClientContext* pc = (pClientContext*)context;
251 proxyData* pdata = pc->pdata;
254 pServerContext* ps = proxy_data_get_server_context(pdata);
256 WINPR_ASSERT(ps->context.update);
257 WINPR_ASSERT(ps->context.update->pointer);
258 WINPR_ASSERT(ps->context.update->pointer->PointerLarge);
259 WLog_DBG(TAG,
"called");
260 return ps->context.update->pointer->PointerLarge(&ps->context, pointer_large);
264static BOOL pf_client_send_pointer_new(rdpContext* context,
const POINTER_NEW_UPDATE* pointer_new)
266 pClientContext* pc = (pClientContext*)context;
269 proxyData* pdata = pc->pdata;
272 pServerContext* ps = proxy_data_get_server_context(pdata);
274 WINPR_ASSERT(ps->context.update);
275 WINPR_ASSERT(ps->context.update->pointer);
276 WINPR_ASSERT(ps->context.update->pointer->PointerNew);
277 WLog_DBG(TAG,
"called");
278 return ps->context.update->pointer->PointerNew(&ps->context, pointer_new);
282static BOOL pf_client_send_pointer_cached(rdpContext* context,
285 pClientContext* pc = (pClientContext*)context;
288 proxyData* pdata = pc->pdata;
291 pServerContext* ps = proxy_data_get_server_context(pdata);
293 WINPR_ASSERT(ps->context.update);
294 WINPR_ASSERT(ps->context.update->pointer);
295 WINPR_ASSERT(ps->context.update->pointer->PointerCached);
296 WLog_DBG(TAG,
"called");
297 return ps->context.update->pointer->PointerCached(&ps->context, pointer_cached);
301static BOOL pf_client_save_session_info(rdpContext* context, UINT32 type,
void* data)
303 logon_info* logonInfo =
nullptr;
304 pClientContext* pc = (pClientContext*)context;
307 proxyData* pdata = pc->pdata;
310 pServerContext* ps = proxy_data_get_server_context(pdata);
312 WINPR_ASSERT(ps->context.update);
313 WINPR_ASSERT(ps->context.update->SaveSessionInfo);
315 WLog_DBG(TAG,
"called");
319 case INFO_TYPE_LOGON:
320 case INFO_TYPE_LOGON_LONG:
322 logonInfo = (logon_info*)data;
323 PROXY_LOG_INFO(TAG, pc,
"client logon info: Username: %s, Domain: %s",
324 logonInfo->username, logonInfo->domain);
332 return ps->context.update->SaveSessionInfo(&ps->context, type, data);
336static BOOL pf_client_server_status_info(rdpContext* context, UINT32 status)
338 pClientContext* pc = (pClientContext*)context;
341 proxyData* pdata = pc->pdata;
343 pServerContext* ps = proxy_data_get_server_context(pdata);
345 WINPR_ASSERT(ps->context.update);
346 WINPR_ASSERT(ps->context.update->ServerStatusInfo);
348 WLog_DBG(TAG,
"called");
349 return ps->context.update->ServerStatusInfo(&ps->context, status);
353static BOOL pf_client_set_keyboard_indicators(rdpContext* context, UINT16 led_flags)
355 pClientContext* pc = (pClientContext*)context;
358 proxyData* pdata = pc->pdata;
361 pServerContext* ps = proxy_data_get_server_context(pdata);
363 WINPR_ASSERT(ps->context.update);
364 WINPR_ASSERT(ps->context.update->SetKeyboardIndicators);
366 WLog_DBG(TAG,
"called");
367 return ps->context.update->SetKeyboardIndicators(&ps->context, led_flags);
371static BOOL pf_client_set_keyboard_ime_status(rdpContext* context, UINT16 imeId, UINT32 imeState,
374 pClientContext* pc = (pClientContext*)context;
377 proxyData* pdata = pc->pdata;
380 pServerContext* ps = proxy_data_get_server_context(pdata);
382 WINPR_ASSERT(ps->context.update);
383 WINPR_ASSERT(ps->context.update->SetKeyboardImeStatus);
385 WLog_DBG(TAG,
"called");
386 return ps->context.update->SetKeyboardImeStatus(&ps->context, imeId, imeState, imeConvMode);
390static BOOL pf_client_SurfaceBits(rdpContext* context,
393 pClientContext* pc = (pClientContext*)context;
396 proxyData* pdata = pc->pdata;
399 pServerContext* ps = proxy_data_get_server_context(pdata);
402 WINPR_ASSERT(ps->context.update);
403 WINPR_ASSERT(ps->context.update->SurfaceBits);
405 WLog_DBG(TAG,
"called");
406 return ps->context.update->SurfaceBits(&ps->context, surfaceBitsCommand);
410static BOOL pf_client_SurfaceFrameMarker(rdpContext* context,
413 pClientContext* pc = (pClientContext*)context;
416 proxyData* pdata = pc->pdata;
419 pServerContext* ps = proxy_data_get_server_context(pdata);
422 WINPR_ASSERT(ps->context.update);
423 WINPR_ASSERT(ps->context.update->SurfaceFrameMarker);
425 WLog_DBG(TAG,
"called");
426 return ps->context.update->SurfaceFrameMarker(&ps->context, surfaceFrameMarker);
430static BOOL pf_client_window_create(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
433 pClientContext* pc = (pClientContext*)context;
436 proxyData* pdata = pc->pdata;
439 pServerContext* ps = proxy_data_get_server_context(pdata);
441 WINPR_ASSERT(ps->context.update);
442 WINPR_ASSERT(ps->context.update->window);
443 WINPR_ASSERT(ps->context.update->window->WindowCreate);
445 WLog_DBG(TAG,
"called");
446 rdp_update_lock(ps->context.update);
447 const BOOL rc = ps->context.update->window->WindowCreate(&ps->context, orderInfo, windowState);
448 rdp_update_unlock(ps->context.update);
453static BOOL pf_client_window_update(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
456 pClientContext* pc = (pClientContext*)context;
459 proxyData* pdata = pc->pdata;
462 pServerContext* ps = proxy_data_get_server_context(pdata);
464 WINPR_ASSERT(ps->context.update);
465 WINPR_ASSERT(ps->context.update->window);
466 WINPR_ASSERT(ps->context.update->window->WindowUpdate);
468 WLog_DBG(TAG,
"called");
469 rdp_update_lock(ps->context.update);
470 const BOOL rc = ps->context.update->window->WindowUpdate(&ps->context, orderInfo, windowState);
471 rdp_update_unlock(ps->context.update);
476static BOOL pf_client_window_icon(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
479 pClientContext* pc = (pClientContext*)context;
482 proxyData* pdata = pc->pdata;
485 pServerContext* ps = proxy_data_get_server_context(pdata);
487 WINPR_ASSERT(ps->context.update);
488 WINPR_ASSERT(ps->context.update->window);
489 WINPR_ASSERT(ps->context.update->window->WindowIcon);
491 WLog_DBG(TAG,
"called");
492 rdp_update_lock(ps->context.update);
493 const BOOL rc = ps->context.update->window->WindowIcon(&ps->context, orderInfo, windowIcon);
494 rdp_update_unlock(ps->context.update);
499static BOOL pf_client_window_cached_icon(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
502 pClientContext* pc = (pClientContext*)context;
505 proxyData* pdata = pc->pdata;
508 pServerContext* ps = proxy_data_get_server_context(pdata);
510 WINPR_ASSERT(ps->context.update);
511 WINPR_ASSERT(ps->context.update->window);
512 WINPR_ASSERT(ps->context.update->window->WindowCachedIcon);
514 WLog_DBG(TAG,
"called");
515 rdp_update_lock(ps->context.update);
517 ps->context.update->window->WindowCachedIcon(&ps->context, orderInfo, windowCachedIcon);
518 rdp_update_unlock(ps->context.update);
523static BOOL pf_client_window_delete(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
525 pClientContext* pc = (pClientContext*)context;
528 proxyData* pdata = pc->pdata;
531 pServerContext* ps = proxy_data_get_server_context(pdata);
533 WINPR_ASSERT(ps->context.update);
534 WINPR_ASSERT(ps->context.update->window);
535 WINPR_ASSERT(ps->context.update->window->WindowDelete);
537 WLog_DBG(TAG,
"called");
538 rdp_update_lock(ps->context.update);
539 const BOOL rc = ps->context.update->window->WindowDelete(&ps->context, orderInfo);
540 rdp_update_unlock(ps->context.update);
545static BOOL pf_client_notify_icon_create(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
548 pClientContext* pc = (pClientContext*)context;
551 proxyData* pdata = pc->pdata;
554 pServerContext* ps = proxy_data_get_server_context(pdata);
556 WINPR_ASSERT(ps->context.update);
557 WINPR_ASSERT(ps->context.update->window);
558 WINPR_ASSERT(ps->context.update->window->NotifyIconCreate);
560 WLog_DBG(TAG,
"called");
561 rdp_update_lock(ps->context.update);
563 ps->context.update->window->NotifyIconCreate(&ps->context, orderInfo, notifyIconState);
564 rdp_update_unlock(ps->context.update);
569static BOOL pf_client_notify_icon_update(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
572 pClientContext* pc = (pClientContext*)context;
575 proxyData* pdata = pc->pdata;
578 pServerContext* ps = proxy_data_get_server_context(pdata);
580 WINPR_ASSERT(ps->context.update);
581 WINPR_ASSERT(ps->context.update->window);
582 WINPR_ASSERT(ps->context.update->window->NotifyIconUpdate);
584 WLog_DBG(TAG,
"called");
585 rdp_update_lock(ps->context.update);
587 ps->context.update->window->NotifyIconUpdate(&ps->context, orderInfo, notifyIconState);
588 rdp_update_unlock(ps->context.update);
593static BOOL pf_client_notify_icon_delete(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
595 pClientContext* pc = (pClientContext*)context;
598 proxyData* pdata = pc->pdata;
601 pServerContext* ps = proxy_data_get_server_context(pdata);
603 WINPR_ASSERT(ps->context.update);
604 WINPR_ASSERT(ps->context.update->window);
605 WINPR_ASSERT(ps->context.update->window->NotifyIconDelete);
607 WLog_DBG(TAG,
"called");
608 rdp_update_lock(ps->context.update);
609 const BOOL rc = ps->context.update->window->NotifyIconDelete(&ps->context, orderInfo);
610 rdp_update_unlock(ps->context.update);
615static BOOL pf_client_monitored_desktop(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
618 pClientContext* pc = (pClientContext*)context;
621 proxyData* pdata = pc->pdata;
624 pServerContext* ps = proxy_data_get_server_context(pdata);
626 WINPR_ASSERT(ps->context.update);
627 WINPR_ASSERT(ps->context.update->window);
628 WINPR_ASSERT(ps->context.update->window->MonitoredDesktop);
630 WLog_DBG(TAG,
"called");
631 rdp_update_lock(ps->context.update);
633 ps->context.update->window->MonitoredDesktop(&ps->context, orderInfo, monitoredDesktop);
634 rdp_update_unlock(ps->context.update);
639static BOOL pf_client_non_monitored_desktop(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
641 pClientContext* pc = (pClientContext*)context;
644 proxyData* pdata = pc->pdata;
647 pServerContext* ps = proxy_data_get_server_context(pdata);
649 WINPR_ASSERT(ps->context.update);
650 WINPR_ASSERT(ps->context.update->window);
651 WINPR_ASSERT(ps->context.update->window->NonMonitoredDesktop);
653 WLog_DBG(TAG,
"called");
654 rdp_update_lock(ps->context.update);
655 const BOOL rc = ps->context.update->window->NonMonitoredDesktop(&ps->context, orderInfo);
656 rdp_update_unlock(ps->context.update);
660void pf_server_register_update_callbacks(rdpUpdate* update)
662 WINPR_ASSERT(update);
663 update->RefreshRect = pf_server_refresh_rect;
664 update->SuppressOutput = pf_server_suppress_output;
667void pf_client_register_update_callbacks(rdpUpdate* update)
669 WINPR_ASSERT(update);
670 update->BeginPaint = pf_client_begin_paint;
671 update->EndPaint = pf_client_end_paint;
672 update->BitmapUpdate = pf_client_bitmap_update;
673 update->DesktopResize = pf_client_desktop_resize;
674 update->RemoteMonitors = pf_client_remote_monitors;
675 update->SaveSessionInfo = pf_client_save_session_info;
676 update->ServerStatusInfo = pf_client_server_status_info;
677 update->SetKeyboardIndicators = pf_client_set_keyboard_indicators;
678 update->SetKeyboardImeStatus = pf_client_set_keyboard_ime_status;
681 update->SurfaceBits = pf_client_SurfaceBits;
682 update->SurfaceFrameMarker = pf_client_SurfaceFrameMarker;
685 update->window->WindowCreate = pf_client_window_create;
686 update->window->WindowUpdate = pf_client_window_update;
687 update->window->WindowIcon = pf_client_window_icon;
688 update->window->WindowCachedIcon = pf_client_window_cached_icon;
689 update->window->WindowDelete = pf_client_window_delete;
690 update->window->NotifyIconCreate = pf_client_notify_icon_create;
691 update->window->NotifyIconUpdate = pf_client_notify_icon_update;
692 update->window->NotifyIconDelete = pf_client_notify_icon_delete;
693 update->window->MonitoredDesktop = pf_client_monitored_desktop;
694 update->window->NonMonitoredDesktop = pf_client_non_monitored_desktop;
697 update->pointer->PointerSystem = pf_client_send_pointer_system;
698 update->pointer->PointerPosition = pf_client_send_pointer_position;
699 update->pointer->PointerColor = pf_client_send_pointer_color;
700 update->pointer->PointerLarge = pf_client_send_pointer_large;
701 update->pointer->PointerNew = pf_client_send_pointer_new;
702 update->pointer->PointerCached = pf_client_send_pointer_cached;
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_copy_item(rdpSettings *dst, const rdpSettings *src, SSIZE_T id)
copies one setting identified by id from src to dst