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>
33#include <freerdp/server/proxy/proxy_context.h>
34#include "proxy_modules.h"
36#define TAG PROXY_TAG("update")
39static BOOL pf_server_refresh_rect(rdpContext* context, BYTE count,
const RECTANGLE_16* areas)
41 pServerContext* ps = (pServerContext*)context;
43 WINPR_ASSERT(ps->pdata);
45 rdpContext* pc = (rdpContext*)ps->pdata->pc;
48 if (!freerdp_is_active_state(pc))
51 WINPR_ASSERT(pc->update);
52 WINPR_ASSERT(pc->update->RefreshRect);
53 return pc->update->RefreshRect(pc, count, areas);
57static BOOL pf_server_suppress_output(rdpContext* context, BYTE allow,
const RECTANGLE_16* area)
59 pServerContext* ps = (pServerContext*)context;
61 WINPR_ASSERT(ps->pdata);
63 rdpContext* pc = (rdpContext*)ps->pdata->pc;
66 if (!freerdp_is_active_state(pc))
69 WINPR_ASSERT(pc->update);
70 WINPR_ASSERT(pc->update->SuppressOutput);
71 return pc->update->SuppressOutput(pc, allow, area);
81static BOOL pf_client_begin_paint(rdpContext* context)
83 pClientContext* pc = (pClientContext*)context;
84 proxyData* pdata =
nullptr;
85 rdpContext* ps =
nullptr;
89 ps = (rdpContext*)pdata->ps;
91 WINPR_ASSERT(ps->update);
92 WINPR_ASSERT(ps->update->BeginPaint);
93 WLog_DBG(TAG,
"called");
94 return ps->update->BeginPaint(ps);
103static BOOL pf_client_end_paint(rdpContext* context)
105 pClientContext* pc = (pClientContext*)context;
106 proxyData* pdata =
nullptr;
107 rdpContext* ps =
nullptr;
111 ps = (rdpContext*)pdata->ps;
113 WINPR_ASSERT(ps->update);
114 WINPR_ASSERT(ps->update->EndPaint);
116 WLog_DBG(TAG,
"called");
119 if (!ps->update->EndPaint(ps))
122 if (!pf_modules_run_hook(pdata->module, HOOK_TYPE_CLIENT_END_PAINT, pdata, context))
129static BOOL pf_client_bitmap_update(rdpContext* context,
const BITMAP_UPDATE* bitmap)
131 pClientContext* pc = (pClientContext*)context;
132 proxyData* pdata =
nullptr;
133 rdpContext* ps =
nullptr;
137 ps = (rdpContext*)pdata->ps;
139 WINPR_ASSERT(ps->update);
140 WINPR_ASSERT(ps->update->BitmapUpdate);
141 WLog_DBG(TAG,
"called");
142 return ps->update->BitmapUpdate(ps, bitmap);
146static BOOL pf_client_desktop_resize(rdpContext* context)
148 pClientContext* pc = (pClientContext*)context;
149 proxyData* pdata =
nullptr;
150 rdpContext* ps =
nullptr;
154 ps = (rdpContext*)pdata->ps;
156 WINPR_ASSERT(ps->update);
157 WINPR_ASSERT(ps->update->DesktopResize);
158 WINPR_ASSERT(context->settings);
159 WINPR_ASSERT(ps->settings);
160 WLog_DBG(TAG,
"called");
165 return ps->update->DesktopResize(ps);
169static BOOL pf_client_remote_monitors(rdpContext* context, UINT32 count,
172 pClientContext* pc = (pClientContext*)context;
173 proxyData* pdata =
nullptr;
174 rdpContext* ps =
nullptr;
178 ps = (rdpContext*)pdata->ps;
180 WLog_DBG(TAG,
"called");
181 return freerdp_display_send_monitor_layout(ps, count, monitors);
185static BOOL pf_client_send_pointer_system(rdpContext* context,
188 pClientContext* pc = (pClientContext*)context;
189 proxyData* pdata =
nullptr;
190 rdpContext* ps =
nullptr;
194 ps = (rdpContext*)pdata->ps;
196 WINPR_ASSERT(ps->update);
197 WINPR_ASSERT(ps->update->pointer);
198 WINPR_ASSERT(ps->update->pointer->PointerSystem);
199 WLog_DBG(TAG,
"called");
200 return ps->update->pointer->PointerSystem(ps, pointer_system);
204static BOOL pf_client_send_pointer_position(rdpContext* context,
207 pClientContext* pc = (pClientContext*)context;
208 proxyData* pdata =
nullptr;
209 rdpContext* ps =
nullptr;
213 ps = (rdpContext*)pdata->ps;
215 WINPR_ASSERT(ps->update);
216 WINPR_ASSERT(ps->update->pointer);
217 WINPR_ASSERT(ps->update->pointer->PointerPosition);
218 WLog_DBG(TAG,
"called");
219 return ps->update->pointer->PointerPosition(ps, pointerPosition);
223static BOOL pf_client_send_pointer_color(rdpContext* context,
226 pClientContext* pc = (pClientContext*)context;
227 proxyData* pdata =
nullptr;
228 rdpContext* ps =
nullptr;
232 ps = (rdpContext*)pdata->ps;
234 WINPR_ASSERT(ps->update);
235 WINPR_ASSERT(ps->update->pointer);
236 WINPR_ASSERT(ps->update->pointer->PointerColor);
237 WLog_DBG(TAG,
"called");
238 return ps->update->pointer->PointerColor(ps, pointer_color);
242static BOOL pf_client_send_pointer_large(rdpContext* context,
245 pClientContext* pc = (pClientContext*)context;
246 proxyData* pdata =
nullptr;
247 rdpContext* ps =
nullptr;
251 ps = (rdpContext*)pdata->ps;
253 WINPR_ASSERT(ps->update);
254 WINPR_ASSERT(ps->update->pointer);
255 WINPR_ASSERT(ps->update->pointer->PointerLarge);
256 WLog_DBG(TAG,
"called");
257 return ps->update->pointer->PointerLarge(ps, pointer_large);
261static BOOL pf_client_send_pointer_new(rdpContext* context,
const POINTER_NEW_UPDATE* pointer_new)
263 pClientContext* pc = (pClientContext*)context;
264 proxyData* pdata =
nullptr;
265 rdpContext* ps =
nullptr;
269 ps = (rdpContext*)pdata->ps;
271 WINPR_ASSERT(ps->update);
272 WINPR_ASSERT(ps->update->pointer);
273 WINPR_ASSERT(ps->update->pointer->PointerNew);
274 WLog_DBG(TAG,
"called");
275 return ps->update->pointer->PointerNew(ps, pointer_new);
279static BOOL pf_client_send_pointer_cached(rdpContext* context,
282 pClientContext* pc = (pClientContext*)context;
283 proxyData* pdata =
nullptr;
284 rdpContext* ps =
nullptr;
288 ps = (rdpContext*)pdata->ps;
290 WINPR_ASSERT(ps->update);
291 WINPR_ASSERT(ps->update->pointer);
292 WINPR_ASSERT(ps->update->pointer->PointerCached);
293 WLog_DBG(TAG,
"called");
294 return ps->update->pointer->PointerCached(ps, pointer_cached);
298static BOOL pf_client_save_session_info(rdpContext* context, UINT32 type,
void* data)
300 logon_info* logonInfo =
nullptr;
301 pClientContext* pc = (pClientContext*)context;
302 proxyData* pdata =
nullptr;
303 rdpContext* ps =
nullptr;
307 ps = (rdpContext*)pdata->ps;
309 WINPR_ASSERT(ps->update);
310 WINPR_ASSERT(ps->update->SaveSessionInfo);
312 WLog_DBG(TAG,
"called");
316 case INFO_TYPE_LOGON:
317 case INFO_TYPE_LOGON_LONG:
319 logonInfo = (logon_info*)data;
320 PROXY_LOG_INFO(TAG, pc,
"client logon info: Username: %s, Domain: %s",
321 logonInfo->username, logonInfo->domain);
329 return ps->update->SaveSessionInfo(ps, type, data);
333static BOOL pf_client_server_status_info(rdpContext* context, UINT32 status)
335 pClientContext* pc = (pClientContext*)context;
336 proxyData* pdata =
nullptr;
337 rdpContext* ps =
nullptr;
341 ps = (rdpContext*)pdata->ps;
343 WINPR_ASSERT(ps->update);
344 WINPR_ASSERT(ps->update->ServerStatusInfo);
346 WLog_DBG(TAG,
"called");
347 return ps->update->ServerStatusInfo(ps, status);
351static BOOL pf_client_set_keyboard_indicators(rdpContext* context, UINT16 led_flags)
353 pClientContext* pc = (pClientContext*)context;
354 proxyData* pdata =
nullptr;
355 rdpContext* ps =
nullptr;
359 ps = (rdpContext*)pdata->ps;
361 WINPR_ASSERT(ps->update);
362 WINPR_ASSERT(ps->update->SetKeyboardIndicators);
364 WLog_DBG(TAG,
"called");
365 return ps->update->SetKeyboardIndicators(ps, led_flags);
369static BOOL pf_client_set_keyboard_ime_status(rdpContext* context, UINT16 imeId, UINT32 imeState,
372 pClientContext* pc = (pClientContext*)context;
373 proxyData* pdata =
nullptr;
374 rdpContext* ps =
nullptr;
378 ps = (rdpContext*)pdata->ps;
380 WINPR_ASSERT(ps->update);
381 WINPR_ASSERT(ps->update->SetKeyboardImeStatus);
383 WLog_DBG(TAG,
"called");
384 return ps->update->SetKeyboardImeStatus(ps, imeId, imeState, imeConvMode);
388static BOOL pf_client_SurfaceBits(rdpContext* context,
391 pClientContext* pc = (pClientContext*)context;
394 proxyData* pdata = pc->pdata;
397 rdpContext* ps = (rdpContext*)pdata->ps;
400 WINPR_ASSERT(ps->update);
401 WINPR_ASSERT(ps->update->SurfaceBits);
403 WLog_DBG(TAG,
"called");
404 return ps->update->SurfaceBits(ps, surfaceBitsCommand);
408static BOOL pf_client_SurfaceFrameMarker(rdpContext* context,
411 pClientContext* pc = (pClientContext*)context;
414 proxyData* pdata = pc->pdata;
417 rdpContext* ps = (rdpContext*)pdata->ps;
420 WINPR_ASSERT(ps->update);
421 WINPR_ASSERT(ps->update->SurfaceFrameMarker);
423 WLog_DBG(TAG,
"called");
424 return ps->update->SurfaceFrameMarker(ps, surfaceFrameMarker);
428static BOOL pf_client_window_create(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
432 pClientContext* pc = (pClientContext*)context;
433 proxyData* pdata =
nullptr;
434 rdpContext* ps =
nullptr;
438 ps = (rdpContext*)pdata->ps;
440 WINPR_ASSERT(ps->update);
441 WINPR_ASSERT(ps->update->window);
442 WINPR_ASSERT(ps->update->window->WindowCreate);
444 WLog_DBG(TAG,
"called");
445 rdp_update_lock(ps->update);
446 rc = ps->update->window->WindowCreate(ps, orderInfo, windowState);
447 rdp_update_unlock(ps->update);
452static BOOL pf_client_window_update(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
456 pClientContext* pc = (pClientContext*)context;
457 proxyData* pdata =
nullptr;
458 rdpContext* ps =
nullptr;
462 ps = (rdpContext*)pdata->ps;
464 WINPR_ASSERT(ps->update);
465 WINPR_ASSERT(ps->update->window);
466 WINPR_ASSERT(ps->update->window->WindowUpdate);
468 WLog_DBG(TAG,
"called");
469 rdp_update_lock(ps->update);
470 rc = ps->update->window->WindowUpdate(ps, orderInfo, windowState);
471 rdp_update_unlock(ps->update);
476static BOOL pf_client_window_icon(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
480 pClientContext* pc = (pClientContext*)context;
481 proxyData* pdata =
nullptr;
482 rdpContext* ps =
nullptr;
486 ps = (rdpContext*)pdata->ps;
488 WINPR_ASSERT(ps->update);
489 WINPR_ASSERT(ps->update->window);
490 WINPR_ASSERT(ps->update->window->WindowIcon);
492 WLog_DBG(TAG,
"called");
493 rdp_update_lock(ps->update);
494 rc = ps->update->window->WindowIcon(ps, orderInfo, windowIcon);
495 rdp_update_unlock(ps->update);
500static BOOL pf_client_window_cached_icon(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
504 pClientContext* pc = (pClientContext*)context;
505 proxyData* pdata =
nullptr;
506 rdpContext* ps =
nullptr;
510 ps = (rdpContext*)pdata->ps;
512 WINPR_ASSERT(ps->update);
513 WINPR_ASSERT(ps->update->window);
514 WINPR_ASSERT(ps->update->window->WindowCachedIcon);
516 WLog_DBG(TAG,
"called");
517 rdp_update_lock(ps->update);
518 rc = ps->update->window->WindowCachedIcon(ps, orderInfo, windowCachedIcon);
519 rdp_update_unlock(ps->update);
524static BOOL pf_client_window_delete(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
527 pClientContext* pc = (pClientContext*)context;
528 proxyData* pdata =
nullptr;
529 rdpContext* ps =
nullptr;
533 ps = (rdpContext*)pdata->ps;
535 WINPR_ASSERT(ps->update);
536 WINPR_ASSERT(ps->update->window);
537 WINPR_ASSERT(ps->update->window->WindowDelete);
539 WLog_DBG(TAG,
"called");
540 rdp_update_lock(ps->update);
541 rc = ps->update->window->WindowDelete(ps, orderInfo);
542 rdp_update_unlock(ps->update);
547static BOOL pf_client_notify_icon_create(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
551 pClientContext* pc = (pClientContext*)context;
552 proxyData* pdata =
nullptr;
553 rdpContext* ps =
nullptr;
557 ps = (rdpContext*)pdata->ps;
559 WINPR_ASSERT(ps->update);
560 WINPR_ASSERT(ps->update->window);
561 WINPR_ASSERT(ps->update->window->NotifyIconCreate);
563 WLog_DBG(TAG,
"called");
564 rdp_update_lock(ps->update);
565 rc = ps->update->window->NotifyIconCreate(ps, orderInfo, notifyIconState);
566 rdp_update_unlock(ps->update);
571static BOOL pf_client_notify_icon_update(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
575 pClientContext* pc = (pClientContext*)context;
576 proxyData* pdata =
nullptr;
577 rdpContext* ps =
nullptr;
581 ps = (rdpContext*)pdata->ps;
583 WINPR_ASSERT(ps->update);
584 WINPR_ASSERT(ps->update->window);
585 WINPR_ASSERT(ps->update->window->NotifyIconUpdate);
587 WLog_DBG(TAG,
"called");
588 rdp_update_lock(ps->update);
589 rc = ps->update->window->NotifyIconUpdate(ps, orderInfo, notifyIconState);
590 rdp_update_unlock(ps->update);
595static BOOL pf_client_notify_icon_delete(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
599 pClientContext* pc = (pClientContext*)context;
600 proxyData* pdata =
nullptr;
601 rdpContext* ps =
nullptr;
605 ps = (rdpContext*)pdata->ps;
607 WINPR_ASSERT(ps->update);
608 WINPR_ASSERT(ps->update->window);
609 WINPR_ASSERT(ps->update->window->NotifyIconDelete);
611 WLog_DBG(TAG,
"called");
612 rdp_update_lock(ps->update);
613 rc = ps->update->window->NotifyIconDelete(ps, orderInfo);
614 rdp_update_unlock(ps->update);
619static BOOL pf_client_monitored_desktop(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
623 pClientContext* pc = (pClientContext*)context;
624 proxyData* pdata =
nullptr;
625 rdpContext* ps =
nullptr;
629 ps = (rdpContext*)pdata->ps;
631 WINPR_ASSERT(ps->update);
632 WINPR_ASSERT(ps->update->window);
633 WINPR_ASSERT(ps->update->window->MonitoredDesktop);
635 WLog_DBG(TAG,
"called");
636 rdp_update_lock(ps->update);
637 rc = ps->update->window->MonitoredDesktop(ps, orderInfo, monitoredDesktop);
638 rdp_update_unlock(ps->update);
643static BOOL pf_client_non_monitored_desktop(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
646 pClientContext* pc = (pClientContext*)context;
647 proxyData* pdata =
nullptr;
648 rdpContext* ps =
nullptr;
652 ps = (rdpContext*)pdata->ps;
654 WINPR_ASSERT(ps->update);
655 WINPR_ASSERT(ps->update->window);
656 WINPR_ASSERT(ps->update->window->NonMonitoredDesktop);
658 WLog_DBG(TAG,
"called");
659 rdp_update_lock(ps->update);
660 rc = ps->update->window->NonMonitoredDesktop(ps, orderInfo);
661 rdp_update_unlock(ps->update);
665void pf_server_register_update_callbacks(rdpUpdate* update)
667 WINPR_ASSERT(update);
668 update->RefreshRect = pf_server_refresh_rect;
669 update->SuppressOutput = pf_server_suppress_output;
672void pf_client_register_update_callbacks(rdpUpdate* update)
674 WINPR_ASSERT(update);
675 update->BeginPaint = pf_client_begin_paint;
676 update->EndPaint = pf_client_end_paint;
677 update->BitmapUpdate = pf_client_bitmap_update;
678 update->DesktopResize = pf_client_desktop_resize;
679 update->RemoteMonitors = pf_client_remote_monitors;
680 update->SaveSessionInfo = pf_client_save_session_info;
681 update->ServerStatusInfo = pf_client_server_status_info;
682 update->SetKeyboardIndicators = pf_client_set_keyboard_indicators;
683 update->SetKeyboardImeStatus = pf_client_set_keyboard_ime_status;
686 update->SurfaceBits = pf_client_SurfaceBits;
687 update->SurfaceFrameMarker = pf_client_SurfaceFrameMarker;
690 update->window->WindowCreate = pf_client_window_create;
691 update->window->WindowUpdate = pf_client_window_update;
692 update->window->WindowIcon = pf_client_window_icon;
693 update->window->WindowCachedIcon = pf_client_window_cached_icon;
694 update->window->WindowDelete = pf_client_window_delete;
695 update->window->NotifyIconCreate = pf_client_notify_icon_create;
696 update->window->NotifyIconUpdate = pf_client_notify_icon_update;
697 update->window->NotifyIconDelete = pf_client_notify_icon_delete;
698 update->window->MonitoredDesktop = pf_client_monitored_desktop;
699 update->window->NonMonitoredDesktop = pf_client_non_monitored_desktop;
702 update->pointer->PointerSystem = pf_client_send_pointer_system;
703 update->pointer->PointerPosition = pf_client_send_pointer_position;
704 update->pointer->PointerColor = pf_client_send_pointer_color;
705 update->pointer->PointerLarge = pf_client_send_pointer_large;
706 update->pointer->PointerNew = pf_client_send_pointer_new;
707 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