*
* @return 0 on success, otherwise a Win32 error code
*/
-static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
+static UINT rdpgfx_send_caps_advertise_pdu(RdpgfxClientContext* context,
+ const RDPGFX_CAPS_ADVERTISE_PDU* pdu)
{
- UINT error;
- UINT32 x;
- wStream* s;
+ UINT error = CHANNEL_RC_OK;
UINT16 index;
- RDPGFX_PLUGIN* gfx;
RDPGFX_HEADER header;
RDPGFX_CAPSET* capsSet;
+ RDPGFX_PLUGIN* gfx;
+ RDPGFX_CHANNEL_CALLBACK* callback;
+ wStream* s;
+ gfx = (RDPGFX_PLUGIN*) context->handle;
+ callback = gfx->listener_callback->channel_callback;
+ header.flags = 0;
+ header.cmdId = RDPGFX_CMDID_CAPSADVERTISE;
+ header.pduLength = RDPGFX_HEADER_SIZE + 2;
+
+ for (index = 0; index < pdu->capsSetCount; index++)
+ {
+ capsSet = &(pdu->capsSets[index]);
+ header.pduLength += RDPGFX_CAPSET_BASE_SIZE + capsSet->length;
+ }
+
+ WLog_Print(gfx->log, WLOG_DEBUG, "SendCapsAdvertisePdu %"PRIu16"", pdu->capsSetCount);
+ s = Stream_New(NULL, header.pduLength);
+
+ if (!s)
+ {
+ WLog_ERR(TAG, "Stream_New failed!");
+ return CHANNEL_RC_NO_MEMORY;
+ }
+
+ if ((error = rdpgfx_write_header(s, &header)))
+ goto fail;
+
+ /* RDPGFX_CAPS_ADVERTISE_PDU */
+ Stream_Write_UINT16(s, pdu->capsSetCount); /* capsSetCount (2 bytes) */
+
+ for (index = 0; index < pdu->capsSetCount; index++)
+ {
+ capsSet = &(pdu->capsSets[index]);
+ Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */
+ Stream_Write_UINT32(s, capsSet->length); /* capsDataLength (4 bytes) */
+ Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
+ Stream_Zero(s, capsSet->length - 4);
+ }
+
+ Stream_SealLength(s);
+ error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s),
+ Stream_Buffer(s), NULL);
+fail:
+ Stream_Free(s, TRUE);
+ return error;
+}
+
+/**
+ * Function description
+ *
+ * @return 0 on success, otherwise a Win32 error code
+ */
+static UINT rdpgfx_send_supported_caps(RDPGFX_CHANNEL_CALLBACK* callback)
+{
+ UINT error = CHANNEL_RC_OK;
+ RDPGFX_PLUGIN* gfx;
+ RdpgfxClientContext* context;
+ RDPGFX_CAPSET* capsSet;
RDPGFX_CAPSET capsSets[RDPGFX_NUMBER_CAPSETS] = { 0 };
RDPGFX_CAPS_ADVERTISE_PDU pdu;
gfx = (RDPGFX_PLUGIN*) callback->plugin;
- header.flags = 0;
- header.cmdId = RDPGFX_CMDID_CAPSADVERTISE;
+ context = (RdpgfxClientContext*) gfx->iface.pInterface;
pdu.capsSetCount = 0;
pdu.capsSets = (RDPGFX_CAPSET*) capsSets;
capsSet = &capsSets[pdu.capsSetCount++];
#endif
}
- header.pduLength = RDPGFX_HEADER_SIZE + 2;
-
- for (x = 0; x < pdu.capsSetCount; x++)
- header.pduLength += RDPGFX_CAPSET_BASE_SIZE + capsSets[x].length;
-
- WLog_Print(gfx->log, WLOG_DEBUG, "SendCapsAdvertisePdu %"PRIu16"", pdu.capsSetCount);
- s = Stream_New(NULL, header.pduLength);
-
- if (!s)
- {
- WLog_ERR(TAG, "Stream_New failed!");
- return CHANNEL_RC_NO_MEMORY;
- }
-
- if ((error = rdpgfx_write_header(s, &header)))
- goto fail;
-
- /* RDPGFX_CAPS_ADVERTISE_PDU */
- Stream_Write_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */
-
- for (index = 0; index < pdu.capsSetCount; index++)
+ if (context)
{
- capsSet = &(pdu.capsSets[index]);
- Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */
- Stream_Write_UINT32(s, capsSet->length); /* capsDataLength (4 bytes) */
- Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
- Stream_Zero(s, capsSet->length - 4);
+ IFCALLRET(context->CapsAdvertise, error, context, &pdu);
}
- Stream_SealLength(s);
- error = callback->channel->Write(callback->channel, (UINT32) Stream_Length(s),
- Stream_Buffer(s), NULL);
-fail:
- Stream_Free(s, TRUE);
return error;
}
UINT32 capsDataLength;
RDPGFX_CAPS_CONFIRM_PDU pdu;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
+ RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
pdu.capsSet = &capsSet;
if (Stream_GetRemainingLength(s) < 12)
gfx->ConnectionCaps = capsSet;
WLog_Print(gfx->log, WLOG_DEBUG, "RecvCapsConfirmPdu: version: 0x%08"PRIX32" flags: 0x%08"PRIX32"",
capsSet.version, capsSet.flags);
+
+ if (context)
+ {
+ IFCALL(context->CapsConfirm, context, &pdu);
+ }
+
return CHANNEL_RC_OK;
}
*
* @return 0 on success, otherwise a Win32 error code
*/
-static UINT rdpgfx_send_frame_acknowledge_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
+static UINT rdpgfx_send_frame_acknowledge_pdu(RdpgfxClientContext* context,
RDPGFX_FRAME_ACKNOWLEDGE_PDU* pdu)
{
UINT error;
wStream* s;
RDPGFX_HEADER header;
- RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
+ RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle;
+ RDPGFX_CHANNEL_CALLBACK* callback = gfx->listener_callback->channel_callback;
header.flags = 0;
header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE;
header.pduLength = RDPGFX_HEADER_SIZE + 12;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
UINT error = CHANNEL_RC_OK;
- BOOL sendAck = TRUE;
if (Stream_GetRemainingLength(s) < RDPGFX_END_FRAME_PDU_SIZE)
{
gfx->TotalDecodedFrames++;
ack.frameId = pdu.frameId;
ack.totalFramesDecoded = gfx->TotalDecodedFrames;
- IFCALLRET(context->PreFrameAck, sendAck, context, &ack);
- if (sendAck)
+ if (gfx->sendFrameAcks)
{
if (gfx->suspendFrameAcks)
{
ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT;
if (gfx->TotalDecodedFrames == 1)
- if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack)))
+ if ((error = rdpgfx_send_frame_acknowledge_pdu(context, &ack)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
{
ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE;
- if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack)))
+ if ((error = rdpgfx_send_frame_acknowledge_pdu(context, &ack)))
WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
qoe.timeDiffEDR = 1;
if ((error = rdpgfx_send_qoe_frame_acknowledge_pdu(callback, &qoe)))
- WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"",
+ WLog_Print(gfx->log, WLOG_ERROR,
+ "rdpgfx_send_qoe_frame_acknowledge_pdu failed with error %"PRIu32"",
error);
}
static UINT rdpgfx_on_open(IWTSVirtualChannelCallback* pChannelCallback)
{
RDPGFX_CHANNEL_CALLBACK* callback = (RDPGFX_CHANNEL_CALLBACK*) pChannelCallback;
- WLog_DBG(TAG, "OnOpen");
- return rdpgfx_send_caps_advertise_pdu(callback);
+ RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin;
+ RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface;
+ UINT error = CHANNEL_RC_OK;
+ BOOL do_caps_advertise = TRUE;
+ gfx->sendFrameAcks = TRUE;
+
+ if (context)
+ {
+ IFCALLRET(context->OnOpen, error, context, &do_caps_advertise, &gfx->sendFrameAcks);
+
+ if (error)
+ WLog_Print(gfx->log, WLOG_ERROR, "context->OnOpen failed with error %"PRIu32"", error);
+ }
+
+ if (do_caps_advertise)
+ error = rdpgfx_send_supported_caps(callback);
+
+ return error;
}
/**
}
}
+ if (context)
+ {
+ IFCALL(context->OnClose, context);
+ }
+
return CHANNEL_RC_OK;
}
context->GetSurfaceData = rdpgfx_get_surface_data;
context->SetCacheSlotData = rdpgfx_set_cache_slot_data;
context->GetCacheSlotData = rdpgfx_get_cache_slot_data;
+ context->CapsAdvertise = rdpgfx_send_caps_advertise_pdu;
+ context->FrameAcknowledge = rdpgfx_send_frame_acknowledge_pdu;
gfx->iface.pInterface = (void*) context;
gfx->zgfx = zgfx_context_new(FALSE);