Merge pull request #5383 from akallabeth/gfx_spec_update

Updated GFX to 10.6 spec
This commit is contained in:
Martin Fleisz 2019-05-08 13:42:50 +02:00 committed by GitHub
commit e4a9172e13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 624 additions and 354 deletions

View File

@ -106,6 +106,32 @@ fail:
return error;
}
static BOOL rdpgfx_is_capability_filtered(RDPGFX_PLUGIN* gfx, UINT32 caps)
{
const UINT32 filter = gfx->capsFilter;
const UINT32 capList[] =
{
RDPGFX_CAPVERSION_8,
RDPGFX_CAPVERSION_81,
RDPGFX_CAPVERSION_10,
RDPGFX_CAPVERSION_101,
RDPGFX_CAPVERSION_102,
RDPGFX_CAPVERSION_103,
RDPGFX_CAPVERSION_104,
RDPGFX_CAPVERSION_105,
RDPGFX_CAPVERSION_106
};
UINT32 x;
for (x = 0; x < ARRAYSIZE(capList); x++)
{
if (caps == capList[x])
return (filter & (1 << x)) != 0;
}
return TRUE;
}
/**
* Function description
*
@ -113,54 +139,69 @@ fail:
*/
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;
if (!callback)
return ERROR_BAD_ARGUMENTS;
gfx = (RDPGFX_PLUGIN*) callback->plugin;
if (!gfx)
return ERROR_BAD_CONFIGURATION;
context = (RdpgfxClientContext*) gfx->iface.pInterface;
if (!context)
return ERROR_BAD_CONFIGURATION;
pdu.capsSetCount = 0;
pdu.capsSets = (RDPGFX_CAPSET*) capsSets;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_8;
capsSet->length = 4;
capsSet->flags = 0;
if (gfx->ThinClient)
capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT;
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_8))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_8;
capsSet->length = 4;
capsSet->flags = 0;
/* in CAPVERSION_8 the spec says that we should not have both
* thinclient and smallcache (and thinclient implies a small cache)
*/
if (gfx->SmallCache && !gfx->ThinClient)
capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
if (gfx->ThinClient)
capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_81;
capsSet->length = 4;
capsSet->flags = 0;
/* in CAPVERSION_8 the spec says that we should not have both
* thinclient and smallcache (and thinclient implies a small cache)
*/
if (gfx->SmallCache && !gfx->ThinClient)
capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
}
if (gfx->ThinClient)
capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT;
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_81))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_81;
capsSet->length = 4;
capsSet->flags = 0;
if (gfx->SmallCache)
capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
if (gfx->ThinClient)
capsSet->flags |= RDPGFX_CAPS_FLAG_THINCLIENT;
if (gfx->SmallCache)
capsSet->flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
#ifdef WITH_GFX_H264
if (gfx->H264)
capsSet->flags |= RDPGFX_CAPS_FLAG_AVC420_ENABLED;
if (gfx->H264)
capsSet->flags |= RDPGFX_CAPS_FLAG_AVC420_ENABLED;
#endif
}
if (!gfx->H264 || gfx->AVC444)
{
UINT32 caps10Flags = 0;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_10;
capsSet->length = 4;
if (gfx->SmallCache)
caps10Flags |= RDPGFX_CAPS_FLAG_SMALL_CACHE;
@ -173,54 +214,68 @@ static UINT rdpgfx_send_supported_caps(RDPGFX_CHANNEL_CALLBACK* callback)
#else
caps10Flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#endif
capsSet->flags = caps10Flags;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_101;
capsSet->length = 0x10;
capsSet->flags = 0;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_102;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_10))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_10;
capsSet->length = 4;
capsSet->flags = caps10Flags;
}
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_101))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_101;
capsSet->length = 0x10;
capsSet->flags = 0;
}
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_102))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_102;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
}
if (gfx->ThinClient)
caps10Flags |= RDPGFX_CAPS_FLAG_AVC_THINCLIENT;
/* Reports from Remmina suggest that current H264 decoder settings do
* not work with newer GFX protocol versions.
* Need to investigate this.
* Until resolved, disable the newer protocol versions. */
#if 0
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_103;
capsSet->length = 0x4;
capsSet->flags = caps10Flags & ~RDPGFX_CAPS_FLAG_SMALL_CACHE;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_104;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_105;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
/* TODO: Until RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU and
* RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU are not implemented do not
* announce the following version */
#if 0
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_106;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
#endif
#endif
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_103))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_103;
capsSet->length = 0x4;
capsSet->flags = caps10Flags & ~RDPGFX_CAPS_FLAG_SMALL_CACHE;
}
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_104))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_104;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
}
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_105))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_105;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
}
if (!rdpgfx_is_capability_filtered(gfx, RDPGFX_CAPVERSION_106))
{
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_106;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
}
}
if (context)
{
IFCALLRET(context->CapsAdvertise, error, context, &pdu);
}
return error;
return IFCALLRESULT(ERROR_BAD_CONFIGURATION, context->CapsAdvertise, context, &pdu);
}
/**
@ -269,8 +324,22 @@ static UINT rdpgfx_send_frame_acknowledge_pdu(RdpgfxClientContext* context,
UINT error;
wStream* s;
RDPGFX_HEADER header;
RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) context->handle;
RDPGFX_CHANNEL_CALLBACK* callback = gfx->listener_callback->channel_callback;
RDPGFX_PLUGIN* gfx;
RDPGFX_CHANNEL_CALLBACK* callback;
if (!context || !pdu)
return ERROR_BAD_ARGUMENTS;
gfx = (RDPGFX_PLUGIN*) context->handle;
if (!gfx)
return ERROR_BAD_CONFIGURATION;
callback = gfx->listener_callback->channel_callback;
if (!callback)
return ERROR_BAD_CONFIGURATION;
header.flags = 0;
header.cmdId = RDPGFX_CMDID_FRAMEACKNOWLEDGE;
header.pduLength = RDPGFX_HEADER_SIZE + 12;
@ -684,6 +753,9 @@ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback,
case RDPGFX_CAPVERSION_10:
case RDPGFX_CAPVERSION_102:
case RDPGFX_CAPVERSION_103:
case RDPGFX_CAPVERSION_104:
case RDPGFX_CAPVERSION_105:
case RDPGFX_CAPVERSION_106:
if (gfx->SendQoeAck)
{
RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU qoe;
@ -1943,6 +2015,7 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
gfx->H264 = gfx->settings->GfxH264;
gfx->AVC444 = gfx->settings->GfxAVC444;
gfx->SendQoeAck = gfx->settings->GfxSendQoeAck;
gfx->capsFilter = gfx->settings->GfxCapsFilter;
if (gfx->H264)
gfx->SmallCache = TRUE;

View File

@ -67,6 +67,7 @@ struct _RDPGFX_PLUGIN
BOOL ProgressiveV2;
BOOL H264;
BOOL AVC444;
UINT32 capsFilter;
ZGFX_CONTEXT* zgfx;
UINT32 UnacknowledgedFrames;

View File

@ -1193,7 +1193,10 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
UINT16 index;
RDPGFX_CAPSET* capsSets;
RDPGFX_CAPS_ADVERTISE_PDU pdu;
UINT error = CHANNEL_RC_OK;
UINT error = ERROR_INVALID_DATA;
if (!context)
return ERROR_BAD_ARGUMENTS;
if (Stream_GetRemainingLength(s) < 2)
{
@ -1214,10 +1217,7 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
RDPGFX_CAPSET* capsSet = &(pdu.capsSets[index]);
if (Stream_GetRemainingLength(s) < 8)
{
WLog_ERR(TAG, "not enough data!");
return ERROR_INVALID_DATA;
}
goto fail;
Stream_Read_UINT32(s, capsSet->version); /* version (4 bytes) */
Stream_Read_UINT32(s, capsSet->length); /* capsDataLength (4 bytes) */
@ -1225,23 +1225,22 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
if (capsSet->length >= 4)
{
if (Stream_GetRemainingLength(s) < 4)
return ERROR_INVALID_DATA;
goto fail;
Stream_Peek_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
}
if (!Stream_SafeSeek(s, capsSet->length))
return ERROR_INVALID_DATA;
goto fail;
}
if (context)
{
IFCALLRET(context->CapsAdvertise, error, context, &pdu);
error = ERROR_BAD_CONFIGURATION;
IFCALLRET(context->CapsAdvertise, error, context, &pdu);
if (error)
WLog_ERR(TAG, "context->CapsAdvertise failed with error %"PRIu32"", error);
}
if (error)
WLog_ERR(TAG, "context->CapsAdvertise failed with error %"PRIu32"", error);
fail:
free(capsSets);
return error;
}

View File

@ -1024,7 +1024,7 @@ static jboolean JNICALL jni_freerdp_send_clipboard_data(
const jbyte* data = jdata != NULL ? (*env)->GetStringUTFChars(env, jdata,
NULL) : NULL;
int data_length = data ? strlen(data) : 0;
jboolean ret = JNI_FALSE;;
jboolean ret = JNI_FALSE;
event = (ANDROID_EVENT*) android_event_clipboard_new((void*)data, data_length);
if (!event)

View File

@ -823,7 +823,7 @@ void wf_size_scrollbars(wfContext* wfc, UINT32 client_width,
{
SCROLLINFO si;
BOOL horiz = wfc->xScrollVisible;
BOOL vert = wfc->yScrollVisible;;
BOOL vert = wfc->yScrollVisible;
if (!horiz && client_width < wfc->context.settings->DesktopWidth)
{

View File

@ -49,10 +49,7 @@ void xf_OnChannelConnectedEventHandler(void* context, ChannelConnectedEventArgs*
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_init(xfc->context.gdi, (RdpgfxClientContext*) e->pInterface);
else
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
xf_graphics_pipeline_init(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0)
{
@ -106,10 +103,7 @@ void xf_OnChannelDisconnectedEventHandler(void* context, ChannelDisconnectedEven
}
else if (strcmp(e->name, RDPGFX_DVC_CHANNEL_NAME) == 0)
{
if (settings->SoftwareGdi)
gdi_graphics_pipeline_uninit(xfc->context.gdi, (RdpgfxClientContext*) e->pInterface);
else
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
xf_graphics_pipeline_uninit(xfc, (RdpgfxClientContext*) e->pInterface);
}
else if (strcmp(e->name, RAIL_SVC_CHANNEL_NAME) == 0)
{

View File

@ -38,19 +38,22 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
RECTANGLE_16 surfaceRect;
rdpGdi* gdi;
UINT32 nbRects, x;
double sx, sy;
const RECTANGLE_16* rects;
gdi = xfc->context.gdi;
surfaceX = surface->gdi.outputOriginX;
surfaceY = surface->gdi.outputOriginY;
surfaceRect.left = 0;
surfaceRect.top = 0;
surfaceRect.right = surface->gdi.width;
surfaceRect.bottom = surface->gdi.height;
surfaceRect.right = surface->gdi.mappedWidth;
surfaceRect.bottom = surface->gdi.mappedHeight;
XSetClipMask(xfc->display, xfc->gc, None);
XSetFunction(xfc->display, xfc->gc, GXcopy);
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
region16_intersect_rect(&(surface->gdi.invalidRegion),
&(surface->gdi.invalidRegion), &surfaceRect);
sx = surface->gdi.outputTargetWidth / (double)surface->gdi.mappedWidth;
sy = surface->gdi.outputTargetHeight / (double)surface->gdi.mappedHeight;
if (!(rects = region16_rects(&surface->gdi.invalidRegion, &nbRects)))
return CHANNEL_RC_OK;
@ -59,19 +62,21 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
{
const UINT32 nXSrc = rects[x].left;
const UINT32 nYSrc = rects[x].top;
const UINT32 width = rects[x].right - nXSrc;
const UINT32 height = rects[x].bottom - nYSrc;
const UINT32 nXDst = surfaceX + nXSrc;
const UINT32 nYDst = surfaceY + nYSrc;
const UINT32 swidth = rects[x].right - nXSrc;
const UINT32 sheight = rects[x].bottom - nYSrc;
const UINT32 nXDst = surfaceX + nXSrc * sx;
const UINT32 nYDst = surfaceY + nYSrc * sy;
const UINT32 dwidth = swidth * sx;
const UINT32 dheight = sheight * sy;
if (surface->stage)
{
if (!freerdp_image_copy(surface->stage, gdi->dstFormat,
surface->stageScanline, nXSrc, nYSrc,
width, height,
surface->gdi.data, surface->gdi.format,
surface->gdi.scanline, nXSrc, nYSrc,
NULL, FREERDP_FLIP_NONE))
if (!freerdp_image_scale(surface->stage, gdi->dstFormat,
surface->stageScanline, nXSrc, nYSrc,
dwidth, dheight,
surface->gdi.data, surface->gdi.format,
surface->gdi.scanline, nXSrc, nYSrc,
swidth, sheight))
goto fail;
}
@ -79,9 +84,9 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
{
XPutImage(xfc->display, xfc->primary, xfc->gc,
surface->image, nXSrc, nYSrc,
nXDst, nYDst, width, height);
nXDst, nYDst, dwidth, dheight);
xf_lock_x11(xfc, FALSE);
xf_rail_paint(xfc, nXDst, nYDst, nXDst + width, nYDst + height);
xf_rail_paint(xfc, nXDst, nYDst, nXDst + dwidth, nYDst + dheight);
xf_unlock_x11(xfc, FALSE);
}
else
@ -90,15 +95,15 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|| xfc->context.settings->MultiTouchGestures)
{
XPutImage(xfc->display, xfc->primary, xfc->gc, surface->image,
nXSrc, nYSrc, nXDst, nYDst, width, height);
xf_draw_screen(xfc, nXDst, nYDst, width, height);
nXSrc, nYSrc, nXDst, nYDst, dwidth, dheight);
xf_draw_screen(xfc, nXDst, nYDst, dwidth, dheight);
}
else
#endif
{
XPutImage(xfc->display, xfc->drawable, xfc->gc,
surface->image, nXSrc, nYSrc,
nXDst, nYDst, width, height);
nXDst, nYDst, dwidth, dheight);
}
}
@ -115,7 +120,6 @@ static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
UINT16 count;
UINT32 index;
UINT status = CHANNEL_RC_OK;
xfGfxSurface* surface;
UINT16* pSurfaceIds = NULL;
rdpGdi* gdi = (rdpGdi*)context->custom;
xfContext* xfc = (xfContext*) gdi->context;
@ -134,12 +138,22 @@ static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
for (index = 0; index < count; index++)
{
surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]);
xfGfxSurface* surface = (xfGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]);
if (!surface || !surface->gdi.outputMapped)
if (!surface)
continue;
status = xf_OutputUpdate(xfc, surface);
/* If UpdateSurfaceArea callback is available, the output has already been updated. */
if (context->UpdateSurfaceArea)
{
if (surface->gdi.windowId != 0)
continue;
}
status = ERROR_INTERNAL_ERROR;
if (surface->gdi.outputMapped)
status = xf_OutputUpdate(xfc, surface);
if (status != 0)
break;
@ -182,8 +196,8 @@ UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y,
surfaceRect.left = surface->gdi.outputOriginX;
surfaceRect.top = surface->gdi.outputOriginY;
surfaceRect.right = surface->gdi.outputOriginX + surface->gdi.width;
surfaceRect.bottom = surface->gdi.outputOriginY + surface->gdi.height;
surfaceRect.right = surface->gdi.outputOriginX + surface->gdi.outputTargetWidth;
surfaceRect.bottom = surface->gdi.outputOriginY + surface->gdi.outputTargetHeight;
if (rectangles_intersection(&invalidRect, &surfaceRect, &intersection))
{
@ -256,8 +270,12 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
}
surface->gdi.surfaceId = createSurface->surfaceId;
surface->gdi.width = (UINT32) createSurface->width;
surface->gdi.height = (UINT32) createSurface->height;
surface->gdi.width = x11_pad_scanline(createSurface->width, 0);
surface->gdi.height = x11_pad_scanline(createSurface->height, 0);
surface->gdi.mappedWidth = createSurface->width;
surface->gdi.mappedHeight = createSurface->height;
surface->gdi.outputTargetWidth = createSurface->width;
surface->gdi.outputTargetHeight = createSurface->height;
switch (createSurface->pixelFormat)
{
@ -291,7 +309,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
if (AreColorFormatsEqualNoAlpha(gdi->dstFormat, surface->gdi.format))
{
surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth, ZPixmap, 0,
(char*) surface->gdi.data, surface->gdi.width, surface->gdi.height,
(char*) surface->gdi.data, surface->gdi.mappedWidth, surface->gdi.mappedHeight,
xfc->scanline_pad, surface->gdi.scanline);
}
else
@ -312,7 +330,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
ZeroMemory(surface->stage, size);
surface->image = XCreateImage(xfc->display, xfc->visual, xfc->depth,
ZPixmap, 0, (char*) surface->stage,
surface->gdi.width, surface->gdi.height,
surface->gdi.mappedWidth, surface->gdi.mappedHeight,
xfc->scanline_pad, surface->stageScanline);
}
@ -363,6 +381,9 @@ static UINT xf_DeleteSurface(RdpgfxClientContext* context,
if (surface)
{
if (surface->gdi.windowId > 0)
IFCALL(context->UnmapWindowForSurface, context, surface->gdi.windowId);
#ifdef WITH_GFX_H264
h264_context_free(surface->gdi.h264);
#endif
@ -389,9 +410,13 @@ void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
{
rdpGdi* gdi = xfc->context.gdi;
gdi_graphics_pipeline_init(gdi, gfx);
gfx->UpdateSurfaces = xf_UpdateSurfaces;
gfx->CreateSurface = xf_CreateSurface;
gfx->DeleteSurface = xf_DeleteSurface;
if (!xfc->context.settings->SoftwareGdi)
{
gfx->UpdateSurfaces = xf_UpdateSurfaces;
gfx->CreateSurface = xf_CreateSurface;
gfx->DeleteSurface = xf_DeleteSurface;
}
}
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx)

View File

@ -51,6 +51,7 @@ UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y,
UINT32 width, UINT32 height);
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx);
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx);
#endif /* FREERDP_CLIENT_X11_GFX_H */

View File

@ -93,6 +93,10 @@ typedef UINT(*pcRdpgfxCapsConfirm)(RdpgfxClientContext* context,
typedef UINT(*pcRdpgfxFrameAcknowledge)(RdpgfxClientContext* context,
const RDPGFX_FRAME_ACKNOWLEDGE_PDU* frameAcknowledge);
typedef UINT(*pcRdpgfxMapWindowForSurface)(RdpgfxClientContext* context, UINT16 surfaceID,
UINT64 windowID);
typedef UINT(*pcRdpgfxUnmapWindowForSurface)(RdpgfxClientContext* context, UINT64 windowID);
struct _rdpgfx_client_context
{
void* handle;
@ -135,6 +139,13 @@ struct _rdpgfx_client_context
pcRdpgfxUpdateSurfaces UpdateSurfaces;
pcRdpgfxUpdateSurfaceArea UpdateSurfaceArea;
/* These callbacks allow crating/destroying a window directly
* mapped to a surface.
* NOTE: The surface is already locked.
*/
pcRdpgfxMapWindowForSurface MapWindowForSurface;
pcRdpgfxUnmapWindowForSurface UnmapWindowForSurface;
CRITICAL_SECTION mux;
PROFILER_DEFINE(SurfaceProfiler)
};

View File

@ -30,6 +30,8 @@ struct gdi_gfx_surface
H264_CONTEXT* h264;
UINT32 width;
UINT32 height;
UINT32 mappedWidth;
UINT32 mappedHeight;
BYTE* data;
UINT32 scanline;
UINT32 format;
@ -37,6 +39,9 @@ struct gdi_gfx_surface
UINT32 outputOriginX;
UINT32 outputOriginY;
REGION16 invalidRegion;
UINT64 windowId;
UINT32 outputTargetWidth;
UINT32 outputTargetHeight;
};
typedef struct gdi_gfx_surface gdiGfxSurface;
@ -56,6 +61,10 @@ extern "C" {
#endif
FREERDP_API BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx);
FREERDP_API BOOL gdi_graphics_pipeline_init_ex(rdpGdi* gdi, RdpgfxClientContext* gfx,
pcRdpgfxMapWindowForSurface map,
pcRdpgfxUnmapWindowForSurface unmap,
pcRdpgfxUpdateSurfaceArea update);
FREERDP_API void gdi_graphics_pipeline_uninit(rdpGdi* gdi, RdpgfxClientContext* gfx);
#ifdef __cplusplus

View File

@ -835,6 +835,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_GfxAVC444 (3845)
#define FreeRDP_GfxSendQoeAck (3846)
#define FreeRDP_GfxAVC444v2 (3847)
#define FreeRDP_GfxCapsFilter (3848)
#define FreeRDP_BitmapCacheV3CodecId (3904)
#define FreeRDP_DrawNineGridEnabled (3968)
#define FreeRDP_DrawNineGridCacheSize (3969)
@ -1419,7 +1420,8 @@ struct rdp_settings
ALIGN64 BOOL GfxAVC444; /* 3845 */
ALIGN64 BOOL GfxSendQoeAck; /* 3846 */
ALIGN64 BOOL GfxAVC444v2; /* 3847 */
UINT64 padding3904[3904 - 3848]; /* 3848 */
ALIGN64 UINT32 GfxCapsFilter; /* 3848 */
UINT64 padding3904[3904 - 3849]; /* 3849 */
/**
* Caches

View File

@ -608,32 +608,42 @@ BOOL freerdp_image_scale(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep,
UINT32 nXSrc, UINT32 nYSrc, UINT32 nSrcWidth, UINT32 nSrcHeight)
{
BOOL rc = FALSE;
const BYTE* src = &pSrcData[nXSrc * 4 + nYSrc * nSrcStep];
BYTE* dst = &pDstData[nXDst * 4 + nYDst * nDstStep];
const BYTE* src = &pSrcData[nXSrc * GetBytesPerPixel(SrcFormat) + nYSrc * nSrcStep];
BYTE* dst = &pDstData[nXDst * GetBytesPerPixel(DstFormat) + nYDst * nDstStep];
/* direct copy is much faster than scaling, so check if we can simply copy... */
if ((nDstWidth == nSrcWidth) && (nDstHeight == nSrcHeight))
{
return freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight,
pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc,
NULL, FREERDP_FLIP_NONE);
}
else
#if defined(SWSCALE_FOUND)
{
int res;
struct SwsContext* resize;
int srcFormat = av_format_for_buffer(SrcFormat);
int dstFormat = av_format_for_buffer(DstFormat);
const int srcStep[1] = { nSrcStep };
const int dstStep[1] = { nDstStep };
const int srcStep[1] = { (int)nSrcStep };
const int dstStep[1] = { (int)nDstStep };
if ((srcFormat == AV_PIX_FMT_NONE) || (dstFormat == AV_PIX_FMT_NONE))
return FALSE;
resize = sws_getContext(nSrcWidth + nXSrc, nSrcHeight + nYSrc, srcFormat,
nDstWidth + nXDst, nDstHeight + nYDst, dstFormat,
SWS_BICUBIC, NULL, NULL, NULL);
resize = sws_getContext((int)nSrcWidth, (int)nSrcHeight, srcFormat,
(int)nDstWidth, (int)nDstHeight, dstFormat,
SWS_BILINEAR, NULL, NULL, NULL);
if (!resize)
goto fail;
res = sws_scale(resize, &pSrcData, srcStep, 0, nSrcHeight + nYSrc, &pDstData, dstStep);
rc = (res == (nDstHeight + nYDst));
res = sws_scale(resize, &src, srcStep, 0, (int)nSrcHeight, &dst, dstStep);
rc = (res == ((int)nDstHeight));
fail:
sws_freeContext(resize);
}
#elif defined(CAIRO_FOUND)
{
const double sx = (double)nDstWidth / (double)nSrcWidth;
@ -672,15 +682,9 @@ BOOL freerdp_image_scale(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep,
cairo_surface_destroy(cdst);
}
#else
if ((nDstWidth == nSrcWidth) && (nDstHeight == nSrcHeight))
{
return freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight,
pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc,
NULL, FREERDP_FLIP_NONE);
WLog_WARN(TAG, "SmartScaling requested but compiled without libcairo support!");
}
WLog_WARN(TAG, "SmartScaling requested but compiled without libcairo support!");
#endif
return rc;
}

View File

@ -147,7 +147,7 @@ rfx_dwt_2d_decode_block_vert_NEON(INT16* l, INT16* h, INT16* dst, int subband_wi
// dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1);
int16x8_t l_n = vld1q_s16(l_ptr);
int16x8_t h_n = vld1q_s16(h_ptr);
int16x8_t tmp_n = vaddq_s16(h_n, vdupq_n_s16(1));;
int16x8_t tmp_n = vaddq_s16(h_n, vdupq_n_s16(1));
if (n == 0)
tmp_n = vaddq_s16(tmp_n, h_n);

View File

@ -1494,5 +1494,5 @@ BOOL rdp_send_server_status_info(rdpContext* context, UINT32 status)
Stream_Write_UINT32(s, status);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_STATUS_INFO, rdp->mcs->userId);;
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_STATUS_INFO, rdp->mcs->userId);
}

View File

@ -33,7 +33,7 @@
static DWORD gfx_align_scanline(DWORD widthInBytes, DWORD alignment)
{
const UINT32 align = 16;
const UINT32 align = alignment;
const UINT32 pad = align - (widthInBytes % alignment);
UINT32 scanline = widthInBytes;
@ -102,13 +102,11 @@ fail:
static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
{
UINT rc = ERROR_INTERNAL_ERROR;
UINT32 nXDst, nYDst;
UINT32 nXSrc, nYSrc;
UINT16 width, height;
UINT32 surfaceX, surfaceY;
RECTANGLE_16 surfaceRect;
const RECTANGLE_16* rects;
UINT32 i, nbRects;
double sx, sy;
rdpUpdate* update = gdi->context->update;
if (gdi->suppressOutput)
@ -118,10 +116,12 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
surfaceY = surface->outputOriginY;
surfaceRect.left = 0;
surfaceRect.top = 0;
surfaceRect.right = surface->width;
surfaceRect.bottom = surface->height;
surfaceRect.right = surface->mappedWidth;
surfaceRect.bottom = surface->mappedHeight;
region16_intersect_rect(&(surface->invalidRegion),
&(surface->invalidRegion), &surfaceRect);
sx = surface->outputTargetWidth / (double)surface->mappedWidth;
sy = surface->outputTargetHeight / (double)surface->mappedHeight;
if (!(rects = region16_rects(&surface->invalidRegion, &nbRects)) || !nbRects)
return CHANNEL_RC_OK;
@ -131,21 +131,22 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
for (i = 0; i < nbRects; i++)
{
nXSrc = rects[i].left;
nYSrc = rects[i].top;
nXDst = surfaceX + nXSrc;
nYDst = surfaceY + nYSrc;
width = rects[i].right - rects[i].left;
height = rects[i].bottom - rects[i].top;
const UINT32 nXSrc = rects[i].left;
const UINT32 nYSrc = rects[i].top;
const UINT32 nXDst = surfaceX + nXSrc * sx;
const UINT32 nYDst = surfaceY + nYSrc * sy;
const UINT32 swidth = rects[i].right - rects[i].left;
const UINT32 sheight = rects[i].bottom - rects[i].top;
const UINT32 dwidth = swidth * sx;
const UINT32 dheight = sheight * sy;
if (!freerdp_image_copy(gdi->primary_buffer, gdi->primary->hdc->format,
gdi->stride,
nXDst, nYDst, width, height,
surface->data, surface->format,
surface->scanline, nXSrc, nYSrc, NULL, FREERDP_FLIP_NONE))
if (!freerdp_image_scale(gdi->primary_buffer, gdi->dstFormat,
gdi->stride, nXDst, nYDst, dwidth, dheight,
surface->data, surface->format,
surface->scanline, nXSrc, nYSrc, swidth, sheight))
return CHANNEL_RC_NULL_DATA;
gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, width, height);
gdi_InvalidateRegion(gdi->primary->hdc, nXDst, nYDst, dwidth, dheight);
}
rc = CHANNEL_RC_OK;
@ -178,10 +179,20 @@ static UINT gdi_UpdateSurfaces(RdpgfxClientContext* context)
{
surface = (gdiGfxSurface*) context->GetSurfaceData(context, pSurfaceIds[index]);
if (!surface || !surface->outputMapped)
if (!surface)
continue;
status = gdi_OutputUpdate(gdi, surface);
/* Already handled in UpdateSurfaceArea callbacks */
if (context->UpdateSurfaceArea)
{
if (surface->windowId != 0)
continue;
}
status = ERROR_INTERNAL_ERROR;
if (surface->outputMapped)
status = gdi_OutputUpdate(gdi, surface);
if (status != CHANNEL_RC_OK)
break;
@ -615,6 +626,41 @@ fail:
#endif
}
static BOOL gdi_apply_alpha(BYTE* data, UINT32 format, UINT32 stride,
RECTANGLE_16* rect, UINT32 startOffsetX, UINT32 count, BYTE a)
{
UINT32 y;
UINT32 written = 0;
BOOL first = TRUE;
const UINT32 bpp = GetBytesPerPixel(format);
for (y = rect->top; y < rect->bottom; y++)
{
UINT32 x;
BYTE* line = &data[stride * y];
for (x = first ? rect->left + startOffsetX : rect->left; x < rect->right; x++)
{
UINT32 color;
BYTE r, g, b;
BYTE* src;
if (written == count)
return TRUE;
src = &line[x * bpp];
color = ReadColor(src, format);
SplitColor(color, format, &r, &g, &b, NULL, NULL);
color = FreeRDPGetColor(format, r, g, b, a);
WriteColor(src, format, color);
written ++;
}
first = FALSE;
}
return TRUE;
}
/**
* Function description
*
@ -624,9 +670,15 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
const RDPGFX_SURFACE_COMMAND* cmd)
{
UINT status = CHANNEL_RC_OK;
UINT32 color;
UINT16 alphaSig, compressed;
gdiGfxSurface* surface;
RECTANGLE_16 invalidRect;
wStream s;
Stream_StaticInit(&s, cmd->data, cmd->length);
if (Stream_GetRemainingLength(&s) < 4)
return ERROR_INVALID_DATA;
surface = (gdiGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
@ -636,13 +688,85 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
return ERROR_NOT_FOUND;
}
WLog_WARN(TAG, "TODO gdi_SurfaceCommand_Alpha: status: %"PRIu32"", status);
/* fill with green for now to distinguish from the rest */
color = FreeRDPGetColor(surface->format, 0x00, 0xFF, 0x00, 0xFF);
Stream_Read_UINT16(&s, alphaSig);
Stream_Read_UINT16(&s, compressed);
if (!freerdp_image_fill(surface->data, surface->format, surface->scanline,
cmd->left, cmd->top, cmd->width, cmd->height, color))
return ERROR_INTERNAL_ERROR;
if (alphaSig != 0x414C)
return ERROR_INVALID_DATA;
if (compressed == 0)
{
UINT32 x, y;
if (Stream_GetRemainingLength(&s) < cmd->height * cmd->width)
return ERROR_INVALID_DATA;
for (y = cmd->top; y < cmd->top + cmd->height; y++)
{
BYTE* line = &surface->data[surface->scanline * y];
for (x = cmd->left; x < cmd->left + cmd->width; x++)
{
UINT32 color;
BYTE r, g, b, a;
BYTE* src = &line[x * GetBytesPerPixel(surface->format)];
Stream_Read_UINT8(&s, a);
color = ReadColor(src, surface->format);
SplitColor(color, surface->format, &r, &g, &b, NULL, NULL);
color = FreeRDPGetColor(surface->format, r, g, b, a);
WriteColor(src, surface->format, color);
}
}
}
else
{
UINT32 startOffsetX = 0;
RECTANGLE_16 rect;
rect.left = cmd->left;
rect.top = cmd->top;
rect.right = cmd->left + cmd->width;
rect.bottom = cmd->top + cmd->height;
while (rect.top < rect.bottom)
{
UINT32 count;
BYTE a;
if (Stream_GetRemainingLength(&s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT8(&s, a);
Stream_Read_UINT8(&s, count);
if (count >= 0xFF)
{
if (Stream_GetRemainingLength(&s) < 2)
return ERROR_INVALID_DATA;
Stream_Read_UINT16(&s, count);
if (count >= 0xFFFF)
{
if (Stream_GetRemainingLength(&s) < 4)
return ERROR_INVALID_DATA;
Stream_Read_UINT32(&s, count);
}
}
if (!gdi_apply_alpha(surface->data, surface->format, surface->scanline, &rect, startOffsetX, count,
a))
return ERROR_INTERNAL_ERROR;
startOffsetX += count;
while (startOffsetX >= cmd->width)
{
startOffsetX -= cmd->width;
rect.top++;
}
}
}
invalidRect.left = cmd->left;
invalidRect.top = cmd->top;
@ -848,8 +972,12 @@ static UINT gdi_CreateSurface(RdpgfxClientContext* context,
}
surface->surfaceId = createSurface->surfaceId;
surface->width = (UINT32) createSurface->width;
surface->height = (UINT32) createSurface->height;
surface->width = gfx_align_scanline(createSurface->width, 16);
surface->height = gfx_align_scanline(createSurface->height, 16);
surface->mappedWidth = createSurface->width;
surface->mappedHeight = createSurface->height;
surface->outputTargetWidth = createSurface->width;
surface->outputTargetHeight = createSurface->height;
switch (createSurface->pixelFormat)
{
@ -899,6 +1027,9 @@ static UINT gdi_DeleteSurface(RdpgfxClientContext* context,
if (surface)
{
if (surface->windowId != 0)
rc = IFCALLRESULT(CHANNEL_RC_OK, context->UnmapWindowForSurface, context, surface->windowId);
#ifdef WITH_GFX_H264
h264_context_free(surface->h264);
#endif
@ -1230,6 +1361,8 @@ static UINT gdi_MapSurfaceToOutput(RdpgfxClientContext* context,
surface->outputMapped = TRUE;
surface->outputOriginX = surfaceToOutput->outputOriginX;
surface->outputOriginY = surfaceToOutput->outputOriginY;
surface->outputTargetWidth = surface->mappedWidth;
surface->outputTargetHeight = surface->mappedHeight;
region16_clear(&surface->invalidRegion);
rc = CHANNEL_RC_OK;
fail:
@ -1252,7 +1385,8 @@ static UINT gdi_MapSurfaceToScaledOutput(RdpgfxClientContext* context,
surface->outputMapped = TRUE;
surface->outputOriginX = surfaceToOutput->outputOriginX;
surface->outputOriginY = surfaceToOutput->outputOriginY;
// TODO: Target x,y
surface->outputTargetWidth = surfaceToOutput->targetWidth;
surface->outputTargetHeight = surfaceToOutput->targetHeight;
region16_clear(&surface->invalidRegion);
rc = CHANNEL_RC_OK;
fail:
@ -1268,16 +1402,74 @@ fail:
static UINT gdi_MapSurfaceToWindow(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_WINDOW_PDU* surfaceToWindow)
{
return CHANNEL_RC_OK;
UINT rc = ERROR_INTERNAL_ERROR;
gdiGfxSurface* surface;
EnterCriticalSection(&context->mux);
surface = (gdiGfxSurface*) context->GetSurfaceData(context,
surfaceToWindow->surfaceId);
if (!surface)
goto fail;
if (surface->windowId != 0)
{
if (surface->windowId != surfaceToWindow->windowId)
goto fail;
}
surface->windowId = surfaceToWindow->windowId;
surface->mappedWidth = surfaceToWindow->mappedWidth;
surface->mappedHeight = surfaceToWindow->mappedHeight;
surface->outputTargetWidth = surfaceToWindow->mappedWidth;
surface->outputTargetHeight = surfaceToWindow->mappedHeight;
rc = IFCALLRESULT(CHANNEL_RC_OK, context->MapWindowForSurface, context,
surfaceToWindow->surfaceId,
surfaceToWindow->windowId);
fail:
LeaveCriticalSection(&context->mux);
return rc;
}
static UINT gdi_MapSurfaceToScaledWindow(RdpgfxClientContext* context,
const RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU* surfaceToWindow)
{
return CHANNEL_RC_OK;
UINT rc = ERROR_INTERNAL_ERROR;
gdiGfxSurface* surface;
EnterCriticalSection(&context->mux);
surface = (gdiGfxSurface*) context->GetSurfaceData(context,
surfaceToWindow->surfaceId);
if (!surface)
goto fail;
if (surface->windowId != 0)
{
if (surface->windowId != surfaceToWindow->windowId)
goto fail;
}
surface->windowId = surfaceToWindow->windowId;
surface->mappedWidth = surfaceToWindow->mappedWidth;
surface->mappedHeight = surfaceToWindow->mappedHeight;
surface->outputTargetWidth = surfaceToWindow->targetWidth;
surface->outputTargetHeight = surfaceToWindow->targetHeight;
rc = IFCALLRESULT(CHANNEL_RC_OK, context->MapWindowForSurface, context,
surfaceToWindow->surfaceId,
surfaceToWindow->windowId);
fail:
LeaveCriticalSection(&context->mux);
return rc;
}
BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx)
{
return gdi_graphics_pipeline_init_ex(gdi, gfx, NULL, NULL, NULL);
}
BOOL gdi_graphics_pipeline_init_ex(rdpGdi* gdi, RdpgfxClientContext* gfx,
pcRdpgfxMapWindowForSurface map,
pcRdpgfxUnmapWindowForSurface unmap,
pcRdpgfxUpdateSurfaceArea update)
{
if (!gdi || !gfx)
return FALSE;
@ -1302,6 +1494,9 @@ BOOL gdi_graphics_pipeline_init(rdpGdi* gdi, RdpgfxClientContext* gfx)
gfx->MapSurfaceToScaledOutput = gdi_MapSurfaceToScaledOutput;
gfx->MapSurfaceToScaledWindow = gdi_MapSurfaceToScaledWindow;
gfx->UpdateSurfaces = gdi_UpdateSurfaces;
gfx->MapWindowForSurface = map;
gfx->UnmapWindowForSurface = unmap;
gfx->UpdateSurfaceArea = update;
InitializeCriticalSection(&gfx->mux);
PROFILER_CREATE(gfx->SurfaceProfiler, "GFX-PROFILER");
return TRUE;

View File

@ -91,7 +91,7 @@ static void mf_peer_rdpsnd_activated(RdpsndServerContext* context)
recorderState.dataFormat.mSampleRate = agreedFormat->nSamplesPerSec;
recorderState.dataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;;
kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
recorderState.dataFormat.mBytesPerPacket = 4;
recorderState.dataFormat.mFramesPerPacket = 1;
recorderState.dataFormat.mBytesPerFrame = 4;

View File

@ -613,6 +613,76 @@ static UINT shadow_client_rdpgfx_frame_acknowledge(RdpgfxServerContext* context,
return CHANNEL_RC_OK;
}
static BOOL shadow_are_caps_filtered(const rdpSettings* settings, UINT32 caps)
{
const UINT32 filter = settings->GfxCapsFilter;
const UINT32 capList[] =
{
RDPGFX_CAPVERSION_8,
RDPGFX_CAPVERSION_81,
RDPGFX_CAPVERSION_10,
RDPGFX_CAPVERSION_101,
RDPGFX_CAPVERSION_102,
RDPGFX_CAPVERSION_103,
RDPGFX_CAPVERSION_104,
RDPGFX_CAPVERSION_105,
RDPGFX_CAPVERSION_106
};
UINT32 x;
for (x = 0; x < ARRAYSIZE(capList); x++)
{
if (caps == capList[x])
return (filter & (1 << x)) != 0;
}
return TRUE;
}
static BOOL shadow_client_caps_test_version(RdpgfxServerContext* context,
const RDPGFX_CAPSET* capsSets,
UINT32 capsSetCount,
UINT32 capsVersion, UINT* rc)
{
UINT32 flags = 0;
UINT32 index;
rdpSettings* settings;
settings = context->rdpcontext->settings;
if (shadow_are_caps_filtered(settings, capsVersion))
return FALSE;
for (index = 0; index < capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsSets[index];
if (currentCaps->version == capsVersion)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
*rc = context->CapsConfirm(context, &pdu);
return TRUE;
}
}
return FALSE;
}
/**
* Function description
*
@ -622,206 +692,92 @@ static UINT shadow_client_rdpgfx_caps_advertise(RdpgfxServerContext* context,
const RDPGFX_CAPS_ADVERTISE_PDU* capsAdvertise)
{
UINT16 index;
UINT rc;
rdpSettings* settings = context->rdpcontext->settings;
UINT32 flags = 0;
/* Request full screen update for new gfx channel */
shadow_client_refresh_rect((rdpShadowClient*)context->custom, 0, NULL);
for (index = 0; index < capsAdvertise->capsSetCount; index++)
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_106, &rc))
return rc;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_105, &rc))
return rc;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_104, &rc))
return rc;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_103, &rc))
return rc;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_102, &rc))
return rc;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_101, &rc))
return rc;
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
RDPGFX_CAPVERSION_10, &rc))
return rc;
if (!shadow_are_caps_filtered(settings, RDPGFX_CAPVERSION_81))
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_106)
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (settings)
if (currentCaps->version == RDPGFX_CAPVERSION_81)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxAVC444v2 = settings->GfxAVC444 = FALSE;
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_THINCLIENT);
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
settings->GfxH264 = FALSE;
pdu.capsSet->flags &= ~RDPGFX_CAPS_FLAG_AVC420_ENABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
settings->GfxH264 = (flags & RDPGFX_CAPS_FLAG_AVC420_ENABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
return context->CapsConfirm(context, &pdu);
}
if (currentCaps->version == RDPGFX_CAPVERSION_105)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
if (currentCaps->version == RDPGFX_CAPVERSION_104)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
if (currentCaps->version == RDPGFX_CAPVERSION_103)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_AVC_THINCLIENT);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
}
for (index = 0; index < capsAdvertise->capsSetCount; index++)
if (!shadow_are_caps_filtered(settings, RDPGFX_CAPVERSION_8))
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_102)
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (settings)
if (currentCaps->version == RDPGFX_CAPVERSION_8)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = !(flags &
RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_THINCLIENT);
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
}
return context->CapsConfirm(context, &pdu);
}
return context->CapsConfirm(context, &pdu);
}
}
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_10)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
#ifndef WITH_GFX_H264
settings->GfxAVC444v2 = settings->GfxAVC444 = settings->GfxH264 = FALSE;
pdu.capsSet->flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#else
settings->GfxAVC444 = settings->GfxH264 = !(flags & RDPGFX_CAPS_FLAG_AVC_DISABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
}
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_81)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxAVC444v2 = settings->GfxAVC444 = FALSE;
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_THINCLIENT);
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
#ifndef WITH_GFX_H264
settings->GfxH264 = FALSE;
pdu.capsSet->flags &= ~RDPGFX_CAPS_FLAG_AVC420_ENABLED;
#else
settings->GfxH264 = (flags & RDPGFX_CAPS_FLAG_AVC420_ENABLED);
#endif
}
return context->CapsConfirm(context, &pdu);
}
}
for (index = 0; index < capsAdvertise->capsSetCount; index++)
{
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
if (currentCaps->version == RDPGFX_CAPVERSION_8)
{
RDPGFX_CAPSET caps = *currentCaps;
RDPGFX_CAPS_CONFIRM_PDU pdu;
pdu.capsSet = &caps;
if (settings)
{
flags = pdu.capsSet->flags;
settings->GfxThinClient = (flags & RDPGFX_CAPS_FLAG_THINCLIENT);
settings->GfxSmallCache = (flags & RDPGFX_CAPS_FLAG_SMALL_CACHE);
}
return context->CapsConfirm(context, &pdu);
}
}

View File

@ -173,7 +173,7 @@ wLogAppender* WLog_JournaldAppender_New(wLog* log)
{
wLogJournaldAppender* appender;
DWORD nSize;
LPCSTR name = "WLOG_JOURNALD_ID";;
LPCSTR name = "WLOG_JOURNALD_ID";
appender = (wLogJournaldAppender*) calloc(1, sizeof(wLogJournaldAppender));
if (!appender)