From a758908c630d9cb21bbab0c19a512eccc96a8e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 4 Oct 2011 16:05:09 -0400 Subject: [PATCH] wfreerdp: start GDI implementation --- client/Windows/wf_gdi.c | 351 +++++++++++++++++++++++++++++++++- client/Windows/wf_gdi.h | 2 + client/Windows/wfreerdp.c | 122 ++++++++++-- client/Windows/wfreerdp.h | 11 +- include/freerdp/codec/color.h | 3 +- include/freerdp/gdi/gdi.h | 2 +- libfreerdp-gdi/gdi.c | 19 +- libfreerdp-utils/stream.c | 6 +- 8 files changed, 492 insertions(+), 24 deletions(-) diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index 791c8c507..cb8695af5 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -26,9 +26,43 @@ #include #include +#include #include "wfreerdp.h" +const uint8 wf_rop2_table[] = +{ + R2_BLACK, /* 0 */ + R2_NOTMERGEPEN, /* DPon */ + R2_MASKNOTPEN, /* DPna */ + R2_NOTCOPYPEN, /* Pn */ + R2_MASKPENNOT, /* PDna */ + R2_NOT, /* Dn */ + R2_XORPEN, /* DPx */ + R2_NOTMASKPEN, /* DPan */ + R2_MASKPEN, /* DPa */ + R2_NOTXORPEN, /* DPxn */ + R2_NOP, /* D */ + R2_MERGENOTPEN, /* DPno */ + R2_COPYPEN, /* P */ + R2_MERGEPENNOT, /* PDno */ + R2_MERGEPEN, /* PDo */ + R2_WHITE, /* 1 */ +}; + +boolean wf_set_rop2(HDC hdc, int rop2) +{ + if ((rop2 < 0x01) || (rop2 > 0x10)) + { + printf("Unsupported ROP2: %d\n", rop2); + return False; + } + + SetROP2(hdc, wf_rop2_table[rop2 - 1]); + + return True; +} + HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data) { HDC hdc; @@ -53,7 +87,7 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data) bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; - bitmap = CreateDIBSection (hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); + bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); if (data != NULL) freerdp_image_convert(data, cdata, width, height, bpp, 24, wfi->clrconv); @@ -95,9 +129,324 @@ void wf_image_free(WF_IMAGE* image) } } +WF_IMAGE* wf_glyph_new(wfInfo* wfi, GLYPH_DATA* glyph) +{ + WF_IMAGE* glyph_bmp; + glyph_bmp = wf_image_new(wfi, glyph->cx, glyph->cy, 1, glyph->aj); + return glyph_bmp; +} + +void wf_glyph_free(WF_IMAGE* glyph) +{ + wf_image_free(glyph); +} + +void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height) +{ + RECT update_rect; + update_rect.left = x; + update_rect.top = y; + update_rect.right = x + width; + update_rect.bottom = y + height; + InvalidateRect(wfi->hwnd, &update_rect, FALSE); + + gdi_InvalidateRegion(wfi->hdc, x, y, width, height); +} + void wf_toggle_fullscreen(wfInfo* wfi) { ShowWindow(wfi->hwnd, SW_HIDE); wfi->fullscreen = !wfi->fullscreen; SetForegroundWindow(wfi->hwnd); } + +void wf_gdi_bitmap_update(rdpUpdate* update, BITMAP_UPDATE* bitmap) +{ + int i; + BITMAP_DATA* bmp; + WF_IMAGE* wf_bmp; + + wfInfo* wfi = GET_WFI(update); + + for (i = 0; i < bitmap->number; i++) + { + bmp = &bitmap->bitmaps[i]; + + wf_bmp = wf_image_new(wfi, bmp->width, bmp->height, wfi->dstBpp, bmp->dstData); + + BitBlt(wfi->primary->hdc, + bmp->left, bmp->top, bmp->right - bmp->left + 1, + bmp->bottom - bmp->top + 1, wf_bmp->hdc, 0, 0, GDI_SRCCOPY); + + wf_invalidate_region(wfi, bmp->left, bmp->top, bmp->right - bmp->left + 1, bmp->bottom - bmp->top + 1); + + wf_image_free(wf_bmp); + } +} + +void wf_gdi_palette_update(rdpUpdate* update, PALETTE_UPDATE* palette) +{ + +} + +void wf_gdi_set_bounds(rdpUpdate* update, BOUNDS* bounds) +{ + HRGN hrgn; + wfInfo* wfi = GET_WFI(update); + + if (bounds != NULL) + { + hrgn = CreateRectRgn(bounds->left, bounds->top, bounds->right, bounds->bottom); + SelectClipRgn(wfi->drawing->hdc, hrgn); + DeleteObject(hrgn); + } + else + { + SelectClipRgn(wfi->drawing->hdc, NULL); + } +} + +void wf_gdi_dstblt(rdpUpdate* update, DSTBLT_ORDER* dstblt) +{ + wfInfo* wfi = GET_WFI(update); + + BitBlt(wfi->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop)); + + wf_invalidate_region(wfi, dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight); +} + +void wf_gdi_patblt(rdpUpdate* update, PATBLT_ORDER* patblt) +{ + +} + +void wf_gdi_scrblt(rdpUpdate* update, SCRBLT_ORDER* scrblt) +{ + wfInfo* wfi = GET_WFI(update); + + BitBlt(wfi->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight, wfi->primary->hdc, + scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop)); + + wf_invalidate_region(wfi, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight); +} + +void wf_gdi_opaque_rect(rdpUpdate* update, OPAQUE_RECT_ORDER* opaque_rect) +{ + RECT rect; + HBRUSH brush; + uint32 brush_color; + wfInfo* wfi = GET_WFI(update); + + brush_color = freerdp_color_convert(opaque_rect->color, wfi->dstBpp, 24, wfi->clrconv); + + rect.left = opaque_rect->nLeftRect; + rect.top = opaque_rect->nTopRect; + rect.right = opaque_rect->nLeftRect + opaque_rect->nWidth; + rect.bottom = opaque_rect->nTopRect + opaque_rect->nHeight; + brush = CreateSolidBrush(brush_color); + FillRect(wfi->drawing->hdc, &rect, brush); + DeleteObject(brush); + + if (wfi->drawing == wfi->primary) + wf_invalidate_region(wfi, rect.left, rect.top, rect.right, rect.bottom); +} + +void wf_gdi_multi_opaque_rect(rdpUpdate* update, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +{ + int i; + RECT rect; + HBRUSH brush; + uint32 brush_color; + DELTA_RECT* rectangle; + wfInfo* wfi = GET_WFI(update); + + for (i = 1; i < multi_opaque_rect->numRectangles + 1; i++) + { + rectangle = &multi_opaque_rect->rectangles[i]; + + brush_color = freerdp_color_convert(multi_opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + + rect.left = rectangle->left; + rect.top = rectangle->top; + rect.right = rectangle->left + rectangle->width; + rect.bottom = rectangle->top + rectangle->height; + brush = CreateSolidBrush(brush_color); + + brush = CreateSolidBrush(brush_color); + FillRect(wfi->drawing->hdc, &rect, brush); + + DeleteObject(brush); + } +} + +void wf_gdi_line_to(rdpUpdate* update, LINE_TO_ORDER* line_to) +{ + HPEN pen; + HPEN org_pen; + uint32 pen_color; + wfInfo* wfi = GET_WFI(update); + + pen_color = freerdp_color_convert(line_to->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + + pen = CreatePen(line_to->penStyle, line_to->penWidth, pen_color); + + wf_set_rop2(wfi->drawing->hdc, line_to->bRop2); + org_pen = (HPEN) SelectObject(wfi->drawing->hdc, pen); + + MoveToEx(wfi->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL); + LineTo(wfi->drawing->hdc, line_to->nXEnd, line_to->nYEnd); + SelectObject(wfi->drawing->hdc, org_pen); + + DeleteObject(pen); +} + +void wf_gdi_polyline(rdpUpdate* update, POLYLINE_ORDER* polyline) +{ + +} + +void wf_gdi_fast_index(rdpUpdate* update, FAST_INDEX_ORDER* fast_index) +{ + +} + +void wf_gdi_create_offscreen_bitmap(rdpUpdate* update, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) +{ + WF_IMAGE* wf_bmp; + wfInfo* wfi = GET_WFI(update); + + wf_bmp = wf_image_new(wfi, create_offscreen_bitmap->cx, create_offscreen_bitmap->cy, wfi->dstBpp, NULL); + offscreen_put(wfi->cache->offscreen, create_offscreen_bitmap->id, (void*) wf_bmp); +} + +void wf_gdi_switch_surface(rdpUpdate* update, SWITCH_SURFACE_ORDER* switch_surface) +{ + WF_IMAGE* wf_bmp; + wfInfo* wfi = GET_WFI(update); + + if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE) + { + wfi->drawing = (WF_IMAGE*) wfi->primary; + } + else + { + wf_bmp = (WF_IMAGE*) offscreen_get(wfi->cache->offscreen, switch_surface->bitmapId); + wfi->drawing = wf_bmp; + } +} + +void wf_gdi_cache_bitmap_v2(rdpUpdate* update, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2) +{ + wfInfo* wfi = GET_WFI(update); + + bitmap_v2_put(wfi->cache->bitmap_v2, cache_bitmap_v2->cacheId, + cache_bitmap_v2->cacheIndex, cache_bitmap_v2->bitmapDataStream); +} + +void wf_gdi_cache_color_table(rdpUpdate* update, CACHE_COLOR_TABLE_ORDER* cache_color_table) +{ + wfInfo* wfi = GET_WFI(update); + color_table_put(wfi->cache->color_table, cache_color_table->cacheIndex, (void*) cache_color_table->colorTable); +} + +void wf_gdi_cache_glyph(rdpUpdate* update, CACHE_GLYPH_ORDER* cache_glyph) +{ + int i; + WF_IMAGE* wf_bmp; + GLYPH_DATA* glyph; + wfInfo* wfi = GET_WFI(update); + + for (i = 0; i < cache_glyph->cGlyphs; i++) + { + glyph = cache_glyph->glyphData[i]; + wf_bmp = wf_glyph_new(wfi, glyph); + glyph_put(wfi->cache->glyph, cache_glyph->cacheId, glyph->cacheIndex, glyph, (void*) wf_bmp); + } +} + +void wf_gdi_cache_glyph_v2(rdpUpdate* update, CACHE_GLYPH_V2_ORDER* cache_glyph_v2) +{ + +} + +void wf_gdi_cache_brush(rdpUpdate* update, CACHE_BRUSH_ORDER* cache_brush) +{ + //wfInfo* wfi = GET_WFI(update); + //brush_put(wfi->cache->brush, cache_brush->index, cache_brush->data, cache_brush->bpp); +} + +void wf_gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command) +{ + +} + +void wf_gdi_bitmap_decompress(rdpUpdate* update, BITMAP_DATA* bitmap_data) +{ + uint16 dstSize; + + dstSize = bitmap_data->width * bitmap_data->height * (bitmap_data->bpp / 8); + + if (bitmap_data->dstData == NULL) + bitmap_data->dstData = (uint8*) xmalloc(dstSize); + else + bitmap_data->dstData = (uint8*) xrealloc(bitmap_data->dstData, dstSize); + + if (bitmap_data->compressed) + { + bitmap_decompress(bitmap_data->srcData, bitmap_data->dstData, + bitmap_data->width, bitmap_data->height, bitmap_data->length, + bitmap_data->bpp, bitmap_data->bpp); + } + else + { + freerdp_image_invert(bitmap_data->srcData, bitmap_data->dstData, + bitmap_data->width, bitmap_data->height, bitmap_data->bpp); + } + + bitmap_data->compressed = False; +} + +void wf_gdi_register_update_callbacks(rdpUpdate* update) +{ + update->Bitmap = wf_gdi_bitmap_update; + update->Palette = wf_gdi_palette_update; + update->SetBounds = wf_gdi_set_bounds; + update->DstBlt = wf_gdi_dstblt; + update->PatBlt = wf_gdi_patblt; + update->ScrBlt = wf_gdi_scrblt; + update->OpaqueRect = wf_gdi_opaque_rect; + update->DrawNineGrid = NULL; + update->MultiDstBlt = NULL; + update->MultiPatBlt = NULL; + update->MultiScrBlt = NULL; + update->MultiOpaqueRect = wf_gdi_multi_opaque_rect; + update->MultiDrawNineGrid = NULL; + update->LineTo = wf_gdi_line_to; + update->Polyline = NULL; + update->MemBlt = NULL; + update->Mem3Blt = NULL; + update->SaveBitmap = NULL; + update->GlyphIndex = NULL; + update->FastIndex = wf_gdi_fast_index; + update->FastGlyph = NULL; + update->PolygonSC = NULL; + update->PolygonCB = NULL; + update->EllipseSC = NULL; + update->EllipseCB = NULL; + update->CreateOffscreenBitmap = wf_gdi_create_offscreen_bitmap; + update->SwitchSurface = wf_gdi_switch_surface; + + update->CacheBitmapV2 = wf_gdi_cache_bitmap_v2; + update->CacheColorTable = wf_gdi_cache_color_table; + update->CacheGlyph = wf_gdi_cache_glyph; + update->CacheGlyphV2 = wf_gdi_cache_glyph_v2; + update->CacheBrush = wf_gdi_cache_brush; + + update->SurfaceBits = wf_gdi_surface_bits; + + update->BitmapDecompress = wf_gdi_bitmap_decompress; +} diff --git a/client/Windows/wf_gdi.h b/client/Windows/wf_gdi.h index 61ce614e0..a0f70dbe0 100644 --- a/client/Windows/wf_gdi.h +++ b/client/Windows/wf_gdi.h @@ -28,4 +28,6 @@ WF_IMAGE* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) void wf_image_free(WF_IMAGE* image); void wf_toggle_fullscreen(wfInfo* wfi); +void wf_gdi_register_update_callbacks(rdpUpdate* update); + #endif /* __WF_GDI_H */ diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index fd2daa152..11a140832 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -57,6 +57,62 @@ int wf_create_console(void) return 0; } +void wf_sw_begin_paint(rdpUpdate* update) +{ + GDI* gdi; + gdi = GET_GDI(update); + gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->ninvalid = 0; +} + +void wf_sw_end_paint(rdpUpdate* update) +{ + int i; + GDI* gdi; + wfInfo* wfi; + sint32 x, y; + uint32 w, h; + int ninvalid; + RECT update_rect; + HGDI_RGN cinvalid; + + gdi = GET_GDI(update); + wfi = GET_WFI(update); + + if (gdi->primary->hdc->hwnd->ninvalid < 1) + return; + + ninvalid = gdi->primary->hdc->hwnd->ninvalid; + cinvalid = gdi->primary->hdc->hwnd->cinvalid; + + for (i = 0; i < ninvalid; i++) + { + x = cinvalid[i].x; + y = cinvalid[i].y; + w = cinvalid[i].w; + h = cinvalid[i].h; + + update_rect.left = x; + update_rect.top = y; + update_rect.right = x + w - 1; + update_rect.bottom = y + h - 1; + + InvalidateRect(wfi->hwnd, &update_rect, FALSE); + } +} + +void wf_hw_begin_paint(rdpUpdate* update) +{ + wfInfo* wfi = GET_WFI(update); + wfi->hdc->hwnd->invalid->null = 1; + wfi->hdc->hwnd->ninvalid = 0; +} + +void wf_hw_end_paint(rdpUpdate* update) +{ + +} + boolean wf_pre_connect(freerdp* instance) { int i1; @@ -81,7 +137,7 @@ boolean wf_pre_connect(freerdp* instance) settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = False; settings->order_support[NEG_LINETO_INDEX] = True; settings->order_support[NEG_POLYLINE_INDEX] = True; - settings->order_support[NEG_MEMBLT_INDEX] = True; + settings->order_support[NEG_MEMBLT_INDEX] = False; settings->order_support[NEG_MEM3BLT_INDEX] = False; settings->order_support[NEG_SAVEBITMAP_INDEX] = True; settings->order_support[NEG_GLYPH_INDEX_INDEX] = True; @@ -96,6 +152,16 @@ boolean wf_pre_connect(freerdp* instance) wfi->fullscreen = settings->fullscreen; wfi->fs_toggle = wfi->fullscreen; + wfi->sw_gdi = settings->sw_gdi; + + wfi->clrconv = (HCLRCONV) xzalloc(sizeof(CLRCONV)); + wfi->clrconv->alpha = 1; + wfi->clrconv->palette = NULL; + + if (wfi->sw_gdi) + { + wfi->cache = cache_new(instance->settings); + } if (wfi->percentscreen > 0) { @@ -141,12 +207,40 @@ boolean wf_post_connect(freerdp* instance) SET_WFI(instance->update, wfi); settings = instance->settings; - gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP); - gdi = GET_GDI(instance->update); - + wfi->dstBpp = 32; width = settings->width; height = settings->height; + if (wfi->sw_gdi) + { + uint8* primary_buffer; + primary_buffer = (uint8*) xmalloc(width * height * (wfi->dstBpp / 8)); + wfi->primary = wf_image_new(wfi, width, height, wfi->dstBpp, primary_buffer); + gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, primary_buffer); + gdi = GET_GDI(instance->update); + wfi->hdc = gdi->primary->hdc; + } + else + { + wf_gdi_register_update_callbacks(instance->update); + wfi->primary = wf_image_new(wfi, width, height, wfi->dstBpp, NULL); + + wfi->hdc = gdi_GetDC(); + wfi->hdc->bitsPerPixel = wfi->dstBpp; + wfi->hdc->bytesPerPixel = wfi->dstBpp / 8; + + wfi->hdc->alpha = wfi->clrconv->alpha; + wfi->hdc->invert = wfi->clrconv->invert; + + wfi->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); + wfi->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + wfi->hdc->hwnd->invalid->null = 1; + + wfi->hdc->hwnd->count = 32; + wfi->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * wfi->hdc->hwnd->count); + wfi->hdc->hwnd->ninvalid = 0; + } + if (strlen(wfi->window_title) > 0) _snwprintf(win_title, sizeof(win_title), L"%S", wfi->window_title); else if (settings->port == 3389) @@ -182,16 +276,23 @@ boolean wf_post_connect(freerdp* instance) SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, width + diff.x, height + diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); } - if (wfi->primary == NULL) - { - wfi->primary = wf_image_new(wfi, width, height, 0, NULL); - BitBlt(wfi->primary->hdc, 0, 0, width, height, NULL, 0, 0, BLACKNESS); - } + BitBlt(wfi->primary->hdc, 0, 0, width, height, NULL, 0, 0, BLACKNESS); wfi->drawing = wfi->primary; ShowWindow(wfi->hwnd, SW_SHOWNORMAL); UpdateWindow(wfi->hwnd); + if (wfi->sw_gdi) + { + instance->update->BeginPaint = wf_sw_begin_paint; + instance->update->EndPaint = wf_sw_end_paint; + } + else + { + instance->update->BeginPaint = wf_hw_begin_paint; + instance->update->EndPaint = wf_hw_end_paint; + } + freerdp_chanman_post_connect(GET_CHANMAN(instance), instance); return True; @@ -362,9 +463,6 @@ static DWORD WINAPI thread_func(LPVOID lpParam) instance = data->instance; wfi = (wfInfo*) xzalloc(sizeof(wfInfo)); - wfi->clrconv = (HCLRCONV) xzalloc(sizeof(CLRCONV)); - wfi->clrconv->alpha = 1; - wfi->clrconv->palette = NULL; SET_WFI(instance, wfi); wfi->instance = instance; diff --git a/client/Windows/wfreerdp.h b/client/Windows/wfreerdp.h index 358bac35a..18bd155d9 100644 --- a/client/Windows/wfreerdp.h +++ b/client/Windows/wfreerdp.h @@ -31,7 +31,10 @@ #include #include -#include +#include +#include +#include +#include #include #include @@ -59,6 +62,9 @@ struct wf_info char window_title[64]; HWND hwnd; + HGDI_DC hdc; + uint16 srcBpp; + uint16 dstBpp; freerdp* instance; WF_IMAGE* primary; WF_IMAGE* drawing; @@ -66,6 +72,9 @@ struct wf_info HCURSOR cursor; HBRUSH brush; HBRUSH org_brush; + + boolean sw_gdi; + rdpCache* cache; }; typedef struct wf_info wfInfo; diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h index 3ffd74822..9138d74be 100644 --- a/include/freerdp/codec/color.h +++ b/include/freerdp/codec/color.h @@ -220,7 +220,8 @@ extern "C" { /* Supported Internal Buffer Formats */ #define CLRBUF_16BPP 8 -#define CLRBUF_32BPP 16 +#define CLRBUF_24BPP 16 +#define CLRBUF_32BPP 32 struct _CLRCONV { diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index 6831f06d5..62de41724 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -262,7 +262,7 @@ FREERDP_API int gdi_is_mono_pixel_set(uint8* data, int x, int y, int width); FREERDP_API GDI_IMAGE* gdi_bitmap_new(GDI *gdi, int width, int height, int bpp, uint8* data); FREERDP_API void gdi_bitmap_free(GDI_IMAGE *gdi_bmp); FREERDP_API void gdi_resize(GDI* gdi, int width, int height); -FREERDP_API int gdi_init(freerdp* instance, uint32 flags); +FREERDP_API int gdi_init(freerdp* instance, uint32 flags, uint8* buffer); FREERDP_API void gdi_free(freerdp* instance); #define SET_GDI(_instance, _gdi) (_instance)->gdi = _gdi diff --git a/libfreerdp-gdi/gdi.c b/libfreerdp-gdi/gdi.c index d11b7df93..ba66fed00 100644 --- a/libfreerdp-gdi/gdi.c +++ b/libfreerdp-gdi/gdi.c @@ -855,7 +855,7 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm surface_bits_command->width, surface_bits_command->height, surface_bits_command->bitmapDataLength); - tile_bitmap = xzalloc(32); + tile_bitmap = (char*) xzalloc(32); if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) { @@ -916,6 +916,8 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm if ((surface_bits_command->bpp != 32) || (gdi->clrconv->alpha == True)) { + uint8* temp_image; + freerdp_image_convert(surface_bits_command->bitmapData, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, gdi->image->bitmap->bitsPerPixel, 32, gdi->clrconv); @@ -923,7 +925,7 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm surface_bits_command->bpp = 32; surface_bits_command->bitmapData = gdi->image->bitmap->data; - uint8* temp_image = (uint8*) xmalloc(gdi->image->bitmap->width * gdi->image->bitmap->height * 4); + temp_image = (uint8*) xmalloc(gdi->image->bitmap->width * gdi->image->bitmap->height * 4); freerdp_image_invert(gdi->image->bitmap->data, temp_image, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); xfree(gdi->image->bitmap->data); gdi->image->bitmap->data = temp_image; @@ -942,7 +944,8 @@ void gdi_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_comm printf("Unsupported codecID %d\n", surface_bits_command->codecID); } - xfree(tile_bitmap); + if (tile_bitmap != NULL) + xfree(tile_bitmap); } void gdi_bitmap_decompress(rdpUpdate* update, BITMAP_DATA* bitmap_data) @@ -1019,7 +1022,7 @@ void gdi_register_update_callbacks(rdpUpdate* update) void gdi_init_primary(GDI* gdi) { - gdi->primary = gdi_bitmap_new(gdi, gdi->width, gdi->height, gdi->dstBpp, NULL); + gdi->primary = gdi_bitmap_new(gdi, gdi->width, gdi->height, gdi->dstBpp, gdi->primary_buffer); gdi->primary_buffer = gdi->primary->bitmap->data; if (gdi->drawing == NULL) @@ -1057,7 +1060,7 @@ void gdi_resize(GDI* gdi, int width, int height) * @return */ -int gdi_init(freerdp* instance, uint32 flags) +int gdi_init(freerdp* instance, uint32 flags, uint8* buffer) { GDI* gdi = (GDI*) malloc(sizeof(GDI)); memset(gdi, 0, sizeof(GDI)); @@ -1066,6 +1069,7 @@ int gdi_init(freerdp* instance, uint32 flags) gdi->width = instance->settings->width; gdi->height = instance->settings->height; gdi->srcBpp = instance->settings->color_depth; + gdi->primary_buffer = buffer; /* default internal buffer format */ gdi->dstBpp = 32; @@ -1078,6 +1082,11 @@ int gdi_init(freerdp* instance, uint32 flags) gdi->dstBpp = 32; gdi->bytesPerPixel = 4; } + else if (flags & CLRBUF_24BPP) + { + gdi->dstBpp = 24; + gdi->bytesPerPixel = 3; + } else if (flags & CLRBUF_16BPP) { gdi->dstBpp = 16; diff --git a/libfreerdp-utils/stream.c b/libfreerdp-utils/stream.c index 4be958f7d..fc24b0987 100644 --- a/libfreerdp-utils/stream.c +++ b/libfreerdp-utils/stream.c @@ -35,7 +35,7 @@ STREAM* stream_new(int size) if (size != 0) { size = size > 0 ? size : 0x400; - stream->data = (uint8*)xzalloc(size); + stream->data = (uint8*) xzalloc(size); stream->p = stream->data; stream->size = size; } @@ -55,15 +55,15 @@ void stream_free(STREAM* stream) void stream_extend(STREAM* stream, int request_size) { + int pos; int original_size; int increased_size; - int pos; pos = stream_get_pos(stream); original_size = stream->size; increased_size = (request_size > original_size ? request_size : original_size); stream->size += increased_size; - stream->data = (uint8*)xrealloc(stream->data, stream->size); + stream->data = (uint8*) xrealloc(stream->data, stream->size); memset(stream->data + original_size, 0, increased_size); stream_set_pos(stream, pos); }