libfreerdp-core: refactoring of core bitmap objects

This commit is contained in:
Marc-André Moreau 2011-10-20 17:28:59 -04:00
parent 5f7aafd7aa
commit b7e7067176
30 changed files with 698 additions and 422 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
# CMake
cmake_install.cmake
*.cmake
CMakeFiles/
CMakeCache.txt
config.h

View File

@ -397,7 +397,7 @@ void wf_gdi_bitmap_decompress(rdpUpdate* update, rdpBitmap* bitmap_data)
void wf_gdi_register_update_callbacks(rdpUpdate* update)
{
update->Bitmap = wf_gdi_bitmap_update;
update->BitmapUpdate = wf_gdi_bitmap_update;
update->Palette = wf_gdi_palette_update;
update->SetBounds = wf_gdi_set_bounds;
update->DstBlt = wf_gdi_dstblt;

View File

@ -27,14 +27,16 @@ add_executable(xfreerdp
xf_rail.h
xf_tsmf.c
xf_tsmf.h
xf_cliprdr.c
xf_cliprdr.h
xf_event.c
xf_event.h
xf_keyboard.c
xf_keyboard.h
xf_cliprdr.c
xf_cliprdr.h
xf_monitor.c
xf_monitor.h
xf_graphics.c
xf_graphics.h
xf_keyboard.c
xf_keyboard.h
xf_window.c
xf_window.h
xfreerdp.c

View File

@ -282,42 +282,6 @@ Pixmap xf_glyph_new(xfInfo* xfi, int width, int height, uint8* data)
return bitmap;
}
void xf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
{
int i;
int x, y;
int w, h;
uint8* data;
XImage* image;
rdpBitmap* bmp;
xfInfo* xfi = ((xfContext*) update->context)->xfi;
for (i = 0; i < bitmap->number; i++)
{
bmp = &bitmap->bitmaps[i];
data = freerdp_image_convert(bmp->dstData, NULL, bmp->width, bmp->height, bmp->bpp, xfi->bpp, xfi->clrconv);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) data, bmp->width, bmp->height, xfi->scanline_pad, 0);
x = bmp->left;
y = bmp->top;
w = bmp->right - bmp->left + 1;
h = bmp->bottom - bmp->top + 1;
XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, x, y, w, h);
XFree(image);
xfree(data);
if (xfi->remote_app != True)
XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, w, h, x, y);
gdi_InvalidateRegion(xfi->hdc, x, y, w, h);
}
}
void xf_gdi_palette_update(rdpUpdate* update, PALETTE_UPDATE* palette)
{
@ -368,12 +332,12 @@ void xf_gdi_dstblt(rdpUpdate* update, DSTBLT_ORDER* dstblt)
void xf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
{
BRUSH* brush;
Pixmap pattern;
rdpBrush* brush;
uint32 foreColor;
uint32 backColor;
xfInfo* xfi = ((xfContext*) update->context)->xfi;
rdpCache* cache = update->context->cache;
xfInfo* xfi = ((xfContext*) update->context)->xfi;
brush = &patblt->brush;
xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop));
@ -955,43 +919,8 @@ void xf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_c
}
}
void xf_gdi_bitmap_decompress(rdpUpdate* update, rdpBitmap* bitmap_data)
{
uint16 length;
length = bitmap_data->width * bitmap_data->height * (bitmap_data->bpp / 8);
if (bitmap_data->dstData == NULL)
bitmap_data->dstData = (uint8*) xmalloc(length);
else
bitmap_data->dstData = (uint8*) xrealloc(bitmap_data->dstData, length);
if (bitmap_data->compressed)
{
boolean status;
status = bitmap_decompress(bitmap_data->srcData, bitmap_data->dstData,
bitmap_data->width, bitmap_data->height, bitmap_data->length,
bitmap_data->bpp, bitmap_data->bpp);
if (status != True)
{
printf("Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(bitmap_data->srcData, bitmap_data->dstData,
bitmap_data->width, bitmap_data->height, bitmap_data->bpp);
}
bitmap_data->compressed = False;
bitmap_data->length = length;
}
void xf_gdi_register_update_callbacks(rdpUpdate* update)
{
update->Bitmap = xf_gdi_bitmap_update;
update->Palette = xf_gdi_palette_update;
update->SetBounds = xf_gdi_set_bounds;
update->DstBlt = xf_gdi_dstblt;
@ -1023,7 +952,5 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update)
update->CacheBrush = xf_gdi_cache_brush;
update->SurfaceBits = xf_gdi_surface_bits;
update->BitmapDecompress = xf_gdi_bitmap_decompress;
}

121
client/X11/xf_graphics.c Normal file
View File

@ -0,0 +1,121 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* X11 Graphical Objects
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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.
*/
#include <freerdp/codec/bitmap.h>
#include "xf_graphics.h"
void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
{
uint8* data;
Pixmap pixmap;
XImage* image;
xfInfo* xfi = ((xfContext*) context)->xfi;
pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth);
if (bitmap->data != NULL)
{
data = freerdp_image_convert(bitmap->data, NULL,
bitmap->width, bitmap->height, bitmap->bpp, xfi->bpp, xfi->clrconv);
image = XCreateImage(xfi->display, xfi->visual, xfi->depth,
ZPixmap, 0, (char*) data, bitmap->width, bitmap->height, xfi->scanline_pad, 0);
XPutImage(xfi->display, pixmap, xfi->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height);
if (data != bitmap->data)
xfree(data);
}
((xfBitmap*) bitmap)->pixmap = pixmap;
((xfBitmap*) bitmap)->image = image;
}
void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
if (((xfBitmap*) bitmap)->pixmap != 0)
XFreePixmap(xfi->display, ((xfBitmap*) bitmap)->pixmap);
}
void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap, int x, int y)
{
xfInfo* xfi = ((xfContext*) context)->xfi;
XPutImage(xfi->display, xfi->primary, xfi->gc,
((xfBitmap*) bitmap)->image, 0, 0, x, y, bitmap->width, bitmap->height);
if (xfi->remote_app != True)
XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, bitmap->width, bitmap->height, x, y);
gdi_InvalidateRegion(xfi->hdc, x, y, bitmap->width, bitmap->height);
}
void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed)
{
uint16 size;
size = width * height * (bpp / 8);
if (bitmap->data == NULL)
bitmap->data = (uint8*) xmalloc(size);
else
bitmap->data = (uint8*) xrealloc(bitmap->data, size);
if (compressed)
{
boolean status;
status = bitmap_decompress(data, bitmap->data,
width, height, length, bpp, bpp);
if (status != True)
{
printf("Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(data, data, width, height, bpp);
}
bitmap->width = width;
bitmap->height = height;
bitmap->compressed = False;
bitmap->length = size;
bitmap->bpp = bpp;
}
void xf_register_graphics(rdpGraphics* graphics)
{
rdpBitmap bitmap;
memset(&bitmap, 0, sizeof(rdpBitmap));
bitmap.size = sizeof(xfBitmap);
bitmap.New = xf_Bitmap_New;
bitmap.Free = xf_Bitmap_Free;
bitmap.Paint = xf_Bitmap_Paint;
bitmap.Decompress = xf_Bitmap_Decompress;
graphics_register_bitmap(graphics, &bitmap);
}

27
client/X11/xf_graphics.h Normal file
View File

@ -0,0 +1,27 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* X11 Graphical Objects
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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 __XF_GRAPHICS_H
#define __XF_GRAPHICS_H
#include "xfreerdp.h"
void xf_register_graphics(rdpGraphics* graphics);
#endif /* __XF_GRAPHICS_H */

View File

@ -43,6 +43,7 @@
#include <freerdp/codec/nsc.h>
#include <freerdp/codec/rfx.h>
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
#include <freerdp/utils/args.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/semaphore.h>
@ -59,6 +60,7 @@
#include "xf_event.h"
#include "xf_cliprdr.h"
#include "xf_monitor.h"
#include "xf_graphics.h"
#include "xf_keyboard.h"
#include "xfreerdp.h"
@ -252,46 +254,6 @@ 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 = ((xfContext*) update->context)->xfi;
_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 = ((xfContext*) update->context)->xfi;
_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 = ((xfContext*) update->context)->xfi;
@ -302,14 +264,6 @@ void xf_set_surface(rdpUpdate* update, xfBitmap* bitmap, boolean primary)
xfi->drawing = bitmap->pixmap;
}
void xf_bitmap_free(rdpUpdate* update, xfBitmap* bitmap)
{
xfInfo* xfi = ((xfContext*) update->context)->xfi;
if (bitmap->pixmap != 0)
XFreePixmap(xfi->display, bitmap->pixmap);
}
void xf_pointer_size(rdpUpdate* update, uint32* size)
{
*size = sizeof(xfPointer);
@ -736,15 +690,10 @@ boolean xf_post_connect(freerdp* instance)
if (xfi->sw_gdi != True)
{
bitmap_cache_register_callbacks(instance->update);
cache->bitmap->BitmapSize = (cbBitmapSize) xf_bitmap_size;
cache->bitmap->BitmapNew = (cbBitmapNew) xf_bitmap_new;
cache->bitmap->BitmapFree = (cbBitmapFree) xf_bitmap_free;
offscreen_cache_register_callbacks(instance->update);
cache->offscreen->BitmapSize = (cbBitmapSize) xf_bitmap_size;
cache->offscreen->BitmapNew = (cbBitmapNew) xf_offscreen_bitmap_new;
cache->offscreen->BitmapFree = (cbBitmapFree) xf_bitmap_free;
cache->offscreen->SetSurface = (cbSetSurface) xf_set_surface;
xf_register_graphics(instance->context->graphics);
}
instance->context->rail = rail_new(instance->settings);

View File

@ -55,6 +55,7 @@ struct xf_bitmap
{
rdpBitmap bitmap;
Pixmap pixmap;
XImage* image;
};
typedef struct xf_bitmap xfBitmap;
@ -63,7 +64,6 @@ struct xf_context
rdpContext _p;
xfInfo* xfi;
//rdpChannels* channels;
rdpSettings* settings;
};
typedef struct xf_context xfContext;

View File

@ -611,11 +611,11 @@ void test_read_cache_bitmap_v2_order(void)
update_read_cache_bitmap_v2_order(s, &cache_bitmap_v2, True, extraFlags);
CU_ASSERT(cache_bitmap_v2.cacheId == 1);
CU_ASSERT(cache_bitmap_v2.bitmap->bpp == 16);
CU_ASSERT(cache_bitmap_v2.bitmapBpp == 16);
CU_ASSERT(cache_bitmap_v2.flags == 0x19);
CU_ASSERT(cache_bitmap_v2.bitmap->width == 32);
CU_ASSERT(cache_bitmap_v2.bitmap->height == 32);
CU_ASSERT(cache_bitmap_v2.bitmap->length == 220);
CU_ASSERT(cache_bitmap_v2.bitmapWidth == 32);
CU_ASSERT(cache_bitmap_v2.bitmapHeight == 32);
CU_ASSERT(cache_bitmap_v2.bitmapLength == 220);
CU_ASSERT(cache_bitmap_v2.cacheIndex == 32767);
CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_v2_order) - 1));

View File

@ -29,10 +29,6 @@
typedef struct _BITMAP_V2_CELL BITMAP_V2_CELL;
typedef struct rdp_bitmap_cache rdpBitmapCache;
typedef void (*cbBitmapSize)(rdpUpdate* update, uint32* size);
typedef void (*cbBitmapNew)(rdpUpdate* update, rdpBitmap* bitmap);
typedef void (*cbBitmapFree)(rdpUpdate* update, rdpBitmap* bitmap);
#include <freerdp/cache/cache.h>
struct _BITMAP_V2_CELL
@ -45,16 +41,17 @@ struct rdp_bitmap_cache
{
pcMemBlt MemBlt;
pcMem3Blt Mem3Blt;
pcCacheBitmap CacheBitmap;
pcCacheBitmapV2 CacheBitmapV2;
pcCacheBitmapV3 CacheBitmapV3;
cbBitmapSize BitmapSize;
cbBitmapNew BitmapNew;
cbBitmapFree BitmapFree;
pcBitmapUpdate BitmapUpdate;
uint8 maxCells;
rdpBitmap* bitmap;
rdpUpdate* update;
rdpContext* context;
rdpSettings* settings;
BITMAP_V2_CELL* cells;
};

View File

@ -31,7 +31,7 @@ struct _BRUSH_ENTRY
};
typedef struct _BRUSH_ENTRY BRUSH_ENTRY;
struct rdp_brush
struct rdp_brush_cache
{
rdpSettings* settings;
uint8 maxEntries;
@ -39,7 +39,7 @@ struct rdp_brush
BRUSH_ENTRY* entries;
BRUSH_ENTRY* monoEntries;
};
typedef struct rdp_brush rdpBrushCache;
typedef struct rdp_brush_cache rdpBrushCache;
FREERDP_API void* brush_cache_get(rdpBrushCache* brush, uint8 index, uint8* bpp);
FREERDP_API void brush_cache_put(rdpBrushCache* brush, uint8 index, void* entry, uint8 bpp);

View File

@ -33,9 +33,6 @@ typedef void (*cbSetSurface)(rdpUpdate* update, rdpBitmap* bitmap, boolean prima
struct rdp_offscreen_cache
{
cbBitmapSize BitmapSize;
cbBitmapNew BitmapNew;
cbBitmapFree BitmapFree;
cbSetSurface SetSurface;
uint16 currentSurface;

View File

@ -25,6 +25,7 @@ typedef struct rdp_gdi rdpGdi;
typedef struct rdp_rail rdpRail;
typedef struct rdp_cache rdpCache;
typedef struct rdp_channels rdpChannels;
typedef struct rdp_graphics rdpGraphics;
typedef struct rdp_freerdp freerdp;
typedef struct rdp_context rdpContext;
@ -67,8 +68,7 @@ struct rdp_context
rdpRail* rail;
rdpCache* cache;
rdpChannels* channels;
void* reserved[32 - 6];
rdpGraphics* graphics;
};
struct rdp_freerdp

View File

@ -224,6 +224,7 @@ typedef GDI_DC* HGDI_DC;
struct gdi_bitmap
{
rdpBitmap _p;
HGDI_DC hdc;
HGDI_BITMAP bitmap;
HGDI_BITMAP org_bitmap;
@ -258,8 +259,6 @@ 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 gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, uint8* data);
FREERDP_API void gdi_bitmap_free_ex(gdiBitmap* gdi_bmp);
FREERDP_API void gdi_resize(rdpGdi* gdi, int width, int height);
FREERDP_API int gdi_init(freerdp* instance, uint32 flags, uint8* buffer);

View File

@ -0,0 +1,77 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Graphical Objects
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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 __GRAPHICS_H
#define __GRAPHICS_H
typedef struct rdp_bitmap rdpBitmap;
#include <stdlib.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/freerdp.h>
typedef void (*pBitmap_New)(rdpContext* context, rdpBitmap* bitmap);
typedef void (*pBitmap_Free)(rdpContext* context, rdpBitmap* bitmap);
typedef void (*pBitmap_Paint)(rdpContext* context, rdpBitmap* bitmap, int x, int y);
typedef void (*pBitmap_Decompress)(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed);
struct rdp_bitmap
{
size_t size;
pBitmap_New New;
pBitmap_Free Free;
pBitmap_Paint Paint;
pBitmap_Decompress Decompress;
uint16 left;
uint16 top;
uint16 right;
uint16 bottom;
uint16 width;
uint16 height;
uint16 bpp;
uint16 flags;
uint32 length;
uint8* data;
boolean compressed;
};
FREERDP_API rdpBitmap* Bitmap_Alloc(rdpContext* context);
FREERDP_API void Bitmap_New(rdpContext* context, rdpBitmap* bitmap);
FREERDP_API void Bitmap_Free(rdpContext* context, rdpBitmap* bitmap);
FREERDP_API void Bitmap_Register(rdpContext* context, rdpBitmap* bitmap);
FREERDP_API void Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed);
struct rdp_graphics
{
rdpContext* context;
rdpBitmap* Bitmap_Prototype;
};
FREERDP_API void graphics_register_bitmap(rdpGraphics* graphics, rdpBitmap* bitmap);
FREERDP_API rdpGraphics* graphics_new(rdpContext* context);
FREERDP_API void graphics_free(rdpGraphics* graphics);
#endif /* __GRAPHICS_H */

View File

@ -25,6 +25,7 @@ typedef struct rdp_update rdpUpdate;
#include <freerdp/rail.h>
#include <freerdp/types.h>
#include <freerdp/freerdp.h>
#include <freerdp/graphics.h>
#include <freerdp/utils/pcap.h>
#include <freerdp/utils/stream.h>
@ -43,7 +44,7 @@ struct _BOUNDS
};
typedef struct _BOUNDS BOUNDS;
struct _BRUSH
struct rdp_brush
{
uint8 x;
uint8 y;
@ -54,32 +55,43 @@ struct _BRUSH
uint8* data;
uint8 p8x8[8];
};
typedef struct _BRUSH BRUSH;
typedef struct rdp_brush rdpBrush;
struct rdp_glyph
{
sint16 x;
sint16 y;
uint16 cx;
uint16 cy;
uint16 cb;
uint8* aj;
};
typedef struct rdp_glyph rdpGlyph;
/* Bitmap Updates */
struct rdp_bitmap
struct _BITMAP_DATA
{
uint16 left;
uint16 top;
uint16 right;
uint16 bottom;
uint16 destLeft;
uint16 destTop;
uint16 destRight;
uint16 destBottom;
uint16 width;
uint16 height;
uint16 bpp;
uint16 bitsPerPixel;
uint16 flags;
uint32 length;
uint8* srcData;
uint8* dstData;
uint16 bitmapLength;
uint8 bitmapComprHdr[8];
uint8* bitmapDataStream;
boolean compressed;
};
typedef struct rdp_bitmap rdpBitmap;
typedef struct _BITMAP_DATA BITMAP_DATA;
struct _BITMAP_UPDATE
{
uint16 count;
uint16 number;
rdpBitmap* bitmaps;
BITMAP_DATA* bitmaps;
};
typedef struct _BITMAP_UPDATE BITMAP_UPDATE;
@ -179,7 +191,7 @@ struct _PATBLT_ORDER
uint8 bRop;
uint32 backColor;
uint32 foreColor;
BRUSH brush;
rdpBrush brush;
};
typedef struct _PATBLT_ORDER PATBLT_ORDER;
@ -246,7 +258,7 @@ struct _MULTI_PATBLT_ORDER
uint8 bRop;
uint32 backColor;
uint32 foreColor;
BRUSH brush;
rdpBrush brush;
uint8 numRectangles;
uint16 cbData;
DELTA_RECT rectangles[45];
@ -355,7 +367,7 @@ struct _MEM3BLT_ORDER
sint16 nYSrc;
uint32 backColor;
uint32 foreColor;
BRUSH brush;
rdpBrush brush;
uint16 cacheIndex;
rdpBitmap* bitmap;
};
@ -405,7 +417,7 @@ struct _GLYPH_INDEX_ORDER
sint16 opTop;
sint16 opRight;
sint16 opBottom;
BRUSH brush;
rdpBrush brush;
sint16 x;
sint16 y;
uint8 cbFragments;
@ -479,7 +491,7 @@ struct _POLYGON_CB_ORDER
uint8 fillMode;
uint32 backColor;
uint32 foreColor;
BRUSH brush;
rdpBrush brush;
uint8 nDeltaEntries;
uint8 cbData;
uint8* codeDeltaList;
@ -508,7 +520,7 @@ struct _ELLIPSE_CB_ORDER
uint8 fillMode;
uint32 backColor;
uint32 foreColor;
BRUSH brush;
rdpBrush brush;
};
typedef struct _ELLIPSE_CB_ORDER ELLIPSE_CB_ORDER;
@ -533,9 +545,14 @@ struct _CACHE_BITMAP_V2_ORDER
uint16 flags;
uint32 key1;
uint32 key2;
uint8 bitmapBpp;
uint16 bitmapWidth;
uint16 bitmapHeight;
uint32 bitmapLength;
uint16 cacheIndex;
boolean compressed;
uint8 bitmapComprHdr[8];
rdpBitmap* bitmap;
uint8* bitmapDataStream;
};
typedef struct _CACHE_BITMAP_V2_ORDER CACHE_BITMAP_V2_ORDER;
@ -1044,7 +1061,7 @@ typedef void (*pcEndPaint)(rdpUpdate* update);
typedef void (*pcSetBounds)(rdpUpdate* update, BOUNDS* bounds);
typedef void (*pcSynchronize)(rdpUpdate* update);
typedef void (*pcDesktopResize)(rdpUpdate* update);
typedef void (*pcBitmap)(rdpUpdate* update, BITMAP_UPDATE* bitmap);
typedef void (*pcBitmapUpdate)(rdpUpdate* update, BITMAP_UPDATE* bitmap);
typedef void (*pcPalette)(rdpUpdate* update, PALETTE_UPDATE* palette);
typedef void (*pcPlaySound)(rdpUpdate* update, PLAY_SOUND_UPDATE* play_sound);
@ -1112,8 +1129,6 @@ 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, rdpBitmap* bitmap);
struct rdp_update
{
rdpContext* context;
@ -1123,7 +1138,7 @@ struct rdp_update
pcSetBounds SetBounds;
pcSynchronize Synchronize;
pcDesktopResize DesktopResize;
pcBitmap Bitmap;
pcBitmapUpdate BitmapUpdate;
pcPalette Palette;
pcPlaySound PlaySound;
pcPointerPosition PointerPosition;
@ -1190,8 +1205,6 @@ struct rdp_update
pcSurfaceBits SurfaceBits;
pcSurfaceCommand SurfaceCommand;
pcBitmapDecompress BitmapDecompress;
boolean glyph_v2;
boolean dump_rfx;

View File

@ -17,22 +17,12 @@
* limitations under the License.
*/
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/memory.h>
#include <freerdp/cache/bitmap.h>
void bitmap_free(rdpBitmap* bitmap)
{
if (bitmap != NULL)
{
if (bitmap->dstData != NULL)
xfree(bitmap->dstData);
xfree(bitmap);
}
}
void update_gdi_memblt(rdpUpdate* update, MEMBLT_ORDER* memblt)
{
rdpBitmap* bitmap;
@ -65,27 +55,50 @@ void update_gdi_cache_bitmap(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bit
{
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
uint32 size = sizeof(rdpBitmap);
rdpCache* cache = update->context->cache;
bitmap = cache_bitmap->bitmap;
IFCALL(cache->bitmap->BitmapSize, update, &size);
bitmap = (rdpBitmap*) xrealloc(bitmap, size);
bitmap = Bitmap_Alloc(update->context);
IFCALL(cache->bitmap->BitmapNew, update, bitmap);
cache_bitmap->bitmap = bitmap;
bitmap->Decompress(update->context, bitmap,
cache_bitmap->bitmapDataStream, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight,
cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength, cache_bitmap->compressed);
bitmap->New(update->context, 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_Free(update->context, prevBitmap);
bitmap_cache_put(cache->bitmap, cache_bitmap->cacheId, cache_bitmap->cacheIndex, bitmap);
}
void update_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap_update)
{
int i;
rdpBitmap* bitmap;
BITMAP_DATA* bitmap_data;
rdpCache* cache = update->context->cache;
if (cache->bitmap->bitmap == NULL)
cache->bitmap->bitmap = Bitmap_Alloc(update->context);
bitmap = cache->bitmap->bitmap;
for (i = 0; i < bitmap_update->number; i++)
{
bitmap_data = &bitmap_update->bitmaps[i];
bitmap->Decompress(update->context, bitmap,
bitmap_data->bitmapDataStream, bitmap_data->width, bitmap_data->height,
bitmap_data->bitsPerPixel, bitmap_data->bitmapLength, bitmap_data->compressed);
bitmap->New(update->context, bitmap);
bitmap->Paint(update->context, bitmap, bitmap_data->destLeft, bitmap_data->destTop);
}
}
rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmap_cache, uint8 id, uint16 index)
{
rdpBitmap* bitmap;
@ -140,6 +153,7 @@ void bitmap_cache_register_callbacks(rdpUpdate* update)
update->MemBlt = update_gdi_memblt;
update->Mem3Blt = update_gdi_mem3blt;
update->CacheBitmapV2 = update_gdi_cache_bitmap;
update->BitmapUpdate = update_gdi_bitmap_update;
}
rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
@ -153,6 +167,7 @@ rdpBitmapCache* bitmap_cache_new(rdpSettings* settings)
{
bitmap_cache->settings = settings;
bitmap_cache->update = ((freerdp*) settings->instance)->update;
bitmap_cache->context = bitmap_cache->update->context;
bitmap_cache->maxCells = 5;
@ -196,14 +211,15 @@ void bitmap_cache_free(rdpBitmapCache* bitmap_cache)
if (bitmap != NULL)
{
IFCALL(bitmap_cache->BitmapFree, bitmap_cache->update, bitmap);
bitmap_free(bitmap);
Bitmap_Free(bitmap_cache->context, bitmap);
}
}
xfree(bitmap_cache->cells[i].entries);
}
bitmap_cache->bitmap->Free(bitmap_cache->context, bitmap);
xfree(bitmap_cache->cells);
xfree(bitmap_cache);
}

View File

@ -26,23 +26,19 @@ void update_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITM
{
rdpBitmap* bitmap;
rdpBitmap* prevBitmap;
uint32 size = sizeof(rdpBitmap);
rdpCache* cache = update->context->cache;
IFCALL(cache->offscreen->BitmapSize, update, &size);
bitmap = (rdpBitmap*) xzalloc(size);
bitmap = Bitmap_Alloc(update->context);
bitmap->width = create_offscreen_bitmap->cx;
bitmap->height = create_offscreen_bitmap->cy;
IFCALL(cache->offscreen->BitmapNew, update, bitmap);
bitmap->New(update->context, bitmap);
prevBitmap = offscreen_cache_get(cache->offscreen, create_offscreen_bitmap->id);
if (prevBitmap != NULL)
{
IFCALL(cache->offscreen->BitmapFree, update, prevBitmap);
bitmap_free(prevBitmap);
}
Bitmap_Free(update->context, prevBitmap);
offscreen_cache_put(cache->offscreen, create_offscreen_bitmap->id, bitmap);
@ -141,10 +137,7 @@ void offscreen_cache_free(rdpOffscreenCache* offscreen_cache)
bitmap = offscreen_cache->entries[i];
if (bitmap != NULL)
{
IFCALL(offscreen_cache->BitmapFree, offscreen_cache->update, bitmap);
bitmap_free(bitmap);
}
Bitmap_Free(offscreen_cache->update->context, bitmap);
}
xfree(offscreen_cache->entries);

View File

@ -52,6 +52,7 @@ set(LIBFREERDP_CORE_SRCS
orders.c
orders.h
freerdp.c
graphics.c
capabilities.c
capabilities.h
certificate.c

View File

@ -150,7 +150,7 @@ static void fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s)
{
case UPDATE_TYPE_BITMAP:
update_read_bitmap(update, s, &update->bitmap_update);
IFCALL(update->Bitmap, update, &update->bitmap_update);
IFCALL(update->BitmapUpdate, update, &update->bitmap_update);
break;
case UPDATE_TYPE_PALETTE:

View File

@ -136,6 +136,7 @@ void freerdp_context_new(freerdp* instance)
IFCALL(instance->ContextSize, instance, &size);
instance->context = (rdpContext*) xzalloc(size);
instance->context->graphics = graphics_new(instance->context);
instance->context->instance = instance;
instance->context->rdp = rdp;

View File

@ -0,0 +1,96 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Graphical Objects
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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.
*/
#include <freerdp/utils/memory.h>
#include <freerdp/graphics.h>
rdpBitmap* Bitmap_Alloc(rdpContext* context)
{
rdpBitmap* bitmap;
rdpGraphics* graphics;
graphics = context->graphics;
bitmap = (rdpBitmap*) xmalloc(graphics->Bitmap_Prototype->size);
if (bitmap != NULL)
{
memcpy(bitmap, context->graphics->Bitmap_Prototype, sizeof(rdpBitmap));
}
return bitmap;
}
void Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
{
}
void Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed)
{
bitmap->Decompress(context, bitmap, data, width, height, bpp, length, compressed);
}
void Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap, int x, int y)
{
bitmap->Paint(context, bitmap, x, y);
}
void Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
{
if (bitmap != NULL)
{
if (bitmap->data != NULL)
xfree(bitmap->data);
xfree(bitmap);
}
}
void graphics_register_bitmap(rdpGraphics* graphics, rdpBitmap* bitmap)
{
memcpy(graphics->Bitmap_Prototype, bitmap, sizeof(rdpBitmap));
}
rdpGraphics* graphics_new(rdpContext* context)
{
rdpGraphics* graphics;
graphics = (rdpGraphics*) xzalloc(sizeof(rdpGraphics));
if (graphics != NULL)
{
graphics->Bitmap_Prototype = (rdpBitmap*) xmalloc(sizeof(rdpBitmap));
graphics->Bitmap_Prototype->size = sizeof(rdpBitmap);
graphics->Bitmap_Prototype->New = Bitmap_New;
graphics->Bitmap_Prototype->Free = Bitmap_Free;
}
return graphics;
}
void graphics_free(rdpGraphics* graphics)
{
if (graphics != NULL)
{
xfree(graphics->Bitmap_Prototype);
xfree(graphics);
}
}

View File

@ -19,6 +19,7 @@
#include "window.h"
#include <freerdp/api.h>
#include <freerdp/graphics.h>
#include <freerdp/codec/bitmap.h>
#include "orders.h"
@ -309,7 +310,7 @@ INLINE void update_seek_glyph_delta(STREAM* s)
stream_seek_uint8(s);
}
INLINE void update_read_brush(STREAM* s, BRUSH* brush, uint8 fieldFlags)
INLINE void update_read_brush(STREAM* s, rdpBrush* brush, uint8 fieldFlags)
{
if (fieldFlags & ORDER_FIELD_01)
stream_read_uint8(s, brush->x);
@ -1393,16 +1394,12 @@ 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;
rdpBitmap* bitmap;
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->bpp = CBR2_BPP[bitsPerPixelId];
cache_bitmap_v2_order->bitmapBpp = CBR2_BPP[bitsPerPixelId];
if (cache_bitmap_v2_order->flags & CBR2_PERSISTENT_KEY_PRESENT)
{
@ -1412,36 +1409,36 @@ 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->width); /* bitmapWidth */
bitmap->height = bitmap->width;
update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapWidth); /* bitmapWidth */
cache_bitmap_v2_order->bitmapHeight = cache_bitmap_v2_order->bitmapWidth;
}
else
{
update_read_2byte_unsigned(s, &bitmap->width); /* bitmapWidth */
update_read_2byte_unsigned(s, &bitmap->height); /* bitmapHeight */
update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapWidth); /* bitmapWidth */
update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapHeight); /* bitmapHeight */
}
update_read_4byte_unsigned(s, &bitmap->length); /* bitmapLength */
update_read_4byte_unsigned(s, &cache_bitmap_v2_order->bitmapLength); /* bitmapLength */
update_read_2byte_unsigned(s, &cache_bitmap_v2_order->cacheIndex); /* cacheIndex */
if (compressed)
{
if ((cache_bitmap_v2_order->flags & CBR2_NO_BITMAP_COMPRESSION_HDR) == 0)
{
uint8* bitmapComprHdr = (uint8*) &(cache_bitmap_v2_order->bitmapComprHdr);
uint8* bitmapComprHdr = (uint8*) &cache_bitmap_v2_order->bitmapComprHdr;
stream_read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */
bitmap->length -= 8;
cache_bitmap_v2_order->bitmapLength -= 8;
}
stream_get_mark(s, bitmap->srcData);
stream_seek(s, bitmap->length);
bitmap->compressed = True;
stream_get_mark(s, cache_bitmap_v2_order->bitmapDataStream);
stream_seek(s, cache_bitmap_v2_order->bitmapLength);
cache_bitmap_v2_order->compressed = True;
}
else
{
stream_get_mark(s, bitmap->srcData);
stream_seek(s, bitmap->length);
bitmap->compressed = False;
stream_get_mark(s, cache_bitmap_v2_order->bitmapDataStream);
stream_seek(s, cache_bitmap_v2_order->bitmapLength);
cache_bitmap_v2_order->compressed = False;
}
}
@ -2019,13 +2016,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);
//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);
//IFCALL(update->BitmapDecompress, update, update->cache_bitmap_v2_order.bitmap);
IFCALL(update->CacheBitmapV2, update, &(update->cache_bitmap_v2_order));
break;

View File

@ -232,4 +232,6 @@ void update_read_draw_gdiplus_cache_first_order(STREAM* s, DRAW_GDIPLUS_CACHE_FI
void update_read_draw_gdiplus_cache_next_order(STREAM* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next);
void update_read_draw_gdiplus_cache_end_order(STREAM* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end);
#define WITH_DEBUG_ORDERS 1
#endif /* __ORDERS_H */

View File

@ -44,21 +44,21 @@ void update_recv_orders(rdpUpdate* update, STREAM* s)
}
}
void update_read_bitmap_data(STREAM* s, rdpBitmap* bitmap_data)
void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
{
uint16 bytesPerPixel;
stream_read_uint16(s, bitmap_data->left);
stream_read_uint16(s, bitmap_data->top);
stream_read_uint16(s, bitmap_data->right);
stream_read_uint16(s, bitmap_data->bottom);
stream_read_uint16(s, bitmap_data->destLeft);
stream_read_uint16(s, bitmap_data->destTop);
stream_read_uint16(s, bitmap_data->destRight);
stream_read_uint16(s, bitmap_data->destBottom);
stream_read_uint16(s, bitmap_data->width);
stream_read_uint16(s, bitmap_data->height);
stream_read_uint16(s, bitmap_data->bpp);
stream_read_uint16(s, bitmap_data->bitsPerPixel);
stream_read_uint16(s, bitmap_data->flags);
stream_read_uint16(s, bitmap_data->length);
stream_read_uint16(s, bitmap_data->bitmapLength);
bytesPerPixel = (bitmap_data->bpp + 7) / 8;
bytesPerPixel = (bitmap_data->bitsPerPixel + 7) / 8;
if (bitmap_data->flags & BITMAP_COMPRESSION)
{
@ -70,17 +70,17 @@ void update_read_bitmap_data(STREAM* s, rdpBitmap* bitmap_data)
stream_seek_uint16(s); /* cbScanWidth (2 bytes) */
stream_read_uint16(s, cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
bitmap_data->length = cbCompMainBodySize;
bitmap_data->bitmapLength = cbCompMainBodySize;
bitmap_data->compressed = True;
stream_get_mark(s, bitmap_data->srcData);
stream_seek(s, bitmap_data->length);
stream_get_mark(s, bitmap_data->bitmapDataStream);
stream_seek(s, bitmap_data->bitmapLength);
}
else
{
bitmap_data->compressed = False;
stream_get_mark(s, bitmap_data->srcData);
stream_seek(s, bitmap_data->length);
stream_get_mark(s, bitmap_data->bitmapDataStream);
stream_seek(s, bitmap_data->bitmapLength);
}
}
@ -96,11 +96,11 @@ void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_upda
count = bitmap_update->number * 2;
bitmap_update->bitmaps = (rdpBitmap*) xrealloc(bitmap_update->bitmaps,
sizeof(rdpBitmap) * count);
bitmap_update->bitmaps = (BITMAP_DATA*) xrealloc(bitmap_update->bitmaps,
sizeof(BITMAP_DATA) * count);
memset(&bitmap_update->bitmaps[bitmap_update->count], 0,
sizeof(rdpBitmap) * (count - bitmap_update->count));
sizeof(BITMAP_DATA) * (count - bitmap_update->count));
bitmap_update->count = count;
}
@ -109,7 +109,6 @@ void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_upda
for (i = 0; i < bitmap_update->number; i++)
{
update_read_bitmap_data(s, &bitmap_update->bitmaps[i]);
IFCALL(update->BitmapDecompress, update, &bitmap_update->bitmaps[i]);
}
}
@ -264,7 +263,7 @@ void update_recv(rdpUpdate* update, STREAM* s)
case UPDATE_TYPE_BITMAP:
update_read_bitmap(update, s, &update->bitmap_update);
IFCALL(update->Bitmap, update, &update->bitmap_update);
IFCALL(update->BitmapUpdate, update, &update->bitmap_update);
break;
case UPDATE_TYPE_PALETTE:
@ -407,7 +406,7 @@ rdpUpdate* update_new(rdpRdp* rdp)
if (update != NULL)
{
update->bitmap_update.count = 64;
update->bitmap_update.bitmaps = (rdpBitmap*) xzalloc(sizeof(rdpBitmap) * update->bitmap_update.count);
update->bitmap_update.bitmaps = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA) * update->bitmap_update.count);
}
return update;
@ -417,19 +416,7 @@ void update_free(rdpUpdate* update)
{
if (update != NULL)
{
uint16 i;
rdpBitmap* bitmaps;
BITMAP_UPDATE* bitmap_update;
bitmap_update = &update->bitmap_update;
bitmaps = update->bitmap_update.bitmaps;
for (i = 0; i < bitmap_update->count; i++)
{
if (bitmaps[i].dstData != NULL)
xfree(bitmaps[i].dstData);
}
xfree(update->bitmap_update.bitmaps);
xfree(update);
}
}

View File

@ -31,7 +31,10 @@ set(FREERDP_GDI_SRCS
pen.c
region.c
shape.c
gdi.c)
graphics.c
graphics.h
gdi.c
gdi.h)
add_library(freerdp-gdi ${FREERDP_GDI_SRCS})

View File

@ -23,6 +23,7 @@
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/bitmap.h>
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
@ -42,6 +43,8 @@
#include <freerdp/gdi/gdi.h>
#include "gdi.h"
/* Ternary Raster Operation Table */
const uint32 rop3_code_table[] =
{
@ -363,87 +366,6 @@ INLINE int gdi_is_mono_pixel_set(uint8* data, int x, int y, int width)
return (data[byte] & (0x80 >> shift)) != 0;
}
HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8* data)
{
uint8* bmpData;
HGDI_BITMAP bitmap;
bmpData = freerdp_image_convert(data, NULL, width, height, gdi->srcBpp, bpp, gdi->clrconv);
bitmap = gdi_CreateBitmap(width, height, gdi->dstBpp, bmpData);
return bitmap;
}
gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, uint8* data)
{
gdiBitmap* bitmap;
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)
bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, width, height);
else
bitmap->bitmap = gdi_create_bitmap(gdi, width, height, bpp, data);
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->bitmap);
bitmap->org_bitmap = NULL;
return bitmap;
}
void gdi_bitmap_free_ex(gdiBitmap* bitmap)
{
if (bitmap != NULL)
{
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->org_bitmap);
gdi_DeleteObject((HGDIOBJECT) bitmap->bitmap);
gdi_DeleteDC(bitmap->hdc);
free(bitmap);
}
}
void gdi_bitmap_size(rdpUpdate* update, uint32* size)
{
*size = sizeof(gdiBitmap);
}
void gdi_bitmap_new(rdpUpdate* update, gdiBitmap* bitmap)
{
uint8* data;
rdpBitmap* _bitmap;
rdpGdi* gdi = update->context->gdi;
_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;
rdpGdi* gdi = update->context->gdi;
_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)
{
rdpGdi* gdi = update->context->gdi;
@ -454,16 +376,6 @@ void gdi_set_surface(rdpUpdate* update, gdiBitmap* bitmap, boolean primary)
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(rdpGdi* gdi, GLYPH_DATA* glyph)
{
uint8* extra;
@ -497,24 +409,34 @@ void gdi_glyph_free(gdiBitmap *gdi_bmp)
}
}
void gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap)
gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, uint8* data)
{
int i;
rdpBitmap* bmp;
gdiBitmap* gdi_bmp;
rdpGdi* gdi = update->context->gdi;
gdiBitmap* bitmap;
for (i = 0; i < bitmap->number; i++)
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)
bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, width, height);
else
bitmap->bitmap = gdi_create_bitmap(gdi, width, height, bpp, data);
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->bitmap);
bitmap->org_bitmap = NULL;
return bitmap;
}
void gdi_bitmap_free_ex(gdiBitmap* bitmap)
{
if (bitmap != NULL)
{
bmp = &bitmap->bitmaps[i];
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_ex((gdiBitmap*) gdi_bmp);
gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->org_bitmap);
gdi_DeleteObject((HGDIOBJECT) bitmap->bitmap);
gdi_DeleteDC(bitmap->hdc);
free(bitmap);
}
}
@ -549,7 +471,7 @@ void gdi_dstblt(rdpUpdate* update, DSTBLT_ORDER* dstblt)
void gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt)
{
uint8* data;
BRUSH* brush;
rdpBrush* brush;
HGDI_BRUSH originalBrush;
rdpGdi* gdi = update->context->gdi;
rdpCache* cache = update->context->cache;
@ -989,40 +911,6 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm
xfree(tile_bitmap);
}
void gdi_bitmap_decompress(rdpUpdate* update, rdpBitmap* bitmap_data)
{
uint16 length;
length = bitmap_data->width * bitmap_data->height * (bitmap_data->bpp / 8);
if (bitmap_data->dstData == NULL)
bitmap_data->dstData = (uint8*) xmalloc(length);
else
bitmap_data->dstData = (uint8*) xrealloc(bitmap_data->dstData, length);
if (bitmap_data->compressed)
{
boolean status;
status = bitmap_decompress(bitmap_data->srcData, bitmap_data->dstData,
bitmap_data->width, bitmap_data->height, bitmap_data->length,
bitmap_data->bpp, bitmap_data->bpp);
if (status != True)
{
printf("Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(bitmap_data->srcData, bitmap_data->dstData,
bitmap_data->width, bitmap_data->height, bitmap_data->bpp);
}
bitmap_data->compressed = False;
bitmap_data->length = length;
}
/**
* Register GDI callbacks with libfreerdp-core.
* @param inst current instance
@ -1031,7 +919,6 @@ void gdi_bitmap_decompress(rdpUpdate* update, rdpBitmap* bitmap_data)
void gdi_register_update_callbacks(rdpUpdate* update)
{
update->Bitmap = gdi_bitmap_update;
update->Palette = gdi_palette_update;
update->SetBounds = gdi_set_bounds;
update->DstBlt = gdi_dstblt;
@ -1063,7 +950,6 @@ void gdi_register_update_callbacks(rdpUpdate* update)
update->CacheBrush = gdi_cache_brush;
update->SurfaceBits = gdi_surface_bits;
update->BitmapDecompress = gdi_bitmap_decompress;
}
void gdi_init_primary(rdpGdi* gdi)
@ -1186,14 +1072,9 @@ int gdi_init(freerdp* instance, uint32 flags, uint8* buffer)
gdi_register_update_callbacks(instance->update);
bitmap_cache_register_callbacks(instance->update);
cache->bitmap->BitmapSize = (cbBitmapSize) gdi_bitmap_size;
cache->bitmap->BitmapNew = (cbBitmapNew) gdi_bitmap_new;
cache->bitmap->BitmapFree = (cbBitmapFree) gdi_bitmap_free;
gdi_register_graphics(instance->context->graphics);
offscreen_cache_register_callbacks(instance->update);
cache->offscreen->BitmapSize = (cbBitmapSize) gdi_bitmap_size;
cache->offscreen->BitmapNew = (cbBitmapNew) gdi_offscreen_bitmap_new;
cache->offscreen->BitmapFree = (cbBitmapFree) gdi_bitmap_free;
cache->offscreen->SetSurface = (cbSetSurface) gdi_set_surface;
gdi->rfx_context = rfx_context_new();

28
libfreerdp-gdi/gdi.h Normal file
View File

@ -0,0 +1,28 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* GDI Library
*
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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 __GDI_CORE_H
#define __GDI_CORE_H
#include "graphics.h"
gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, uint8* data);
void gdi_bitmap_free_ex(gdiBitmap* gdi_bmp);
#endif /* __GDI_CORE_H */

128
libfreerdp-gdi/graphics.c Normal file
View File

@ -0,0 +1,128 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Graphical Objects
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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.
*/
#include <freerdp/gdi/dc.h>
#include <freerdp/gdi/bitmap.h>
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
#include <freerdp/utils/memory.h>
#include <freerdp/codec/bitmap.h>
#include "graphics.h"
HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8* data)
{
uint8* bmpData;
HGDI_BITMAP bitmap;
bmpData = freerdp_image_convert(data, NULL, width, height, gdi->srcBpp, bpp, gdi->clrconv);
bitmap = gdi_CreateBitmap(width, height, gdi->dstBpp, bmpData);
return bitmap;
}
void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
{
gdiBitmap* gdi_bitmap;
rdpGdi* gdi = context->gdi;
gdi_bitmap = (gdiBitmap*) bitmap;
gdi_bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc);
if (bitmap->data == NULL)
gdi_bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, bitmap->width, bitmap->height);
else
gdi_bitmap->bitmap = gdi_create_bitmap(gdi, bitmap->width, bitmap->height, gdi->dstBpp, bitmap->data);
gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT) gdi_bitmap->bitmap);
gdi_bitmap->org_bitmap = NULL;
}
void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
{
gdiBitmap* gdi_bitmap = (gdiBitmap*) bitmap;
if (gdi_bitmap != NULL)
{
gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT) gdi_bitmap->org_bitmap);
gdi_DeleteObject((HGDIOBJECT) gdi_bitmap->bitmap);
gdi_DeleteDC(gdi_bitmap->hdc);
}
}
void gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap, int x, int y)
{
gdiBitmap* gdi_bitmap = (gdiBitmap*) bitmap;
gdi_BitBlt(context->gdi->primary->hdc, x, y,
bitmap->width, bitmap->height,
gdi_bitmap->hdc, 0, 0, GDI_SRCCOPY);
}
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed)
{
uint16 size;
size = width * height * (bpp / 8);
if (bitmap->data == NULL)
bitmap->data = (uint8*) xmalloc(size);
else
bitmap->data = (uint8*) xrealloc(bitmap->data, size);
if (compressed)
{
boolean status;
status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp);
if (status != True)
{
printf("Bitmap Decompression Failed\n");
}
}
else
{
freerdp_image_flip(data, bitmap->data, width, height, bpp);
}
bitmap->width = width;
bitmap->height = height;
bitmap->compressed = False;
bitmap->length = size;
bitmap->bpp = bpp;
}
void gdi_register_graphics(rdpGraphics* graphics)
{
rdpBitmap bitmap;
memset(&bitmap, 0, sizeof(rdpBitmap));
bitmap.size = sizeof(gdiBitmap);
bitmap.New = gdi_Bitmap_New;
bitmap.Free = gdi_Bitmap_Free;
bitmap.Paint = gdi_Bitmap_Paint;
bitmap.Decompress = gdi_Bitmap_Decompress;
graphics_register_bitmap(graphics, &bitmap);
}

34
libfreerdp-gdi/graphics.h Normal file
View File

@ -0,0 +1,34 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Graphical Objects
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* 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 __GDI_GRAPHICS_H
#define __GDI_GRAPHICS_H
#include <freerdp/gdi/gdi.h>
#include <freerdp/graphics.h>
HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8* data);
void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap);
void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap);
void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
uint8* data, int width, int height, int bpp, int length, boolean compressed);
void gdi_register_graphics(rdpGraphics* graphics);
#endif /* __GDI_GRAPHICS_H */