21 #include <winpr/sysinfo.h>
25 #define TAG CLIENT_TAG("wayland.disp")
27 #define RESIZE_MIN_DELAY 200
29 struct s_wlfDispContext
32 DispClientContext* disp;
34 int eventBase, errorBase;
35 int lastSentWidth, lastSentHeight;
37 int targetWidth, targetHeight;
41 UINT16 lastSentDesktopOrientation;
42 UINT32 lastSentDesktopScaleFactor;
43 UINT32 lastSentDeviceScaleFactor;
46 static UINT wlf_disp_sendLayout(DispClientContext* disp,
const rdpMonitor* monitors,
49 static BOOL wlf_disp_settings_changed(wlfDispContext* wlfDisp)
51 rdpSettings* settings = NULL;
53 WINPR_ASSERT(wlfDisp);
54 WINPR_ASSERT(wlfDisp->wlc);
56 settings = wlfDisp->wlc->common.context.settings;
57 WINPR_ASSERT(settings);
59 if (wlfDisp->lastSentWidth != wlfDisp->targetWidth)
62 if (wlfDisp->lastSentHeight != wlfDisp->targetHeight)
65 if (wlfDisp->lastSentDesktopOrientation !=
69 if (wlfDisp->lastSentDesktopScaleFactor !=
73 if (wlfDisp->lastSentDeviceScaleFactor !=
77 if (wlfDisp->fullscreen != wlfDisp->wlc->fullscreen)
83 static BOOL wlf_update_last_sent(wlfDispContext* wlfDisp)
85 rdpSettings* settings = NULL;
87 WINPR_ASSERT(wlfDisp);
88 WINPR_ASSERT(wlfDisp->wlc);
90 settings = wlfDisp->wlc->common.context.settings;
91 WINPR_ASSERT(settings);
93 wlfDisp->lastSentWidth = wlfDisp->targetWidth;
94 wlfDisp->lastSentHeight = wlfDisp->targetHeight;
95 wlfDisp->lastSentDesktopOrientation =
97 wlfDisp->lastSentDesktopScaleFactor =
99 wlfDisp->lastSentDeviceScaleFactor =
101 wlfDisp->fullscreen = wlfDisp->wlc->fullscreen;
105 static BOOL wlf_disp_sendResize(wlfDispContext* wlfDisp)
109 rdpSettings* settings = NULL;
111 if (!wlfDisp || !wlfDisp->wlc)
115 settings = wlc->common.context.settings;
120 if (!wlfDisp->activated || !wlfDisp->disp)
123 if (GetTickCount64() - wlfDisp->lastSentDate < RESIZE_MIN_DELAY)
126 wlfDisp->lastSentDate = GetTickCount64();
128 if (!wlf_disp_settings_changed(wlfDisp))
141 wlfDisp->waitingResize = TRUE;
142 layout.Flags = DISPLAY_CONTROL_MONITOR_PRIMARY;
143 layout.Top = layout.Left = 0;
144 layout.Width = wlfDisp->targetWidth;
145 layout.Height = wlfDisp->targetHeight;
147 layout.DesktopScaleFactor =
150 layout.PhysicalWidth = wlfDisp->targetWidth;
151 layout.PhysicalHeight = wlfDisp->targetHeight;
153 if (IFCALLRESULT(CHANNEL_RC_OK, wlfDisp->disp->SendMonitorLayout, wlfDisp->disp, 1,
154 &layout) != CHANNEL_RC_OK)
157 return wlf_update_last_sent(wlfDisp);
160 static BOOL wlf_disp_set_window_resizable(wlfDispContext* wlfDisp)
167 static BOOL wlf_disp_check_context(
void* context,
wlfContext** ppwlc, wlfDispContext** ppwlfDisp,
168 rdpSettings** ppSettings)
180 if (!wlc->common.context.settings)
184 *ppwlfDisp = wlc->disp;
185 *ppSettings = wlc->common.context.settings;
189 static void wlf_disp_OnActivated(
void* context,
const ActivatedEventArgs* e)
192 wlfDispContext* wlfDisp = NULL;
193 rdpSettings* settings = NULL;
195 if (!wlf_disp_check_context(context, &wlc, &wlfDisp, &settings))
198 wlfDisp->waitingResize = FALSE;
202 wlf_disp_set_window_resizable(wlfDisp);
204 if (e->firstActivation)
207 wlf_disp_sendResize(wlfDisp);
211 static void wlf_disp_OnGraphicsReset(
void* context,
const GraphicsResetEventArgs* e)
214 wlfDispContext* wlfDisp = NULL;
215 rdpSettings* settings = NULL;
218 if (!wlf_disp_check_context(context, &wlc, &wlfDisp, &settings))
221 wlfDisp->waitingResize = FALSE;
225 wlf_disp_set_window_resizable(wlfDisp);
226 wlf_disp_sendResize(wlfDisp);
230 static void wlf_disp_OnTimer(
void* context,
const TimerEventArgs* e)
233 wlfDispContext* wlfDisp = NULL;
234 rdpSettings* settings = NULL;
237 if (!wlf_disp_check_context(context, &wlc, &wlfDisp, &settings))
243 wlf_disp_sendResize(wlfDisp);
248 wlfDispContext* ret = NULL;
249 wPubSub* pubSub = NULL;
250 rdpSettings* settings = NULL;
252 if (!wlc || !wlc->common.context.settings || !wlc->common.context.pubSub)
255 settings = wlc->common.context.settings;
256 pubSub = wlc->common.context.pubSub;
257 ret = calloc(1,
sizeof(wlfDispContext));
263 ret->lastSentWidth = ret->targetWidth =
265 ret->lastSentHeight = ret->targetHeight =
267 PubSub_SubscribeActivated(pubSub, wlf_disp_OnActivated);
268 PubSub_SubscribeGraphicsReset(pubSub, wlf_disp_OnGraphicsReset);
269 PubSub_SubscribeTimer(pubSub, wlf_disp_OnTimer);
273 void wlf_disp_free(wlfDispContext* disp)
280 wPubSub* pubSub = disp->wlc->common.context.pubSub;
281 PubSub_UnsubscribeActivated(pubSub, wlf_disp_OnActivated);
282 PubSub_UnsubscribeGraphicsReset(pubSub, wlf_disp_OnGraphicsReset);
283 PubSub_UnsubscribeTimer(pubSub, wlf_disp_OnTimer);
289 UINT wlf_disp_sendLayout(DispClientContext* disp,
const rdpMonitor* monitors,
size_t nmonitors)
291 UINT ret = CHANNEL_RC_OK;
293 wlfDispContext* wlfDisp = NULL;
294 rdpSettings* settings = NULL;
297 WINPR_ASSERT(monitors);
298 WINPR_ASSERT(nmonitors > 0);
299 WINPR_ASSERT(nmonitors <= UINT32_MAX);
301 wlfDisp = (wlfDispContext*)disp->custom;
302 WINPR_ASSERT(wlfDisp);
303 WINPR_ASSERT(wlfDisp->wlc);
305 settings = wlfDisp->wlc->common.context.settings;
306 WINPR_ASSERT(settings);
311 return CHANNEL_RC_NO_MEMORY;
313 for (
size_t i = 0; i < nmonitors; i++)
318 layout->Flags = (monitor->is_primary ? DISPLAY_CONTROL_MONITOR_PRIMARY : 0);
319 layout->Left = monitor->x;
320 layout->Top = monitor->y;
321 layout->Width = monitor->width;
322 layout->Height = monitor->height;
323 layout->Orientation = ORIENTATION_LANDSCAPE;
324 layout->PhysicalWidth = monitor->attributes.physicalWidth;
325 layout->PhysicalHeight = monitor->attributes.physicalHeight;
327 switch (monitor->attributes.orientation)
330 layout->Orientation = ORIENTATION_PORTRAIT;
334 layout->Orientation = ORIENTATION_LANDSCAPE_FLIPPED;
338 layout->Orientation = ORIENTATION_PORTRAIT_FLIPPED;
350 layout->Orientation = ORIENTATION_LANDSCAPE;
354 layout->DesktopScaleFactor =
356 layout->DeviceScaleFactor =
360 ret = IFCALLRESULT(CHANNEL_RC_OK, disp->SendMonitorLayout, disp, (UINT32)nmonitors, layouts);
365 BOOL wlf_disp_handle_configure(wlfDispContext* disp, int32_t width, int32_t height)
370 disp->targetWidth = width;
371 disp->targetHeight = height;
372 return wlf_disp_sendResize(disp);
375 static UINT wlf_DisplayControlCaps(DispClientContext* disp, UINT32 maxNumMonitors,
376 UINT32 maxMonitorAreaFactorA, UINT32 maxMonitorAreaFactorB)
379 wlfDispContext* wlfDisp = NULL;
380 rdpSettings* settings = NULL;
384 wlfDisp = (wlfDispContext*)disp->custom;
385 WINPR_ASSERT(wlfDisp);
386 WINPR_ASSERT(wlfDisp->wlc);
388 settings = wlfDisp->wlc->common.context.settings;
389 WINPR_ASSERT(settings);
392 "DisplayControlCapsPdu: MaxNumMonitors: %" PRIu32
" MaxMonitorAreaFactorA: %" PRIu32
393 " MaxMonitorAreaFactorB: %" PRIu32
"",
394 maxNumMonitors, maxMonitorAreaFactorA, maxMonitorAreaFactorB);
395 wlfDisp->activated = TRUE;
398 return CHANNEL_RC_OK;
400 WLog_DBG(TAG,
"DisplayControlCapsPdu: setting the window as resizable");
401 return wlf_disp_set_window_resizable(wlfDisp) ? CHANNEL_RC_OK : CHANNEL_RC_NO_MEMORY;
404 BOOL wlf_disp_init(wlfDispContext* wlfDisp, DispClientContext* disp)
406 rdpSettings* settings = NULL;
408 if (!wlfDisp || !wlfDisp->wlc || !disp)
411 settings = wlfDisp->wlc->common.context.settings;
416 wlfDisp->disp = disp;
417 disp->custom = (
void*)wlfDisp;
421 disp->DisplayControlCaps = wlf_DisplayControlCaps;
427 BOOL wlf_disp_uninit(wlfDispContext* wlfDisp, DispClientContext* disp)
429 if (!wlfDisp || !disp)
432 wlfDisp->disp = NULL;
438 uint32_t nmonitors = UwacDisplayGetNbOutputs(wlc->display);
440 for (uint32_t i = 0; i < nmonitors; i++)
442 const UwacOutput* monitor = UwacDisplayGetOutput(wlc->display, i);
448 UwacOutputGetPosition(monitor, &pos);
449 UwacOutputGetResolution(monitor, &resolution);
451 printf(
" %s [%u] %dx%d\t+%d+%d\n", (i == 0) ?
"*" :
" ", i, resolution.width,
452 resolution.height, pos.x, pos.y);
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.
FREERDP_API UINT16 freerdp_settings_get_uint16(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt16 id)
Returns a UINT16 settings value.