diff --git a/client/Windows/cli/wfreerdp.c b/client/Windows/cli/wfreerdp.c index c5f5fa0a8..a661ce7fe 100644 --- a/client/Windows/cli/wfreerdp.c +++ b/client/Windows/cli/wfreerdp.c @@ -63,6 +63,8 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine settings = context->settings; wfc = (wfContext*) context; + settings->SoftwareGdi = TRUE; + context->argc = __argc; context->argv = (char**) malloc(sizeof(char*) * __argc); diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index d02c36970..e41b59a71 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -339,6 +339,106 @@ void wf_toggle_fullscreen(wfContext* wfc) } } +void wf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate) +{ + HDC hdc; + int status; + int nXDst; + int nYDst; + int nXSrc; + int nYSrc; + int nWidth; + int nHeight; + HBITMAP dib; + UINT32 index; + BYTE* pSrcData; + BYTE* pDstData; + UINT32 SrcSize; + BOOL compressed; + UINT32 SrcFormat; + UINT32 bitsPerPixel; + UINT32 bytesPerPixel; + BITMAP_DATA* bitmap; + rdpCodecs* codecs = context->codecs; + wfContext* wfc = (wfContext*) context; + + hdc = CreateCompatibleDC(GetDC(NULL)); + + for (index = 0; index < bitmapUpdate->number; index++) + { + bitmap = &(bitmapUpdate->rectangles[index]); + + nXSrc = 0; + nYSrc = 0; + + nXDst = bitmap->destLeft; + nYDst = bitmap->destTop; + + nWidth = bitmap->width; + nHeight = bitmap->height; + + pSrcData = bitmap->bitmapDataStream; + SrcSize = bitmap->bitmapLength; + + compressed = bitmap->compressed; + bitsPerPixel = bitmap->bitsPerPixel; + bytesPerPixel = (bitsPerPixel + 7) / 8; + + SrcFormat = gdi_get_pixel_format(bitsPerPixel, TRUE); + + if (wfc->bitmap_size < (nWidth * nHeight * 4)) + { + wfc->bitmap_size = nWidth * nHeight * 4; + wfc->bitmap_buffer = (BYTE*) _aligned_realloc(wfc->bitmap_buffer, wfc->bitmap_size, 16); + + if (!wfc->bitmap_buffer) + return; + } + + if (compressed) + { + pDstData = wfc->bitmap_buffer; + + if (bitsPerPixel < 32) + { + freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_INTERLEAVED); + + status = interleaved_decompress(codecs->interleaved, pSrcData, SrcSize, bitsPerPixel, + &pDstData, PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight); + } + else + { + freerdp_client_codecs_prepare(codecs, FREERDP_CODEC_PLANAR); + + status = planar_decompress(codecs->planar, pSrcData, SrcSize, &pDstData, + PIXEL_FORMAT_XRGB32, nWidth * 4, 0, 0, nWidth, nHeight); + } + + if (status < 0) + { + DEBUG_WARN("wf_gdi_bitmap_update: bitmap decompression failure\n"); + return; + } + + pSrcData = wfc->bitmap_buffer; + } + + dib = wf_create_dib(wfc, nWidth, nHeight, 32, pSrcData, NULL); + SelectObject(hdc, dib); + + nWidth = bitmap->destRight - bitmap->destLeft + 1; /* clip width */ + nHeight = bitmap->destBottom - bitmap->destTop + 1; /* clip height */ + + BitBlt(wfc->primary->hdc, nXDst, nYDst, nWidth, nHeight, hdc, 0, 0, SRCCOPY); + + gdi_InvalidateRegion(wfc->hdc, nXDst, nYDst, nWidth, nHeight); + + DeleteObject(dib); + } + + ReleaseDC(NULL, hdc); +} + void wf_gdi_palette_update(wfContext* wfc, PALETTE_UPDATE* palette) { @@ -453,12 +553,12 @@ void wf_gdi_multi_opaque_rect(wfContext* wfc, MULTI_OPAQUE_RECT_ORDER* multi_opa UINT32 brush_color; DELTA_RECT* rectangle; + brush_color = freerdp_color_convert_var_rgb(multi_opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv); + for (i = 1; i < (int) multi_opaque_rect->numRectangles + 1; i++) { rectangle = &multi_opaque_rect->rectangles[i]; - brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv); - rect.left = rectangle->left; rect.top = rectangle->top; rect.right = rectangle->left + rectangle->width; diff --git a/client/Windows/wf_gdi.h b/client/Windows/wf_gdi.h index b7ab1cfda..bc966f052 100644 --- a/client/Windows/wf_gdi.h +++ b/client/Windows/wf_gdi.h @@ -31,6 +31,7 @@ void wf_update_offset(wfContext* wfc); void wf_resize_window(wfContext* wfc); void wf_toggle_fullscreen(wfContext* wfc); +void wf_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate); void wf_gdi_register_update_callbacks(rdpUpdate* update); void wf_update_canvas_diff(wfContext* wfc); diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index 67a44d08a..2ca2b244e 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -146,55 +146,58 @@ void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap, { int status; UINT16 size; + BYTE* pSrcData; + BYTE* pDstData; + UINT32 SrcSize; + UINT32 SrcFormat; + UINT32 bytesPerPixel; - size = width * height * (bpp / 8); + bytesPerPixel = (bpp + 7) / 8; + size = width * height * 4; if (!bitmap->data) bitmap->data = (BYTE*) _aligned_malloc(size, 16); else bitmap->data = (BYTE*) _aligned_realloc(bitmap->data, size, 16); + pSrcData = data; + SrcSize = (UINT32) length; + pDstData = bitmap->data; + if (compressed) { - BYTE* pDstData; - UINT32 SrcSize; - - SrcSize = (UINT32) length; - pDstData = bitmap->data; - if (bpp < 32) { freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_INTERLEAVED); - status = interleaved_decompress(wfc->codecs->interleaved, data, SrcSize, bpp, - &pDstData, PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height); - - if (status < 0) - { - DEBUG_WARN("wf_Bitmap_Decompress: Bitmap Decompression Failed\n"); - } + status = interleaved_decompress(wfc->codecs->interleaved, pSrcData, SrcSize, bpp, + &pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, width, height); } else { freerdp_client_codecs_prepare(wfc->codecs, FREERDP_CODEC_PLANAR); - status = planar_decompress(wfc->codecs->planar, data, SrcSize, &pDstData, + status = planar_decompress(wfc->codecs->planar, pSrcData, SrcSize, &pDstData, PIXEL_FORMAT_XRGB32_VF, width * 4, 0, 0, width, height); + } - if (status < 0) - { - DEBUG_WARN("wf_Bitmap_Decompress: Bitmap Decompression Failed\n"); - } + if (status < 0) + { + DEBUG_WARN("wf_Bitmap_Decompress: Bitmap Decompression Failed\n"); + return; } } else { - freerdp_image_flip(data, bitmap->data, width, height, bpp); + SrcFormat = gdi_get_pixel_format(bpp, TRUE); + + status = freerdp_image_copy(pDstData, PIXEL_FORMAT_XRGB32, width * 4, 0, 0, + width, height, pSrcData, SrcFormat, width * bytesPerPixel, 0, 0); } bitmap->compressed = FALSE; bitmap->length = size; - bitmap->bpp = bpp; + bitmap->bpp = 32; } void wf_Bitmap_SetSurface(wfContext* wfc, rdpBitmap* bitmap, BOOL primary) @@ -277,30 +280,13 @@ void wf_Pointer_SetDefault(wfContext* wfc) } -/* Graphics Module */ - -void wf_register_graphics(rdpGraphics* graphics) +void wf_register_pointer(rdpGraphics* graphics) { wfContext* wfc; rdpPointer pointer; wfc = (wfContext*) graphics->context; - if (wfc->sw_gdi == FALSE) - { - rdpBitmap bitmap; - - ZeroMemory(&bitmap, sizeof(rdpBitmap)); - bitmap.size = sizeof(wfBitmap); - bitmap.New = (pBitmap_New) wf_Bitmap_New; - bitmap.Free = (pBitmap_Free) wf_Bitmap_Free; - bitmap.Paint = (pBitmap_Paint) wf_Bitmap_Paint; - bitmap.Decompress = (pBitmap_Decompress) wf_Bitmap_Decompress; - bitmap.SetSurface = (pBitmap_SetSurface) wf_Bitmap_SetSurface; - - graphics_register_bitmap(graphics, &bitmap); - } - ZeroMemory(&pointer, sizeof(rdpPointer)); pointer.size = sizeof(wfPointer); pointer.New = (pPointer_New) wf_Pointer_New; @@ -311,3 +297,23 @@ void wf_register_graphics(rdpGraphics* graphics) graphics_register_pointer(graphics, &pointer); } + +/* Graphics Module */ + +void wf_register_graphics(rdpGraphics* graphics) +{ + wfContext* wfc; + rdpBitmap bitmap; + + wfc = (wfContext*) graphics->context; + + ZeroMemory(&bitmap, sizeof(rdpBitmap)); + bitmap.size = sizeof(wfBitmap); + bitmap.New = (pBitmap_New) wf_Bitmap_New; + bitmap.Free = (pBitmap_Free) wf_Bitmap_Free; + bitmap.Paint = (pBitmap_Paint) wf_Bitmap_Paint; + bitmap.Decompress = (pBitmap_Decompress) wf_Bitmap_Decompress; + bitmap.SetSurface = (pBitmap_SetSurface) wf_Bitmap_SetSurface; + + graphics_register_bitmap(graphics, &bitmap); +} diff --git a/client/Windows/wf_graphics.h b/client/Windows/wf_graphics.h index a27c6a679..cfc2a9639 100644 --- a/client/Windows/wf_graphics.h +++ b/client/Windows/wf_graphics.h @@ -26,6 +26,7 @@ HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data); void wf_image_free(wfBitmap* image); +void wf_register_pointer(rdpGraphics* graphics); void wf_register_graphics(rdpGraphics* graphics); #endif /* WF_GRAPHICS */ diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 1b5caeb97..1d11ebda4 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -36,10 +36,6 @@ #include #include -#ifdef _MSC_VER -#include -#endif - #include #include #include @@ -104,8 +100,8 @@ void wf_sw_end_paint(wfContext* wfc) update_rect.left = x; update_rect.top = y; - update_rect.right = x + w - 1; - update_rect.bottom = y + h - 1; + update_rect.right = x + w; + update_rect.bottom = y + h; InvalidateRect(wfc->hwnd, &update_rect, FALSE); } @@ -237,9 +233,9 @@ BOOL wf_pre_connect(freerdp* instance) settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE; wfc->fullscreen = settings->Fullscreen; + if (wfc->fullscreen) wfc->fs_toggle = 1; - wfc->sw_gdi = settings->SoftwareGdi; wfc->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); ZeroMemory(wfc->clrconv, sizeof(CLRCONV)); @@ -345,7 +341,7 @@ BOOL wf_post_connect(freerdp* instance) wfc->width = settings->DesktopWidth; wfc->height = settings->DesktopHeight; - if (wfc->sw_gdi) + if (settings->SoftwareGdi) { wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL); @@ -421,7 +417,7 @@ BOOL wf_post_connect(freerdp* instance) ShowWindow(wfc->hwnd, SW_SHOWNORMAL); UpdateWindow(wfc->hwnd); - if (wfc->sw_gdi) + if (settings->SoftwareGdi) { instance->update->BeginPaint = (pBeginPaint) wf_sw_begin_paint; instance->update->EndPaint = (pEndPaint) wf_sw_end_paint; @@ -435,19 +431,21 @@ BOOL wf_post_connect(freerdp* instance) } pointer_cache_register_callbacks(instance->update); + wf_register_pointer(context->graphics); - if (wfc->sw_gdi != TRUE) + if (!settings->SoftwareGdi) { brush_cache_register_callbacks(instance->update); bitmap_cache_register_callbacks(instance->update); offscreen_cache_register_callbacks(instance->update); + wf_register_graphics(context->graphics); + instance->update->BitmapUpdate = wf_gdi_bitmap_update; } - wf_register_graphics(instance->context->graphics); + freerdp_channels_post_connect(context->channels, instance); - freerdp_channels_post_connect(instance->context->channels, instance); + wf_cliprdr_init(wfc, context->channels); - wf_cliprdr_init(wfc, instance->context->channels); if (wfc->fullscreen) floatbar_window_create(wfc); @@ -1142,9 +1140,13 @@ int wfreerdp_client_new(freerdp* instance, rdpContext* context) void wfreerdp_client_free(freerdp* instance, rdpContext* context) { + wfContext* wfc = (wfContext*) context; + if (context->cache) cache_free(context->cache); + _aligned_free(wfc->bitmap_buffer); + freerdp_channels_free(context->channels); } diff --git a/client/Windows/wf_interface.h b/client/Windows/wf_interface.h index feb0846f7..05e56a073 100644 --- a/client/Windows/wf_interface.h +++ b/client/Windows/wf_interface.h @@ -82,6 +82,8 @@ struct wf_context int client_y; int client_width; int client_height; + UINT32 bitmap_size; + BYTE* bitmap_buffer; HANDLE keyboardThread; @@ -112,7 +114,7 @@ struct wf_context DWORD mainThreadId; DWORD keyboardThreadId; - BOOL sw_gdi; + //BOOL sw_gdi; rdpFile* connectionRdpFile;