[gfx] Added new UpdateWindowFromSurface callback
* Adds a new callback and settings in gdiGfxSurface to allow updating a window directly from surface bitmap data * Adds new BOOL in gdiGfxSurface windowMapped and handleInUpdateSurfaceArea to control where surface data update is being handled
This commit is contained in:
parent
60d2e525f5
commit
325c03501e
@ -118,6 +118,13 @@ fail:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT xf_WindowUpdate(RdpgfxClientContext* context, xfGfxSurface* surface)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(context);
|
||||||
|
WINPR_ASSERT(surface);
|
||||||
|
return IFCALLRESULT(CHANNEL_RC_OK, context->UpdateWindowFromSurface, context, &surface->gdi);
|
||||||
|
}
|
||||||
|
|
||||||
static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
|
static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
|
||||||
{
|
{
|
||||||
UINT16 count;
|
UINT16 count;
|
||||||
@ -147,16 +154,16 @@ static UINT xf_UpdateSurfaces(RdpgfxClientContext* context)
|
|||||||
/* If UpdateSurfaceArea callback is available, the output has already been updated. */
|
/* If UpdateSurfaceArea callback is available, the output has already been updated. */
|
||||||
if (context->UpdateSurfaceArea)
|
if (context->UpdateSurfaceArea)
|
||||||
{
|
{
|
||||||
if (surface->gdi.windowId != 0)
|
if (surface->gdi.handleInUpdateSurfaceArea)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ERROR_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
if (surface->gdi.outputMapped)
|
if (surface->gdi.outputMapped)
|
||||||
status = xf_OutputUpdate(xfc, surface);
|
status = xf_OutputUpdate(xfc, surface);
|
||||||
|
else if (surface->gdi.windowMapped)
|
||||||
|
status = xf_WindowUpdate(context, surface);
|
||||||
|
|
||||||
if (status != 0)
|
if (status != CHANNEL_RC_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,10 +177,8 @@ UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y, UINT32 width, UINT32 he
|
|||||||
UINT16 count;
|
UINT16 count;
|
||||||
UINT32 index;
|
UINT32 index;
|
||||||
UINT status = ERROR_INTERNAL_ERROR;
|
UINT status = ERROR_INTERNAL_ERROR;
|
||||||
xfGfxSurface* surface;
|
RECTANGLE_16 invalidRect = { 0 };
|
||||||
RECTANGLE_16 invalidRect;
|
RECTANGLE_16 intersection = { 0 };
|
||||||
RECTANGLE_16 surfaceRect;
|
|
||||||
RECTANGLE_16 intersection;
|
|
||||||
UINT16* pSurfaceIds = NULL;
|
UINT16* pSurfaceIds = NULL;
|
||||||
RdpgfxClientContext* context;
|
RdpgfxClientContext* context;
|
||||||
|
|
||||||
@ -199,9 +204,10 @@ UINT xf_OutputExpose(xfContext* xfc, UINT32 x, UINT32 y, UINT32 width, UINT32 he
|
|||||||
}
|
}
|
||||||
for (index = 0; index < count; index++)
|
for (index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
surface = (xfGfxSurface*)context->GetSurfaceData(context, pSurfaceIds[index]);
|
RECTANGLE_16 surfaceRect = { 0 };
|
||||||
|
xfGfxSurface* surface = (xfGfxSurface*)context->GetSurfaceData(context, pSurfaceIds[index]);
|
||||||
|
|
||||||
if (!surface || !surface->gdi.outputMapped)
|
if (!surface || (!surface->gdi.outputMapped && !surface->gdi.windowMapped))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
surfaceRect.left = surface->gdi.outputOriginX;
|
surfaceRect.left = surface->gdi.outputOriginX;
|
||||||
@ -352,7 +358,7 @@ static UINT xf_CreateSurface(RdpgfxClientContext* context,
|
|||||||
|
|
||||||
surface->image->byte_order = LSBFirst;
|
surface->image->byte_order = LSBFirst;
|
||||||
surface->image->bitmap_bit_order = LSBFirst;
|
surface->image->bitmap_bit_order = LSBFirst;
|
||||||
surface->gdi.outputMapped = FALSE;
|
|
||||||
region16_init(&surface->gdi.invalidRegion);
|
region16_init(&surface->gdi.invalidRegion);
|
||||||
|
|
||||||
if (context->SetSurfaceData(context, surface->gdi.surfaceId, (void*)surface) != CHANNEL_RC_OK)
|
if (context->SetSurfaceData(context, surface->gdi.surfaceId, (void*)surface) != CHANNEL_RC_OK)
|
||||||
@ -390,7 +396,7 @@ static UINT xf_DeleteSurface(RdpgfxClientContext* context,
|
|||||||
|
|
||||||
if (surface)
|
if (surface)
|
||||||
{
|
{
|
||||||
if (surface->gdi.windowId > 0)
|
if (surface->gdi.windowMapped)
|
||||||
IFCALL(context->UnmapWindowForSurface, context, surface->gdi.windowId);
|
IFCALL(context->UnmapWindowForSurface, context, surface->gdi.windowId);
|
||||||
|
|
||||||
#ifdef WITH_GFX_H264
|
#ifdef WITH_GFX_H264
|
||||||
@ -414,6 +420,24 @@ static UINT xf_DeleteSurface(RdpgfxClientContext* context,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT xf_UpdateWindowFromSurface(RdpgfxClientContext* context, gdiGfxSurface* surface)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(context);
|
||||||
|
WINPR_ASSERT(surface);
|
||||||
|
|
||||||
|
rdpGdi* gdi = (rdpGdi*)context->custom;
|
||||||
|
WINPR_ASSERT(gdi);
|
||||||
|
|
||||||
|
xfContext* xfc = (xfContext*)gdi->context;
|
||||||
|
WINPR_ASSERT(gdi->context);
|
||||||
|
|
||||||
|
// if (freerdp_settings_get_bool(gdi->context->settings, FreeRDP_RemoteApplicationMode))
|
||||||
|
// return xf_AppUpdateWindowFromSurface(xfc, surface);
|
||||||
|
|
||||||
|
WLog_WARN(TAG, "[%s] function not implemented", __func__);
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
|
void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
|
||||||
{
|
{
|
||||||
rdpGdi* gdi;
|
rdpGdi* gdi;
|
||||||
@ -434,6 +458,7 @@ void xf_graphics_pipeline_init(xfContext* xfc, RdpgfxClientContext* gfx)
|
|||||||
gfx->CreateSurface = xf_CreateSurface;
|
gfx->CreateSurface = xf_CreateSurface;
|
||||||
gfx->DeleteSurface = xf_DeleteSurface;
|
gfx->DeleteSurface = xf_DeleteSurface;
|
||||||
}
|
}
|
||||||
|
gfx->UpdateWindowFromSurface = xf_UpdateWindowFromSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx)
|
void xf_graphics_pipeline_uninit(xfContext* xfc, RdpgfxClientContext* gfx)
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
/**
|
/**
|
||||||
* Client Interface
|
* Client Interface
|
||||||
*/
|
*/
|
||||||
|
typedef struct gdi_gfx_surface gdiGfxSurface;
|
||||||
typedef struct s_rdpgfx_client_context RdpgfxClientContext;
|
typedef struct s_rdpgfx_client_context RdpgfxClientContext;
|
||||||
|
|
||||||
typedef UINT (*pcRdpgfxResetGraphics)(RdpgfxClientContext* context,
|
typedef UINT (*pcRdpgfxResetGraphics)(RdpgfxClientContext* context,
|
||||||
@ -84,6 +84,9 @@ typedef void* (*pcRdpgfxGetCacheSlotData)(RdpgfxClientContext* context, UINT16 c
|
|||||||
|
|
||||||
typedef UINT (*pcRdpgfxUpdateSurfaces)(RdpgfxClientContext* context);
|
typedef UINT (*pcRdpgfxUpdateSurfaces)(RdpgfxClientContext* context);
|
||||||
|
|
||||||
|
typedef UINT (*pcRdpgfxUpdateWindowFromSurface)(RdpgfxClientContext* context,
|
||||||
|
gdiGfxSurface* surface);
|
||||||
|
|
||||||
typedef UINT (*pcRdpgfxUpdateSurfaceArea)(RdpgfxClientContext* context, UINT16 surfaceId,
|
typedef UINT (*pcRdpgfxUpdateSurfaceArea)(RdpgfxClientContext* context, UINT16 surfaceId,
|
||||||
UINT32 nrRects, const RECTANGLE_16* rects);
|
UINT32 nrRects, const RECTANGLE_16* rects);
|
||||||
|
|
||||||
@ -147,6 +150,7 @@ struct s_rdpgfx_client_context
|
|||||||
/* No locking required */
|
/* No locking required */
|
||||||
pcRdpgfxUpdateSurfaces UpdateSurfaces;
|
pcRdpgfxUpdateSurfaces UpdateSurfaces;
|
||||||
pcRdpgfxUpdateSurfaceArea UpdateSurfaceArea;
|
pcRdpgfxUpdateSurfaceArea UpdateSurfaceArea;
|
||||||
|
pcRdpgfxUpdateWindowFromSurface UpdateWindowFromSurface;
|
||||||
|
|
||||||
/* These callbacks allow crating/destroying a window directly
|
/* These callbacks allow crating/destroying a window directly
|
||||||
* mapped to a surface.
|
* mapped to a surface.
|
||||||
|
@ -42,6 +42,8 @@ struct gdi_gfx_surface
|
|||||||
UINT64 windowId;
|
UINT64 windowId;
|
||||||
UINT32 outputTargetWidth;
|
UINT32 outputTargetWidth;
|
||||||
UINT32 outputTargetHeight;
|
UINT32 outputTargetHeight;
|
||||||
|
BOOL windowMapped;
|
||||||
|
BOOL handleInUpdateSurfaceArea;
|
||||||
};
|
};
|
||||||
typedef struct gdi_gfx_surface gdiGfxSurface;
|
typedef struct gdi_gfx_surface gdiGfxSurface;
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "../core/update.h"
|
#include "../core/update.h"
|
||||||
|
|
||||||
|
#include <freerdp/api.h>
|
||||||
#include <freerdp/log.h>
|
#include <freerdp/log.h>
|
||||||
#include <freerdp/gdi/gfx.h>
|
#include <freerdp/gdi/gfx.h>
|
||||||
#include <freerdp/gdi/region.h>
|
#include <freerdp/gdi/region.h>
|
||||||
@ -45,10 +46,10 @@ static BOOL is_within_surface(const gdiGfxSurface* surface, const RDPGFX_SURFACE
|
|||||||
RECTANGLE_16 rect;
|
RECTANGLE_16 rect;
|
||||||
if (!surface || !cmd)
|
if (!surface || !cmd)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
rect.left = cmd->left;
|
rect.left = (UINT16)MIN(UINT16_MAX, cmd->left);
|
||||||
rect.top = cmd->top;
|
rect.top = (UINT16)MIN(UINT16_MAX, cmd->top);
|
||||||
rect.right = cmd->right;
|
rect.right = (UINT16)MIN(UINT16_MAX, cmd->right);
|
||||||
rect.bottom = cmd->bottom;
|
rect.bottom = (UINT16)MIN(UINT16_MAX, cmd->bottom);
|
||||||
if (!is_rect_valid(&rect, surface->width, surface->height))
|
if (!is_rect_valid(&rect, surface->width, surface->height))
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG,
|
WLog_ERR(TAG,
|
||||||
@ -129,9 +130,6 @@ static UINT gdi_ResetGraphics(RdpgfxClientContext* context,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
memset(surface->data, 0xFF, (size_t)surface->scanline * surface->height);
|
memset(surface->data, 0xFF, (size_t)surface->scanline * surface->height);
|
||||||
if (!surface->outputMapped)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
region16_clear(&surface->invalidRegion);
|
region16_clear(&surface->invalidRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,15 +137,16 @@ static UINT gdi_ResetGraphics(RdpgfxClientContext* context,
|
|||||||
|
|
||||||
if (!freerdp_settings_get_bool(gdi->context->settings, FreeRDP_DeactivateClientDecoding))
|
if (!freerdp_settings_get_bool(gdi->context->settings, FreeRDP_DeactivateClientDecoding))
|
||||||
{
|
{
|
||||||
if (!freerdp_client_codecs_reset(context->codecs,
|
const UINT32 width = (UINT32)MIN(0, gdi->width);
|
||||||
freerdp_settings_get_codecs_flags(settings), gdi->width,
|
const UINT32 height = (UINT32)MIN(0, gdi->height);
|
||||||
gdi->height))
|
|
||||||
|
if (!freerdp_client_codecs_reset(
|
||||||
|
context->codecs, freerdp_settings_get_codecs_flags(settings), width, height))
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (!freerdp_client_codecs_reset(gdi->context->codecs,
|
if (!freerdp_client_codecs_reset(
|
||||||
freerdp_settings_get_codecs_flags(settings), gdi->width,
|
gdi->context->codecs, freerdp_settings_get_codecs_flags(settings), width, height))
|
||||||
gdi->height))
|
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -183,8 +182,8 @@ static UINT gdi_OutputUpdate(rdpGdi* gdi, gdiGfxSurface* surface)
|
|||||||
surfaceY = surface->outputOriginY;
|
surfaceY = surface->outputOriginY;
|
||||||
surfaceRect.left = 0;
|
surfaceRect.left = 0;
|
||||||
surfaceRect.top = 0;
|
surfaceRect.top = 0;
|
||||||
surfaceRect.right = surface->mappedWidth;
|
surfaceRect.right = (UINT16)MIN(UINT16_MAX, surface->mappedWidth);
|
||||||
surfaceRect.bottom = surface->mappedHeight;
|
surfaceRect.bottom = (UINT16)MIN(UINT16_MAX, surface->mappedHeight);
|
||||||
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect);
|
region16_intersect_rect(&(surface->invalidRegion), &(surface->invalidRegion), &surfaceRect);
|
||||||
sx = surface->outputTargetWidth / (double)surface->mappedWidth;
|
sx = surface->outputTargetWidth / (double)surface->mappedWidth;
|
||||||
sy = surface->outputTargetHeight / (double)surface->mappedHeight;
|
sy = surface->outputTargetHeight / (double)surface->mappedHeight;
|
||||||
@ -228,6 +227,13 @@ fail:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT gdi_WindowUpdate(RdpgfxClientContext* context, gdiGfxSurface* surface)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(context);
|
||||||
|
WINPR_ASSERT(surface);
|
||||||
|
return IFCALLRESULT(CHANNEL_RC_OK, context->UpdateWindowFromSurface, context, surface);
|
||||||
|
}
|
||||||
|
|
||||||
static UINT gdi_UpdateSurfaces(RdpgfxClientContext* context)
|
static UINT gdi_UpdateSurfaces(RdpgfxClientContext* context)
|
||||||
{
|
{
|
||||||
UINT16 count;
|
UINT16 count;
|
||||||
@ -256,14 +262,14 @@ static UINT gdi_UpdateSurfaces(RdpgfxClientContext* context)
|
|||||||
/* Already handled in UpdateSurfaceArea callbacks */
|
/* Already handled in UpdateSurfaceArea callbacks */
|
||||||
if (context->UpdateSurfaceArea)
|
if (context->UpdateSurfaceArea)
|
||||||
{
|
{
|
||||||
if (surface->windowId != 0)
|
if (surface->handleInUpdateSurfaceArea)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!surface->outputMapped)
|
if (surface->outputMapped)
|
||||||
continue;
|
|
||||||
|
|
||||||
status = gdi_OutputUpdate(gdi, surface);
|
status = gdi_OutputUpdate(gdi, surface);
|
||||||
|
else if (surface->windowMapped)
|
||||||
|
status = gdi_WindowUpdate(context, surface);
|
||||||
|
|
||||||
if (status != CHANNEL_RC_OK)
|
if (status != CHANNEL_RC_OK)
|
||||||
break;
|
break;
|
||||||
@ -329,7 +335,8 @@ static UINT gdi_SurfaceCommand_Uncompressed(rdpGdi* gdi, RdpgfxClientContext* co
|
|||||||
WINPR_ASSERT(gdi);
|
WINPR_ASSERT(gdi);
|
||||||
WINPR_ASSERT(context);
|
WINPR_ASSERT(context);
|
||||||
WINPR_ASSERT(cmd);
|
WINPR_ASSERT(cmd);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
surface =
|
||||||
|
(gdiGfxSurface*)context->GetSurfaceData(context, (UINT16)MIN(UINT16_MAX, cmd->surfaceId));
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -355,10 +362,10 @@ static UINT gdi_SurfaceCommand_Uncompressed(rdpGdi* gdi, RdpgfxClientContext* co
|
|||||||
FREERDP_FLIP_NONE))
|
FREERDP_FLIP_NONE))
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
|
||||||
invalidRect.left = cmd->left;
|
invalidRect.left = (UINT16)MIN(UINT16_MAX, cmd->left);
|
||||||
invalidRect.top = cmd->top;
|
invalidRect.top = (UINT16)MIN(UINT16_MAX, cmd->top);
|
||||||
invalidRect.right = cmd->right;
|
invalidRect.right = (UINT16)MIN(UINT16_MAX, cmd->right);
|
||||||
invalidRect.bottom = cmd->bottom;
|
invalidRect.bottom = (UINT16)MIN(UINT16_MAX, cmd->bottom);
|
||||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||||
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
||||||
&invalidRect);
|
&invalidRect);
|
||||||
@ -392,7 +399,8 @@ static UINT gdi_SurfaceCommand_RemoteFX(rdpGdi* gdi, RdpgfxClientContext* contex
|
|||||||
WINPR_ASSERT(gdi);
|
WINPR_ASSERT(gdi);
|
||||||
WINPR_ASSERT(context);
|
WINPR_ASSERT(context);
|
||||||
WINPR_ASSERT(cmd);
|
WINPR_ASSERT(cmd);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
surface =
|
||||||
|
(gdiGfxSurface*)context->GetSurfaceData(context, (UINT16)MIN(UINT16_MAX, cmd->surfaceId));
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -449,7 +457,8 @@ static UINT gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* cont
|
|||||||
WINPR_ASSERT(gdi);
|
WINPR_ASSERT(gdi);
|
||||||
WINPR_ASSERT(context);
|
WINPR_ASSERT(context);
|
||||||
WINPR_ASSERT(cmd);
|
WINPR_ASSERT(cmd);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
surface =
|
||||||
|
(gdiGfxSurface*)context->GetSurfaceData(context, (UINT16)MIN(UINT16_MAX, cmd->surfaceId));
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -469,10 +478,10 @@ static UINT gdi_SurfaceCommand_ClearCodec(rdpGdi* gdi, RdpgfxClientContext* cont
|
|||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidRect.left = cmd->left;
|
invalidRect.left = (UINT16)MIN(UINT16_MAX, cmd->left);
|
||||||
invalidRect.top = cmd->top;
|
invalidRect.top = (UINT16)MIN(UINT16_MAX, cmd->top);
|
||||||
invalidRect.right = cmd->right;
|
invalidRect.right = (UINT16)MIN(UINT16_MAX, cmd->right);
|
||||||
invalidRect.bottom = cmd->bottom;
|
invalidRect.bottom = (UINT16)MIN(UINT16_MAX, cmd->bottom);
|
||||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||||
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
||||||
&invalidRect);
|
&invalidRect);
|
||||||
@ -505,7 +514,8 @@ static UINT gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
WINPR_ASSERT(gdi);
|
WINPR_ASSERT(gdi);
|
||||||
WINPR_ASSERT(context);
|
WINPR_ASSERT(context);
|
||||||
WINPR_ASSERT(cmd);
|
WINPR_ASSERT(cmd);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
surface =
|
||||||
|
(gdiGfxSurface*)context->GetSurfaceData(context, (UINT16)MIN(UINT16_MAX, cmd->surfaceId));
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -524,10 +534,10 @@ static UINT gdi_SurfaceCommand_Planar(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
cmd->width, cmd->height, FALSE))
|
cmd->width, cmd->height, FALSE))
|
||||||
return ERROR_INTERNAL_ERROR;
|
return ERROR_INTERNAL_ERROR;
|
||||||
|
|
||||||
invalidRect.left = cmd->left;
|
invalidRect.left = (UINT16)MIN(UINT16_MAX, cmd->left);
|
||||||
invalidRect.top = cmd->top;
|
invalidRect.top = (UINT16)MIN(UINT16_MAX, cmd->top);
|
||||||
invalidRect.right = cmd->right;
|
invalidRect.right = (UINT16)MIN(UINT16_MAX, cmd->right);
|
||||||
invalidRect.bottom = cmd->bottom;
|
invalidRect.bottom = (UINT16)MIN(UINT16_MAX, cmd->bottom);
|
||||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||||
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
||||||
&invalidRect);
|
&invalidRect);
|
||||||
@ -564,7 +574,8 @@ static UINT gdi_SurfaceCommand_AVC420(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
WINPR_ASSERT(context);
|
WINPR_ASSERT(context);
|
||||||
WINPR_ASSERT(cmd);
|
WINPR_ASSERT(cmd);
|
||||||
|
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
surface =
|
||||||
|
(gdiGfxSurface*)context->GetSurfaceData(context, (UINT16)MIN(UINT16_MAX, cmd->surfaceId));
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -643,16 +654,17 @@ static UINT gdi_SurfaceCommand_AVC444(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
INT32 rc;
|
INT32 rc;
|
||||||
UINT status = CHANNEL_RC_OK;
|
UINT status = CHANNEL_RC_OK;
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface = NULL;
|
||||||
RDPGFX_AVC444_BITMAP_STREAM* bs;
|
RDPGFX_AVC444_BITMAP_STREAM* bs = NULL;
|
||||||
RDPGFX_AVC420_BITMAP_STREAM* avc1;
|
RDPGFX_AVC420_BITMAP_STREAM* avc1 = NULL;
|
||||||
RDPGFX_H264_METABLOCK* meta1;
|
RDPGFX_H264_METABLOCK* meta1 = NULL;
|
||||||
RDPGFX_AVC420_BITMAP_STREAM* avc2;
|
RDPGFX_AVC420_BITMAP_STREAM* avc2 = NULL;
|
||||||
RDPGFX_H264_METABLOCK* meta2;
|
RDPGFX_H264_METABLOCK* meta2 = NULL;
|
||||||
WINPR_ASSERT(gdi);
|
WINPR_ASSERT(gdi);
|
||||||
WINPR_ASSERT(context);
|
WINPR_ASSERT(context);
|
||||||
WINPR_ASSERT(cmd);
|
WINPR_ASSERT(cmd);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
surface =
|
||||||
|
(gdiGfxSurface*)context->GetSurfaceData(context, (UINT16)MIN(UINT16_MAX, cmd->surfaceId));
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -738,28 +750,24 @@ fail:
|
|||||||
static BOOL gdi_apply_alpha(BYTE* data, UINT32 format, UINT32 stride, RECTANGLE_16* rect,
|
static BOOL gdi_apply_alpha(BYTE* data, UINT32 format, UINT32 stride, RECTANGLE_16* rect,
|
||||||
UINT32 startOffsetX, UINT32 count, BYTE a)
|
UINT32 startOffsetX, UINT32 count, BYTE a)
|
||||||
{
|
{
|
||||||
UINT32 y;
|
|
||||||
UINT32 written = 0;
|
UINT32 written = 0;
|
||||||
BOOL first = TRUE;
|
BOOL first = TRUE;
|
||||||
const UINT32 bpp = FreeRDPGetBytesPerPixel(format);
|
const UINT32 bpp = FreeRDPGetBytesPerPixel(format);
|
||||||
WINPR_ASSERT(rect);
|
WINPR_ASSERT(rect);
|
||||||
|
|
||||||
for (y = rect->top; y < rect->bottom; y++)
|
for (UINT32 y = rect->top; y < rect->bottom; y++)
|
||||||
{
|
{
|
||||||
UINT32 x;
|
|
||||||
BYTE* line = &data[stride * y];
|
BYTE* line = &data[stride * y];
|
||||||
|
|
||||||
for (x = first ? rect->left + startOffsetX : rect->left; x < rect->right; x++)
|
for (UINT32 x = first ? rect->left + startOffsetX : rect->left; x < rect->right; x++)
|
||||||
{
|
{
|
||||||
UINT32 color;
|
BYTE r = 0, g = 0, b = 0;
|
||||||
BYTE r, g, b;
|
|
||||||
BYTE* src;
|
|
||||||
|
|
||||||
if (written == count)
|
if (written == count)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
src = &line[x * bpp];
|
BYTE* src = &line[x * bpp];
|
||||||
color = FreeRDPReadColor(src, format);
|
UINT32 color = FreeRDPReadColor(src, format);
|
||||||
FreeRDPSplitColor(color, format, &r, &g, &b, NULL, NULL);
|
FreeRDPSplitColor(color, format, &r, &g, &b, NULL, NULL);
|
||||||
color = FreeRDPGetColor(format, r, g, b, a);
|
color = FreeRDPGetColor(format, r, g, b, a);
|
||||||
FreeRDPWriteColor(src, format, color);
|
FreeRDPWriteColor(src, format, color);
|
||||||
@ -794,7 +802,8 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
|
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
surface =
|
||||||
|
(gdiGfxSurface*)context->GetSurfaceData(context, (UINT16)MIN(UINT16_MAX, cmd->surfaceId));
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -814,16 +823,14 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
|
|
||||||
if (compressed == 0)
|
if (compressed == 0)
|
||||||
{
|
{
|
||||||
UINT32 x, y;
|
|
||||||
|
|
||||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, cmd->height * cmd->width * 1ULL))
|
if (!Stream_CheckAndLogRequiredLength(TAG, s, cmd->height * cmd->width * 1ULL))
|
||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
for (y = cmd->top; y < cmd->top + cmd->height; y++)
|
for (UINT32 y = cmd->top; y < cmd->top + cmd->height; y++)
|
||||||
{
|
{
|
||||||
BYTE* line = &surface->data[surface->scanline * y];
|
BYTE* line = &surface->data[surface->scanline * y];
|
||||||
|
|
||||||
for (x = cmd->left; x < cmd->left + cmd->width; x++)
|
for (UINT32 x = cmd->left; x < cmd->left + cmd->width; x++)
|
||||||
{
|
{
|
||||||
UINT32 color;
|
UINT32 color;
|
||||||
BYTE r, g, b, a;
|
BYTE r, g, b, a;
|
||||||
@ -839,11 +846,11 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINT32 startOffsetX = 0;
|
UINT32 startOffsetX = 0;
|
||||||
RECTANGLE_16 rect;
|
RECTANGLE_16 rect = { 0 };
|
||||||
rect.left = cmd->left;
|
rect.left = (UINT16)MIN(UINT16_MAX, cmd->left);
|
||||||
rect.top = cmd->top;
|
rect.top = (UINT16)MIN(UINT16_MAX, cmd->top);
|
||||||
rect.right = cmd->left + cmd->width;
|
rect.right = (UINT16)MIN(UINT16_MAX, cmd->left + cmd->width);
|
||||||
rect.bottom = cmd->top + cmd->height;
|
rect.bottom = (UINT16)MIN(UINT16_MAX, cmd->top + cmd->height);
|
||||||
|
|
||||||
while (rect.top < rect.bottom)
|
while (rect.top < rect.bottom)
|
||||||
{
|
{
|
||||||
@ -886,10 +893,10 @@ static UINT gdi_SurfaceCommand_Alpha(rdpGdi* gdi, RdpgfxClientContext* context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidRect.left = cmd->left;
|
invalidRect.left = (UINT16)MIN(UINT16_MAX, cmd->left);
|
||||||
invalidRect.top = cmd->top;
|
invalidRect.top = (UINT16)MIN(UINT16_MAX, cmd->top);
|
||||||
invalidRect.right = cmd->right;
|
invalidRect.right = (UINT16)MIN(UINT16_MAX, cmd->right);
|
||||||
invalidRect.bottom = cmd->bottom;
|
invalidRect.bottom = (UINT16)MIN(UINT16_MAX, cmd->bottom);
|
||||||
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
region16_union_rect(&(surface->invalidRegion), &(surface->invalidRegion), &invalidRect);
|
||||||
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
status = IFCALLRESULT(CHANNEL_RC_OK, context->UpdateSurfaceArea, context, surface->surfaceId, 1,
|
||||||
&invalidRect);
|
&invalidRect);
|
||||||
@ -929,7 +936,8 @@ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* con
|
|||||||
WINPR_ASSERT(gdi);
|
WINPR_ASSERT(gdi);
|
||||||
WINPR_ASSERT(context);
|
WINPR_ASSERT(context);
|
||||||
WINPR_ASSERT(cmd);
|
WINPR_ASSERT(cmd);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, cmd->surfaceId);
|
const UINT16 surfaceId = (UINT16)MIN(UINT16_MAX, cmd->surfaceId);
|
||||||
|
surface = (gdiGfxSurface*)context->GetSurfaceData(context, surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
{
|
{
|
||||||
@ -942,8 +950,8 @@ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* con
|
|||||||
return ERROR_INVALID_DATA;
|
return ERROR_INVALID_DATA;
|
||||||
|
|
||||||
WINPR_ASSERT(surface->codecs);
|
WINPR_ASSERT(surface->codecs);
|
||||||
rc = progressive_create_surface_context(surface->codecs->progressive, cmd->surfaceId,
|
rc = progressive_create_surface_context(surface->codecs->progressive, surfaceId, surface->width,
|
||||||
surface->width, surface->height);
|
surface->height);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
@ -955,7 +963,7 @@ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* con
|
|||||||
|
|
||||||
rc = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, surface->data,
|
rc = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, surface->data,
|
||||||
surface->format, surface->scanline, cmd->left, cmd->top,
|
surface->format, surface->scanline, cmd->left, cmd->top,
|
||||||
&invalidRegion, cmd->surfaceId, gdi->frameId);
|
&invalidRegion, surfaceId, gdi->frameId);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
{
|
{
|
||||||
@ -1068,6 +1076,10 @@ static UINT
|
|||||||
gdi_DeleteEncodingContext(RdpgfxClientContext* context,
|
gdi_DeleteEncodingContext(RdpgfxClientContext* context,
|
||||||
const RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext)
|
const RDPGFX_DELETE_ENCODING_CONTEXT_PDU* deleteEncodingContext)
|
||||||
{
|
{
|
||||||
|
WINPR_ASSERT(context);
|
||||||
|
WINPR_ASSERT(deleteEncodingContext);
|
||||||
|
WINPR_UNUSED(context);
|
||||||
|
WINPR_UNUSED(deleteEncodingContext);
|
||||||
return CHANNEL_RC_OK;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,7 +1150,6 @@ static UINT gdi_CreateSurface(RdpgfxClientContext* context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
memset(surface->data, 0xFF, (size_t)surface->scanline * surface->height);
|
memset(surface->data, 0xFF, (size_t)surface->scanline * surface->height);
|
||||||
surface->outputMapped = FALSE;
|
|
||||||
region16_init(&surface->invalidRegion);
|
region16_init(&surface->invalidRegion);
|
||||||
rc = context->SetSurfaceData(context, surface->surfaceId, (void*)surface);
|
rc = context->SetSurfaceData(context, surface->surfaceId, (void*)surface);
|
||||||
fail:
|
fail:
|
||||||
@ -1163,7 +1174,7 @@ static UINT gdi_DeleteSurface(RdpgfxClientContext* context,
|
|||||||
|
|
||||||
if (surface)
|
if (surface)
|
||||||
{
|
{
|
||||||
if (surface->windowId != 0)
|
if (surface->windowMapped)
|
||||||
rc = IFCALLRESULT(CHANNEL_RC_OK, context->UnmapWindowForSurface, context,
|
rc = IFCALLRESULT(CHANNEL_RC_OK, context->UnmapWindowForSurface, context,
|
||||||
surface->windowId);
|
surface->windowId);
|
||||||
|
|
||||||
@ -1295,7 +1306,9 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context,
|
|||||||
for (index = 0; index < surfaceToSurface->destPtsCount; index++)
|
for (index = 0; index < surfaceToSurface->destPtsCount; index++)
|
||||||
{
|
{
|
||||||
const RDPGFX_POINT16* destPt = &surfaceToSurface->destPts[index];
|
const RDPGFX_POINT16* destPt = &surfaceToSurface->destPts[index];
|
||||||
const RECTANGLE_16 rect = { destPt->x, destPt->y, destPt->x + nWidth, destPt->y + nHeight };
|
const RECTANGLE_16 rect = { destPt->x, destPt->y,
|
||||||
|
(UINT16)MIN(UINT16_MAX, destPt->x + nWidth),
|
||||||
|
(UINT16)MIN(UINT16_MAX, destPt->y + nHeight) };
|
||||||
if (!is_rect_valid(&rect, surfaceDst->width, surfaceDst->height))
|
if (!is_rect_valid(&rect, surfaceDst->width, surfaceDst->height))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -1408,8 +1421,9 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context,
|
|||||||
for (index = 0; index < cacheToSurface->destPtsCount; index++)
|
for (index = 0; index < cacheToSurface->destPtsCount; index++)
|
||||||
{
|
{
|
||||||
const RDPGFX_POINT16* destPt = &cacheToSurface->destPts[index];
|
const RDPGFX_POINT16* destPt = &cacheToSurface->destPts[index];
|
||||||
const RECTANGLE_16 rect = { destPt->x, destPt->y, destPt->x + cacheEntry->width,
|
const RECTANGLE_16 rect = { destPt->x, destPt->y,
|
||||||
destPt->y + cacheEntry->height };
|
(UINT16)MIN(UINT16_MAX, destPt->x + cacheEntry->width),
|
||||||
|
(UINT16)MIN(UINT16_MAX, destPt->y + cacheEntry->height) };
|
||||||
|
|
||||||
if (rectangle_is_empty(&rect))
|
if (rectangle_is_empty(&rect))
|
||||||
continue;
|
continue;
|
||||||
@ -1551,8 +1565,8 @@ static UINT gdi_ExportCacheEntry(RdpgfxClientContext* context, UINT16 cacheSlot,
|
|||||||
if (cacheEntry)
|
if (cacheEntry)
|
||||||
{
|
{
|
||||||
exportCacheEntry->key64 = cacheEntry->cacheKey;
|
exportCacheEntry->key64 = cacheEntry->cacheKey;
|
||||||
exportCacheEntry->width = cacheEntry->width;
|
exportCacheEntry->width = (UINT16)MIN(UINT16_MAX, cacheEntry->width);
|
||||||
exportCacheEntry->height = cacheEntry->height;
|
exportCacheEntry->height = (UINT16)MIN(UINT16_MAX, cacheEntry->height);
|
||||||
exportCacheEntry->size = cacheEntry->width * cacheEntry->height * 4;
|
exportCacheEntry->size = cacheEntry->width * cacheEntry->height * 4;
|
||||||
exportCacheEntry->flags = 0;
|
exportCacheEntry->flags = 0;
|
||||||
exportCacheEntry->data = cacheEntry->data;
|
exportCacheEntry->data = cacheEntry->data;
|
||||||
@ -1595,13 +1609,16 @@ static UINT gdi_MapSurfaceToOutput(RdpgfxClientContext* context,
|
|||||||
const RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput)
|
const RDPGFX_MAP_SURFACE_TO_OUTPUT_PDU* surfaceToOutput)
|
||||||
{
|
{
|
||||||
UINT rc = ERROR_INTERNAL_ERROR;
|
UINT rc = ERROR_INTERNAL_ERROR;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface = NULL;
|
||||||
EnterCriticalSection(&context->mux);
|
EnterCriticalSection(&context->mux);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, surfaceToOutput->surfaceId);
|
surface = (gdiGfxSurface*)context->GetSurfaceData(context, surfaceToOutput->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (surface->windowMapped)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
surface->outputMapped = TRUE;
|
surface->outputMapped = TRUE;
|
||||||
surface->outputOriginX = surfaceToOutput->outputOriginX;
|
surface->outputOriginX = surfaceToOutput->outputOriginX;
|
||||||
surface->outputOriginY = surfaceToOutput->outputOriginY;
|
surface->outputOriginY = surfaceToOutput->outputOriginY;
|
||||||
@ -1619,13 +1636,15 @@ gdi_MapSurfaceToScaledOutput(RdpgfxClientContext* context,
|
|||||||
const RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU* surfaceToOutput)
|
const RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU* surfaceToOutput)
|
||||||
{
|
{
|
||||||
UINT rc = ERROR_INTERNAL_ERROR;
|
UINT rc = ERROR_INTERNAL_ERROR;
|
||||||
gdiGfxSurface* surface;
|
gdiGfxSurface* surface = NULL;
|
||||||
EnterCriticalSection(&context->mux);
|
EnterCriticalSection(&context->mux);
|
||||||
surface = (gdiGfxSurface*)context->GetSurfaceData(context, surfaceToOutput->surfaceId);
|
surface = (gdiGfxSurface*)context->GetSurfaceData(context, surfaceToOutput->surfaceId);
|
||||||
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (surface->windowMapped)
|
||||||
|
goto fail;
|
||||||
surface->outputMapped = TRUE;
|
surface->outputMapped = TRUE;
|
||||||
surface->outputOriginX = surfaceToOutput->outputOriginX;
|
surface->outputOriginX = surfaceToOutput->outputOriginX;
|
||||||
surface->outputOriginY = surfaceToOutput->outputOriginY;
|
surface->outputOriginY = surfaceToOutput->outputOriginY;
|
||||||
@ -1654,11 +1673,15 @@ static UINT gdi_MapSurfaceToWindow(RdpgfxClientContext* context,
|
|||||||
if (!surface)
|
if (!surface)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (surface->windowId != 0)
|
if (surface->outputMapped)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (surface->windowMapped)
|
||||||
{
|
{
|
||||||
if (surface->windowId != surfaceToWindow->windowId)
|
if (surface->windowId != surfaceToWindow->windowId)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
surface->windowMapped = TRUE;
|
||||||
|
|
||||||
surface->windowId = surfaceToWindow->windowId;
|
surface->windowId = surfaceToWindow->windowId;
|
||||||
surface->mappedWidth = surfaceToWindow->mappedWidth;
|
surface->mappedWidth = surfaceToWindow->mappedWidth;
|
||||||
@ -1684,11 +1707,15 @@ gdi_MapSurfaceToScaledWindow(RdpgfxClientContext* context,
|
|||||||
if (!surface)
|
if (!surface)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (surface->windowId != 0)
|
if (surface->outputMapped)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (surface->windowMapped)
|
||||||
{
|
{
|
||||||
if (surface->windowId != surfaceToWindow->windowId)
|
if (surface->windowId != surfaceToWindow->windowId)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
surface->windowMapped = TRUE;
|
||||||
|
|
||||||
surface->windowId = surfaceToWindow->windowId;
|
surface->windowId = surfaceToWindow->windowId;
|
||||||
surface->mappedWidth = surfaceToWindow->mappedWidth;
|
surface->mappedWidth = surfaceToWindow->mappedWidth;
|
||||||
|
Loading…
Reference in New Issue
Block a user