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;
42 rdpContext* pc =
nullptr;
44 WINPR_ASSERT(ps->pdata);
45 pc = (rdpContext*)ps->pdata->pc;
47 WINPR_ASSERT(pc->update);
48 WINPR_ASSERT(pc->update->RefreshRect);
49 return pc->update->RefreshRect(pc, count, areas);
53static BOOL pf_server_suppress_output(rdpContext* context, BYTE allow,
const RECTANGLE_16* area)
55 pServerContext* ps = (pServerContext*)context;
56 rdpContext* pc =
nullptr;
58 WINPR_ASSERT(ps->pdata);
59 pc = (rdpContext*)ps->pdata->pc;
61 WINPR_ASSERT(pc->update);
62 WINPR_ASSERT(pc->update->SuppressOutput);
63 return pc->update->SuppressOutput(pc, allow, area);
73static BOOL pf_client_begin_paint(rdpContext* context)
75 pClientContext* pc = (pClientContext*)context;
76 proxyData* pdata =
nullptr;
77 rdpContext* ps =
nullptr;
81 ps = (rdpContext*)pdata->ps;
83 WINPR_ASSERT(ps->update);
84 WINPR_ASSERT(ps->update->BeginPaint);
85 WLog_DBG(TAG,
"called");
86 return ps->update->BeginPaint(ps);
95static BOOL pf_client_end_paint(rdpContext* context)
97 pClientContext* pc = (pClientContext*)context;
98 proxyData* pdata =
nullptr;
99 rdpContext* ps =
nullptr;
103 ps = (rdpContext*)pdata->ps;
105 WINPR_ASSERT(ps->update);
106 WINPR_ASSERT(ps->update->EndPaint);
108 WLog_DBG(TAG,
"called");
111 if (!ps->update->EndPaint(ps))
114 if (!pf_modules_run_hook(pdata->module, HOOK_TYPE_CLIENT_END_PAINT, pdata, context))
121static BOOL pf_client_bitmap_update(rdpContext* context,
const BITMAP_UPDATE* bitmap)
123 pClientContext* pc = (pClientContext*)context;
124 proxyData* pdata =
nullptr;
125 rdpContext* ps =
nullptr;
129 ps = (rdpContext*)pdata->ps;
131 WINPR_ASSERT(ps->update);
132 WINPR_ASSERT(ps->update->BitmapUpdate);
133 WLog_DBG(TAG,
"called");
134 return ps->update->BitmapUpdate(ps, bitmap);
138static BOOL pf_client_desktop_resize(rdpContext* context)
140 pClientContext* pc = (pClientContext*)context;
141 proxyData* pdata =
nullptr;
142 rdpContext* ps =
nullptr;
146 ps = (rdpContext*)pdata->ps;
148 WINPR_ASSERT(ps->update);
149 WINPR_ASSERT(ps->update->DesktopResize);
150 WINPR_ASSERT(context->settings);
151 WINPR_ASSERT(ps->settings);
152 WLog_DBG(TAG,
"called");
157 return ps->update->DesktopResize(ps);
161static BOOL pf_client_remote_monitors(rdpContext* context, UINT32 count,
164 pClientContext* pc = (pClientContext*)context;
165 proxyData* pdata =
nullptr;
166 rdpContext* ps =
nullptr;
170 ps = (rdpContext*)pdata->ps;
172 WLog_DBG(TAG,
"called");
173 return freerdp_display_send_monitor_layout(ps, count, monitors);
177static BOOL pf_client_send_pointer_system(rdpContext* context,
180 pClientContext* pc = (pClientContext*)context;
181 proxyData* pdata =
nullptr;
182 rdpContext* ps =
nullptr;
186 ps = (rdpContext*)pdata->ps;
188 WINPR_ASSERT(ps->update);
189 WINPR_ASSERT(ps->update->pointer);
190 WINPR_ASSERT(ps->update->pointer->PointerSystem);
191 WLog_DBG(TAG,
"called");
192 return ps->update->pointer->PointerSystem(ps, pointer_system);
196static BOOL pf_client_send_pointer_position(rdpContext* context,
199 pClientContext* pc = (pClientContext*)context;
200 proxyData* pdata =
nullptr;
201 rdpContext* ps =
nullptr;
205 ps = (rdpContext*)pdata->ps;
207 WINPR_ASSERT(ps->update);
208 WINPR_ASSERT(ps->update->pointer);
209 WINPR_ASSERT(ps->update->pointer->PointerPosition);
210 WLog_DBG(TAG,
"called");
211 return ps->update->pointer->PointerPosition(ps, pointerPosition);
215static BOOL pf_client_send_pointer_color(rdpContext* context,
218 pClientContext* pc = (pClientContext*)context;
219 proxyData* pdata =
nullptr;
220 rdpContext* ps =
nullptr;
224 ps = (rdpContext*)pdata->ps;
226 WINPR_ASSERT(ps->update);
227 WINPR_ASSERT(ps->update->pointer);
228 WINPR_ASSERT(ps->update->pointer->PointerColor);
229 WLog_DBG(TAG,
"called");
230 return ps->update->pointer->PointerColor(ps, pointer_color);
234static BOOL pf_client_send_pointer_large(rdpContext* context,
237 pClientContext* pc = (pClientContext*)context;
238 proxyData* pdata =
nullptr;
239 rdpContext* ps =
nullptr;
243 ps = (rdpContext*)pdata->ps;
245 WINPR_ASSERT(ps->update);
246 WINPR_ASSERT(ps->update->pointer);
247 WINPR_ASSERT(ps->update->pointer->PointerLarge);
248 WLog_DBG(TAG,
"called");
249 return ps->update->pointer->PointerLarge(ps, pointer_large);
253static BOOL pf_client_send_pointer_new(rdpContext* context,
const POINTER_NEW_UPDATE* pointer_new)
255 pClientContext* pc = (pClientContext*)context;
256 proxyData* pdata =
nullptr;
257 rdpContext* ps =
nullptr;
261 ps = (rdpContext*)pdata->ps;
263 WINPR_ASSERT(ps->update);
264 WINPR_ASSERT(ps->update->pointer);
265 WINPR_ASSERT(ps->update->pointer->PointerNew);
266 WLog_DBG(TAG,
"called");
267 return ps->update->pointer->PointerNew(ps, pointer_new);
271static BOOL pf_client_send_pointer_cached(rdpContext* context,
274 pClientContext* pc = (pClientContext*)context;
275 proxyData* pdata =
nullptr;
276 rdpContext* ps =
nullptr;
280 ps = (rdpContext*)pdata->ps;
282 WINPR_ASSERT(ps->update);
283 WINPR_ASSERT(ps->update->pointer);
284 WINPR_ASSERT(ps->update->pointer->PointerCached);
285 WLog_DBG(TAG,
"called");
286 return ps->update->pointer->PointerCached(ps, pointer_cached);
290static BOOL pf_client_save_session_info(rdpContext* context, UINT32 type,
void* data)
292 logon_info* logonInfo =
nullptr;
293 pClientContext* pc = (pClientContext*)context;
294 proxyData* pdata =
nullptr;
295 rdpContext* ps =
nullptr;
299 ps = (rdpContext*)pdata->ps;
301 WINPR_ASSERT(ps->update);
302 WINPR_ASSERT(ps->update->SaveSessionInfo);
304 WLog_DBG(TAG,
"called");
308 case INFO_TYPE_LOGON:
309 case INFO_TYPE_LOGON_LONG:
311 logonInfo = (logon_info*)data;
312 PROXY_LOG_INFO(TAG, pc,
"client logon info: Username: %s, Domain: %s",
313 logonInfo->username, logonInfo->domain);
321 return ps->update->SaveSessionInfo(ps, type, data);
325static BOOL pf_client_server_status_info(rdpContext* context, UINT32 status)
327 pClientContext* pc = (pClientContext*)context;
328 proxyData* pdata =
nullptr;
329 rdpContext* ps =
nullptr;
333 ps = (rdpContext*)pdata->ps;
335 WINPR_ASSERT(ps->update);
336 WINPR_ASSERT(ps->update->ServerStatusInfo);
338 WLog_DBG(TAG,
"called");
339 return ps->update->ServerStatusInfo(ps, status);
343static BOOL pf_client_set_keyboard_indicators(rdpContext* context, UINT16 led_flags)
345 pClientContext* pc = (pClientContext*)context;
346 proxyData* pdata =
nullptr;
347 rdpContext* ps =
nullptr;
351 ps = (rdpContext*)pdata->ps;
353 WINPR_ASSERT(ps->update);
354 WINPR_ASSERT(ps->update->SetKeyboardIndicators);
356 WLog_DBG(TAG,
"called");
357 return ps->update->SetKeyboardIndicators(ps, led_flags);
361static BOOL pf_client_set_keyboard_ime_status(rdpContext* context, UINT16 imeId, UINT32 imeState,
364 pClientContext* pc = (pClientContext*)context;
365 proxyData* pdata =
nullptr;
366 rdpContext* ps =
nullptr;
370 ps = (rdpContext*)pdata->ps;
372 WINPR_ASSERT(ps->update);
373 WINPR_ASSERT(ps->update->SetKeyboardImeStatus);
375 WLog_DBG(TAG,
"called");
376 return ps->update->SetKeyboardImeStatus(ps, imeId, imeState, imeConvMode);
380static BOOL pf_client_window_create(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
384 pClientContext* pc = (pClientContext*)context;
385 proxyData* pdata =
nullptr;
386 rdpContext* ps =
nullptr;
390 ps = (rdpContext*)pdata->ps;
392 WINPR_ASSERT(ps->update);
393 WINPR_ASSERT(ps->update->window);
394 WINPR_ASSERT(ps->update->window->WindowCreate);
396 WLog_DBG(TAG,
"called");
397 rdp_update_lock(ps->update);
398 rc = ps->update->window->WindowCreate(ps, orderInfo, windowState);
399 rdp_update_unlock(ps->update);
404static BOOL pf_client_window_update(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
408 pClientContext* pc = (pClientContext*)context;
409 proxyData* pdata =
nullptr;
410 rdpContext* ps =
nullptr;
414 ps = (rdpContext*)pdata->ps;
416 WINPR_ASSERT(ps->update);
417 WINPR_ASSERT(ps->update->window);
418 WINPR_ASSERT(ps->update->window->WindowUpdate);
420 WLog_DBG(TAG,
"called");
421 rdp_update_lock(ps->update);
422 rc = ps->update->window->WindowUpdate(ps, orderInfo, windowState);
423 rdp_update_unlock(ps->update);
428static BOOL pf_client_window_icon(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->WindowIcon);
444 WLog_DBG(TAG,
"called");
445 rdp_update_lock(ps->update);
446 rc = ps->update->window->WindowIcon(ps, orderInfo, windowIcon);
447 rdp_update_unlock(ps->update);
452static BOOL pf_client_window_cached_icon(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->WindowCachedIcon);
468 WLog_DBG(TAG,
"called");
469 rdp_update_lock(ps->update);
470 rc = ps->update->window->WindowCachedIcon(ps, orderInfo, windowCachedIcon);
471 rdp_update_unlock(ps->update);
476static BOOL pf_client_window_delete(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
479 pClientContext* pc = (pClientContext*)context;
480 proxyData* pdata =
nullptr;
481 rdpContext* ps =
nullptr;
485 ps = (rdpContext*)pdata->ps;
487 WINPR_ASSERT(ps->update);
488 WINPR_ASSERT(ps->update->window);
489 WINPR_ASSERT(ps->update->window->WindowDelete);
491 WLog_DBG(TAG,
"called");
492 rdp_update_lock(ps->update);
493 rc = ps->update->window->WindowDelete(ps, orderInfo);
494 rdp_update_unlock(ps->update);
499static BOOL pf_client_notify_icon_create(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo,
503 pClientContext* pc = (pClientContext*)context;
504 proxyData* pdata =
nullptr;
505 rdpContext* ps =
nullptr;
509 ps = (rdpContext*)pdata->ps;
511 WINPR_ASSERT(ps->update);
512 WINPR_ASSERT(ps->update->window);
513 WINPR_ASSERT(ps->update->window->NotifyIconCreate);
515 WLog_DBG(TAG,
"called");
516 rdp_update_lock(ps->update);
517 rc = ps->update->window->NotifyIconCreate(ps, orderInfo, notifyIconState);
518 rdp_update_unlock(ps->update);
523static BOOL pf_client_notify_icon_update(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->NotifyIconUpdate);
539 WLog_DBG(TAG,
"called");
540 rdp_update_lock(ps->update);
541 rc = ps->update->window->NotifyIconUpdate(ps, orderInfo, notifyIconState);
542 rdp_update_unlock(ps->update);
547static BOOL pf_client_notify_icon_delete(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->NotifyIconDelete);
563 WLog_DBG(TAG,
"called");
564 rdp_update_lock(ps->update);
565 rc = ps->update->window->NotifyIconDelete(ps, orderInfo);
566 rdp_update_unlock(ps->update);
571static BOOL pf_client_monitored_desktop(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->MonitoredDesktop);
587 WLog_DBG(TAG,
"called");
588 rdp_update_lock(ps->update);
589 rc = ps->update->window->MonitoredDesktop(ps, orderInfo, monitoredDesktop);
590 rdp_update_unlock(ps->update);
595static BOOL pf_client_non_monitored_desktop(rdpContext* context,
const WINDOW_ORDER_INFO* orderInfo)
598 pClientContext* pc = (pClientContext*)context;
599 proxyData* pdata =
nullptr;
600 rdpContext* ps =
nullptr;
604 ps = (rdpContext*)pdata->ps;
606 WINPR_ASSERT(ps->update);
607 WINPR_ASSERT(ps->update->window);
608 WINPR_ASSERT(ps->update->window->NonMonitoredDesktop);
610 WLog_DBG(TAG,
"called");
611 rdp_update_lock(ps->update);
612 rc = ps->update->window->NonMonitoredDesktop(ps, orderInfo);
613 rdp_update_unlock(ps->update);
617void pf_server_register_update_callbacks(rdpUpdate* update)
619 WINPR_ASSERT(update);
620 update->RefreshRect = pf_server_refresh_rect;
621 update->SuppressOutput = pf_server_suppress_output;
624void pf_client_register_update_callbacks(rdpUpdate* update)
626 WINPR_ASSERT(update);
627 update->BeginPaint = pf_client_begin_paint;
628 update->EndPaint = pf_client_end_paint;
629 update->BitmapUpdate = pf_client_bitmap_update;
630 update->DesktopResize = pf_client_desktop_resize;
631 update->RemoteMonitors = pf_client_remote_monitors;
632 update->SaveSessionInfo = pf_client_save_session_info;
633 update->ServerStatusInfo = pf_client_server_status_info;
634 update->SetKeyboardIndicators = pf_client_set_keyboard_indicators;
635 update->SetKeyboardImeStatus = pf_client_set_keyboard_ime_status;
638 update->window->WindowCreate = pf_client_window_create;
639 update->window->WindowUpdate = pf_client_window_update;
640 update->window->WindowIcon = pf_client_window_icon;
641 update->window->WindowCachedIcon = pf_client_window_cached_icon;
642 update->window->WindowDelete = pf_client_window_delete;
643 update->window->NotifyIconCreate = pf_client_notify_icon_create;
644 update->window->NotifyIconUpdate = pf_client_notify_icon_update;
645 update->window->NotifyIconDelete = pf_client_notify_icon_delete;
646 update->window->MonitoredDesktop = pf_client_monitored_desktop;
647 update->window->NonMonitoredDesktop = pf_client_non_monitored_desktop;
650 update->pointer->PointerSystem = pf_client_send_pointer_system;
651 update->pointer->PointerPosition = pf_client_send_pointer_position;
652 update->pointer->PointerColor = pf_client_send_pointer_color;
653 update->pointer->PointerLarge = pf_client_send_pointer_large;
654 update->pointer->PointerNew = pf_client_send_pointer_new;
655 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