Since ec027bf dynamic resolution is broken when used with egfx. Before that commit
we were tracking a server sent resize by setting a DesktopResize callback. This callback
is called when the desktop is resized by the server. Anyway the problem was that when this
callback is called, the activation sequence is not always completed, which were leading to
some freeze with 2012r2 servers (sending packets before the sequence is finished).
So with the faulty commit, we are tracking server resizes by subscribing to the Actived
event, that is called at the end of a reactivation sequence, so we're sure to not send packets
when not fully activated.
Anyway the issue that shows on (#4330) is that when you use egfx, no reactivation sequence happens,
the server only sends a ResetGraphics message with the new size, and so we miss the resized event.
This fix introduces a new GraphicsReset event, makes the display channel subscribe to that event,
and react accordingly.
wStream* s;
RDPGFX_AVC420_BITMAP_STREAM h264;
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
- s = Stream_New(cmd->data, cmd->length);
+ s = Stream_New(cmd->data, cmd->length);
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
s = Stream_New(cmd->data, cmd->length);
-
if (!s)
{
WLog_ERR(TAG, "Stream_New failed!");
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
UINT error = CHANNEL_RC_OK;
+ GraphicsResetEventArgs graphicsReset;
if (Stream_GetRemainingLength(s) < 12)
{
WLog_Print(gfx->log, WLOG_ERROR, "context->ResetGraphics failed with error %"PRIu32"", error);
}
+ /* some listeners may be interested (namely the display channel) */
+ EventArgsInit(&graphicsReset, "xfreerdp");
+ graphicsReset.width = pdu.width;
+ graphicsReset.height = pdu.height;
+ PubSub_OnGraphicsReset(gfx->rdpcontext->pubSub, gfx->rdpcontext, &graphicsReset);
+
free(pdu.monitorDefArray);
return error;
}
gfx->iface.Connected = NULL;
gfx->iface.Disconnected = NULL;
gfx->iface.Terminated = rdpgfx_plugin_terminated;
- gfx->SurfaceTable = HashTable_New(TRUE);
+ gfx->rdpcontext = ((freerdp *)gfx->settings->instance)->context;
+ gfx->SurfaceTable = HashTable_New(TRUE);
if (!gfx->SurfaceTable)
{
free(gfx);
gfx->SmallCache = TRUE;
gfx->MaxCacheSlot = gfx->SmallCache ? 4096 : 25600;
- context = (RdpgfxClientContext *)calloc(1, sizeof(RdpgfxClientContext));
+ context = (RdpgfxClientContext *)calloc(1, sizeof(RdpgfxClientContext));
if (!context)
{
free(gfx);
}
}
+
+static void xf_disp_OnGraphicsReset(rdpContext* context, GraphicsResetEventArgs* e)
+{
+ xfContext *xfc = (xfContext *)context;
+ xfDispContext *xfDisp = xfc->xfDisp;
+ rdpSettings *settings = context->settings;
+
+ xfDisp->waitingResize = FALSE;
+
+ if (xfDisp->activated && !settings->Fullscreen)
+ {
+ xf_disp_set_window_resizable(xfDisp);
+
+ /* if a resize has been done recently don't do anything and let the timer
+ * perform the resize */
+ if (GetTickCount64() - xfDisp->lastSentDate < RESIZE_MIN_DELAY)
+ return;
+
+ if ((xfDisp->lastSentWidth != xfDisp->targetWidth) || (xfDisp->lastSentHeight != xfDisp->targetHeight))
+ {
+ WLog_DBG(TAG, "performing delayed resize to %dx%d", xfDisp->targetWidth, xfDisp->targetHeight);
+ xf_disp_sendResize(xfDisp, xfDisp->targetWidth, xfDisp->targetHeight);
+ }
+ }
+}
+
static void xf_disp_OnTimer(rdpContext* context, TimerEventArgs* e)
{
xfContext *xfc = (xfContext *)context;
ret->lastSentHeight = ret->targetHeight = xfc->context.settings->DesktopHeight;
PubSub_SubscribeActivated(xfc->context.pubSub, (pActivatedEventHandler)xf_disp_OnActivated);
+ PubSub_SubscribeGraphicsReset(xfc->context.pubSub, (pGraphicsResetEventHandler)xf_disp_OnGraphicsReset);
PubSub_SubscribeTimer(xfc->context.pubSub, (pTimerEventHandler)xf_disp_OnTimer);
return ret;
}
UINT64 now;
DEFINE_EVENT_END(Timer)
+DEFINE_EVENT_BEGIN(GraphicsReset)
+UINT32 width;
+UINT32 height;
+DEFINE_EVENT_END(GraphicsReset)
+
#ifdef __cplusplus
}
#endif
DEFINE_EVENT_ENTRY(MouseEvent)
DEFINE_EVENT_ENTRY(Activated)
DEFINE_EVENT_ENTRY(Timer)
+ DEFINE_EVENT_ENTRY(GraphicsReset)
};
/** Allocator function for a rdp context.