libfreerdp-cache: refactoring of bitmap and offscreen bitmap cache, fix major memory leaks

This commit is contained in:
Marc-André Moreau 2011-10-13 15:51:07 -04:00
parent 2121a4a5cc
commit 8999bd8599
14 changed files with 517 additions and 282 deletions

View File

@ -163,7 +163,7 @@ void wf_toggle_fullscreen(wfInfo* wfi)
void wf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
{
int i;
BITMAP_DATA* bmp;
rdpBitmap* bmp;
WF_IMAGE* wf_bmp;
wfInfo* wfi = GET_WFI(update);
@ -364,7 +364,7 @@ void wf_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surfa
void wf_gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
{
WF_IMAGE* bitmap;
BITMAP_DATA* bitmap_data;
rdpBitmap* bitmap_data;
wfInfo* wfi = GET_WFI(update);
bitmap_data = cache_bitmap_v2->bitmap_data;
@ -411,7 +411,7 @@ void wf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_c
}
void wf_gdi_bitmap_decompress(rdpUpdate* update, BITMAP_DATA* bitmap_data)
void wf_gdi_bitmap_decompress(rdpUpdate* update, rdpBitmap* bitmap_data)
{
uint16 dstSize;

View File

@ -194,7 +194,30 @@ boolean xf_set_rop3(xfInfo* xfi, int rop3)
return True;
}
Pixmap xf_bitmap_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
Pixmap xf_brush_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
{
Pixmap bitmap;
uint8* cdata;
XImage* image;
bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, xfi->depth);
if(data != NULL)
{
cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) cdata, width, height, xfi->scanline_pad, 0);
XPutImage(xfi->display, bitmap, xfi->gc, image, 0, 0, 0, 0, width, height);
XFree(image);
if (cdata != data)
xfree(cdata);
}
return bitmap;
}
Pixmap xf_offscreen_new(xfInfo* xfi, int width, int height, int bpp, uint8* data)
{
Pixmap bitmap;
uint8* cdata;
@ -266,7 +289,7 @@ void xf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
int w, h;
uint8* data;
XImage* image;
BITMAP_DATA* bmp;
rdpBitmap* bmp;
xfInfo* xfi = GET_XFI(update);
for (i = 0; i < bitmap->number; i++)
@ -371,7 +394,7 @@ void xf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
{
if (brush->bpp > 1)
{
pattern = xf_bitmap_new(xfi, 8, 8, brush->bpp, brush->data);
pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data);
XSetFillStyle(xfi->display, xfi->gc, FillTiled);
XSetTile(xfi->display, xfi->gc, pattern);
@ -612,34 +635,22 @@ void xf_gdi_polyline(rdpUpdate* update, POLYLINE_ORDER* polyline)
void xf_gdi_memblt(rdpUpdate* update, MEMBLT_ORDER* memblt)
{
void* extra;
Pixmap bitmap;
xfBitmap* bitmap;
xfInfo* xfi = GET_XFI(update);
bitmap = (xfBitmap*) memblt->bitmap;
xf_set_rop3(xfi, gdi_rop3_code(memblt->bRop));
if(memblt->cacheId == 0xFF)
extra = offscreen_cache_get(xfi->cache->offscreen, memblt->cacheIndex);
else
bitmap_cache_get(xfi->cache->bitmap, memblt->cacheId, memblt->cacheIndex, (void**) &extra);
bitmap = (Pixmap) extra;
if (extra == NULL)
return;
XCopyArea(xfi->display, bitmap, xfi->drawing, xfi->gc,
memblt->nXSrc, memblt->nYSrc,
memblt->nWidth, memblt->nHeight,
XCopyArea(xfi->display, bitmap->pixmap, xfi->drawing, xfi->gc,
memblt->nXSrc, memblt->nYSrc, memblt->nWidth, memblt->nHeight,
memblt->nLeftRect, memblt->nTopRect);
if (xfi->drawing == xfi->primary)
{
if (xfi->remote_app != True)
{
XCopyArea(xfi->display, bitmap, xfi->drawable, xfi->gc,
memblt->nXSrc, memblt->nYSrc,
memblt->nWidth, memblt->nHeight,
XCopyArea(xfi->display, bitmap->pixmap, xfi->drawable, xfi->gc,
memblt->nXSrc, memblt->nYSrc, memblt->nWidth, memblt->nHeight,
memblt->nLeftRect, memblt->nTopRect);
}
@ -781,45 +792,6 @@ void xf_gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
}
}
void xf_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
{
Pixmap surface;
xfInfo* xfi = GET_XFI(update);
surface = xf_bitmap_new(xfi, create_offscreen_bitmap->cx, create_offscreen_bitmap->cy, xfi->bpp, NULL);
offscreen_cache_put(xfi->cache->offscreen, create_offscreen_bitmap->id, (void*) surface);
}
void xf_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface)
{
Pixmap surface;
xfInfo* xfi = GET_XFI(update);
if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE)
{
xfi->drawing = xfi->primary;
}
else
{
surface = (Pixmap) offscreen_cache_get(xfi->cache->offscreen, switch_surface->bitmapId);
xfi->drawing = surface;
}
}
void xf_gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
{
Pixmap bitmap;
BITMAP_DATA* bitmap_data;
xfInfo* xfi = GET_XFI(update);
bitmap_data = cache_bitmap_v2->bitmap_data;
bitmap = xf_bitmap_new(xfi, bitmap_data->width, bitmap_data->height, bitmap_data->bpp, bitmap_data->dstData);
bitmap_cache_put(xfi->cache->bitmap, cache_bitmap_v2->cacheId,
cache_bitmap_v2->cacheIndex, bitmap_data, (void*) bitmap);
}
void xf_gdi_cache_color_table(rdpUpdate* update, CACHE_COLOR_TABLE_ORDER* cache_color_table)
{
@ -974,7 +946,7 @@ void xf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_c
}
}
void xf_gdi_bitmap_decompress(rdpUpdate* update, BITMAP_DATA* bitmap_data)
void xf_gdi_bitmap_decompress(rdpUpdate* update, rdpBitmap* bitmap_data)
{
uint16 length;
@ -1035,10 +1007,7 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update)
update->PolygonCB = NULL;
update->EllipseSC = NULL;
update->EllipseCB = NULL;
update->CreateOffscreenBitmap = xf_gdi_create_offscreen_bitmap;
update->SwitchSurface = xf_gdi_switch_surface;
update->CacheBitmapV2 = xf_gdi_cache_bitmap_v2;
update->CacheColorTable = xf_gdi_cache_color_table;
update->CacheGlyph = xf_gdi_cache_glyph;
update->CacheGlyphV2 = xf_gdi_cache_glyph_v2;

View File

@ -232,6 +232,64 @@ void xf_hw_desktop_resize(rdpUpdate* update)
}
}
void xf_bitmap_size(rdpUpdate* update, uint32* size)
{
*size = sizeof(xfBitmap);
}
void xf_bitmap_new(rdpUpdate* update, xfBitmap* bitmap)
{
uint8* cdata;
XImage* image;
rdpBitmap* _bitmap;
xfInfo* xfi = GET_XFI(update);
_bitmap = (rdpBitmap*) &bitmap->bitmap;
bitmap->pixmap = XCreatePixmap(xfi->display, xfi->drawable, _bitmap->width, _bitmap->height, xfi->depth);
if (_bitmap->dstData != NULL)
{
cdata = freerdp_image_convert(_bitmap->dstData, NULL,
_bitmap->width, _bitmap->height, _bitmap->bpp, xfi->bpp, xfi->clrconv);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) cdata, _bitmap->width, _bitmap->height, xfi->scanline_pad, 0);
XPutImage(xfi->display, bitmap->pixmap, xfi->gc, image, 0, 0, 0, 0, _bitmap->width, _bitmap->height);
XFree(image);
if (cdata != _bitmap->dstData)
xfree(cdata);
}
}
void xf_offscreen_bitmap_new(rdpUpdate* update, xfBitmap* bitmap)
{
rdpBitmap* _bitmap;
xfInfo* xfi = GET_XFI(update);
_bitmap = (rdpBitmap*) &bitmap->bitmap;
bitmap->pixmap = XCreatePixmap(xfi->display, xfi->drawable, _bitmap->width, _bitmap->height, xfi->depth);
}
void xf_set_surface(rdpUpdate* update, xfBitmap* bitmap, boolean primary)
{
xfInfo* xfi = GET_XFI(update);
if (primary)
xfi->drawing = xfi->primary;
else
xfi->drawing = bitmap->pixmap;
}
void xf_bitmap_free(rdpUpdate* update, xfBitmap* bitmap)
{
xfInfo* xfi = GET_XFI(update);
if (bitmap->pixmap != 0)
XFreePixmap(xfi->display, bitmap->pixmap);
}
void xf_pointer_size(rdpUpdate* update, uint32* size)
{
*size = sizeof(xfPointer);
@ -523,6 +581,7 @@ boolean xf_pre_connect(freerdp* instance)
xfi->cache = cache_new(instance->settings);
instance->update->cache = (void*) xfi->cache;
instance->cache = instance->update->cache;
xfi->xfds = ConnectionNumber(xfi->display);
xfi->screen_number = DefaultScreen(xfi->display);
@ -643,6 +702,20 @@ boolean xf_post_connect(freerdp* instance)
xfi->cache->pointer->PointerNew = (cbPointerNew) xf_pointer_new;
xfi->cache->pointer->PointerFree = (cbPointerFree) xf_pointer_free;
if (xfi->sw_gdi != True)
{
bitmap_cache_register_callbacks(instance->update);
xfi->cache->bitmap->BitmapSize = (cbBitmapSize) xf_bitmap_size;
xfi->cache->bitmap->BitmapNew = (cbBitmapNew) xf_bitmap_new;
xfi->cache->bitmap->BitmapFree = (cbBitmapFree) xf_bitmap_free;
offscreen_cache_register_callbacks(instance->update);
xfi->cache->offscreen->OffscreenBitmapSize = (cbOffscreenBitmapSize) xf_bitmap_size;
xfi->cache->offscreen->OffscreenBitmapNew = (cbOffscreenBitmapNew) xf_offscreen_bitmap_new;
xfi->cache->offscreen->OffscreenBitmapFree = (cbOffscreenBitmapFree) xf_bitmap_free;
xfi->cache->offscreen->SetSurface = (cbSetSurface) xf_set_surface;
}
xfi->rail = rail_new(instance->settings);
instance->update->rail = (void*) xfi->rail;
rail_register_update_callbacks(xfi->rail, instance->update);

View File

@ -57,6 +57,13 @@ struct xf_pointer
};
typedef struct xf_pointer xfPointer;
struct xf_bitmap
{
rdpBitmap bitmap;
Pixmap pixmap;
};
typedef struct xf_bitmap xfBitmap;
struct xf_info
{
GC gc;

View File

@ -22,34 +22,51 @@
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/update.h>
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
struct _BITMAP_V2_ENTRY
{
void* entry;
void* extra;
};
typedef struct _BITMAP_V2_ENTRY BITMAP_V2_ENTRY;
typedef struct _BITMAP_V2_CELL BITMAP_V2_CELL;
typedef struct rdp_bitmap_cache rdpBitmapCache;
#include <freerdp/cache/cache.h>
struct _BITMAP_V2_CELL
{
uint32 number;
BITMAP_V2_ENTRY* entries;
rdpBitmap** entries;
};
typedef struct _BITMAP_V2_CELL BITMAP_V2_CELL;
struct rdp_bitmap_v2
typedef void (*cbBitmapSize)(rdpUpdate* update, uint32* size);
typedef void (*cbBitmapNew)(rdpUpdate* update, rdpBitmap* bitmap);
typedef void (*cbBitmapFree)(rdpUpdate* update, rdpBitmap* bitmap);
struct rdp_bitmap_cache
{
pcMemBlt MemBlt;
pcMem3Blt Mem3Blt;
pcCacheBitmap CacheBitmap;
pcCacheBitmapV2 CacheBitmapV2;
pcCacheBitmapV3 CacheBitmapV3;
cbBitmapSize BitmapSize;
cbBitmapNew BitmapNew;
cbBitmapFree BitmapFree;
uint8 maxCells;
rdpUpdate* update;
rdpSettings* settings;
BITMAP_V2_CELL* cells;
};
typedef struct rdp_bitmap_v2 rdpBitmapCache;
FREERDP_API void* bitmap_cache_get(rdpBitmapCache* bitmap_v2, uint8 id, uint16 index, void** extra);
FREERDP_API void bitmap_cache_put(rdpBitmapCache* bitmap_v2, uint8 id, uint16 index, void* entry, void* extra);
FREERDP_API void bitmap_free(rdpBitmap* bitmap);
FREERDP_API rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index);
FREERDP_API void bitmap_cache_put(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index, rdpBitmap* bitmap);
FREERDP_API void bitmap_cache_register_callbacks(rdpUpdate* update);
FREERDP_API rdpBitmapCache* bitmap_cache_new(rdpSettings* settings);
FREERDP_API void bitmap_cache_free(rdpBitmapCache* bitmap_v2);
FREERDP_API void bitmap_cache_free(rdpBitmapCache* bitmap_cache);
#endif /* __BITMAP_V2_CACHE_H */

View File

@ -26,26 +26,34 @@
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
typedef struct _OFFSCREEN_ENTRY OFFSCREEN_ENTRY;
typedef struct rdp_offscreen_cache rdpOffscreenCache;
#include <freerdp/cache/cache.h>
struct _OFFSCREEN_ENTRY
{
void* bitmap;
};
typedef void (*cbOffscreenBitmapSize)(rdpUpdate* update, uint32* size);
typedef void (*cbOffscreenBitmapNew)(rdpUpdate* update, rdpBitmap* bitmap);
typedef void (*cbOffscreenBitmapFree)(rdpUpdate* update, rdpBitmap* bitmap);
typedef void (*cbSetSurface)(rdpUpdate* update, rdpBitmap* bitmap, boolean primary);
struct rdp_offscreen_cache
{
cbOffscreenBitmapSize OffscreenBitmapSize;
cbOffscreenBitmapNew OffscreenBitmapNew;
cbOffscreenBitmapFree OffscreenBitmapFree;
cbSetSurface SetSurface;
uint16 maxSize;
uint16 maxEntries;
rdpUpdate* update;
rdpSettings* settings;
OFFSCREEN_ENTRY* entries;
rdpBitmap** entries;
};
FREERDP_API void* offscreen_cache_get(rdpOffscreenCache* offscreen, uint16 index);
FREERDP_API void offscreen_cache_put(rdpOffscreenCache* offscreen, uint16 index, void* bitmap);
FREERDP_API rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint16 index);
FREERDP_API void offscreen_cache_put(rdpOffscreenCache* offscreen_cache, uint16 index, rdpBitmap* bitmap);
FREERDP_API void offscreen_cache_register_callbacks(rdpUpdate* update);
FREERDP_API rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings);
FREERDP_API void offscreen_cache_free(rdpOffscreenCache* offscreen);

View File

@ -50,9 +50,9 @@ typedef void (*pcDisconnect)(freerdp* instance);
struct rdp_freerdp
{
void* rdp;
void* cache;
void* client;
void* chanman;
void* param3;
void* param4;
rdpInput* input;

View File

@ -221,14 +221,14 @@ struct _GDI_DC
typedef struct _GDI_DC GDI_DC;
typedef GDI_DC* HGDI_DC;
struct _GDI_IMAGE
struct gdi_bitmap
{
rdpBitmap _p;
HGDI_DC hdc;
HGDI_BITMAP bitmap;
HGDI_BITMAP org_bitmap;
};
typedef struct _GDI_IMAGE GDI_IMAGE;
typedef GDI_IMAGE* HGDI_IMAGE;
typedef struct gdi_bitmap gdiBitmap;
struct _GDI
{
@ -242,14 +242,14 @@ struct _GDI
HGDI_DC hdc;
HCLRCONV clrconv;
GDI_IMAGE* primary;
GDI_IMAGE* drawing;
gdiBitmap* primary;
gdiBitmap* drawing;
uint8* primary_buffer;
GDI_COLOR textColor;
void* rfx_context;
void* nsc_context;
GDI_IMAGE* tile;
GDI_IMAGE* image;
gdiBitmap* tile;
gdiBitmap* image;
rdpCache* cache;
};
@ -259,8 +259,8 @@ FREERDP_API uint32 gdi_rop3_code(uint8 code);
FREERDP_API uint8* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y);
FREERDP_API uint8* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y);
FREERDP_API int gdi_is_mono_pixel_set(uint8* data, int x, int y, int width);
FREERDP_API GDI_IMAGE* gdi_bitmap_new(GDI *gdi, int width, int height, int bpp, uint8* data);
FREERDP_API void gdi_bitmap_free(GDI_IMAGE *gdi_bmp);
FREERDP_API gdiBitmap* gdi_bitmap_new_ex(GDI *gdi, int width, int height, int bpp, uint8* data);
FREERDP_API void gdi_bitmap_free_ex(gdiBitmap *gdi_bmp);
FREERDP_API void gdi_resize(GDI* gdi, int width, int height);
FREERDP_API int gdi_init(freerdp* instance, uint32 flags, uint8* buffer);
FREERDP_API void gdi_free(freerdp* instance);

View File

@ -55,7 +55,7 @@ typedef struct _BRUSH BRUSH;
/* Bitmap Updates */
struct _BITMAP_DATA
struct rdp_bitmap
{
uint16 left;
uint16 top;
@ -70,13 +70,13 @@ struct _BITMAP_DATA
uint8* dstData;
boolean compressed;
};
typedef struct _BITMAP_DATA BITMAP_DATA;
typedef struct rdp_bitmap rdpBitmap;
struct _BITMAP_UPDATE
{
uint16 count;
uint16 number;
BITMAP_DATA* bitmaps;
rdpBitmap* bitmaps;
};
typedef struct _BITMAP_UPDATE BITMAP_UPDATE;
@ -336,6 +336,7 @@ struct _MEMBLT_ORDER
sint16 nXSrc;
sint16 nYSrc;
uint16 cacheIndex;
rdpBitmap* bitmap;
};
typedef struct _MEMBLT_ORDER MEMBLT_ORDER;
@ -353,6 +354,7 @@ struct _MEM3BLT_ORDER
uint32 foreColor;
BRUSH brush;
uint16 cacheIndex;
rdpBitmap* bitmap;
};
typedef struct _MEM3BLT_ORDER MEM3BLT_ORDER;
@ -530,7 +532,7 @@ struct _CACHE_BITMAP_V2_ORDER
uint32 key2;
uint16 cacheIndex;
uint8 bitmapComprHdr[8];
BITMAP_DATA* bitmap_data;
rdpBitmap* bitmap;
};
typedef struct _CACHE_BITMAP_V2_ORDER CACHE_BITMAP_V2_ORDER;
@ -1108,7 +1110,7 @@ typedef void (*pcNonMonitoredDesktop)(rdpUpdate* update, WINDOW_ORDER_INFO* orde
typedef void (*pcSurfaceBits)(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command);
typedef void (*pcSurfaceCommand)(rdpUpdate* update, STREAM* s);
typedef void (*pcBitmapDecompress)(rdpUpdate* update, BITMAP_DATA* bitmap_data);
typedef void (*pcBitmapDecompress)(rdpUpdate* update, rdpBitmap* bitmap);
struct rdp_update
{
@ -1198,8 +1200,6 @@ struct rdp_update
pcBitmapDecompress BitmapDecompress;
void* state_start;
BITMAP_UPDATE bitmap_update;
PALETTE_UPDATE palette_update;
PLAY_SOUND_UPDATE play_sound;
@ -1262,8 +1262,6 @@ struct rdp_update
MONITORED_DESKTOP_ORDER monitored_desktop;
SURFACE_BITS_COMMAND surface_bits_command;
void* state_end;
};
#endif /* __UPDATE_API_H */

View File

@ -22,44 +22,99 @@
#include <freerdp/cache/bitmap.h>
void* bitmap_cache_get(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index, void** extra)
void bitmap_free(rdpBitmap* bitmap)
{
void* entry;
if (id > bitmap_cache->maxCells)
if (bitmap != NULL)
{
printf("get invalid bitmap_v2 cell id: %d\n", id);
return NULL;
if (bitmap->dstData != NULL)
xfree(bitmap->dstData);
xfree(bitmap);
}
if (index == 0x7FFF)
index = bitmap_cache->cells[id].number - 1;
if (index > bitmap_cache->cells[id].number)
{
printf("get invalid bitmap_v2 index %d in cell id: %d\n", index, id);
return NULL;
}
entry = bitmap_cache->cells[id].entries[index].entry;
if (extra != NULL)
*extra = bitmap_cache->cells[id].entries[index].extra;
if (entry == NULL)
{
printf("get invalid bitmap_v2 at index %d in cell id: %d\n", index, id);
return NULL;
}
return entry;
}
void bitmap_cache_put(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index, void* entry, void* extra)
void update_gdi_memblt(rdpUpdate* update, MEMBLT_ORDER* memblt)
{
rdpBitmap* bitmap;
rdpCache* cache = (rdpCache*) update->cache;
if (memblt->cacheIndex == 0xFF)
bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex);
else
bitmap = bitmap_cache_get(cache->bitmap, memblt->cacheId, memblt->cacheIndex);
memblt->bitmap = bitmap;
IFCALL(cache->bitmap->MemBlt, update, memblt);
}
void update_gdi_mem3blt(rdpUpdate* update, MEM3BLT_ORDER* mem3blt)
{
rdpBitmap* bitmap;
rdpCache* cache = (rdpCache*) update->cache;
if (mem3blt->cacheIndex == 0xFF)
bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex);
else
bitmap = bitmap_cache_get(cache->bitmap, mem3blt->cacheId, mem3blt->cacheIndex);
mem3blt->bitmap = bitmap;
IFCALL(cache->bitmap->Mem3Blt, update, mem3blt);
}
void update_gdi_cache_bitmap(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap)
{
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
uint32 size = sizeof(rdpBitmap);
rdpCache* cache = (rdpCache*) update->cache;
bitmap = cache_bitmap->bitmap;
IFCALL(cache->bitmap->BitmapSize, update, &size);
bitmap = (rdpBitmap*) xrealloc(bitmap, size);
IFCALL(cache->bitmap->BitmapNew, update, bitmap);
cache_bitmap->bitmap = bitmap;
prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap->cacheId, cache_bitmap->cacheIndex);
if (prevBitmap != NULL)
{
IFCALL(cache->bitmap->BitmapFree, update, prevBitmap);
bitmap_free(prevBitmap);
}
bitmap_cache_put(cache->bitmap, cache_bitmap->cacheId, cache_bitmap->cacheIndex, bitmap);
}
rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index)
{
rdpBitmap* bitmap;
if (id > bitmap_cache->maxCells)
{
printf("get invalid bitmap cell id: %d\n", id);
return NULL;
}
if (index == 0x7FFF)
index = bitmap_cache->cells[id].number - 1;
if (index > bitmap_cache->cells[id].number)
{
printf("get invalid bitmap index %d in cell id: %d\n", index, id);
return NULL;
}
bitmap = bitmap_cache->cells[id].entries[index];
return bitmap;
}
void bitmap_cache_put(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index, rdpBitmap* bitmap)
{
if (id > bitmap_cache->maxCells)
{
printf("put invalid bitmap_v2 cell id: %d\n", id);
printf("put invalid bitmap cell id: %d\n", id);
return;
}
@ -68,12 +123,23 @@ void bitmap_cache_put(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index, void
if (index > bitmap_cache->cells[id].number)
{
printf("put invalid bitmap_v2 index %d in cell id: %d\n", index, id);
printf("put invalid bitmap index %d in cell id: %d\n", index, id);
return;
}
bitmap_cache->cells[id].entries[index].entry = entry;
bitmap_cache->cells[id].entries[index].extra = extra;
bitmap_cache->cells[id].entries[index] = bitmap;
}
void bitmap_cache_register_callbacks(rdpUpdate* update)
{
rdpCache* cache = (rdpCache*) update->cache;
cache->bitmap->MemBlt = update->MemBlt;
cache->bitmap->Mem3Blt = update->Mem3Blt;
update->MemBlt = update_gdi_memblt;
update->Mem3Blt = update_gdi_mem3blt;
update->CacheBitmapV2 = update_gdi_cache_bitmap;
}
rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
@ -86,6 +152,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
if (bitmap_cache != NULL)
{
bitmap_cache->settings = settings;
bitmap_cache->update = ((freerdp*) settings->instance)->update;
bitmap_cache->maxCells = 5;
@ -107,7 +174,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
for (i = 0; i < bitmap_cache->maxCells; i++)
{
bitmap_cache->cells[i].number = settings->bitmapCacheV2CellInfo[i].numEntries;
bitmap_cache->cells[i].entries = (BITMAP_V2_ENTRY*) xzalloc(sizeof(BITMAP_V2_ENTRY) * bitmap_cache->cells[i].number);
bitmap_cache->cells[i].entries = (rdpBitmap**) xzalloc(sizeof(rdpBitmap*) * bitmap_cache->cells[i].number);
}
}
@ -117,6 +184,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
void bitmap_cache_free(rdpBitmapCache* bitmap_cache)
{
int i, j;
rdpBitmap* bitmap;
if (bitmap_cache != NULL)
{
@ -124,8 +192,13 @@ void bitmap_cache_free(rdpBitmapCache* bitmap_cache)
{
for (j = 0; j < (int) bitmap_cache->cells[i].number; j++)
{
if (bitmap_cache->cells[i].entries[j].entry != NULL)
xfree(bitmap_cache->cells[i].entries[j].entry);
bitmap = bitmap_cache->cells[i].entries[j];
if (bitmap != NULL)
{
IFCALL(bitmap_cache->BitmapFree, bitmap_cache->update, bitmap);
bitmap_free(bitmap);
}
}
xfree(bitmap_cache->cells[i].entries);

View File

@ -22,9 +22,47 @@
#include <freerdp/cache/offscreen.h>
void* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint16 index)
void update_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
{
void* bitmap;
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
uint32 size = sizeof(rdpBitmap);
rdpCache* cache = (rdpCache*) update->cache;
IFCALL(cache->offscreen->OffscreenBitmapSize, update, &size);
bitmap = (rdpBitmap*) xzalloc(size);
IFCALL(cache->offscreen->OffscreenBitmapNew, update, bitmap);
prevBitmap = offscreen_cache_get(cache->offscreen, create_offscreen_bitmap->id);
if (prevBitmap != NULL)
{
IFCALL(cache->offscreen->OffscreenBitmapFree, update, prevBitmap);
bitmap_free(prevBitmap);
}
offscreen_cache_put(cache->offscreen, create_offscreen_bitmap->id, bitmap);
}
void update_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface)
{
rdpCache* cache = (rdpCache*) update->cache;
if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE)
{
IFCALL(cache->offscreen->SetSurface, update, NULL, True);
}
else
{
rdpBitmap* bitmap;
bitmap = offscreen_cache_get(cache->offscreen, switch_surface->bitmapId);
IFCALL(cache->offscreen->SetSurface, update, bitmap, False);
}
}
rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint16 index)
{
rdpBitmap* bitmap;
if (index > offscreen_cache->maxEntries)
{
@ -32,7 +70,7 @@ void* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint16 index)
return NULL;
}
bitmap = offscreen_cache->entries[index].bitmap;
bitmap = offscreen_cache->entries[index];
if (bitmap == NULL)
{
@ -43,7 +81,7 @@ void* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint16 index)
return bitmap;
}
void offscreen_cache_put(rdpOffscreenCache* offscreen, uint16 index, void* bitmap)
void offscreen_cache_put(rdpOffscreenCache* offscreen, uint16 index, rdpBitmap* bitmap)
{
if (index > offscreen->maxEntries)
{
@ -51,7 +89,13 @@ void offscreen_cache_put(rdpOffscreenCache* offscreen, uint16 index, void* bitma
return;
}
offscreen->entries[index].bitmap = bitmap;
offscreen->entries[index] = bitmap;
}
void offscreen_cache_register_callbacks(rdpUpdate* update)
{
update->CreateOffscreenBitmap = update_gdi_create_offscreen_bitmap;
update->SwitchSurface = update_gdi_switch_surface;
}
rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings)
@ -63,15 +107,15 @@ rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings)
if (offscreen_cache != NULL)
{
offscreen_cache->settings = settings;
offscreen_cache->update = ((freerdp*) settings->instance)->update;
offscreen_cache->maxSize = 7680;
offscreen_cache->maxEntries = 100;
settings->offscreen_bitmap_cache = True;
settings->offscreen_bitmap_cache_size = offscreen_cache->maxSize;
settings->offscreen_bitmap_cache_entries = offscreen_cache->maxEntries;
offscreen_cache->entries = (OFFSCREEN_ENTRY*) xzalloc(sizeof(OFFSCREEN_ENTRY) * offscreen_cache->maxEntries);
offscreen_cache->entries = (rdpBitmap**) xzalloc(sizeof(rdpBitmap*) * offscreen_cache->maxEntries);
}
return offscreen_cache;
@ -79,8 +123,22 @@ rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings)
void offscreen_cache_free(rdpOffscreenCache* offscreen_cache)
{
int i;
rdpBitmap* bitmap;
if (offscreen_cache != NULL)
{
for (i = 0; i < offscreen_cache->maxEntries; i++)
{
bitmap = offscreen_cache->entries[i];
if (bitmap != NULL)
{
IFCALL(offscreen_cache->OffscreenBitmapFree, offscreen_cache->update, bitmap);
bitmap_free(bitmap);
}
}
xfree(offscreen_cache->entries);
xfree(offscreen_cache);
}

View File

@ -1396,16 +1396,16 @@ void update_read_cache_bitmap_order(STREAM* s, CACHE_BITMAP_ORDER* cache_bitmap_
void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, boolean compressed, uint16 flags)
{
uint8 bitsPerPixelId;
BITMAP_DATA* bitmap_data;
rdpBitmap* bitmap;
bitmap_data = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA));
cache_bitmap_v2_order->bitmap_data = bitmap_data;
bitmap = (rdpBitmap*) xzalloc(sizeof(rdpBitmap));
cache_bitmap_v2_order->bitmap = bitmap;
cache_bitmap_v2_order->cacheId = flags & 0x0003;
cache_bitmap_v2_order->flags = (flags & 0xFF80) >> 7;
bitsPerPixelId = (flags & 0x0078) >> 3;
bitmap_data->bpp = CBR2_BPP[bitsPerPixelId];
bitmap->bpp = CBR2_BPP[bitsPerPixelId];
if (cache_bitmap_v2_order->flags & CBR2_PERSISTENT_KEY_PRESENT)
{
@ -1415,16 +1415,16 @@ void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_b
if (cache_bitmap_v2_order->flags & CBR2_HEIGHT_SAME_AS_WIDTH)
{
update_read_2byte_unsigned(s, &bitmap_data->width); /* bitmapWidth */
bitmap_data->height = bitmap_data->width;
update_read_2byte_unsigned(s, &bitmap->width); /* bitmapWidth */
bitmap->height = bitmap->width;
}
else
{
update_read_2byte_unsigned(s, &bitmap_data->width); /* bitmapWidth */
update_read_2byte_unsigned(s, &bitmap_data->height); /* bitmapHeight */
update_read_2byte_unsigned(s, &bitmap->width); /* bitmapWidth */
update_read_2byte_unsigned(s, &bitmap->height); /* bitmapHeight */
}
update_read_4byte_unsigned(s, &bitmap_data->length); /* bitmapLength */
update_read_4byte_unsigned(s, &bitmap->length); /* bitmapLength */
update_read_2byte_unsigned(s, &cache_bitmap_v2_order->cacheIndex); /* cacheIndex */
if (compressed)
@ -1433,18 +1433,18 @@ void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_b
{
uint8* bitmapComprHdr = (uint8*) &(cache_bitmap_v2_order->bitmapComprHdr);
stream_read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */
bitmap_data->length -= 8;
bitmap->length -= 8;
}
stream_get_mark(s, bitmap_data->srcData);
stream_seek(s, bitmap_data->length);
bitmap_data->compressed = True;
stream_get_mark(s, bitmap->srcData);
stream_seek(s, bitmap->length);
bitmap->compressed = True;
}
else
{
stream_get_mark(s, bitmap_data->srcData);
stream_seek(s, bitmap_data->length);
bitmap_data->compressed = False;
stream_get_mark(s, bitmap->srcData);
stream_seek(s, bitmap->length);
bitmap->compressed = False;
}
}
@ -2022,13 +2022,13 @@ void update_recv_secondary_order(rdpUpdate* update, STREAM* s, uint8 flags)
case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2:
update_read_cache_bitmap_v2_order(s, &(update->cache_bitmap_v2_order), False, extraFlags);
IFCALL(update->BitmapDecompress, update, update->cache_bitmap_v2_order.bitmap_data);
IFCALL(update->BitmapDecompress, update, update->cache_bitmap_v2_order.bitmap);
IFCALL(update->CacheBitmapV2, update, &(update->cache_bitmap_v2_order));
break;
case ORDER_TYPE_BITMAP_COMPRESSED_V2:
update_read_cache_bitmap_v2_order(s, &(update->cache_bitmap_v2_order), True, extraFlags);
IFCALL(update->BitmapDecompress, update, update->cache_bitmap_v2_order.bitmap_data);
IFCALL(update->BitmapDecompress, update, update->cache_bitmap_v2_order.bitmap);
IFCALL(update->CacheBitmapV2, update, &(update->cache_bitmap_v2_order));
break;

View File

@ -44,7 +44,7 @@ void update_recv_orders(rdpUpdate* update, STREAM* s)
}
}
void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
void update_read_bitmap_data(STREAM* s, rdpBitmap* bitmap_data)
{
uint16 bytesPerPixel;
@ -96,11 +96,11 @@ void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_upda
count = bitmap_update->number * 2;
bitmap_update->bitmaps = (BITMAP_DATA*) xrealloc(bitmap_update->bitmaps,
sizeof(BITMAP_DATA) * count);
bitmap_update->bitmaps = (rdpBitmap*) xrealloc(bitmap_update->bitmaps,
sizeof(rdpBitmap) * count);
memset(&bitmap_update->bitmaps[bitmap_update->count], 0,
sizeof(BITMAP_DATA) * (count - bitmap_update->count));
sizeof(rdpBitmap) * (count - bitmap_update->count));
bitmap_update->count = count;
}
@ -304,22 +304,33 @@ void update_recv(rdpUpdate* update, STREAM* s)
void update_reset_state(rdpUpdate* update)
{
int length;
uint16 bitmap_count;
BITMAP_DATA* bitmaps;
memset(&update->order_info, 0, sizeof(ORDER_INFO));
memset(&update->dstblt, 0, sizeof(DSTBLT_ORDER));
memset(&update->patblt, 0, sizeof(PATBLT_ORDER));
memset(&update->scrblt, 0, sizeof(SCRBLT_ORDER));
memset(&update->opaque_rect, 0, sizeof(OPAQUE_RECT_ORDER));
memset(&update->draw_nine_grid, 0, sizeof(DRAW_NINE_GRID_ORDER));
memset(&update->multi_dstblt, 0, sizeof(MULTI_DSTBLT_ORDER));
memset(&update->multi_patblt, 0, sizeof(MULTI_PATBLT_ORDER));
memset(&update->multi_scrblt, 0, sizeof(MULTI_SCRBLT_ORDER));
memset(&update->multi_opaque_rect, 0, sizeof(MULTI_OPAQUE_RECT_ORDER));
memset(&update->multi_draw_nine_grid, 0, sizeof(MULTI_DRAW_NINE_GRID_ORDER));
memset(&update->line_to, 0, sizeof(LINE_TO_ORDER));
memset(&update->polyline, 0, sizeof(POLYLINE_ORDER));
memset(&update->memblt, 0, sizeof(MEMBLT_ORDER));
memset(&update->mem3blt, 0, sizeof(MEM3BLT_ORDER));
memset(&update->save_bitmap, 0, sizeof(SAVE_BITMAP_ORDER));
memset(&update->glyph_index, 0, sizeof(GLYPH_INDEX_ORDER));
memset(&update->fast_index, 0, sizeof(FAST_INDEX_ORDER));
memset(&update->fast_glyph, 0, sizeof(FAST_GLYPH_ORDER));
memset(&update->polygon_sc, 0, sizeof(POLYGON_SC_ORDER));
memset(&update->polygon_cb, 0, sizeof(POLYGON_CB_ORDER));
memset(&update->ellipse_sc, 0, sizeof(ELLIPSE_SC_ORDER));
memset(&update->ellipse_cb, 0, sizeof(ELLIPSE_CB_ORDER));
bitmaps = update->bitmap_update.bitmaps;
bitmap_count = update->bitmap_update.count;
length = &update->state_end - &update->state_start;
memset(&update->state_start, 0, length);
update->order_info.orderType = ORDER_TYPE_PATBLT;
update->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE;
IFCALL(update->SwitchSurface, update, &(update->switch_surface));
update->bitmap_update.bitmaps = bitmaps;
update->bitmap_update.count = bitmap_count;
}
static void update_begin_paint(rdpUpdate* update)
@ -398,7 +409,7 @@ rdpUpdate* update_new(rdpRdp* rdp)
update->rdp = (void*) rdp;
update->bitmap_update.count = 64;
update->bitmap_update.bitmaps = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA) * update->bitmap_update.count);
update->bitmap_update.bitmaps = (rdpBitmap*) xzalloc(sizeof(rdpBitmap) * update->bitmap_update.count);
}
return update;
@ -409,7 +420,7 @@ void update_free(rdpUpdate* update)
if (update != NULL)
{
uint16 i;
BITMAP_DATA* bitmaps;
rdpBitmap* bitmaps;
BITMAP_UPDATE* bitmap_update;
bitmap_update = &update->bitmap_update;

View File

@ -374,47 +374,102 @@ HGDI_BITMAP gdi_create_bitmap(GDI* gdi, int width, int height, int bpp, uint8* d
return bitmap;
}
GDI_IMAGE* gdi_bitmap_new(GDI* gdi, int width, int height, int bpp, uint8* data)
gdiBitmap* gdi_bitmap_new_ex(GDI* gdi, int width, int height, int bpp, uint8* data)
{
GDI_IMAGE *gdi_bmp;
gdiBitmap* bitmap;
gdi_bmp = (GDI_IMAGE*) malloc(sizeof(GDI_IMAGE));
gdi_bmp->hdc = gdi_CreateCompatibleDC(gdi->hdc);
bitmap = (gdiBitmap*) malloc(sizeof(gdiBitmap));
bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc);
DEBUG_GDI("gdi_bitmap_new: width:%d height:%d bpp:%d", width, height, bpp);
if (data == NULL)
{
gdi_bmp->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, width, height);
}
bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, width, height);
else
{
gdi_bmp->bitmap = gdi_create_bitmap(gdi, width, height, bpp, data);
}
bitmap->bitmap = gdi_create_bitmap(gdi, width, height, bpp, data);
gdi_SelectObject(gdi_bmp->hdc, (HGDIOBJECT) gdi_bmp->bitmap);
gdi_bmp->org_bitmap = NULL;
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->bitmap);
bitmap->org_bitmap = NULL;
return gdi_bmp;
return bitmap;
}
void gdi_bitmap_free(GDI_IMAGE *gdi_bmp)
void gdi_bitmap_free_ex(gdiBitmap* bitmap)
{
if (gdi_bmp != 0)
if (bitmap != NULL)
{
gdi_SelectObject(gdi_bmp->hdc, (HGDIOBJECT) gdi_bmp->org_bitmap);
gdi_DeleteObject((HGDIOBJECT) gdi_bmp->bitmap);
gdi_DeleteDC(gdi_bmp->hdc);
free(gdi_bmp);
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->org_bitmap);
gdi_DeleteObject((HGDIOBJECT) bitmap->bitmap);
gdi_DeleteDC(bitmap->hdc);
free(bitmap);
}
}
GDI_IMAGE* gdi_glyph_new(GDI* gdi, GLYPH_DATA* glyph)
void gdi_bitmap_size(rdpUpdate* update, uint32* size)
{
*size = sizeof(gdiBitmap);
}
void gdi_bitmap_new(rdpUpdate* update, gdiBitmap* bitmap)
{
uint8* data;
rdpBitmap* _bitmap;
GDI* gdi = GET_GDI(update);
_bitmap = &(bitmap->_p);
bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc);
data = _bitmap->dstData;
if (data == NULL)
bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, _bitmap->width, _bitmap->height);
else
bitmap->bitmap = gdi_create_bitmap(gdi, _bitmap->width, _bitmap->height, gdi->dstBpp, data);
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->bitmap);
bitmap->org_bitmap = NULL;
}
void gdi_offscreen_bitmap_new(rdpUpdate* update, gdiBitmap* bitmap)
{
rdpBitmap* _bitmap;
GDI* gdi = GET_GDI(update);
_bitmap = &(bitmap->_p);
bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc);
bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, _bitmap->width, _bitmap->height);
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->bitmap);
bitmap->org_bitmap = NULL;
}
void gdi_set_surface(rdpUpdate* update, gdiBitmap* bitmap, boolean primary)
{
GDI* gdi = GET_GDI(update);
if (primary)
gdi->drawing = gdi->primary;
else
gdi->drawing = bitmap;
}
void gdi_bitmap_free(rdpUpdate* update, gdiBitmap* bitmap)
{
if (bitmap != NULL)
{
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->org_bitmap);
gdi_DeleteObject((HGDIOBJECT) bitmap->bitmap);
gdi_DeleteDC(bitmap->hdc);
}
}
gdiBitmap* gdi_glyph_new(GDI* gdi, GLYPH_DATA* glyph)
{
uint8* extra;
GDI_IMAGE* gdi_bmp;
gdiBitmap* gdi_bmp;
gdi_bmp = (GDI_IMAGE*) malloc(sizeof(GDI_IMAGE));
gdi_bmp = (gdiBitmap*) malloc(sizeof(gdiBitmap));
gdi_bmp->hdc = gdi_GetDC();
gdi_bmp->hdc->bytesPerPixel = 1;
@ -431,7 +486,7 @@ GDI_IMAGE* gdi_glyph_new(GDI* gdi, GLYPH_DATA* glyph)
return gdi_bmp;
}
void gdi_glyph_free(GDI_IMAGE *gdi_bmp)
void gdi_glyph_free(gdiBitmap *gdi_bmp)
{
if (gdi_bmp != 0)
{
@ -445,21 +500,21 @@ void gdi_glyph_free(GDI_IMAGE *gdi_bmp)
void gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
{
int i;
BITMAP_DATA* bmp;
GDI_IMAGE* gdi_bmp;
rdpBitmap* bmp;
gdiBitmap* gdi_bmp;
GDI* gdi = GET_GDI(update);
for (i = 0; i < bitmap->number; i++)
{
bmp = &bitmap->bitmaps[i];
gdi_bmp = gdi_bitmap_new(gdi, bmp->width, bmp->height, gdi->dstBpp, bmp->dstData);
gdi_bmp = gdi_bitmap_new_ex(gdi, bmp->width, bmp->height, gdi->dstBpp, bmp->dstData);
gdi_BitBlt(gdi->primary->hdc,
bmp->left, bmp->top, bmp->right - bmp->left + 1,
bmp->bottom - bmp->top + 1, gdi_bmp->hdc, 0, 0, GDI_SRCCOPY);
gdi_bitmap_free((GDI_IMAGE*) gdi_bmp);
gdi_bitmap_free_ex((gdiBitmap*) gdi_bmp);
}
}
@ -647,22 +702,13 @@ void gdi_polyline(rdpUpdate* update, POLYLINE_ORDER* polyline)
void gdi_memblt(rdpUpdate* update, MEMBLT_ORDER* memblt)
{
void* extra;
GDI_IMAGE* gdi_bmp;
gdiBitmap* bitmap;
GDI* gdi = GET_GDI(update);
if(memblt->cacheId == 0xFF)
extra = offscreen_cache_get(gdi->cache->offscreen, memblt->cacheIndex);
else
bitmap_cache_get(gdi->cache->bitmap, memblt->cacheId, memblt->cacheIndex, (void**) &extra);
gdi_bmp = (GDI_IMAGE*) extra;
if (extra == NULL)
return;
bitmap = (gdiBitmap*) memblt->bitmap;
gdi_BitBlt(gdi->drawing->hdc, memblt->nLeftRect, memblt->nTopRect,
memblt->nWidth, memblt->nHeight, gdi_bmp->hdc,
memblt->nWidth, memblt->nHeight, bitmap->hdc,
memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop));
}
@ -679,8 +725,8 @@ void gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
uint32 bgcolor;
uint32 fgcolor;
HGDI_BRUSH brush;
GDI_IMAGE* bmp;
GDI_IMAGE** bmps;
gdiBitmap* bmp;
gdiBitmap** bmps;
GLYPH_DATA* glyph;
GLYPH_DATA** glyphs;
GLYPH_FRAGMENT* fragment;
@ -719,7 +765,7 @@ void gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
}
else
{
bmps = (GDI_IMAGE**) xmalloc(sizeof(GDI_IMAGE*) * fragment->nindices);
bmps = (gdiBitmap**) xmalloc(sizeof(gdiBitmap*) * fragment->nindices);
glyphs = (GLYPH_DATA**) xmalloc(sizeof(GLYPH_DATA*) * fragment->nindices);
for (j = 0; j < fragment->nindices; j++)
@ -770,45 +816,6 @@ void gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index)
gdi_DeleteObject((HGDIOBJECT) brush);
}
void gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap)
{
GDI_IMAGE* gdi_bmp;
GDI* gdi = GET_GDI(update);
gdi_bmp = gdi_bitmap_new(gdi, create_offscreen_bitmap->cx, create_offscreen_bitmap->cy, gdi->dstBpp, NULL);
offscreen_cache_put(gdi->cache->offscreen, create_offscreen_bitmap->id, (void*) gdi_bmp);
}
void gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface)
{
GDI_IMAGE* gdi_bmp;
GDI* gdi = GET_GDI(update);
if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE)
{
gdi->drawing = (GDI_IMAGE*) gdi->primary;
}
else
{
gdi_bmp = (GDI_IMAGE*) offscreen_cache_get(gdi->cache->offscreen, switch_surface->bitmapId);
gdi->drawing = gdi_bmp;
}
}
void gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2)
{
GDI_IMAGE* bitmap;
BITMAP_DATA* bitmap_data;
GDI* gdi = GET_GDI(update);
bitmap_data = cache_bitmap_v2->bitmap_data;
bitmap = gdi_bitmap_new(gdi, bitmap_data->width, bitmap_data->height, gdi->dstBpp, bitmap_data->dstData);
bitmap_cache_put(gdi->cache->bitmap, cache_bitmap_v2->cacheId,
cache_bitmap_v2->cacheIndex, bitmap_data, (void*) bitmap);
}
void gdi_cache_color_table(rdpUpdate* update, CACHE_COLOR_TABLE_ORDER* cache_color_table)
{
GDI* gdi = GET_GDI(update);
@ -819,7 +826,7 @@ void gdi_cache_glyph(rdpUpdate* update, CACHE_GLYPH_ORDER* cache_glyph)
{
int i;
GLYPH_DATA* glyph;
GDI_IMAGE* gdi_bmp;
gdiBitmap* gdi_bmp;
GDI* gdi = GET_GDI(update);
for (i = 0; i < cache_glyph->cGlyphs; i++)
@ -835,13 +842,13 @@ void gdi_cache_glyph_v2(rdpUpdate* update, CACHE_GLYPH_V2_ORDER* cache_glyph_v2)
int i;
uint8* extra;
GLYPH_DATA_V2* glyph;
GDI_IMAGE* gdi_bmp;
gdiBitmap* gdi_bmp;
GDI* gdi = GET_GDI(update);
for (i = 0; i < cache_glyph_v2->cGlyphs; i++)
{
glyph = cache_glyph_v2->glyphData[i];
gdi_bmp = (GDI_IMAGE*) malloc(sizeof(GDI_IMAGE));
gdi_bmp = (gdiBitmap*) malloc(sizeof(gdiBitmap));
gdi_bmp->hdc = gdi_GetDC();
gdi_bmp->hdc->bytesPerPixel = 1;
@ -979,7 +986,7 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm
xfree(tile_bitmap);
}
void gdi_bitmap_decompress(rdpUpdate* update, BITMAP_DATA* bitmap_data)
void gdi_bitmap_decompress(rdpUpdate* update, rdpBitmap* bitmap_data)
{
uint16 length;
@ -1046,10 +1053,7 @@ void gdi_register_update_callbacks(rdpUpdate* update)
update->PolygonCB = NULL;
update->EllipseSC = NULL;
update->EllipseCB = NULL;
update->CreateOffscreenBitmap = gdi_create_offscreen_bitmap;
update->SwitchSurface = gdi_switch_surface;
update->CacheBitmapV2 = gdi_cache_bitmap_v2;
update->CacheColorTable = gdi_cache_color_table;
update->CacheGlyph = gdi_cache_glyph;
update->CacheGlyphV2 = gdi_cache_glyph_v2;
@ -1061,7 +1065,7 @@ void gdi_register_update_callbacks(rdpUpdate* update)
void gdi_init_primary(GDI* gdi)
{
gdi->primary = gdi_bitmap_new(gdi, gdi->width, gdi->height, gdi->dstBpp, gdi->primary_buffer);
gdi->primary = gdi_bitmap_new_ex(gdi, gdi->width, gdi->height, gdi->dstBpp, gdi->primary_buffer);
gdi->primary_buffer = gdi->primary->bitmap->data;
if (gdi->drawing == NULL)
@ -1087,7 +1091,7 @@ void gdi_resize(GDI* gdi, int width, int height)
gdi->width = width;
gdi->height = height;
gdi_bitmap_free(gdi->primary);
gdi_bitmap_free_ex(gdi->primary);
gdi_init_primary(gdi);
}
}
@ -1162,12 +1166,29 @@ int gdi_init(freerdp* instance, uint32 flags, uint8* buffer)
gdi_init_primary(gdi);
gdi->tile = gdi_bitmap_new(gdi, 64, 64, 32, NULL);
gdi->image = gdi_bitmap_new(gdi, 64, 64, 32, NULL);
gdi->tile = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL);
gdi->image = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL);
if (instance->cache == NULL)
{
instance->cache = (void*) cache_new(instance->settings);
instance->update->cache = instance->cache;
}
gdi->cache = (rdpCache*) instance->cache;
gdi_register_update_callbacks(instance->update);
gdi->cache = cache_new(instance->settings);
bitmap_cache_register_callbacks(instance->update);
gdi->cache->bitmap->BitmapSize = (cbBitmapSize) gdi_bitmap_size;
gdi->cache->bitmap->BitmapNew = (cbBitmapNew) gdi_bitmap_new;
gdi->cache->bitmap->BitmapFree = (cbBitmapFree) gdi_bitmap_free;
offscreen_cache_register_callbacks(instance->update);
gdi->cache->offscreen->OffscreenBitmapSize = (cbOffscreenBitmapSize) gdi_bitmap_size;
gdi->cache->offscreen->OffscreenBitmapNew = (cbOffscreenBitmapNew) gdi_offscreen_bitmap_new;
gdi->cache->offscreen->OffscreenBitmapFree = (cbOffscreenBitmapFree) gdi_bitmap_free;
gdi->cache->offscreen->SetSurface = (cbSetSurface) gdi_set_surface;
gdi->rfx_context = rfx_context_new();
gdi->nsc_context = nsc_context_new();
@ -1181,9 +1202,9 @@ void gdi_free(freerdp* instance)
if (gdi)
{
gdi_bitmap_free(gdi->primary);
gdi_bitmap_free(gdi->tile);
gdi_bitmap_free(gdi->image);
gdi_bitmap_free_ex(gdi->primary);
gdi_bitmap_free_ex(gdi->tile);
gdi_bitmap_free_ex(gdi->image);
gdi_DeleteDC(gdi->hdc);
cache_free(gdi->cache);
rfx_context_free((RFX_CONTEXT*)gdi->rfx_context);