Updated GFX to 10.6 spec
This commit is contained in:
parent
49805aae89
commit
3b7e46fb0e
@ -186,11 +186,6 @@ static UINT rdpgfx_send_supported_caps(RDPGFX_CHANNEL_CALLBACK* callback)
|
||||
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;
|
||||
@ -203,16 +198,10 @@ static UINT rdpgfx_send_supported_caps(RDPGFX_CHANNEL_CALLBACK* callback)
|
||||
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 (context)
|
||||
@ -684,6 +673,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;
|
||||
|
@ -38,6 +38,7 @@ 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;
|
||||
@ -51,6 +52,8 @@ static UINT xf_OutputUpdate(xfContext* xfc, xfGfxSurface* surface)
|
||||
XSetFillStyle(xfc->display, xfc->gc, FillSolid);
|
||||
region16_intersect_rect(&(surface->gdi.invalidRegion),
|
||||
&(surface->gdi.invalidRegion), &surfaceRect);
|
||||
sx = surface->gdi.outputTargetWidth / (double)surface->gdi.width;
|
||||
sy = surface->gdi.outputTargetHeight / (double)surface->gdi.height;
|
||||
|
||||
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,19 @@ 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);
|
||||
/* Already handled in UpdateSurfaceArea callbacks */
|
||||
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 +193,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))
|
||||
{
|
||||
@ -363,6 +374,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
|
||||
@ -386,9 +400,16 @@ static UINT xf_DeleteSurface(RdpgfxClientContext* context,
|
||||
}
|
||||
|
||||
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
|
||||
{
|
||||
xf_graphics_pipeline_init_ex(xfc, gfx, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void xf_graphics_pipeline_init_ex(xfContext* xfc, RdpgfxClientContext* gfx,
|
||||
pcRdpgfxMapWindowForSurface map, pcRdpgfxUnmapWindowForSurface unmap,
|
||||
pcRdpgfxUpdateSurfaceArea update)
|
||||
{
|
||||
rdpGdi* gdi = xfc->context.gdi;
|
||||
gdi_graphics_pipeline_init(gdi, gfx);
|
||||
gdi_graphics_pipeline_init_ex(gdi, gfx, map, unmap, update);
|
||||
gfx->UpdateSurfaces = xf_UpdateSurfaces;
|
||||
gfx->CreateSurface = xf_CreateSurface;
|
||||
gfx->DeleteSurface = xf_DeleteSurface;
|
||||
|
@ -51,6 +51,10 @@ 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_init_ex(xfContext* xfc, RdpgfxClientContext* gfx,
|
||||
pcRdpgfxMapWindowForSurface map,
|
||||
pcRdpgfxUnmapWindowForSurface unmap,
|
||||
pcRdpgfxUpdateSurfaceArea update);
|
||||
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx);
|
||||
|
||||
#endif /* FREERDP_CLIENT_X11_GFX_H */
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -37,6 +37,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 +59,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
|
||||
|
@ -100,13 +100,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)
|
||||
@ -120,6 +118,8 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
|
||||
surfaceRect.bottom = surface->height;
|
||||
region16_intersect_rect(&(surface->invalidRegion),
|
||||
&(surface->invalidRegion), &surfaceRect);
|
||||
sx = surface->outputTargetWidth / (double)surface->width;
|
||||
sy = surface->outputTargetHeight / (double)surface->height;
|
||||
|
||||
if (!(rects = region16_rects(&surface->invalidRegion, &nbRects)) || !nbRects)
|
||||
return CHANNEL_RC_OK;
|
||||
@ -129,21 +129,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);
|
||||
}
|
||||
|
||||
if (!IFCALLRESULT(FALSE, update->EndPaint, gdi->context))
|
||||
@ -175,10 +176,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;
|
||||
@ -612,6 +623,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
|
||||
*
|
||||
@ -621,9 +667,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)
|
||||
@ -633,13 +685,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;
|
||||
@ -896,6 +1020,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
|
||||
@ -1227,6 +1354,8 @@ static UINT gdi_MapSurfaceToOutput(RdpgfxClientContext* context,
|
||||
surface->outputMapped = TRUE;
|
||||
surface->outputOriginX = surfaceToOutput->outputOriginX;
|
||||
surface->outputOriginY = surfaceToOutput->outputOriginY;
|
||||
surface->outputTargetWidth = surface->width;
|
||||
surface->outputTargetHeight = surface->height;
|
||||
region16_clear(&surface->invalidRegion);
|
||||
rc = CHANNEL_RC_OK;
|
||||
fail:
|
||||
@ -1249,7 +1378,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:
|
||||
@ -1265,16 +1395,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->width = surfaceToWindow->mappedWidth;
|
||||
surface->height = 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->width = surfaceToWindow->mappedWidth;
|
||||
surface->height = 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;
|
||||
@ -1299,6 +1487,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;
|
||||
|
@ -613,6 +613,47 @@ static UINT shadow_client_rdpgfx_frame_acknowledge(RdpgfxServerContext* context,
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 = ∩︀
|
||||
|
||||
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,159 +663,39 @@ 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++)
|
||||
{
|
||||
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
|
||||
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
|
||||
RDPGFX_CAPVERSION_106, &rc))
|
||||
return rc;
|
||||
|
||||
if (currentCaps->version == RDPGFX_CAPVERSION_106)
|
||||
{
|
||||
RDPGFX_CAPSET caps = *currentCaps;
|
||||
RDPGFX_CAPS_CONFIRM_PDU pdu;
|
||||
pdu.capsSet = ∩︀
|
||||
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
|
||||
RDPGFX_CAPVERSION_105, &rc))
|
||||
return rc;
|
||||
|
||||
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
|
||||
}
|
||||
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
|
||||
RDPGFX_CAPVERSION_104, &rc))
|
||||
return rc;
|
||||
|
||||
return context->CapsConfirm(context, &pdu);
|
||||
}
|
||||
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
|
||||
RDPGFX_CAPVERSION_103, &rc))
|
||||
return rc;
|
||||
|
||||
if (currentCaps->version == RDPGFX_CAPVERSION_105)
|
||||
{
|
||||
RDPGFX_CAPSET caps = *currentCaps;
|
||||
RDPGFX_CAPS_CONFIRM_PDU pdu;
|
||||
pdu.capsSet = ∩︀
|
||||
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
|
||||
RDPGFX_CAPVERSION_102, &rc))
|
||||
return rc;
|
||||
|
||||
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
|
||||
}
|
||||
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
|
||||
RDPGFX_CAPVERSION_101, &rc))
|
||||
return rc;
|
||||
|
||||
return context->CapsConfirm(context, &pdu);
|
||||
}
|
||||
|
||||
if (currentCaps->version == RDPGFX_CAPVERSION_104)
|
||||
{
|
||||
RDPGFX_CAPSET caps = *currentCaps;
|
||||
RDPGFX_CAPS_CONFIRM_PDU pdu;
|
||||
pdu.capsSet = ∩︀
|
||||
|
||||
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 = ∩︀
|
||||
|
||||
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++)
|
||||
{
|
||||
const RDPGFX_CAPSET* currentCaps = &capsAdvertise->capsSets[index];
|
||||
|
||||
if (currentCaps->version == RDPGFX_CAPVERSION_102)
|
||||
{
|
||||
RDPGFX_CAPSET caps = *currentCaps;
|
||||
RDPGFX_CAPS_CONFIRM_PDU pdu;
|
||||
pdu.capsSet = ∩︀
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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 = ∩︀
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (shadow_client_caps_test_version(context, capsAdvertise->capsSets, capsAdvertise->capsSetCount,
|
||||
RDPGFX_CAPVERSION_10, &rc))
|
||||
return rc;
|
||||
|
||||
for (index = 0; index < capsAdvertise->capsSetCount; index++)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user