wfreerdp: fix gdi usage

This commit is contained in:
Marc-André Moreau
2014-09-12 11:34:30 -04:00
parent efd9b8f7a9
commit ff2df7489d
7 changed files with 169 additions and 55 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -36,10 +36,6 @@
#include <assert.h>
#include <sys/types.h>
#ifdef _MSC_VER
#include <intrin.h>
#endif
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/utils/event.h>
@@ -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);
}

View File

@@ -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;