mirror of https://github.com/FreeRDP/FreeRDP
Refactored order updates
Unified order creation/copy/delete to avoid memory leaks.
This commit is contained in:
parent
8cba201999
commit
e5767f07ac
|
@ -82,6 +82,6 @@
|
|||
|
||||
#define IFCALL(_cb, ...) do { if (_cb != NULL) { _cb( __VA_ARGS__ ); } } while (0)
|
||||
#define IFCALLRET(_cb, _ret, ...) do { if (_cb != NULL) { _ret = _cb( __VA_ARGS__ ); } } while (0)
|
||||
#define IFCALLRESULT(_default_return, _cb, ...) (_cb != NULL) ? _cb( __VA_ARGS__ ) : (_default_return)
|
||||
#define IFCALLRESULT(_default_return, _cb, ...) ((_cb != NULL) ? _cb( __VA_ARGS__ ) : (_default_return))
|
||||
|
||||
#endif /* FREERDP_API */
|
||||
|
|
|
@ -93,14 +93,6 @@ struct rdp_pointer_update
|
|||
pPointerNew PointerNew; /* 19 */
|
||||
pPointerCached PointerCached; /* 20 */
|
||||
UINT32 paddingB[32 - 21]; /* 21 */
|
||||
|
||||
/* internal */
|
||||
|
||||
POINTER_POSITION_UPDATE pointer_position;
|
||||
POINTER_SYSTEM_UPDATE pointer_system;
|
||||
POINTER_COLOR_UPDATE pointer_color;
|
||||
POINTER_NEW_UPDATE pointer_new;
|
||||
POINTER_CACHED_UPDATE pointer_cached;
|
||||
};
|
||||
typedef struct rdp_pointer_update rdpPointerUpdate;
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ struct _CACHE_GLYPH_ORDER
|
|||
UINT32 cacheId;
|
||||
UINT32 cGlyphs;
|
||||
GLYPH_DATA glyphData[256];
|
||||
BYTE* unicodeCharacters;
|
||||
WCHAR* unicodeCharacters;
|
||||
};
|
||||
typedef struct _CACHE_GLYPH_ORDER CACHE_GLYPH_ORDER;
|
||||
|
||||
|
@ -147,7 +147,7 @@ struct _CACHE_GLYPH_V2_ORDER
|
|||
UINT32 flags;
|
||||
UINT32 cGlyphs;
|
||||
GLYPH_DATA_V2 glyphData[256];
|
||||
BYTE* unicodeCharacters;
|
||||
WCHAR* unicodeCharacters;
|
||||
};
|
||||
typedef struct _CACHE_GLYPH_V2_ORDER CACHE_GLYPH_V2_ORDER;
|
||||
|
||||
|
@ -164,19 +164,19 @@ struct _CACHE_BRUSH_ORDER
|
|||
typedef struct _CACHE_BRUSH_ORDER CACHE_BRUSH_ORDER;
|
||||
|
||||
typedef BOOL (*pCacheBitmap)(rdpContext* context,
|
||||
const CACHE_BITMAP_ORDER* cache_bitmap_order);
|
||||
const CACHE_BITMAP_ORDER* cache_bitmap_order);
|
||||
typedef BOOL (*pCacheBitmapV2)(rdpContext* context,
|
||||
CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order);
|
||||
CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order);
|
||||
typedef BOOL (*pCacheBitmapV3)(rdpContext* context,
|
||||
CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order);
|
||||
CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order);
|
||||
typedef BOOL (*pCacheColorTable)(rdpContext* context,
|
||||
const CACHE_COLOR_TABLE_ORDER* cache_color_table_order);
|
||||
const CACHE_COLOR_TABLE_ORDER* cache_color_table_order);
|
||||
typedef BOOL (*pCacheGlyph)(rdpContext* context,
|
||||
const CACHE_GLYPH_ORDER* cache_glyph_order);
|
||||
const CACHE_GLYPH_ORDER* cache_glyph_order);
|
||||
typedef BOOL (*pCacheGlyphV2)(rdpContext* context,
|
||||
const CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order);
|
||||
const CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order);
|
||||
typedef BOOL (*pCacheBrush)(rdpContext* context,
|
||||
const CACHE_BRUSH_ORDER* cache_brush_order);
|
||||
const CACHE_BRUSH_ORDER* cache_brush_order);
|
||||
|
||||
struct rdp_secondary_update
|
||||
{
|
||||
|
@ -195,13 +195,6 @@ struct rdp_secondary_update
|
|||
/* internal */
|
||||
|
||||
BOOL glyph_v2;
|
||||
CACHE_BITMAP_ORDER cache_bitmap_order;
|
||||
CACHE_BITMAP_V2_ORDER cache_bitmap_v2_order;
|
||||
CACHE_BITMAP_V3_ORDER cache_bitmap_v3_order;
|
||||
CACHE_COLOR_TABLE_ORDER cache_color_table_order;
|
||||
CACHE_GLYPH_ORDER cache_glyph_order;
|
||||
CACHE_GLYPH_V2_ORDER cache_glyph_v2_order;
|
||||
CACHE_BRUSH_ORDER cache_brush_order;
|
||||
};
|
||||
typedef struct rdp_secondary_update rdpSecondaryUpdate;
|
||||
|
||||
|
|
|
@ -20,11 +20,17 @@ set(MODULE_PREFIX "FREERDP_CACHE")
|
|||
|
||||
freerdp_module_add(
|
||||
brush.c
|
||||
brush.h
|
||||
pointer.c
|
||||
pointer.h
|
||||
bitmap.c
|
||||
bitmap.h
|
||||
nine_grid.c
|
||||
offscreen.c
|
||||
palette.c
|
||||
palette.h
|
||||
glyph.c
|
||||
cache.c)
|
||||
glyph.h
|
||||
cache.c
|
||||
cache.h)
|
||||
|
||||
|
|
|
@ -36,15 +36,17 @@
|
|||
#include "../gdi/gdi.h"
|
||||
#include "../core/graphics.h"
|
||||
|
||||
#include "bitmap.h"
|
||||
|
||||
#define TAG FREERDP_TAG("cache.bitmap")
|
||||
|
||||
static rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id,
|
||||
UINT32 index);
|
||||
UINT32 index);
|
||||
static BOOL bitmap_cache_put(rdpBitmapCache* bitmap_cache, UINT32 id,
|
||||
UINT32 index, rdpBitmap* bitmap);
|
||||
UINT32 index, rdpBitmap* bitmap);
|
||||
|
||||
static BOOL update_gdi_memblt(rdpContext* context,
|
||||
MEMBLT_ORDER* memblt)
|
||||
MEMBLT_ORDER* memblt)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
rdpCache* cache = context->cache;
|
||||
|
@ -53,7 +55,7 @@ static BOOL update_gdi_memblt(rdpContext* context,
|
|||
bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex);
|
||||
else
|
||||
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) memblt->cacheId,
|
||||
memblt->cacheIndex);
|
||||
memblt->cacheIndex);
|
||||
|
||||
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
|
||||
if (bitmap == NULL)
|
||||
|
@ -64,7 +66,7 @@ static BOOL update_gdi_memblt(rdpContext* context,
|
|||
}
|
||||
|
||||
static BOOL update_gdi_mem3blt(rdpContext* context,
|
||||
MEM3BLT_ORDER* mem3blt)
|
||||
MEM3BLT_ORDER* mem3blt)
|
||||
{
|
||||
BYTE style;
|
||||
rdpBitmap* bitmap;
|
||||
|
@ -76,7 +78,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context,
|
|||
bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex);
|
||||
else
|
||||
bitmap = bitmap_cache_get(cache->bitmap, (BYTE) mem3blt->cacheId,
|
||||
mem3blt->cacheIndex);
|
||||
mem3blt->cacheIndex);
|
||||
|
||||
/* XP-SP2 servers sometimes ask for cached bitmaps they've never defined. */
|
||||
if (!bitmap)
|
||||
|
@ -101,7 +103,7 @@ static BOOL update_gdi_mem3blt(rdpContext* context,
|
|||
}
|
||||
|
||||
static BOOL update_gdi_cache_bitmap(rdpContext* context,
|
||||
const CACHE_BITMAP_ORDER* cacheBitmap)
|
||||
const CACHE_BITMAP_ORDER* cacheBitmap)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
rdpBitmap* prevBitmap;
|
||||
|
@ -112,13 +114,13 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context,
|
|||
return FALSE;
|
||||
|
||||
Bitmap_SetDimensions(bitmap, cacheBitmap->bitmapWidth,
|
||||
cacheBitmap->bitmapHeight);
|
||||
cacheBitmap->bitmapHeight);
|
||||
|
||||
if (!bitmap->Decompress(context, bitmap,
|
||||
cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth,
|
||||
cacheBitmap->bitmapHeight,
|
||||
cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength,
|
||||
cacheBitmap->compressed, RDP_CODEC_ID_NONE))
|
||||
cacheBitmap->bitmapDataStream, cacheBitmap->bitmapWidth,
|
||||
cacheBitmap->bitmapHeight,
|
||||
cacheBitmap->bitmapBpp, cacheBitmap->bitmapLength,
|
||||
cacheBitmap->compressed, RDP_CODEC_ID_NONE))
|
||||
{
|
||||
Bitmap_Free(context, bitmap);
|
||||
return FALSE;
|
||||
|
@ -131,15 +133,15 @@ static BOOL update_gdi_cache_bitmap(rdpContext* context,
|
|||
}
|
||||
|
||||
prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmap->cacheId,
|
||||
cacheBitmap->cacheIndex);
|
||||
cacheBitmap->cacheIndex);
|
||||
Bitmap_Free(context, prevBitmap);
|
||||
return bitmap_cache_put(cache->bitmap, cacheBitmap->cacheId,
|
||||
cacheBitmap->cacheIndex,
|
||||
bitmap);
|
||||
cacheBitmap->cacheIndex,
|
||||
bitmap);
|
||||
}
|
||||
|
||||
static BOOL update_gdi_cache_bitmap_v2(rdpContext* context,
|
||||
CACHE_BITMAP_V2_ORDER* cacheBitmapV2)
|
||||
CACHE_BITMAP_V2_ORDER* cacheBitmapV2)
|
||||
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
|
@ -158,23 +160,23 @@ static BOOL update_gdi_cache_bitmap_v2(rdpContext* context,
|
|||
cacheBitmapV2->bitmapBpp = settings->ColorDepth;
|
||||
|
||||
Bitmap_SetDimensions(bitmap, cacheBitmapV2->bitmapWidth,
|
||||
cacheBitmapV2->bitmapHeight);
|
||||
cacheBitmapV2->bitmapHeight);
|
||||
|
||||
if (!bitmap->Decompress(context, bitmap,
|
||||
cacheBitmapV2->bitmapDataStream,
|
||||
cacheBitmapV2->bitmapWidth,
|
||||
cacheBitmapV2->bitmapHeight,
|
||||
cacheBitmapV2->bitmapBpp,
|
||||
cacheBitmapV2->bitmapLength,
|
||||
cacheBitmapV2->compressed,
|
||||
RDP_CODEC_ID_NONE))
|
||||
cacheBitmapV2->bitmapDataStream,
|
||||
cacheBitmapV2->bitmapWidth,
|
||||
cacheBitmapV2->bitmapHeight,
|
||||
cacheBitmapV2->bitmapBpp,
|
||||
cacheBitmapV2->bitmapLength,
|
||||
cacheBitmapV2->compressed,
|
||||
RDP_CODEC_ID_NONE))
|
||||
{
|
||||
Bitmap_Free(context, bitmap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV2->cacheId,
|
||||
cacheBitmapV2->cacheIndex);
|
||||
cacheBitmapV2->cacheIndex);
|
||||
|
||||
if (!bitmap->New(context, bitmap))
|
||||
{
|
||||
|
@ -184,11 +186,11 @@ static BOOL update_gdi_cache_bitmap_v2(rdpContext* context,
|
|||
|
||||
Bitmap_Free(context, prevBitmap);
|
||||
return bitmap_cache_put(cache->bitmap, cacheBitmapV2->cacheId,
|
||||
cacheBitmapV2->cacheIndex, bitmap);
|
||||
cacheBitmapV2->cacheIndex, bitmap);
|
||||
}
|
||||
|
||||
static BOOL update_gdi_cache_bitmap_v3(rdpContext* context,
|
||||
CACHE_BITMAP_V3_ORDER* cacheBitmapV3)
|
||||
CACHE_BITMAP_V3_ORDER* cacheBitmapV3)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
rdpBitmap* prevBitmap;
|
||||
|
@ -208,9 +210,9 @@ static BOOL update_gdi_cache_bitmap_v3(rdpContext* context,
|
|||
Bitmap_SetDimensions(bitmap, bitmapData->width, bitmapData->height);
|
||||
|
||||
if (!bitmap->Decompress(context, bitmap,
|
||||
bitmapData->data, bitmapData->width, bitmapData->height,
|
||||
bitmapData->bpp, bitmapData->length, compressed,
|
||||
bitmapData->codecID))
|
||||
bitmapData->data, bitmapData->width, bitmapData->height,
|
||||
bitmapData->bpp, bitmapData->length, compressed,
|
||||
bitmapData->codecID))
|
||||
{
|
||||
Bitmap_Free(context, bitmap);
|
||||
return FALSE;
|
||||
|
@ -223,14 +225,14 @@ static BOOL update_gdi_cache_bitmap_v3(rdpContext* context,
|
|||
}
|
||||
|
||||
prevBitmap = bitmap_cache_get(cache->bitmap, cacheBitmapV3->cacheId,
|
||||
cacheBitmapV3->cacheIndex);
|
||||
cacheBitmapV3->cacheIndex);
|
||||
Bitmap_Free(context, prevBitmap);
|
||||
return bitmap_cache_put(cache->bitmap, cacheBitmapV3->cacheId,
|
||||
cacheBitmapV3->cacheIndex, bitmap);
|
||||
cacheBitmapV3->cacheIndex, bitmap);
|
||||
}
|
||||
|
||||
rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id,
|
||||
UINT32 index)
|
||||
UINT32 index)
|
||||
{
|
||||
rdpBitmap* bitmap;
|
||||
|
||||
|
@ -255,7 +257,7 @@ rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmapCache, UINT32 id,
|
|||
}
|
||||
|
||||
BOOL bitmap_cache_put(rdpBitmapCache* bitmapCache, UINT32 id, UINT32 index,
|
||||
rdpBitmap* bitmap)
|
||||
rdpBitmap* bitmap)
|
||||
{
|
||||
if (id > bitmapCache->maxCells)
|
||||
{
|
||||
|
@ -304,7 +306,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
|
|||
bitmapCache->context = bitmapCache->update->context;
|
||||
bitmapCache->maxCells = settings->BitmapCacheV2NumCells;
|
||||
bitmapCache->cells = (BITMAP_V2_CELL*) calloc(bitmapCache->maxCells,
|
||||
sizeof(BITMAP_V2_CELL));
|
||||
sizeof(BITMAP_V2_CELL));
|
||||
|
||||
if (!bitmapCache->cells)
|
||||
goto fail;
|
||||
|
@ -314,7 +316,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
|
|||
bitmapCache->cells[i].number = settings->BitmapCacheV2CellInfo[i].numEntries;
|
||||
/* allocate an extra entry for BITMAP_CACHE_WAITING_LIST_INDEX */
|
||||
bitmapCache->cells[i].entries = (rdpBitmap**) calloc((
|
||||
bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*));
|
||||
bitmapCache->cells[i].number + 1), sizeof(rdpBitmap*));
|
||||
|
||||
if (!bitmapCache->cells[i].entries)
|
||||
goto fail;
|
||||
|
@ -355,3 +357,174 @@ void bitmap_cache_free(rdpBitmapCache* bitmapCache)
|
|||
free(bitmapCache);
|
||||
}
|
||||
}
|
||||
|
||||
static void free_bitmap_data(BITMAP_DATA* data, size_t count)
|
||||
{
|
||||
size_t x;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
for (x = 0; x < count; x++)
|
||||
free(data[x].bitmapDataStream);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
static BITMAP_DATA* copy_bitmap_data(const BITMAP_DATA* data, size_t count)
|
||||
{
|
||||
size_t x;
|
||||
BITMAP_DATA* dst = (BITMAP_DATA*) calloc(count, sizeof(BITMAP_DATA));
|
||||
|
||||
if (!dst)
|
||||
goto fail;
|
||||
|
||||
for (x = 0; x < count; x++)
|
||||
{
|
||||
dst[x] = data[x];
|
||||
|
||||
if (data[x].bitmapLength > 0)
|
||||
{
|
||||
dst[x].bitmapDataStream = malloc(data[x].bitmapLength);
|
||||
|
||||
if (!dst[x].bitmapDataStream)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst[x].bitmapDataStream, data[x].bitmapDataStream, data[x].bitmapLength);
|
||||
}
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_bitmap_data(dst, count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_bitmap_update(rdpContext* context, BITMAP_UPDATE* pointer)
|
||||
{
|
||||
if (!pointer)
|
||||
return;
|
||||
|
||||
free_bitmap_data(pointer->rectangles, pointer->number);
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
BITMAP_UPDATE* copy_bitmap_update(rdpContext* context, const BITMAP_UPDATE* pointer)
|
||||
{
|
||||
BITMAP_UPDATE* dst = calloc(1, sizeof(BITMAP_UPDATE));
|
||||
|
||||
if (!dst || !pointer)
|
||||
goto fail;
|
||||
|
||||
*dst = *pointer;
|
||||
dst->rectangles = copy_bitmap_data(pointer->rectangles, pointer->number);
|
||||
|
||||
if (!dst->rectangles)
|
||||
goto fail;
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_bitmap_update(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CACHE_BITMAP_ORDER* copy_cache_bitmap_order(rdpContext* context, const CACHE_BITMAP_ORDER* order)
|
||||
{
|
||||
CACHE_BITMAP_ORDER* dst = calloc(1, sizeof(CACHE_BITMAP_ORDER));
|
||||
|
||||
if (!dst || !order)
|
||||
goto fail;
|
||||
|
||||
*dst = *order;
|
||||
|
||||
if (order->bitmapLength > 0)
|
||||
{
|
||||
dst->bitmapDataStream = malloc(order->bitmapLength);
|
||||
|
||||
if (!dst->bitmapDataStream)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->bitmapDataStream, order->bitmapDataStream, order->bitmapLength);
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_cache_bitmap_order(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_cache_bitmap_order(rdpContext* context, CACHE_BITMAP_ORDER* order)
|
||||
{
|
||||
if (order)
|
||||
free(order->bitmapDataStream);
|
||||
|
||||
free(order);
|
||||
}
|
||||
|
||||
CACHE_BITMAP_V2_ORDER* copy_cache_bitmap_v2_order(rdpContext* context,
|
||||
const CACHE_BITMAP_V2_ORDER* order)
|
||||
{
|
||||
CACHE_BITMAP_V2_ORDER* dst = calloc(1, sizeof(CACHE_BITMAP_V2_ORDER));
|
||||
|
||||
if (!dst || !order)
|
||||
goto fail;
|
||||
|
||||
*dst = *order;
|
||||
|
||||
if (order->bitmapLength > 0)
|
||||
{
|
||||
dst->bitmapDataStream = malloc(order->bitmapLength);
|
||||
|
||||
if (!dst->bitmapDataStream)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->bitmapDataStream, order->bitmapDataStream, order->bitmapLength);
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_cache_bitmap_v2_order(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_cache_bitmap_v2_order(rdpContext* context, CACHE_BITMAP_V2_ORDER* order)
|
||||
{
|
||||
if (order)
|
||||
free(order->bitmapDataStream);
|
||||
|
||||
free(order);
|
||||
}
|
||||
|
||||
CACHE_BITMAP_V3_ORDER* copy_cache_bitmap_v3_order(rdpContext* context,
|
||||
const CACHE_BITMAP_V3_ORDER* order)
|
||||
{
|
||||
CACHE_BITMAP_V3_ORDER* dst = calloc(1, sizeof(CACHE_BITMAP_V3_ORDER));
|
||||
|
||||
if (!dst || !order)
|
||||
goto fail;
|
||||
|
||||
*dst = *order;
|
||||
|
||||
if (order->bitmapData.length > 0)
|
||||
{
|
||||
dst->bitmapData.data = malloc(order->bitmapData.length);
|
||||
|
||||
if (!dst->bitmapData.data)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->bitmapData.data, order->bitmapData.data, order->bitmapData.length);
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_cache_bitmap_v3_order(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_cache_bitmap_v3_order(rdpContext* context, CACHE_BITMAP_V3_ORDER* order)
|
||||
{
|
||||
if (order)
|
||||
free(order->bitmapData.data);
|
||||
|
||||
free(order);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2018 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_CACHE_BITMAP_H
|
||||
#define FREERDP_LIB_CACHE_BITMAP_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/update.h>
|
||||
|
||||
FREERDP_LOCAL BITMAP_UPDATE* copy_bitmap_update(rdpContext* context, const BITMAP_UPDATE* pointer);
|
||||
FREERDP_LOCAL void free_bitmap_update(rdpContext* context, BITMAP_UPDATE* pointer);
|
||||
|
||||
FREERDP_LOCAL CACHE_BITMAP_ORDER* copy_cache_bitmap_order(rdpContext* context,
|
||||
const CACHE_BITMAP_ORDER* order);
|
||||
FREERDP_LOCAL void free_cache_bitmap_order(rdpContext* context, CACHE_BITMAP_ORDER* order);
|
||||
|
||||
FREERDP_LOCAL CACHE_BITMAP_V2_ORDER* copy_cache_bitmap_v2_order(rdpContext* context,
|
||||
const CACHE_BITMAP_V2_ORDER* order);
|
||||
FREERDP_LOCAL void free_cache_bitmap_v2_order(rdpContext* context, CACHE_BITMAP_V2_ORDER* order);
|
||||
|
||||
FREERDP_LOCAL CACHE_BITMAP_V3_ORDER* copy_cache_bitmap_v3_order(rdpContext* context,
|
||||
const CACHE_BITMAP_V3_ORDER* order);
|
||||
FREERDP_LOCAL void free_cache_bitmap_v3_order(rdpContext* context, CACHE_BITMAP_V3_ORDER* order);
|
||||
|
||||
#endif /* FREERDP_LIB_CACHE_BITMAP_H */
|
|
@ -29,19 +29,19 @@
|
|||
#include <freerdp/freerdp.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
|
||||
#include <freerdp/cache/brush.h>
|
||||
|
||||
#include "brush.h"
|
||||
|
||||
#define TAG FREERDP_TAG("cache.brush")
|
||||
|
||||
static BOOL update_gdi_patblt(rdpContext* context,
|
||||
PATBLT_ORDER* patblt)
|
||||
PATBLT_ORDER* patblt)
|
||||
{
|
||||
BYTE style;
|
||||
BOOL ret = TRUE;
|
||||
rdpBrush* brush = &patblt->brush;
|
||||
const rdpCache* cache = context->cache;
|
||||
|
||||
style = brush->style;
|
||||
|
||||
if (brush->style & CACHED_BRUSH)
|
||||
|
@ -56,20 +56,19 @@ static BOOL update_gdi_patblt(rdpContext* context,
|
|||
}
|
||||
|
||||
static BOOL update_gdi_polygon_sc(rdpContext* context,
|
||||
const POLYGON_SC_ORDER* polygon_sc)
|
||||
const POLYGON_SC_ORDER* polygon_sc)
|
||||
{
|
||||
rdpCache* cache = context->cache;
|
||||
return IFCALLRESULT(TRUE, cache->brush->PolygonSC, context, polygon_sc);
|
||||
}
|
||||
|
||||
static BOOL update_gdi_polygon_cb(rdpContext* context,
|
||||
POLYGON_CB_ORDER* polygon_cb)
|
||||
POLYGON_CB_ORDER* polygon_cb)
|
||||
{
|
||||
BYTE style;
|
||||
rdpBrush* brush = &polygon_cb->brush;
|
||||
rdpCache* cache = context->cache;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
style = brush->style;
|
||||
|
||||
if (brush->style & CACHED_BRUSH)
|
||||
|
@ -80,24 +79,22 @@ static BOOL update_gdi_polygon_cb(rdpContext* context,
|
|||
|
||||
IFCALLRET(cache->brush->PolygonCB, ret, context, polygon_cb);
|
||||
brush->style = style;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL update_gdi_cache_brush(rdpContext* context,
|
||||
const CACHE_BRUSH_ORDER* cacheBrush)
|
||||
const CACHE_BRUSH_ORDER* cacheBrush)
|
||||
{
|
||||
UINT32 length;
|
||||
void* data = NULL;
|
||||
rdpCache* cache = context->cache;
|
||||
|
||||
length = cacheBrush->bpp * 64 / 8;
|
||||
|
||||
data = malloc(length);
|
||||
|
||||
if (!data)
|
||||
return FALSE;
|
||||
CopyMemory(data, cacheBrush->data, length);
|
||||
|
||||
CopyMemory(data, cacheBrush->data, length);
|
||||
brush_cache_put(cache->brush, cacheBrush->index, data, cacheBrush->bpp);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -156,7 +153,6 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3
|
|||
}
|
||||
|
||||
free(brushCache->monoEntries[index].entry);
|
||||
|
||||
brushCache->monoEntries[index].bpp = bpp;
|
||||
brushCache->monoEntries[index].entry = entry;
|
||||
}
|
||||
|
@ -170,7 +166,6 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3
|
|||
}
|
||||
|
||||
free(brushCache->entries[index].entry);
|
||||
|
||||
brushCache->entries[index].bpp = bpp;
|
||||
brushCache->entries[index].entry = entry;
|
||||
}
|
||||
|
@ -179,11 +174,9 @@ void brush_cache_put(rdpBrushCache* brushCache, UINT32 index, void* entry, UINT3
|
|||
void brush_cache_register_callbacks(rdpUpdate* update)
|
||||
{
|
||||
rdpCache* cache = update->context->cache;
|
||||
|
||||
cache->brush->PatBlt = update->primary->PatBlt;
|
||||
cache->brush->PolygonSC = update->primary->PolygonSC;
|
||||
cache->brush->PolygonCB = update->primary->PolygonCB;
|
||||
|
||||
update->primary->PatBlt = update_gdi_patblt;
|
||||
update->primary->PolygonSC = update_gdi_polygon_sc;
|
||||
update->primary->PolygonCB = update_gdi_polygon_cb;
|
||||
|
@ -193,27 +186,25 @@ void brush_cache_register_callbacks(rdpUpdate* update)
|
|||
rdpBrushCache* brush_cache_new(rdpSettings* settings)
|
||||
{
|
||||
rdpBrushCache* brushCache;
|
||||
|
||||
brushCache = (rdpBrushCache*) calloc(1, sizeof(rdpBrushCache));
|
||||
|
||||
if (!brushCache)
|
||||
return NULL;
|
||||
|
||||
brushCache->settings = settings;
|
||||
|
||||
brushCache->maxEntries = 64;
|
||||
brushCache->maxMonoEntries = 64;
|
||||
|
||||
brushCache->entries = (BRUSH_ENTRY*)calloc(brushCache->maxEntries, sizeof(BRUSH_ENTRY));
|
||||
|
||||
if (!brushCache->entries)
|
||||
goto error_entries;
|
||||
|
||||
brushCache->monoEntries = (BRUSH_ENTRY*) calloc(brushCache->maxMonoEntries, sizeof(BRUSH_ENTRY));
|
||||
|
||||
if (!brushCache->monoEntries)
|
||||
goto error_mono;
|
||||
|
||||
return brushCache;
|
||||
|
||||
error_mono:
|
||||
free(brushCache->entries);
|
||||
error_entries:
|
||||
|
@ -246,3 +237,22 @@ void brush_cache_free(rdpBrushCache* brushCache)
|
|||
free(brushCache);
|
||||
}
|
||||
}
|
||||
|
||||
void free_cache_brush_order(rdpContext* context, CACHE_BRUSH_ORDER* order)
|
||||
{
|
||||
free(order);
|
||||
}
|
||||
|
||||
CACHE_BRUSH_ORDER* copy_cache_brush_order(rdpContext* context, const CACHE_BRUSH_ORDER* order)
|
||||
{
|
||||
CACHE_BRUSH_ORDER* dst = calloc(1, sizeof(CACHE_BRUSH_ORDER));
|
||||
|
||||
if (!dst || !order)
|
||||
goto fail;
|
||||
|
||||
*dst = *order;
|
||||
return dst;
|
||||
fail:
|
||||
free_cache_brush_order(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2018 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_CACHE_BRUSH_H
|
||||
#define FREERDP_LIB_CACHE_BRUSH_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/pointer.h>
|
||||
|
||||
FREERDP_LOCAL CACHE_BRUSH_ORDER* copy_cache_brush_order(rdpContext* context,
|
||||
const CACHE_BRUSH_ORDER* order);
|
||||
FREERDP_LOCAL void free_cache_brush_order(rdpContext* context, CACHE_BRUSH_ORDER* order);
|
||||
|
||||
#endif /* FREERDP_LIB_CACHE_BRUSH_H */
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include <freerdp/cache/cache.h>
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
rdpCache* cache_new(rdpSettings* settings)
|
||||
{
|
||||
rdpCache* cache;
|
||||
|
@ -90,3 +92,23 @@ void cache_free(rdpCache* cache)
|
|||
free(cache);
|
||||
}
|
||||
}
|
||||
|
||||
CACHE_COLOR_TABLE_ORDER* copy_cache_color_table_order(rdpContext* context,
|
||||
const CACHE_COLOR_TABLE_ORDER* order)
|
||||
{
|
||||
CACHE_COLOR_TABLE_ORDER* dst = calloc(1, sizeof(CACHE_COLOR_TABLE_ORDER));
|
||||
|
||||
if (!dst || !order)
|
||||
goto fail;
|
||||
|
||||
*dst = *order;
|
||||
return dst;
|
||||
fail:
|
||||
free_cache_color_table_order(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_cache_color_table_order(rdpContext* context, CACHE_COLOR_TABLE_ORDER* order)
|
||||
{
|
||||
free(order);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2018 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_CACHE_CACHE_H
|
||||
#define FREERDP_LIB_CACHE_CACHE_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/pointer.h>
|
||||
|
||||
FREERDP_LOCAL CACHE_COLOR_TABLE_ORDER* copy_cache_color_table_order(rdpContext* context,
|
||||
const CACHE_COLOR_TABLE_ORDER* order);
|
||||
FREERDP_LOCAL void free_cache_color_table_order(rdpContext* context,
|
||||
CACHE_COLOR_TABLE_ORDER* order);
|
||||
|
||||
#endif /* FREERDP_LIB_CACHE_CACHE_H */
|
|
@ -31,6 +31,8 @@
|
|||
#include <freerdp/log.h>
|
||||
#include <freerdp/cache/glyph.h>
|
||||
|
||||
#include "glyph.h"
|
||||
|
||||
#define TAG FREERDP_TAG("cache.glyph")
|
||||
|
||||
static rdpGlyph* glyph_cache_get(rdpGlyphCache* glyph_cache, UINT32 id,
|
||||
|
@ -761,3 +763,120 @@ void glyph_cache_free(rdpGlyphCache* glyphCache)
|
|||
free(glyphCache);
|
||||
}
|
||||
}
|
||||
|
||||
CACHE_GLYPH_ORDER* copy_cache_glyph_order(rdpContext* context, const CACHE_GLYPH_ORDER* glyph)
|
||||
{
|
||||
size_t x;
|
||||
CACHE_GLYPH_ORDER* dst = calloc(1, sizeof(CACHE_GLYPH_ORDER));
|
||||
|
||||
if (!dst || !glyph)
|
||||
goto fail;
|
||||
|
||||
*dst = *glyph;
|
||||
|
||||
for (x = 0; x < glyph->cGlyphs; x++)
|
||||
{
|
||||
const GLYPH_DATA* src = &glyph->glyphData[x];
|
||||
GLYPH_DATA* data = &dst->glyphData[x];
|
||||
|
||||
if (src->aj)
|
||||
{
|
||||
const size_t size = src->cb;
|
||||
data->aj = malloc(size);
|
||||
|
||||
if (!data->aj)
|
||||
goto fail;
|
||||
|
||||
memcpy(data->aj, src->aj, size);
|
||||
}
|
||||
}
|
||||
|
||||
if (glyph->unicodeCharacters)
|
||||
{
|
||||
dst->unicodeCharacters = calloc(glyph->cGlyphs, sizeof(WCHAR));
|
||||
|
||||
if (!dst->unicodeCharacters)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->unicodeCharacters, glyph->unicodeCharacters, sizeof(WCHAR) * glyph->cGlyphs);
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_cache_glyph_order(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_cache_glyph_order(rdpContext* context, CACHE_GLYPH_ORDER* glyph)
|
||||
{
|
||||
if (glyph)
|
||||
{
|
||||
size_t x;
|
||||
|
||||
for (x = 0; x < ARRAYSIZE(glyph->glyphData); x++)
|
||||
free(glyph->glyphData[x].aj);
|
||||
|
||||
free(glyph->unicodeCharacters);
|
||||
}
|
||||
|
||||
free(glyph);
|
||||
}
|
||||
|
||||
CACHE_GLYPH_V2_ORDER* copy_cache_glyph_v2_order(rdpContext* context,
|
||||
const CACHE_GLYPH_V2_ORDER* glyph)
|
||||
{
|
||||
size_t x;
|
||||
CACHE_GLYPH_V2_ORDER* dst = calloc(1, sizeof(CACHE_GLYPH_V2_ORDER));
|
||||
|
||||
if (!dst || !glyph)
|
||||
goto fail;
|
||||
|
||||
*dst = *glyph;
|
||||
|
||||
for (x = 0; x < glyph->cGlyphs; x++)
|
||||
{
|
||||
const GLYPH_DATA_V2* src = &glyph->glyphData[x];
|
||||
GLYPH_DATA_V2* data = &dst->glyphData[x];
|
||||
|
||||
if (src->aj)
|
||||
{
|
||||
const size_t size = src->cb;
|
||||
data->aj = malloc(size);
|
||||
|
||||
if (!data->aj)
|
||||
goto fail;
|
||||
|
||||
memcpy(data->aj, src->aj, size);
|
||||
}
|
||||
}
|
||||
|
||||
if (glyph->unicodeCharacters)
|
||||
{
|
||||
dst->unicodeCharacters = calloc(glyph->cGlyphs, sizeof(WCHAR));
|
||||
|
||||
if (!dst->unicodeCharacters)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->unicodeCharacters, glyph->unicodeCharacters, sizeof(WCHAR) * glyph->cGlyphs);
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_cache_glyph_v2_order(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_cache_glyph_v2_order(rdpContext* context, CACHE_GLYPH_V2_ORDER* glyph)
|
||||
{
|
||||
if (glyph)
|
||||
{
|
||||
size_t x;
|
||||
|
||||
for (x = 0; x < ARRAYSIZE(glyph->glyphData); x++)
|
||||
free(glyph->glyphData[x].aj);
|
||||
|
||||
free(glyph->unicodeCharacters);
|
||||
}
|
||||
|
||||
free(glyph);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2018 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_CACHE_GLYPH_H
|
||||
#define FREERDP_LIB_CACHE_GLYPH_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/pointer.h>
|
||||
|
||||
FREERDP_LOCAL CACHE_GLYPH_ORDER* copy_cache_glyph_order(rdpContext* context,
|
||||
const CACHE_GLYPH_ORDER* glyph);
|
||||
FREERDP_LOCAL void free_cache_glyph_order(rdpContext* context, CACHE_GLYPH_ORDER* glyph);
|
||||
|
||||
FREERDP_LOCAL CACHE_GLYPH_V2_ORDER* copy_cache_glyph_v2_order(rdpContext* context,
|
||||
const CACHE_GLYPH_V2_ORDER* glyph);
|
||||
FREERDP_LOCAL void free_cache_glyph_v2_order(rdpContext* context, CACHE_GLYPH_V2_ORDER* glyph);
|
||||
|
||||
#endif /* FREERDP_LIB_CACHE_GLYPH_H */
|
|
@ -28,6 +28,8 @@
|
|||
#include <freerdp/log.h>
|
||||
#include <freerdp/cache/palette.h>
|
||||
|
||||
#include "palette.h"
|
||||
|
||||
#define TAG FREERDP_TAG("cache.palette")
|
||||
|
||||
static void* palette_cache_get(rdpPaletteCache* palette, UINT32 index);
|
||||
|
@ -35,16 +37,16 @@ static void* palette_cache_get(rdpPaletteCache* palette, UINT32 index);
|
|||
static void palette_cache_put(rdpPaletteCache* palette, UINT32 index, void* entry);
|
||||
|
||||
static BOOL update_gdi_cache_color_table(rdpContext* context,
|
||||
const CACHE_COLOR_TABLE_ORDER* cacheColorTable)
|
||||
const CACHE_COLOR_TABLE_ORDER* cacheColorTable)
|
||||
{
|
||||
UINT32* colorTable;
|
||||
rdpCache* cache = context->cache;
|
||||
|
||||
colorTable = (UINT32*) malloc(sizeof(UINT32) * 256);
|
||||
|
||||
if (!colorTable)
|
||||
return FALSE;
|
||||
CopyMemory(colorTable, cacheColorTable->colorTable, sizeof(UINT32) * 256);
|
||||
|
||||
CopyMemory(colorTable, cacheColorTable->colorTable, sizeof(UINT32) * 256);
|
||||
palette_cache_put(cache->palette, cacheColorTable->cacheIndex, (void*) colorTable);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -80,7 +82,6 @@ void palette_cache_put(rdpPaletteCache* paletteCache, UINT32 index, void* entry)
|
|||
}
|
||||
|
||||
free(paletteCache->entries[index].entry);
|
||||
|
||||
paletteCache->entries[index].entry = entry;
|
||||
}
|
||||
|
||||
|
@ -92,14 +93,14 @@ void palette_cache_register_callbacks(rdpUpdate* update)
|
|||
rdpPaletteCache* palette_cache_new(rdpSettings* settings)
|
||||
{
|
||||
rdpPaletteCache* paletteCache;
|
||||
|
||||
paletteCache = (rdpPaletteCache*) calloc(1, sizeof(rdpPaletteCache));
|
||||
|
||||
if (paletteCache)
|
||||
{
|
||||
paletteCache->settings = settings;
|
||||
paletteCache->maxEntries = 6;
|
||||
paletteCache->entries = (PALETTE_TABLE_ENTRY*) calloc(paletteCache->maxEntries, sizeof(PALETTE_TABLE_ENTRY));
|
||||
paletteCache->entries = (PALETTE_TABLE_ENTRY*) calloc(paletteCache->maxEntries,
|
||||
sizeof(PALETTE_TABLE_ENTRY));
|
||||
}
|
||||
|
||||
return paletteCache;
|
||||
|
@ -111,10 +112,29 @@ void palette_cache_free(rdpPaletteCache* paletteCache)
|
|||
{
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i< paletteCache->maxEntries; i++)
|
||||
for (i = 0; i < paletteCache->maxEntries; i++)
|
||||
free(paletteCache->entries[i].entry);
|
||||
|
||||
free(paletteCache->entries);
|
||||
free(paletteCache);
|
||||
}
|
||||
}
|
||||
|
||||
void free_palette_update(rdpContext* context, PALETTE_UPDATE* pointer)
|
||||
{
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
PALETTE_UPDATE* copy_palette_update(rdpContext* context, const PALETTE_UPDATE* pointer)
|
||||
{
|
||||
PALETTE_UPDATE* dst = calloc(1, sizeof(PALETTE_UPDATE));
|
||||
|
||||
if (!dst || !pointer)
|
||||
goto fail;
|
||||
|
||||
*dst = *pointer;
|
||||
return dst;
|
||||
fail:
|
||||
free_palette_update(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2018 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_CACHE_PALETTE_H
|
||||
#define FREERDP_LIB_CACHE_PALETTE_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/update.h>
|
||||
|
||||
FREERDP_LOCAL PALETTE_UPDATE* copy_palette_update(rdpContext* context,
|
||||
const PALETTE_UPDATE* pointer);
|
||||
FREERDP_LOCAL void free_palette_update(rdpContext* context, PALETTE_UPDATE* pointer);
|
||||
|
||||
#endif /* FREERDP_LIB_CACHE_PALETTE_H */
|
|
@ -30,6 +30,7 @@
|
|||
#include <freerdp/log.h>
|
||||
#include <freerdp/cache/pointer.h>
|
||||
|
||||
#include "pointer.h"
|
||||
|
||||
#define TAG FREERDP_TAG("cache.pointer")
|
||||
|
||||
|
@ -312,3 +313,156 @@ void pointer_cache_free(rdpPointerCache* pointer_cache)
|
|||
free(pointer_cache);
|
||||
}
|
||||
}
|
||||
|
||||
POINTER_COLOR_UPDATE* copy_pointer_color_update(rdpContext* context,
|
||||
const POINTER_COLOR_UPDATE* src)
|
||||
{
|
||||
POINTER_COLOR_UPDATE* dst = calloc(1, sizeof(POINTER_COLOR_UPDATE));
|
||||
|
||||
if (!dst || !src)
|
||||
goto fail;
|
||||
|
||||
*dst = *src;
|
||||
|
||||
if (src->lengthAndMask > 0)
|
||||
{
|
||||
dst->andMaskData = calloc(src->lengthAndMask, sizeof(BYTE));
|
||||
|
||||
if (!dst->andMaskData)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->andMaskData, src->andMaskData, src->lengthAndMask);
|
||||
}
|
||||
|
||||
if (src->lengthXorMask > 0)
|
||||
{
|
||||
dst->xorMaskData = calloc(src->lengthXorMask, sizeof(BYTE));
|
||||
|
||||
if (!dst->xorMaskData)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->xorMaskData, src->xorMaskData, src->lengthXorMask);
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_pointer_color_update(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_pointer_color_update(rdpContext* context, POINTER_COLOR_UPDATE* pointer)
|
||||
{
|
||||
if (!pointer)
|
||||
return;
|
||||
|
||||
free(pointer->xorMaskData);
|
||||
free(pointer->andMaskData);
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
POINTER_NEW_UPDATE* copy_pointer_new_update(rdpContext* context, const POINTER_NEW_UPDATE* src)
|
||||
{
|
||||
POINTER_NEW_UPDATE* dst = calloc(1, sizeof(POINTER_NEW_UPDATE));
|
||||
|
||||
if (!dst || !src)
|
||||
goto fail;
|
||||
|
||||
*dst = *src;
|
||||
|
||||
if (src->colorPtrAttr.lengthAndMask > 0)
|
||||
{
|
||||
dst->colorPtrAttr.andMaskData = calloc(src->colorPtrAttr.lengthAndMask, sizeof(BYTE));
|
||||
|
||||
if (!dst->colorPtrAttr.andMaskData)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->colorPtrAttr.andMaskData, src->colorPtrAttr.andMaskData,
|
||||
src->colorPtrAttr.lengthAndMask);
|
||||
}
|
||||
|
||||
if (src->colorPtrAttr.lengthXorMask > 0)
|
||||
{
|
||||
dst->colorPtrAttr.xorMaskData = calloc(src->colorPtrAttr.lengthXorMask, sizeof(BYTE));
|
||||
|
||||
if (!dst->colorPtrAttr.xorMaskData)
|
||||
goto fail;
|
||||
|
||||
memcpy(dst->colorPtrAttr.xorMaskData, src->colorPtrAttr.xorMaskData,
|
||||
src->colorPtrAttr.lengthXorMask);
|
||||
}
|
||||
|
||||
return dst;
|
||||
fail:
|
||||
free_pointer_new_update(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_pointer_new_update(rdpContext* context, POINTER_NEW_UPDATE* pointer)
|
||||
{
|
||||
if (!pointer)
|
||||
return;
|
||||
|
||||
free(pointer->colorPtrAttr.xorMaskData);
|
||||
free(pointer->colorPtrAttr.andMaskData);
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
POINTER_CACHED_UPDATE* copy_pointer_cached_update(rdpContext* context,
|
||||
const POINTER_CACHED_UPDATE* pointer)
|
||||
{
|
||||
POINTER_CACHED_UPDATE* dst = calloc(1, sizeof(POINTER_CACHED_UPDATE));
|
||||
|
||||
if (!dst)
|
||||
goto fail;
|
||||
|
||||
*dst = *pointer;
|
||||
return dst;
|
||||
fail:
|
||||
free_pointer_cached_update(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_pointer_cached_update(rdpContext* context, POINTER_CACHED_UPDATE* pointer)
|
||||
{
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
void free_pointer_position_update(rdpContext* context, POINTER_POSITION_UPDATE* pointer)
|
||||
{
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
POINTER_POSITION_UPDATE* copy_pointer_position_update(rdpContext* context,
|
||||
const POINTER_POSITION_UPDATE* pointer)
|
||||
{
|
||||
POINTER_POSITION_UPDATE* dst = calloc(1, sizeof(POINTER_POSITION_UPDATE));
|
||||
|
||||
if (!dst || !pointer)
|
||||
goto fail;
|
||||
|
||||
*dst = *pointer;
|
||||
return dst;
|
||||
fail:
|
||||
free_pointer_position_update(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free_pointer_system_update(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer)
|
||||
{
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
POINTER_SYSTEM_UPDATE* copy_pointer_system_update(rdpContext* context,
|
||||
const POINTER_SYSTEM_UPDATE* pointer)
|
||||
{
|
||||
POINTER_SYSTEM_UPDATE* dst = calloc(1, sizeof(POINTER_SYSTEM_UPDATE));
|
||||
|
||||
if (!dst || !pointer)
|
||||
goto fail;
|
||||
|
||||
*dst = *pointer;
|
||||
return dst;
|
||||
fail:
|
||||
free_pointer_system_update(context, dst);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
*
|
||||
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
|
||||
* Copyright 2018 Thincast Technologies GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LIB_CACHE_POINTER_H
|
||||
#define FREERDP_LIB_CACHE_POINTER_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/pointer.h>
|
||||
|
||||
FREERDP_LOCAL POINTER_COLOR_UPDATE* copy_pointer_color_update(rdpContext* context,
|
||||
const POINTER_COLOR_UPDATE* pointer);
|
||||
FREERDP_LOCAL void free_pointer_color_update(rdpContext* context, POINTER_COLOR_UPDATE* pointer);
|
||||
|
||||
FREERDP_LOCAL POINTER_NEW_UPDATE* copy_pointer_new_update(rdpContext* context,
|
||||
const POINTER_NEW_UPDATE* pointer);
|
||||
FREERDP_LOCAL void free_pointer_new_update(rdpContext* context, POINTER_NEW_UPDATE* pointer);
|
||||
|
||||
FREERDP_LOCAL POINTER_CACHED_UPDATE* copy_pointer_cached_update(rdpContext* context,
|
||||
const POINTER_CACHED_UPDATE* pointer);
|
||||
FREERDP_LOCAL void free_pointer_cached_update(rdpContext* context, POINTER_CACHED_UPDATE* pointer);
|
||||
|
||||
FREERDP_LOCAL POINTER_POSITION_UPDATE* copy_pointer_position_update(rdpContext* context,
|
||||
const POINTER_POSITION_UPDATE* pointer);
|
||||
FREERDP_LOCAL void free_pointer_position_update(rdpContext* context,
|
||||
POINTER_POSITION_UPDATE* pointer);
|
||||
|
||||
FREERDP_LOCAL POINTER_SYSTEM_UPDATE* copy_pointer_system_update(rdpContext* context,
|
||||
const POINTER_SYSTEM_UPDATE* pointer);
|
||||
FREERDP_LOCAL void free_pointer_system_update(rdpContext* context,
|
||||
POINTER_SYSTEM_UPDATE* pointer);
|
||||
|
||||
#endif /* FREERDP_LIB_CACHE_POINTER_H */
|
|
@ -41,6 +41,10 @@
|
|||
#include "fastpath.h"
|
||||
#include "rdp.h"
|
||||
|
||||
#include "../cache/pointer.h"
|
||||
#include "../cache/palette.h"
|
||||
#include "../cache/bitmap.h"
|
||||
|
||||
#define TAG FREERDP_TAG("core.fastpath")
|
||||
|
||||
/**
|
||||
|
@ -72,6 +76,14 @@ static const char* const FASTPATH_UPDATETYPE_STRINGS[] =
|
|||
};
|
||||
#endif
|
||||
|
||||
static const char* fastpath_update_to_string(UINT8 update)
|
||||
{
|
||||
if (update >= ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS))
|
||||
return "UNKNOWN";
|
||||
|
||||
return FASTPATH_UPDATETYPE_STRINGS[update];
|
||||
}
|
||||
|
||||
/*
|
||||
* The fastpath header may be two or three bytes long.
|
||||
* This function assumes that at least two bytes are available in the stream
|
||||
|
@ -281,6 +293,7 @@ static BOOL fastpath_recv_orders(rdpFastPath* fastpath, wStream* s)
|
|||
|
||||
static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
UINT16 updateType;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
|
@ -303,21 +316,34 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
|
|||
switch (updateType)
|
||||
{
|
||||
case UPDATE_TYPE_BITMAP:
|
||||
if (!update_read_bitmap_update(update, s, &update->bitmap_update))
|
||||
return FALSE;
|
||||
{
|
||||
BITMAP_UPDATE* bitmap_update = update_read_bitmap_update(update, s);
|
||||
|
||||
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
|
||||
if (!bitmap_update)
|
||||
return FALSE;
|
||||
|
||||
rc = IFCALLRESULT(FALSE, update->BitmapUpdate, context, &update->bitmap_update);
|
||||
free_bitmap_update(context, bitmap_update);
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATE_TYPE_PALETTE:
|
||||
if (!update_read_palette(update, s, &update->palette_update))
|
||||
return FALSE;
|
||||
{
|
||||
PALETTE_UPDATE* palette_update = update_read_palette(update, s);
|
||||
|
||||
IFCALL(update->Palette, context, &update->palette_update);
|
||||
if (!palette_update)
|
||||
return FALSE;
|
||||
|
||||
rc = IFCALLRESULT(FALSE, update->Palette, context, &update->palette_update);
|
||||
free_palette_update(context, palette_update);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s)
|
||||
|
@ -328,8 +354,9 @@ static BOOL fastpath_recv_update_synchronize(rdpFastPath* fastpath, wStream* s)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, wStream* s)
|
||||
static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, UINT32 size, wStream* s)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
int status = 0;
|
||||
rdpUpdate* update;
|
||||
rdpContext* context;
|
||||
|
@ -346,103 +373,109 @@ static int fastpath_recv_update(rdpFastPath* fastpath, BYTE updateCode, wStream*
|
|||
context = update->context;
|
||||
pointer = update->pointer;
|
||||
#ifdef WITH_DEBUG_RDP
|
||||
DEBUG_RDP("recv Fast-Path %s Update (0x%02"PRIX8"), length:%"PRIuz"",
|
||||
updateCode < ARRAYSIZE(FASTPATH_UPDATETYPE_STRINGS) ? FASTPATH_UPDATETYPE_STRINGS[updateCode] :
|
||||
"???", updateCode, Stream_Length(s));
|
||||
DEBUG_RDP("recv Fast-Path %s Update (0x%02"PRIX8"), length:%"PRIu32"",
|
||||
fastpath_update_to_string(updateCode), updateCode, size);
|
||||
#endif
|
||||
|
||||
switch (updateCode)
|
||||
{
|
||||
case FASTPATH_UPDATETYPE_ORDERS:
|
||||
if (!fastpath_recv_orders(fastpath, s))
|
||||
{
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_orders()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fastpath_recv_orders(fastpath, s);
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_BITMAP:
|
||||
case FASTPATH_UPDATETYPE_PALETTE:
|
||||
if (!fastpath_recv_update_common(fastpath, s))
|
||||
{
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_ORDERS - fastpath_recv_update_common()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fastpath_recv_update_common(fastpath, s);
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
|
||||
if (!fastpath_recv_update_synchronize(fastpath, s))
|
||||
WLog_ERR(TAG, "fastpath_recv_update_synchronize failure but we continue");
|
||||
else
|
||||
IFCALL(update->Synchronize, context);
|
||||
rc = IFCALLRESULT(TRUE, update->Synchronize, context);
|
||||
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_SURFCMDS:
|
||||
status = update_recv_surfcmds(update, s);
|
||||
|
||||
if (status < 0)
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_SURFCMDS - update_recv_surfcmds() - %i", status);
|
||||
|
||||
rc = (status < 0) ? FALSE : TRUE;
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_PTR_NULL:
|
||||
pointer->pointer_system.type = SYSPTR_NULL;
|
||||
IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
|
||||
{
|
||||
POINTER_SYSTEM_UPDATE pointer_system;
|
||||
pointer_system.type = SYSPTR_NULL;
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerSystem, context, &pointer_system);
|
||||
}
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
|
||||
update->pointer->pointer_system.type = SYSPTR_DEFAULT;
|
||||
IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
|
||||
{
|
||||
POINTER_SYSTEM_UPDATE pointer_system;
|
||||
pointer_system.type = SYSPTR_DEFAULT;
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerSystem, context, &pointer_system);
|
||||
}
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_PTR_POSITION:
|
||||
if (!update_read_pointer_position(s, &pointer->pointer_position))
|
||||
{
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_PTR_POSITION - update_read_pointer_position()");
|
||||
return -1;
|
||||
}
|
||||
POINTER_POSITION_UPDATE* pointer_position = update_read_pointer_position(update, s);
|
||||
|
||||
IFCALL(pointer->PointerPosition, context, &pointer->pointer_position);
|
||||
if (pointer_position)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerPosition, context, pointer_position);
|
||||
free_pointer_position_update(context, pointer_position);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_COLOR:
|
||||
if (!update_read_pointer_color(s, &pointer->pointer_color, 24))
|
||||
{
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_COLOR - update_read_pointer_color()");
|
||||
return -1;
|
||||
}
|
||||
POINTER_COLOR_UPDATE* pointer_color = update_read_pointer_color(update, s, 24);
|
||||
|
||||
IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
|
||||
if (pointer_color)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerColor, context, pointer_color);
|
||||
free_pointer_color_update(context, pointer_color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_CACHED:
|
||||
if (!update_read_pointer_cached(s, &pointer->pointer_cached))
|
||||
{
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_CACHED - update_read_pointer_cached()");
|
||||
return -1;
|
||||
}
|
||||
POINTER_CACHED_UPDATE* pointer_cached = update_read_pointer_cached(update, s);
|
||||
|
||||
IFCALL(pointer->PointerCached, context, &pointer->pointer_cached);
|
||||
if (pointer_cached)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerCached, context, pointer_cached);
|
||||
free_pointer_cached_update(context, pointer_cached);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_POINTER:
|
||||
if (!update_read_pointer_new(s, &pointer->pointer_new))
|
||||
{
|
||||
WLog_ERR(TAG, "FASTPATH_UPDATETYPE_POINTER - update_read_pointer_new()");
|
||||
return -1;
|
||||
}
|
||||
POINTER_NEW_UPDATE* pointer_new = update_read_pointer_new(update, s);
|
||||
|
||||
IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
|
||||
if (pointer_new)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerNew, context, pointer_new);
|
||||
free_pointer_new_update(context, pointer_new);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown updateCode 0x%02"PRIX8"", updateCode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
WLog_ERR(TAG, "Fastpath update %s [%"PRIx8"] failed, status %d",
|
||||
fastpath_update_to_string(updateCode), updateCode, status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -603,18 +636,22 @@ int fastpath_recv_updates(rdpFastPath* fastpath, wStream* s)
|
|||
return -1;
|
||||
|
||||
update = fastpath->rdp->update;
|
||||
IFCALL(update->BeginPaint, update->context);
|
||||
|
||||
if (!IFCALLRESULT(FALSE, update->BeginPaint, update->context))
|
||||
return -2;
|
||||
|
||||
while (Stream_GetRemainingLength(s) >= 3)
|
||||
{
|
||||
if (fastpath_recv_update_data(fastpath, s) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "fastpath_recv_update_data() fail");
|
||||
return -1;
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
IFCALL(update->EndPaint, update->context);
|
||||
if (!IFCALLRESULT(FALSE, update->EndPaint, update->context))
|
||||
return -4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -734,8 +771,8 @@ static BOOL fastpath_recv_input_event_unicode(rdpFastPath* fastpath, wStream* s,
|
|||
else
|
||||
flags |= KBD_FLAGS_DOWN;
|
||||
|
||||
IFCALL(fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, flags, unicodeCode);
|
||||
return TRUE;
|
||||
return IFCALLRESULT(FALSE, fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, flags,
|
||||
unicodeCode);
|
||||
}
|
||||
|
||||
static BOOL fastpath_recv_input_event(rdpFastPath* fastpath, wStream* s)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,6 +35,11 @@
|
|||
|
||||
#include "orders.h"
|
||||
|
||||
#include "../cache/glyph.h"
|
||||
#include "../cache/bitmap.h"
|
||||
#include "../cache/brush.h"
|
||||
#include "../cache/cache.h"
|
||||
|
||||
#define TAG FREERDP_TAG("core.orders")
|
||||
|
||||
static const char* const PRIMARY_DRAWING_ORDER_STRINGS[] =
|
||||
|
@ -174,6 +179,14 @@ static const BYTE BPP_BMF[] =
|
|||
6, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const char* update_secondary_order_to_string(BYTE order)
|
||||
{
|
||||
if (order >= ARRAYSIZE(SECONDARY_DRAWING_ORDER_STRINGS))
|
||||
return "UNKNOWN";
|
||||
|
||||
return SECONDARY_DRAWING_ORDER_STRINGS[order];
|
||||
}
|
||||
|
||||
static INLINE BOOL update_read_coord(wStream* s, INT32* coord, BOOL delta)
|
||||
{
|
||||
INT8 lsi8;
|
||||
|
@ -1672,12 +1685,16 @@ static BOOL update_read_ellipse_cb_order(wStream* s, ORDER_INFO* orderInfo,
|
|||
return update_read_brush(s, &ellipse_cb->brush, orderInfo->fieldFlags >> 8);
|
||||
}
|
||||
/* Secondary Drawing Orders */
|
||||
static BOOL update_read_cache_bitmap_order(wStream* s,
|
||||
CACHE_BITMAP_ORDER* cache_bitmap,
|
||||
static CACHE_BITMAP_ORDER* update_read_cache_bitmap_order(rdpUpdate* update, wStream* s,
|
||||
BOOL compressed, UINT16 flags)
|
||||
{
|
||||
CACHE_BITMAP_ORDER* cache_bitmap = calloc(1, sizeof(CACHE_BITMAP_ORDER));
|
||||
|
||||
if (!cache_bitmap || !update || !s)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 9)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT8(s, cache_bitmap->cacheId); /* cacheId (1 byte) */
|
||||
Stream_Seek_UINT8(s); /* pad1Octet (1 byte) */
|
||||
|
@ -1688,7 +1705,7 @@ static BOOL update_read_cache_bitmap_order(wStream* s,
|
|||
if ((cache_bitmap->bitmapBpp < 1) || (cache_bitmap->bitmapBpp > 32))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid bitmap bpp %"PRIu32"", cache_bitmap->bitmapBpp);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
Stream_Read_UINT16(s, cache_bitmap->bitmapLength); /* bitmapLength (2 bytes) */
|
||||
|
@ -1701,29 +1718,27 @@ static BOOL update_read_cache_bitmap_order(wStream* s,
|
|||
BYTE* bitmapComprHdr = (BYTE*) & (cache_bitmap->bitmapComprHdr);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */
|
||||
cache_bitmap->bitmapLength -= 8;
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength)
|
||||
return FALSE;
|
||||
|
||||
Stream_GetPointer(s, cache_bitmap->bitmapDataStream);
|
||||
Stream_Seek(s, cache_bitmap->bitmapLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength)
|
||||
return FALSE;
|
||||
|
||||
Stream_GetPointer(s, cache_bitmap->bitmapDataStream);
|
||||
Stream_Seek(s, cache_bitmap->bitmapLength); /* bitmapDataStream */
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < cache_bitmap->bitmapLength)
|
||||
goto fail;
|
||||
|
||||
cache_bitmap->bitmapDataStream = malloc(cache_bitmap->bitmapLength);
|
||||
|
||||
if (!cache_bitmap->bitmapDataStream)
|
||||
goto fail;
|
||||
|
||||
Stream_Read(s, cache_bitmap->bitmapDataStream, cache_bitmap->bitmapLength);
|
||||
cache_bitmap->compressed = compressed;
|
||||
return TRUE;
|
||||
return cache_bitmap;
|
||||
fail:
|
||||
free_cache_bitmap_order(update->context, cache_bitmap);
|
||||
return NULL;
|
||||
}
|
||||
int update_approximate_cache_bitmap_order(const CACHE_BITMAP_ORDER*
|
||||
cache_bitmap,
|
||||
|
@ -1773,11 +1788,15 @@ BOOL update_write_cache_bitmap_order(wStream* s,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_cache_bitmap_v2_order(wStream* s,
|
||||
CACHE_BITMAP_V2_ORDER* cache_bitmap_v2,
|
||||
static CACHE_BITMAP_V2_ORDER* update_read_cache_bitmap_v2_order(rdpUpdate* update, wStream* s,
|
||||
BOOL compressed, UINT16 flags)
|
||||
{
|
||||
BYTE bitsPerPixelId;
|
||||
CACHE_BITMAP_V2_ORDER* cache_bitmap_v2 = calloc(1, sizeof(CACHE_BITMAP_V2_ORDER));
|
||||
|
||||
if (!cache_bitmap_v2 || !update || !s)
|
||||
goto fail;
|
||||
|
||||
cache_bitmap_v2->cacheId = flags & 0x0003;
|
||||
cache_bitmap_v2->flags = (flags & 0xFF80) >> 7;
|
||||
bitsPerPixelId = (flags & 0x0078) >> 3;
|
||||
|
@ -1786,7 +1805,7 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s,
|
|||
if (cache_bitmap_v2->flags & CBR2_PERSISTENT_KEY_PRESENT)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT32(s, cache_bitmap_v2->key1); /* key1 (4 bytes) */
|
||||
Stream_Read_UINT32(s, cache_bitmap_v2->key2); /* key2 (4 bytes) */
|
||||
|
@ -1796,7 +1815,7 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s,
|
|||
{
|
||||
if (!update_read_2byte_unsigned(s,
|
||||
&cache_bitmap_v2->bitmapWidth)) /* bitmapWidth */
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
cache_bitmap_v2->bitmapHeight = cache_bitmap_v2->bitmapWidth;
|
||||
}
|
||||
|
@ -1806,13 +1825,13 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s,
|
|||
|| /* bitmapWidth */
|
||||
!update_read_2byte_unsigned(s,
|
||||
&cache_bitmap_v2->bitmapHeight)) /* bitmapHeight */
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!update_read_4byte_unsigned(s, &cache_bitmap_v2->bitmapLength)
|
||||
|| /* bitmapLength */
|
||||
!update_read_2byte_unsigned(s, &cache_bitmap_v2->cacheIndex)) /* cacheIndex */
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
if (cache_bitmap_v2->flags & CBR2_DO_NOT_CACHE)
|
||||
cache_bitmap_v2->cacheIndex = BITMAP_CACHE_WAITING_LIST_INDEX;
|
||||
|
@ -1822,7 +1841,7 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s,
|
|||
if (!(cache_bitmap_v2->flags & CBR2_NO_BITMAP_COMPRESSION_HDR))
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s,
|
||||
cache_bitmap_v2->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
|
||||
|
@ -1833,24 +1852,22 @@ static BOOL update_read_cache_bitmap_v2_order(wStream* s,
|
|||
cache_bitmap_v2->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
|
||||
cache_bitmap_v2->bitmapLength = cache_bitmap_v2->cbCompMainBodySize;
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength)
|
||||
return FALSE;
|
||||
|
||||
Stream_GetPointer(s, cache_bitmap_v2->bitmapDataStream);
|
||||
Stream_Seek(s, cache_bitmap_v2->bitmapLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength)
|
||||
return FALSE;
|
||||
|
||||
Stream_GetPointer(s, cache_bitmap_v2->bitmapDataStream);
|
||||
Stream_Seek(s, cache_bitmap_v2->bitmapLength);
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < cache_bitmap_v2->bitmapLength)
|
||||
goto fail;
|
||||
|
||||
cache_bitmap_v2->bitmapDataStream = malloc(cache_bitmap_v2->bitmapLength);
|
||||
|
||||
if (!cache_bitmap_v2->bitmapDataStream)
|
||||
goto fail;
|
||||
|
||||
Stream_Read(s, cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapLength);
|
||||
cache_bitmap_v2->compressed = compressed;
|
||||
return TRUE;
|
||||
return cache_bitmap_v2;
|
||||
fail:
|
||||
free_cache_bitmap_v2_order(update->context, cache_bitmap_v2);
|
||||
return NULL;
|
||||
}
|
||||
int update_approximate_cache_bitmap_v2_order(CACHE_BITMAP_V2_ORDER*
|
||||
cache_bitmap_v2, BOOL compressed, UINT16* flags)
|
||||
|
@ -1932,21 +1949,25 @@ BOOL update_write_cache_bitmap_v2_order(wStream* s,
|
|||
cache_bitmap_v2->compressed = compressed;
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_cache_bitmap_v3_order(wStream* s,
|
||||
CACHE_BITMAP_V3_ORDER* cache_bitmap_v3,
|
||||
static CACHE_BITMAP_V3_ORDER* update_read_cache_bitmap_v3_order(rdpUpdate* update, wStream* s,
|
||||
UINT16 flags)
|
||||
{
|
||||
BYTE bitsPerPixelId;
|
||||
BITMAP_DATA_EX* bitmapData;
|
||||
UINT32 new_len;
|
||||
BYTE* new_data;
|
||||
CACHE_BITMAP_V3_ORDER* cache_bitmap_v3 = calloc(1, sizeof(CACHE_BITMAP_V3_ORDER));
|
||||
|
||||
if (!cache_bitmap_v3 || !update || !s)
|
||||
goto fail;
|
||||
|
||||
cache_bitmap_v3->cacheId = flags & 0x00000003;
|
||||
cache_bitmap_v3->flags = (flags & 0x0000FF80) >> 7;
|
||||
bitsPerPixelId = (flags & 0x00000078) >> 3;
|
||||
cache_bitmap_v3->bpp = CBR23_BPP[bitsPerPixelId];
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 21)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s, cache_bitmap_v3->cacheIndex); /* cacheIndex (2 bytes) */
|
||||
Stream_Read_UINT32(s, cache_bitmap_v3->key1); /* key1 (4 bytes) */
|
||||
|
@ -1957,7 +1978,7 @@ static BOOL update_read_cache_bitmap_v3_order(wStream* s,
|
|||
if ((bitmapData->bpp < 1) || (bitmapData->bpp > 32))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid bpp value %"PRIu32"", bitmapData->bpp);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
Stream_Seek_UINT8(s); /* reserved1 (1 byte) */
|
||||
|
@ -1968,18 +1989,22 @@ static BOOL update_read_cache_bitmap_v3_order(wStream* s,
|
|||
Stream_Read_UINT32(s, new_len); /* length (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < new_len)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
new_data = (BYTE*) realloc(bitmapData->data, new_len);
|
||||
|
||||
if (!new_data)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
bitmapData->data = new_data;
|
||||
bitmapData->length = new_len;
|
||||
Stream_Read(s, bitmapData->data, bitmapData->length);
|
||||
return TRUE;
|
||||
return cache_bitmap_v3;
|
||||
fail:
|
||||
free_cache_bitmap_v3_order(update->context, cache_bitmap_v3);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int update_approximate_cache_bitmap_v3_order(CACHE_BITMAP_V3_ORDER*
|
||||
cache_bitmap_v3, UINT16* flags)
|
||||
{
|
||||
|
@ -2014,15 +2039,18 @@ BOOL update_write_cache_bitmap_v3_order(wStream* s,
|
|||
Stream_Write(s, bitmapData->data, bitmapData->length);
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_cache_color_table_order(wStream* s,
|
||||
CACHE_COLOR_TABLE_ORDER* cache_color_table,
|
||||
static CACHE_COLOR_TABLE_ORDER* update_read_cache_color_table_order(rdpUpdate* update, wStream* s,
|
||||
UINT16 flags)
|
||||
{
|
||||
int i;
|
||||
UINT32* colorTable;
|
||||
CACHE_COLOR_TABLE_ORDER* cache_color_table = calloc(1, sizeof(CACHE_COLOR_TABLE_ORDER));
|
||||
|
||||
if (!cache_color_table)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 3)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT8(s, cache_color_table->cacheIndex); /* cacheIndex (1 byte) */
|
||||
Stream_Read_UINT16(s,
|
||||
|
@ -2031,19 +2059,23 @@ static BOOL update_read_cache_color_table_order(wStream* s,
|
|||
if (cache_color_table->numberColors != 256)
|
||||
{
|
||||
/* This field MUST be set to 256 */
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < cache_color_table->numberColors * 4)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
colorTable = (UINT32*) &cache_color_table->colorTable;
|
||||
|
||||
for (i = 0; i < (int) cache_color_table->numberColors; i++)
|
||||
update_read_color_quad(s, &colorTable[i]);
|
||||
|
||||
return TRUE;
|
||||
return cache_color_table;
|
||||
fail:
|
||||
free_cache_color_table_order(update->context, cache_color_table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int update_approximate_cache_color_table_order(
|
||||
const CACHE_COLOR_TABLE_ORDER* cache_color_table, UINT16* flags)
|
||||
{
|
||||
|
@ -2076,14 +2108,16 @@ BOOL update_write_cache_color_table_order(wStream* s,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_cache_glyph_order(wStream* s,
|
||||
CACHE_GLYPH_ORDER* cache_glyph_order,
|
||||
UINT16 flags)
|
||||
static CACHE_GLYPH_ORDER* update_read_cache_glyph_order(rdpUpdate* update, wStream* s, UINT16 flags)
|
||||
{
|
||||
UINT32 i;
|
||||
CACHE_GLYPH_ORDER* cache_glyph_order = calloc(1, sizeof(CACHE_GLYPH_ORDER));
|
||||
|
||||
if (!cache_glyph_order || !update || !s)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT8(s, cache_glyph_order->cacheId); /* cacheId (1 byte) */
|
||||
Stream_Read_UINT8(s, cache_glyph_order->cGlyphs); /* cGlyphs (1 byte) */
|
||||
|
@ -2093,7 +2127,7 @@ static BOOL update_read_cache_glyph_order(wStream* s,
|
|||
GLYPH_DATA* glyph = &cache_glyph_order->glyphData[i];
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 10)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s, glyph->cacheIndex);
|
||||
Stream_Read_INT16(s, glyph->x);
|
||||
|
@ -2104,23 +2138,35 @@ static BOOL update_read_cache_glyph_order(wStream* s,
|
|||
glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < glyph->cb)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
glyph->aj = (BYTE*) malloc(glyph->cb);
|
||||
|
||||
if (!glyph->aj)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read(s, glyph->aj, glyph->cb);
|
||||
}
|
||||
|
||||
if (flags & CG_GLYPH_UNICODE_PRESENT)
|
||||
if ((flags & CG_GLYPH_UNICODE_PRESENT) && (cache_glyph_order->cGlyphs > 0))
|
||||
{
|
||||
return Stream_SafeSeek(s, cache_glyph_order->cGlyphs * 2);
|
||||
cache_glyph_order->unicodeCharacters = calloc(cache_glyph_order->cGlyphs, sizeof(WCHAR));
|
||||
|
||||
if (!cache_glyph_order->unicodeCharacters)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < sizeof(WCHAR) * cache_glyph_order->cGlyphs)
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UTF16_String(s, cache_glyph_order->unicodeCharacters, cache_glyph_order->cGlyphs);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return cache_glyph_order;
|
||||
fail:
|
||||
free_cache_glyph_order(update->context, cache_glyph_order);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int update_approximate_cache_glyph_order(
|
||||
const CACHE_GLYPH_ORDER* cache_glyph, UINT16* flags)
|
||||
{
|
||||
|
@ -2164,11 +2210,15 @@ BOOL update_write_cache_glyph_order(wStream* s,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
static BOOL update_read_cache_glyph_v2_order(wStream* s,
|
||||
CACHE_GLYPH_V2_ORDER* cache_glyph_v2,
|
||||
static CACHE_GLYPH_V2_ORDER* update_read_cache_glyph_v2_order(rdpUpdate* update, wStream* s,
|
||||
UINT16 flags)
|
||||
{
|
||||
UINT32 i;
|
||||
CACHE_GLYPH_V2_ORDER* cache_glyph_v2 = calloc(1, sizeof(CACHE_GLYPH_V2_ORDER));
|
||||
|
||||
if (!cache_glyph_v2)
|
||||
goto fail;
|
||||
|
||||
cache_glyph_v2->cacheId = (flags & 0x000F);
|
||||
cache_glyph_v2->flags = (flags & 0x00F0) >> 4;
|
||||
cache_glyph_v2->cGlyphs = (flags & 0xFF00) >> 8;
|
||||
|
@ -2178,7 +2228,7 @@ static BOOL update_read_cache_glyph_v2_order(wStream* s,
|
|||
GLYPH_DATA_V2* glyph = &cache_glyph_v2->glyphData[i];
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 1)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT8(s, glyph->cacheIndex);
|
||||
|
||||
|
@ -2187,33 +2237,48 @@ static BOOL update_read_cache_glyph_v2_order(wStream* s,
|
|||
!update_read_2byte_unsigned(s, &glyph->cx) ||
|
||||
!update_read_2byte_unsigned(s, &glyph->cy))
|
||||
{
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy;
|
||||
glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < glyph->cb)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
glyph->aj = (BYTE*) malloc(glyph->cb);
|
||||
|
||||
if (!glyph->aj)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read(s, glyph->aj, glyph->cb);
|
||||
}
|
||||
|
||||
if (flags & CG_GLYPH_UNICODE_PRESENT)
|
||||
return Stream_SafeSeek(s, cache_glyph_v2->cGlyphs * 2);
|
||||
if ((flags & CG_GLYPH_UNICODE_PRESENT) && (cache_glyph_v2->cGlyphs > 0))
|
||||
{
|
||||
cache_glyph_v2->unicodeCharacters = calloc(cache_glyph_v2->cGlyphs, sizeof(WCHAR));
|
||||
|
||||
return TRUE;
|
||||
if (!cache_glyph_v2->unicodeCharacters)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < sizeof(WCHAR) * cache_glyph_v2->cGlyphs)
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UTF16_String(s, cache_glyph_v2->unicodeCharacters, cache_glyph_v2->cGlyphs);
|
||||
}
|
||||
|
||||
return cache_glyph_v2;
|
||||
fail:
|
||||
free_cache_glyph_v2_order(update->context, cache_glyph_v2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int update_approximate_cache_glyph_v2_order(
|
||||
const CACHE_GLYPH_V2_ORDER* cache_glyph_v2, UINT16* flags)
|
||||
{
|
||||
return 8 + cache_glyph_v2->cGlyphs * 32;
|
||||
}
|
||||
|
||||
BOOL update_write_cache_glyph_v2_order(wStream* s,
|
||||
const CACHE_GLYPH_V2_ORDER* cache_glyph_v2,
|
||||
UINT16* flags)
|
||||
|
@ -2290,16 +2355,18 @@ static BOOL update_compress_brush(wStream* s, const BYTE* input, BYTE bpp)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
static BOOL update_read_cache_brush_order(wStream* s,
|
||||
CACHE_BRUSH_ORDER* cache_brush,
|
||||
UINT16 flags)
|
||||
static CACHE_BRUSH_ORDER* update_read_cache_brush_order(rdpUpdate* update, wStream* s, UINT16 flags)
|
||||
{
|
||||
int i;
|
||||
BYTE iBitmapFormat;
|
||||
BOOL compressed = FALSE;
|
||||
CACHE_BRUSH_ORDER* cache_brush = calloc(1, sizeof(CACHE_BRUSH_ORDER));
|
||||
|
||||
if (!cache_brush)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 6)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT8(s, cache_brush->index); /* cacheEntry (1 byte) */
|
||||
Stream_Read_UINT8(s, iBitmapFormat); /* iBitmapFormat (1 byte) */
|
||||
|
@ -2316,12 +2383,12 @@ static BOOL update_read_cache_brush_order(wStream* s,
|
|||
if (cache_brush->length != 8)
|
||||
{
|
||||
WLog_ERR(TAG, "incompatible 1bpp brush of length:%"PRIu32"", cache_brush->length);
|
||||
return TRUE; // should be FALSE ?
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* rows are encoded in reverse order */
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
for (i = 7; i >= 0; i--)
|
||||
{
|
||||
|
@ -2341,7 +2408,7 @@ static BOOL update_read_cache_brush_order(wStream* s,
|
|||
{
|
||||
/* compressed brush */
|
||||
if (!update_decompress_brush(s, cache_brush->data, cache_brush->bpp))
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2349,7 +2416,7 @@ static BOOL update_read_cache_brush_order(wStream* s,
|
|||
UINT32 scanline = (cache_brush->bpp / 8) * 8;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < scanline * 8)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
for (i = 7; i >= 0; i--)
|
||||
{
|
||||
|
@ -2359,7 +2426,10 @@ static BOOL update_read_cache_brush_order(wStream* s,
|
|||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return cache_brush;
|
||||
fail:
|
||||
free_cache_brush_order(update->context, cache_brush);
|
||||
return NULL;
|
||||
}
|
||||
int update_approximate_cache_brush_order(
|
||||
const CACHE_BRUSH_ORDER* cache_brush, UINT16* flags)
|
||||
|
@ -3252,6 +3322,7 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags)
|
|||
static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s,
|
||||
BYTE flags)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
BYTE* next;
|
||||
BYTE orderType;
|
||||
UINT16 extraFlags;
|
||||
|
@ -3269,135 +3340,111 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s,
|
|||
Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */
|
||||
Stream_Read_UINT8(s, orderType); /* orderType (1 byte) */
|
||||
next = Stream_Pointer(s) + ((INT16) orderLength) + 7;
|
||||
|
||||
if (orderType < SECONDARY_DRAWING_ORDER_COUNT)
|
||||
WLog_Print(update->log, WLOG_DEBUG, "%s Secondary Drawing Order (0x%02"PRIX8")",
|
||||
SECONDARY_DRAWING_ORDER_STRINGS[orderType], orderType);
|
||||
else
|
||||
WLog_Print(update->log, WLOG_DEBUG, "Unknown Secondary Drawing Order (0x%02"PRIX8")",
|
||||
orderType);
|
||||
WLog_Print(update->log, WLOG_DEBUG, "%s Secondary Drawing Order (0x%02"PRIX8")",
|
||||
update_secondary_order_to_string(orderType), orderType);
|
||||
|
||||
switch (orderType)
|
||||
{
|
||||
case ORDER_TYPE_BITMAP_UNCOMPRESSED:
|
||||
if (!update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), FALSE,
|
||||
extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_BITMAP_UNCOMPRESSED - update_read_cache_bitmap_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order));
|
||||
break;
|
||||
|
||||
case ORDER_TYPE_CACHE_BITMAP_COMPRESSED:
|
||||
if (!update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), TRUE,
|
||||
extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_CACHE_BITMAP_COMPRESSED - update_read_cache_bitmap_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
const BOOL compressed = (orderType == ORDER_TYPE_CACHE_BITMAP_COMPRESSED);
|
||||
CACHE_BITMAP_ORDER* order = update_read_cache_bitmap_order(update, s, compressed, extraFlags);
|
||||
|
||||
IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order));
|
||||
if (order)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, secondary->CacheBitmap, context, order);
|
||||
free_cache_bitmap_order(context, order);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2:
|
||||
if (!update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order),
|
||||
FALSE, extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_BITMAP_UNCOMPRESSED_V2 - update_read_cache_bitmap_v2_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order));
|
||||
break;
|
||||
|
||||
case ORDER_TYPE_BITMAP_COMPRESSED_V2:
|
||||
if (!update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order),
|
||||
TRUE, extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_BITMAP_COMPRESSED_V2 - update_read_cache_bitmap_v2_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
const BOOL compressed = (orderType == ORDER_TYPE_BITMAP_COMPRESSED_V2);
|
||||
CACHE_BITMAP_V2_ORDER* order = update_read_cache_bitmap_v2_order(update, s, compressed, extraFlags);
|
||||
|
||||
IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order));
|
||||
if (order)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, secondary->CacheBitmapV2, context, order);
|
||||
free_cache_bitmap_v2_order(context, order);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ORDER_TYPE_BITMAP_COMPRESSED_V3:
|
||||
if (!update_read_cache_bitmap_v3_order(s, &(secondary->cache_bitmap_v3_order),
|
||||
extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_BITMAP_COMPRESSED_V3 - update_read_cache_bitmap_v3_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
CACHE_BITMAP_V3_ORDER* order = update_read_cache_bitmap_v3_order(update, s, extraFlags);
|
||||
|
||||
IFCALL(secondary->CacheBitmapV3, context, &(secondary->cache_bitmap_v3_order));
|
||||
if (order)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, secondary->CacheBitmapV3, context, order);
|
||||
free_cache_bitmap_v3_order(context, order);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ORDER_TYPE_CACHE_COLOR_TABLE:
|
||||
if (!update_read_cache_color_table_order(s,
|
||||
&(secondary->cache_color_table_order), extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_CACHE_COLOR_TABLE - update_read_cache_color_table_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
CACHE_COLOR_TABLE_ORDER* order = update_read_cache_color_table_order(update, s, extraFlags);
|
||||
|
||||
IFCALL(secondary->CacheColorTable, context,
|
||||
&(secondary->cache_color_table_order));
|
||||
if (order)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, secondary->CacheColorTable, context, order);
|
||||
free_cache_color_table_order(context, order);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ORDER_TYPE_CACHE_GLYPH:
|
||||
if (secondary->glyph_v2)
|
||||
{
|
||||
if (!update_read_cache_glyph_v2_order(s, &(secondary->cache_glyph_v2_order),
|
||||
extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_CACHE_GLYPH - update_read_cache_glyph_v2_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
CACHE_GLYPH_V2_ORDER* order = update_read_cache_glyph_v2_order(update, s, extraFlags);
|
||||
|
||||
IFCALL(secondary->CacheGlyphV2, context, &(secondary->cache_glyph_v2_order));
|
||||
if (order)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, secondary->CacheGlyphV2, context, order);
|
||||
free_cache_glyph_v2_order(context, order);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!update_read_cache_glyph_order(s, &(secondary->cache_glyph_order),
|
||||
extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_CACHE_GLYPH - update_read_cache_glyph_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
CACHE_GLYPH_ORDER* order = update_read_cache_glyph_order(update, s, extraFlags);
|
||||
|
||||
IFCALL(secondary->CacheGlyph, context, &(secondary->cache_glyph_order));
|
||||
if (order)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, secondary->CacheGlyph, context, order);
|
||||
free_cache_glyph_order(context, order);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ORDER_TYPE_CACHE_BRUSH:
|
||||
if (!update_read_cache_brush_order(s, &(secondary->cache_brush_order),
|
||||
extraFlags))
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"ORDER_TYPE_CACHE_BRUSH - update_read_cache_brush_order() failed");
|
||||
return FALSE;
|
||||
}
|
||||
CACHE_BRUSH_ORDER* order = update_read_cache_brush_order(update, s, extraFlags);
|
||||
|
||||
IFCALL(secondary->CacheBrush, context, &(secondary->cache_brush_order));
|
||||
if (order)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, secondary->CacheBrush, context, order);
|
||||
free_cache_brush_order(context, order);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
WLog_ERR(TAG, "SECONDARY ORDER %s [%"PRIx16"] failed", update_secondary_order_to_string(orderType),
|
||||
orderType);
|
||||
}
|
||||
|
||||
Stream_SetPointer(s, next);
|
||||
return TRUE;
|
||||
return rc;
|
||||
}
|
||||
static BOOL update_recv_altsec_order(rdpUpdate* update, wStream* s,
|
||||
BYTE flags)
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include <freerdp/peer.h>
|
||||
#include <freerdp/codec/bitmap.h>
|
||||
|
||||
#include "../cache/pointer.h"
|
||||
#include "../cache/palette.h"
|
||||
#include "../cache/bitmap.h"
|
||||
|
||||
#define TAG FREERDP_TAG("core.update")
|
||||
|
||||
|
@ -50,6 +53,14 @@ static const char* const UPDATE_TYPE_STRINGS[] =
|
|||
"Synchronize"
|
||||
};
|
||||
|
||||
static const char* update_type_to_string(UINT16 updateType)
|
||||
{
|
||||
if (updateType >= ARRAYSIZE(UPDATE_TYPE_STRINGS))
|
||||
return "UNKNOWN";
|
||||
|
||||
return UPDATE_TYPE_STRINGS[updateType];
|
||||
}
|
||||
|
||||
static BOOL update_recv_orders(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
UINT16 numberOrders;
|
||||
|
@ -172,13 +183,16 @@ static BOOL update_write_bitmap_data(rdpUpdate* update, wStream* s,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s,
|
||||
BITMAP_UPDATE* bitmapUpdate)
|
||||
BITMAP_UPDATE* update_read_bitmap_update(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
UINT32 i;
|
||||
BITMAP_UPDATE* bitmapUpdate = calloc(1, sizeof(BITMAP_UPDATE));
|
||||
|
||||
if (!bitmapUpdate)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */
|
||||
WLog_Print(update->log, WLOG_TRACE, "BitmapUpdate: %"PRIu32"", bitmapUpdate->number);
|
||||
|
@ -192,7 +206,7 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s,
|
|||
sizeof(BITMAP_DATA) * count);
|
||||
|
||||
if (!newdata)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
bitmapUpdate->rectangles = newdata;
|
||||
ZeroMemory(&bitmapUpdate->rectangles[bitmapUpdate->count],
|
||||
|
@ -204,10 +218,13 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s,
|
|||
for (i = 0; i < bitmapUpdate->number; i++)
|
||||
{
|
||||
if (!update_read_bitmap_data(update, s, &bitmapUpdate->rectangles[i]))
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return bitmapUpdate;
|
||||
fail:
|
||||
free_bitmap_update(update->context, bitmapUpdate);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL update_write_bitmap_update(rdpUpdate* update, wStream* s,
|
||||
|
@ -231,14 +248,17 @@ static BOOL update_write_bitmap_update(rdpUpdate* update, wStream* s,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL update_read_palette(rdpUpdate* update, wStream* s,
|
||||
PALETTE_UPDATE* palette_update)
|
||||
PALETTE_UPDATE* update_read_palette(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
int i;
|
||||
PALETTE_ENTRY* entry;
|
||||
PALETTE_UPDATE* palette_update = calloc(1, sizeof(PALETTE_UPDATE));
|
||||
|
||||
if (!palette_update)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 6)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Seek_UINT16(s); /* pad2Octets (2 bytes) */
|
||||
Stream_Read_UINT32(s,
|
||||
|
@ -248,7 +268,7 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s,
|
|||
palette_update->number = 256;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < palette_update->number * 3)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
/* paletteEntries */
|
||||
for (i = 0; i < (int) palette_update->number; i++)
|
||||
|
@ -259,7 +279,10 @@ BOOL update_read_palette(rdpUpdate* update, wStream* s,
|
|||
Stream_Read_UINT8(s, entry->blue);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return palette_update;
|
||||
fail:
|
||||
free_palette_update(update->context, palette_update);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void update_read_synchronize(rdpUpdate* update, wStream* s)
|
||||
|
@ -290,35 +313,51 @@ BOOL update_recv_play_sound(rdpUpdate* update, wStream* s)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL update_read_pointer_position(wStream* s,
|
||||
POINTER_POSITION_UPDATE* pointer_position)
|
||||
POINTER_POSITION_UPDATE* update_read_pointer_position(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
POINTER_POSITION_UPDATE* pointer_position = calloc(1, sizeof(POINTER_POSITION_UPDATE));
|
||||
|
||||
if (!pointer_position)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s, pointer_position->xPos); /* xPos (2 bytes) */
|
||||
Stream_Read_UINT16(s, pointer_position->yPos); /* yPos (2 bytes) */
|
||||
return TRUE;
|
||||
return pointer_position;
|
||||
fail:
|
||||
free_pointer_position_update(update->context, pointer_position);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL update_read_pointer_system(wStream* s,
|
||||
POINTER_SYSTEM_UPDATE* pointer_system)
|
||||
POINTER_SYSTEM_UPDATE* update_read_pointer_system(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
POINTER_SYSTEM_UPDATE* pointer_system = calloc(1, sizeof(POINTER_SYSTEM_UPDATE));
|
||||
|
||||
if (!pointer_system)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT32(s, pointer_system->type); /* systemPointerType (4 bytes) */
|
||||
return TRUE;
|
||||
return pointer_system;
|
||||
fail:
|
||||
free_pointer_system_update(update->context, pointer_system);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color,
|
||||
int xorBpp)
|
||||
static BOOL _update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color, BYTE xorBpp)
|
||||
{
|
||||
BYTE* newMask;
|
||||
UINT32 scanlineSize;
|
||||
|
||||
if (!pointer_color)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 14)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */
|
||||
Stream_Read_UINT16(s, pointer_color->xPos); /* xPos (2 bytes) */
|
||||
|
@ -336,7 +375,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color,
|
|||
Stream_Read_UINT16(s, pointer_color->height); /* height (2 bytes) */
|
||||
|
||||
if ((pointer_color->width > 96) || (pointer_color->height > 96))
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s,
|
||||
pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */
|
||||
|
@ -369,7 +408,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color,
|
|||
* In fact instead of 24-bpp, the bpp parameter is given by the containing packet.
|
||||
*/
|
||||
if (Stream_GetRemainingLength(s) < pointer_color->lengthXorMask)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
scanlineSize = (7 + xorBpp * pointer_color->width) / 8;
|
||||
scanlineSize = ((scanlineSize + 1) / 2) * 2;
|
||||
|
@ -380,13 +419,13 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color,
|
|||
"invalid lengthXorMask: width=%"PRIu32" height=%"PRIu32", %"PRIu32" instead of %"PRIu32"",
|
||||
pointer_color->width, pointer_color->height,
|
||||
pointer_color->lengthXorMask, scanlineSize * pointer_color->height);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newMask = realloc(pointer_color->xorMaskData, pointer_color->lengthXorMask);
|
||||
|
||||
if (!newMask)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
pointer_color->xorMaskData = newMask;
|
||||
Stream_Read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask);
|
||||
|
@ -402,7 +441,7 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color,
|
|||
* bytes).
|
||||
*/
|
||||
if (Stream_GetRemainingLength(s) < pointer_color->lengthAndMask)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
scanlineSize = ((7 + pointer_color->width) / 8);
|
||||
scanlineSize = ((1 + scanlineSize) / 2) * 2;
|
||||
|
@ -411,13 +450,13 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color,
|
|||
{
|
||||
WLog_ERR(TAG, "invalid lengthAndMask: %"PRIu32" instead of %"PRIu32"",
|
||||
pointer_color->lengthAndMask, scanlineSize * pointer_color->height);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newMask = realloc(pointer_color->andMaskData, pointer_color->lengthAndMask);
|
||||
|
||||
if (!newMask)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
pointer_color->andMaskData = newMask;
|
||||
Stream_Read(s, pointer_color->andMaskData, pointer_color->lengthAndMask);
|
||||
|
@ -427,37 +466,74 @@ BOOL update_read_pointer_color(wStream* s, POINTER_COLOR_UPDATE* pointer_color,
|
|||
Stream_Seek_UINT8(s); /* pad (1 byte) */
|
||||
|
||||
return TRUE;
|
||||
fail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL update_read_pointer_new(wStream* s, POINTER_NEW_UPDATE* pointer_new)
|
||||
POINTER_COLOR_UPDATE* update_read_pointer_color(rdpUpdate* update, wStream* s, BYTE xorBpp)
|
||||
{
|
||||
POINTER_COLOR_UPDATE* pointer_color = calloc(1, sizeof(POINTER_COLOR_UPDATE));
|
||||
|
||||
if (!pointer_color)
|
||||
goto fail;
|
||||
|
||||
if (!_update_read_pointer_color(s, pointer_color, xorBpp))
|
||||
goto fail;
|
||||
|
||||
return pointer_color;
|
||||
fail:
|
||||
free_pointer_color_update(update->context, pointer_color);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
POINTER_NEW_UPDATE* update_read_pointer_new(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
POINTER_NEW_UPDATE* pointer_new = calloc(1, sizeof(POINTER_NEW_UPDATE));
|
||||
|
||||
if (!pointer_new)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
|
||||
|
||||
if ((pointer_new->xorBpp < 1) || (pointer_new->xorBpp > 32))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid xorBpp %"PRIu32"", pointer_new->xorBpp);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return update_read_pointer_color(s, &pointer_new->colorPtrAttr,
|
||||
pointer_new->xorBpp); /* colorPtrAttr */
|
||||
if (!_update_read_pointer_color(s, &pointer_new->colorPtrAttr,
|
||||
pointer_new->xorBpp)) /* colorPtrAttr */
|
||||
goto fail;
|
||||
|
||||
return pointer_new;
|
||||
fail:
|
||||
free_pointer_new_update(update->context, pointer_new);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL update_read_pointer_cached(wStream* s,
|
||||
POINTER_CACHED_UPDATE* pointer_cached)
|
||||
POINTER_CACHED_UPDATE* update_read_pointer_cached(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
POINTER_CACHED_UPDATE* pointer = calloc(1, sizeof(POINTER_CACHED_UPDATE));
|
||||
|
||||
if (!pointer)
|
||||
goto fail;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
|
||||
return TRUE;
|
||||
Stream_Read_UINT16(s, pointer->cacheIndex); /* cacheIndex (2 bytes) */
|
||||
return pointer;
|
||||
fail:
|
||||
free_pointer_cached_update(update->context, pointer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL update_recv_pointer(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
UINT16 messageType;
|
||||
rdpContext* context = update->context;
|
||||
rdpPointerUpdate* pointer = update->pointer;
|
||||
|
@ -471,49 +547,75 @@ BOOL update_recv_pointer(rdpUpdate* update, wStream* s)
|
|||
switch (messageType)
|
||||
{
|
||||
case PTR_MSG_TYPE_POSITION:
|
||||
if (!update_read_pointer_position(s, &pointer->pointer_position))
|
||||
return FALSE;
|
||||
{
|
||||
POINTER_POSITION_UPDATE* pointer_position = update_read_pointer_position(update, s);
|
||||
|
||||
IFCALL(pointer->PointerPosition, context, &pointer->pointer_position);
|
||||
if (pointer_position)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerPosition, context, pointer_position);
|
||||
free_pointer_position_update(context, pointer_position);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PTR_MSG_TYPE_SYSTEM:
|
||||
if (!update_read_pointer_system(s, &pointer->pointer_system))
|
||||
return FALSE;
|
||||
{
|
||||
POINTER_SYSTEM_UPDATE* pointer_system = update_read_pointer_system(update, s);
|
||||
|
||||
IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
|
||||
if (pointer_system)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerSystem, context, pointer_system);
|
||||
free_pointer_system_update(context, pointer_system);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PTR_MSG_TYPE_COLOR:
|
||||
if (!update_read_pointer_color(s, &pointer->pointer_color, 24))
|
||||
return FALSE;
|
||||
{
|
||||
POINTER_COLOR_UPDATE* pointer_color = update_read_pointer_color(update, s, 24);
|
||||
|
||||
IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
|
||||
if (pointer_color)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerColor, context, pointer_color);
|
||||
free_pointer_color_update(context, pointer_color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PTR_MSG_TYPE_POINTER:
|
||||
if (!update_read_pointer_new(s, &pointer->pointer_new))
|
||||
return FALSE;
|
||||
{
|
||||
POINTER_NEW_UPDATE* pointer_new = update_read_pointer_new(update, s);
|
||||
|
||||
IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
|
||||
if (pointer_new)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerNew, context, pointer_new);
|
||||
free_pointer_new_update(context, pointer_new);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PTR_MSG_TYPE_CACHED:
|
||||
if (!update_read_pointer_cached(s, &pointer->pointer_cached))
|
||||
return FALSE;
|
||||
{
|
||||
POINTER_CACHED_UPDATE* pointer_cached = update_read_pointer_cached(update, s);
|
||||
|
||||
IFCALL(pointer->PointerCached, context, &pointer->pointer_cached);
|
||||
if (pointer_cached)
|
||||
{
|
||||
rc = IFCALLRESULT(FALSE, pointer->PointerCached, context, pointer_cached);
|
||||
free_pointer_cached_update(context, pointer_cached);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL update_recv(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
UINT16 updateType;
|
||||
rdpContext* context = update->context;
|
||||
|
||||
|
@ -524,52 +626,65 @@ BOOL update_recv(rdpUpdate* update, wStream* s)
|
|||
}
|
||||
|
||||
Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */
|
||||
|
||||
//WLog_DBG(TAG, "%s Update Data PDU", UPDATE_TYPE_STRINGS[updateType]);
|
||||
IFCALL(update->BeginPaint, context);
|
||||
if (!IFCALLRESULT(FALSE, update->BeginPaint, context))
|
||||
return FALSE;
|
||||
|
||||
switch (updateType)
|
||||
{
|
||||
case UPDATE_TYPE_ORDERS:
|
||||
if (!update_recv_orders(update, s))
|
||||
{
|
||||
/* XXX: Do we have to call EndPaint? */
|
||||
WLog_ERR(TAG, "UPDATE_TYPE_ORDERS - update_recv_orders() failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = update_recv_orders(update, s);
|
||||
break;
|
||||
|
||||
case UPDATE_TYPE_BITMAP:
|
||||
if (!update_read_bitmap_update(update, s, &update->bitmap_update))
|
||||
{
|
||||
WLog_ERR(TAG, "UPDATE_TYPE_BITMAP - update_read_bitmap_update() failed");
|
||||
return FALSE;
|
||||
}
|
||||
BITMAP_UPDATE* bitmap_update = update_read_bitmap_update(update, s);
|
||||
|
||||
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
|
||||
if (!bitmap_update)
|
||||
{
|
||||
WLog_ERR(TAG, "UPDATE_TYPE_BITMAP - update_read_bitmap_update() failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = IFCALLRESULT(FALSE, update->BitmapUpdate, context, &update->bitmap_update);
|
||||
free_bitmap_update(update->context, bitmap_update);
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATE_TYPE_PALETTE:
|
||||
if (!update_read_palette(update, s, &update->palette_update))
|
||||
{
|
||||
WLog_ERR(TAG, "UPDATE_TYPE_PALETTE - update_read_palette() failed");
|
||||
return FALSE;
|
||||
}
|
||||
PALETTE_UPDATE* palette_update = update_read_palette(update, s);
|
||||
|
||||
IFCALL(update->Palette, context, &update->palette_update);
|
||||
if (!palette_update)
|
||||
{
|
||||
WLog_ERR(TAG, "UPDATE_TYPE_PALETTE - update_read_palette() failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rc = IFCALLRESULT(FALSE, update->Palette, context, palette_update);
|
||||
free_palette_update(context, palette_update);
|
||||
}
|
||||
break;
|
||||
|
||||
case UPDATE_TYPE_SYNCHRONIZE:
|
||||
update_read_synchronize(update, s);
|
||||
IFCALL(update->Synchronize, context);
|
||||
rc = IFCALLRESULT(TRUE, update->Synchronize, context);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown update type %"PRIu16"", updateType);
|
||||
break;
|
||||
}
|
||||
|
||||
IFCALL(update->EndPaint, context);
|
||||
if (!rc)
|
||||
{
|
||||
WLog_ERR(TAG, "UPDATE_TYPE %s [%"PRIu16"] failed", update_type_to_string(updateType), updateType);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!IFCALLRESULT(FALSE, update->EndPaint, context))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2133,10 +2248,6 @@ void update_free(rdpUpdate* update)
|
|||
deleteList = &(update->altsec->create_offscreen_bitmap.deleteList);
|
||||
free(deleteList->indices);
|
||||
free(update->bitmap_update.rectangles);
|
||||
free(update->pointer->pointer_color.andMaskData);
|
||||
free(update->pointer->pointer_color.xorMaskData);
|
||||
free(update->pointer->pointer_new.colorPtrAttr.andMaskData);
|
||||
free(update->pointer->pointer_new.colorPtrAttr.xorMaskData);
|
||||
free(update->pointer);
|
||||
free(update->primary->polyline.points);
|
||||
free(update->primary->polygon_sc.points);
|
||||
|
|
|
@ -43,21 +43,21 @@ FREERDP_LOCAL void update_free(rdpUpdate* update);
|
|||
FREERDP_LOCAL void update_reset_state(rdpUpdate* update);
|
||||
FREERDP_LOCAL BOOL update_post_connect(rdpUpdate* update);
|
||||
FREERDP_LOCAL void update_post_disconnect(rdpUpdate* update);
|
||||
FREERDP_LOCAL BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s,
|
||||
BITMAP_UPDATE* bitmapUpdate);
|
||||
FREERDP_LOCAL BOOL update_read_palette(rdpUpdate* update, wStream* s,
|
||||
PALETTE_UPDATE* palette_update);
|
||||
|
||||
FREERDP_LOCAL BOOL update_recv_play_sound(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL BOOL update_recv_pointer(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL BOOL update_recv(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL BOOL update_read_pointer_position(wStream* s,
|
||||
POINTER_POSITION_UPDATE* pointer_position);
|
||||
FREERDP_LOCAL BOOL update_read_pointer_color(wStream* s,
|
||||
POINTER_COLOR_UPDATE* pointer_color, int xorBpp);
|
||||
FREERDP_LOCAL BOOL update_read_pointer_new(wStream* s,
|
||||
POINTER_NEW_UPDATE* pointer_new);
|
||||
FREERDP_LOCAL BOOL update_read_pointer_cached(wStream* s,
|
||||
POINTER_CACHED_UPDATE* pointer_cached);
|
||||
|
||||
FREERDP_LOCAL BITMAP_UPDATE* update_read_bitmap_update(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL PALETTE_UPDATE* update_read_palette(rdpUpdate* update, wStream* s);
|
||||
|
||||
FREERDP_LOCAL POINTER_SYSTEM_UPDATE* update_read_pointer_system(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL POINTER_POSITION_UPDATE* update_read_pointer_position(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL POINTER_COLOR_UPDATE* update_read_pointer_color(rdpUpdate* update, wStream* s,
|
||||
BYTE xorBpp);
|
||||
FREERDP_LOCAL POINTER_NEW_UPDATE* update_read_pointer_new(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL POINTER_CACHED_UPDATE* update_read_pointer_cached(rdpUpdate* update, wStream* s);
|
||||
|
||||
FREERDP_LOCAL BOOL update_read_refresh_rect(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL BOOL update_read_suppress_output(rdpUpdate* update, wStream* s);
|
||||
FREERDP_LOCAL void update_register_server_callbacks(rdpUpdate* update);
|
||||
|
|
Loading…
Reference in New Issue