From b7e70671761a9e368698aad354f950e91d37892c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 20 Oct 2011 17:28:59 -0400 Subject: [PATCH] libfreerdp-core: refactoring of core bitmap objects --- .gitignore | 2 +- client/Windows/wf_gdi.c | 2 +- client/X11/CMakeLists.txt | 10 +- client/X11/xf_gdi.c | 77 +------------ client/X11/xf_graphics.c | 121 ++++++++++++++++++++ client/X11/xf_graphics.h | 27 +++++ client/X11/xfreerdp.c | 59 +--------- client/X11/xfreerdp.h | 2 +- cunit/test_orders.c | 8 +- include/freerdp/cache/bitmap.h | 11 +- include/freerdp/cache/brush.h | 4 +- include/freerdp/cache/offscreen.h | 3 - include/freerdp/freerdp.h | 4 +- include/freerdp/gdi/gdi.h | 3 +- include/freerdp/graphics.h | 77 +++++++++++++ include/freerdp/update.h | 65 ++++++----- libfreerdp-cache/bitmap.c | 62 +++++++---- libfreerdp-cache/offscreen.c | 17 +-- libfreerdp-core/CMakeLists.txt | 1 + libfreerdp-core/fastpath.c | 2 +- libfreerdp-core/freerdp.c | 1 + libfreerdp-core/graphics.c | 96 ++++++++++++++++ libfreerdp-core/orders.c | 39 +++---- libfreerdp-core/orders.h | 2 + libfreerdp-core/update.c | 51 ++++----- libfreerdp-gdi/CMakeLists.txt | 5 +- libfreerdp-gdi/gdi.c | 179 +++++------------------------- libfreerdp-gdi/gdi.h | 28 +++++ libfreerdp-gdi/graphics.c | 128 +++++++++++++++++++++ libfreerdp-gdi/graphics.h | 34 ++++++ 30 files changed, 698 insertions(+), 422 deletions(-) create mode 100644 client/X11/xf_graphics.c create mode 100644 client/X11/xf_graphics.h create mode 100644 include/freerdp/graphics.h create mode 100644 libfreerdp-core/graphics.c create mode 100644 libfreerdp-gdi/gdi.h create mode 100644 libfreerdp-gdi/graphics.c create mode 100644 libfreerdp-gdi/graphics.h diff --git a/.gitignore b/.gitignore index 2735a4bdb..c0e27708d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # CMake -cmake_install.cmake +*.cmake CMakeFiles/ CMakeCache.txt config.h diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index 90f89797e..446ff3415 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -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; diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index 2d4795f68..d770bfab0 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -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 diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 020c7adea..49bb910f8 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -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; } diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c new file mode 100644 index 000000000..4bd45e84f --- /dev/null +++ b/client/X11/xf_graphics.c @@ -0,0 +1,121 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 + +#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); +} diff --git a/client/X11/xf_graphics.h b/client/X11/xf_graphics.h new file mode 100644 index 000000000..14216f330 --- /dev/null +++ b/client/X11/xf_graphics.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 */ diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index ddd7523f3..a63e033ad 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 56c782f68..748e8a681 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -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; diff --git a/cunit/test_orders.c b/cunit/test_orders.c index b6d13c1e9..c05c08f33 100644 --- a/cunit/test_orders.c +++ b/cunit/test_orders.c @@ -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)); diff --git a/include/freerdp/cache/bitmap.h b/include/freerdp/cache/bitmap.h index fb6e5d1a6..b57d43bd4 100644 --- a/include/freerdp/cache/bitmap.h +++ b/include/freerdp/cache/bitmap.h @@ -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 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; }; diff --git a/include/freerdp/cache/brush.h b/include/freerdp/cache/brush.h index 767f3c22d..2d53bb5aa 100644 --- a/include/freerdp/cache/brush.h +++ b/include/freerdp/cache/brush.h @@ -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); diff --git a/include/freerdp/cache/offscreen.h b/include/freerdp/cache/offscreen.h index dac478a97..22058f055 100644 --- a/include/freerdp/cache/offscreen.h +++ b/include/freerdp/cache/offscreen.h @@ -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; diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index 7f370257d..e061a3f96 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -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 diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index 49840e43a..1970d6909 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -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); diff --git a/include/freerdp/graphics.h b/include/freerdp/graphics.h new file mode 100644 index 000000000..771048a40 --- /dev/null +++ b/include/freerdp/graphics.h @@ -0,0 +1,77 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 +#include +#include +#include + +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 */ diff --git a/include/freerdp/update.h b/include/freerdp/update.h index dc4edee8c..cf52b63fd 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -25,6 +25,7 @@ typedef struct rdp_update rdpUpdate; #include #include #include +#include #include #include @@ -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; diff --git a/libfreerdp-cache/bitmap.c b/libfreerdp-cache/bitmap.c index de8f0b512..7eeeb85e2 100644 --- a/libfreerdp-cache/bitmap.c +++ b/libfreerdp-cache/bitmap.c @@ -17,22 +17,12 @@ * limitations under the License. */ +#include #include #include #include -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); } diff --git a/libfreerdp-cache/offscreen.c b/libfreerdp-cache/offscreen.c index 2fdabd562..701c6a878 100644 --- a/libfreerdp-cache/offscreen.c +++ b/libfreerdp-cache/offscreen.c @@ -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); diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index 84d1a3796..e0d326e36 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -52,6 +52,7 @@ set(LIBFREERDP_CORE_SRCS orders.c orders.h freerdp.c + graphics.c capabilities.c capabilities.h certificate.c diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c index 73d476322..cfef247b6 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp-core/fastpath.c @@ -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: diff --git a/libfreerdp-core/freerdp.c b/libfreerdp-core/freerdp.c index a23da105a..4f599d9b6 100644 --- a/libfreerdp-core/freerdp.c +++ b/libfreerdp-core/freerdp.c @@ -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; diff --git a/libfreerdp-core/graphics.c b/libfreerdp-core/graphics.c new file mode 100644 index 000000000..d6db1c882 --- /dev/null +++ b/libfreerdp-core/graphics.c @@ -0,0 +1,96 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 + +#include + +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); + } +} diff --git a/libfreerdp-core/orders.c b/libfreerdp-core/orders.c index f8064b403..0e17bafb0 100644 --- a/libfreerdp-core/orders.c +++ b/libfreerdp-core/orders.c @@ -19,6 +19,7 @@ #include "window.h" #include +#include #include #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; diff --git a/libfreerdp-core/orders.h b/libfreerdp-core/orders.h index 89ed2b3f5..91d6ccf0a 100644 --- a/libfreerdp-core/orders.h +++ b/libfreerdp-core/orders.h @@ -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 */ diff --git a/libfreerdp-core/update.c b/libfreerdp-core/update.c index 7983488ec..a88ddd179 100644 --- a/libfreerdp-core/update.c +++ b/libfreerdp-core/update.c @@ -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); } } diff --git a/libfreerdp-gdi/CMakeLists.txt b/libfreerdp-gdi/CMakeLists.txt index e8699ddc1..b6c9d3a38 100644 --- a/libfreerdp-gdi/CMakeLists.txt +++ b/libfreerdp-gdi/CMakeLists.txt @@ -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}) diff --git a/libfreerdp-gdi/gdi.c b/libfreerdp-gdi/gdi.c index cfddd27ed..7ef531aef 100644 --- a/libfreerdp-gdi/gdi.c +++ b/libfreerdp-gdi/gdi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,8 @@ #include +#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(); diff --git a/libfreerdp-gdi/gdi.h b/libfreerdp-gdi/gdi.h new file mode 100644 index 000000000..99fa73683 --- /dev/null +++ b/libfreerdp-gdi/gdi.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Library + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * 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 */ diff --git a/libfreerdp-gdi/graphics.c b/libfreerdp-gdi/graphics.c new file mode 100644 index 000000000..c7b6182d3 --- /dev/null +++ b/libfreerdp-gdi/graphics.c @@ -0,0 +1,128 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 +#include +#include +#include +#include +#include + +#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); +} + diff --git a/libfreerdp-gdi/graphics.h b/libfreerdp-gdi/graphics.h new file mode 100644 index 000000000..3940a44be --- /dev/null +++ b/libfreerdp-gdi/graphics.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 +#include + +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 */