[client,xfreerdp] use FreeRDP timer API for updates

Use the freerdp_timer_add API to delay a display update
This commit is contained in:
Armin Novak 2025-05-14 14:33:26 +02:00 committed by akallabeth
parent 8e3e163fd4
commit 9bb7e5dfaa
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5

View File

@ -20,6 +20,9 @@
#include <math.h>
#include <winpr/assert.h>
#include <winpr/sysinfo.h>
#include <freerdp/timer.h>
#include <X11/Xutil.h>
#ifdef WITH_XRANDR
@ -37,7 +40,7 @@
#include <freerdp/log.h>
#define TAG CLIENT_TAG("x11disp")
#define RESIZE_MIN_DELAY 200 /* minimum delay in ms between two resizes */
#define RESIZE_MIN_DELAY_NS 200000UL /* minimum delay in ms between two resizes */
struct s_xfDispContext
{
@ -59,8 +62,12 @@ struct s_xfDispContext
UINT32 lastSentDesktopScaleFactor;
UINT32 lastSentDeviceScaleFactor;
BYTE reserved3[4];
FreeRDP_TimerID timerID;
};
static BOOL xf_disp_check_context(void* context, xfContext** ppXfc, xfDispContext** ppXfDisp,
rdpSettings** ppSettings);
static BOOL xf_disp_sendResize(xfDispContext* xfDisp, BOOL fromTimer);
static UINT xf_disp_sendLayout(DispClientContext* disp, const rdpMonitor* monitors,
UINT32 nmonitors);
@ -120,31 +127,71 @@ static BOOL xf_update_last_sent(xfDispContext* xfDisp)
return TRUE;
}
static BOOL xf_disp_sendResize(xfDispContext* xfDisp)
static uint64_t xf_disp_OnTimer(rdpContext* context, WINPR_ATTR_UNUSED void* userdata,
WINPR_ATTR_UNUSED FreeRDP_TimerID timerID,
WINPR_ATTR_UNUSED uint64_t timestamp,
WINPR_ATTR_UNUSED uint64_t interval)
{
xfContext* xfc = NULL;
xfDispContext* xfDisp = NULL;
rdpSettings* settings = NULL;
if (!xf_disp_check_context(context, &xfc, &xfDisp, &settings))
return interval;
if (!xfDisp->activated)
return interval;
xf_disp_sendResize(xfDisp, TRUE);
xfDisp->timerID = 0;
return 0;
}
static BOOL update_timer(xfDispContext* xfDisp, uint64_t intervalNS)
{
WINPR_ASSERT(xfDisp);
if (xfDisp->timerID == 0)
{
rdpContext* context = &xfDisp->xfc->common.context;
xfDisp->timerID = freerdp_timer_add(context, intervalNS, xf_disp_OnTimer, NULL, true);
}
return TRUE;
}
BOOL xf_disp_sendResize(xfDispContext* xfDisp, BOOL fromTimer)
{
DISPLAY_CONTROL_MONITOR_LAYOUT layout = { 0 };
xfContext* xfc = NULL;
rdpSettings* settings = NULL;
if (!xfDisp || !xfDisp->xfc)
return FALSE;
xfc = xfDisp->xfc;
settings = xfc->common.context.settings;
/* If there is already a timer running skip the update and wait for the timer to expire. */
if ((xfDisp->timerID != 0) && !fromTimer)
return TRUE;
xfContext* xfc = xfDisp->xfc;
rdpSettings* settings = xfc->common.context.settings;
if (!settings)
return FALSE;
if (!xfDisp->activated || !xfDisp->disp)
return TRUE;
return update_timer(xfDisp, RESIZE_MIN_DELAY_NS);
if (GetTickCount64() - xfDisp->lastSentDate < RESIZE_MIN_DELAY)
return TRUE;
const uint64_t diff = winpr_GetTickCount64NS() - xfDisp->lastSentDate;
if (diff < RESIZE_MIN_DELAY_NS)
{
const uint64_t interval = RESIZE_MIN_DELAY_NS - diff;
return update_timer(xfDisp, interval);
}
if (!xf_disp_settings_changed(xfDisp))
return TRUE;
xfDisp->lastSentDate = GetTickCount64();
xfDisp->lastSentDate = winpr_GetTickCount64NS();
const UINT32 mcount = freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount);
if (mcount > 1)
@ -184,8 +231,7 @@ static BOOL xf_disp_queueResize(xfDispContext* xfDisp, UINT32 width, UINT32 heig
return TRUE;
xfDisp->targetWidth = width;
xfDisp->targetHeight = height;
xfDisp->lastSentDate = GetTickCount64();
return xf_disp_sendResize(xfDisp);
return xf_disp_sendResize(xfDisp, FALSE);
}
static BOOL xf_disp_set_window_resizable(xfDispContext* xfDisp)
@ -207,8 +253,8 @@ static BOOL xf_disp_set_window_resizable(xfDispContext* xfDisp)
return TRUE;
}
static BOOL xf_disp_check_context(void* context, xfContext** ppXfc, xfDispContext** ppXfDisp,
rdpSettings** ppSettings)
BOOL xf_disp_check_context(void* context, xfContext** ppXfc, xfDispContext** ppXfDisp,
rdpSettings** ppSettings)
{
xfContext* xfc = NULL;
@ -245,7 +291,7 @@ static void xf_disp_OnActivated(void* context, const ActivatedEventArgs* e)
if (e->firstActivation)
return;
xf_disp_sendResize(xfDisp);
xf_disp_sendResize(xfDisp, FALSE);
}
}
@ -263,27 +309,10 @@ static void xf_disp_OnGraphicsReset(void* context, const GraphicsResetEventArgs*
if (xfDisp->activated && !freerdp_settings_get_bool(settings, FreeRDP_Fullscreen))
{
xf_disp_set_window_resizable(xfDisp);
xf_disp_sendResize(xfDisp);
xf_disp_sendResize(xfDisp, FALSE);
}
}
static void xf_disp_OnTimer(void* context, const TimerEventArgs* e)
{
xfContext* xfc = NULL;
xfDispContext* xfDisp = NULL;
rdpSettings* settings = NULL;
WINPR_UNUSED(e);
if (!xf_disp_check_context(context, &xfc, &xfDisp, &settings))
return;
if (!xfDisp->activated)
return;
xf_disp_sendResize(xfDisp);
}
static void xf_disp_OnWindowStateChange(void* context, const WindowStateChangeEventArgs* e)
{
xfContext* xfc = NULL;
@ -298,7 +327,7 @@ static void xf_disp_OnWindowStateChange(void* context, const WindowStateChangeEv
if (!xfDisp->activated || !xfc->fullscreen)
return;
xf_disp_sendResize(xfDisp);
xf_disp_sendResize(xfDisp, FALSE);
}
xfDispContext* xf_disp_new(xfContext* xfc)
@ -335,7 +364,6 @@ xfDispContext* xf_disp_new(xfContext* xfc)
freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
PubSub_SubscribeActivated(pubSub, xf_disp_OnActivated);
PubSub_SubscribeGraphicsReset(pubSub, xf_disp_OnGraphicsReset);
PubSub_SubscribeTimer(pubSub, xf_disp_OnTimer);
PubSub_SubscribeWindowStateChange(pubSub, xf_disp_OnWindowStateChange);
return ret;
}
@ -350,7 +378,6 @@ void xf_disp_free(xfDispContext* disp)
wPubSub* pubSub = disp->xfc->common.context.pubSub;
PubSub_UnsubscribeActivated(pubSub, xf_disp_OnActivated);
PubSub_UnsubscribeGraphicsReset(pubSub, xf_disp_OnGraphicsReset);
PubSub_UnsubscribeTimer(pubSub, xf_disp_OnTimer);
PubSub_UnsubscribeWindowStateChange(pubSub, xf_disp_OnWindowStateChange);
}