From 8bb1554851e9b37421373268a34fb2ec02529b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 16 Dec 2011 14:43:14 -0500 Subject: [PATCH] wfreerdp: fix RemoteFX --- client/Windows/wf_gdi.c | 31 ++++++++++++++++---------- client/Windows/wf_graphics.c | 26 ++++++++++++++++++---- client/Windows/wf_graphics.h | 3 ++- client/Windows/wfreerdp.c | 43 +++++++++++++++++++++++++++++++++++- client/Windows/wfreerdp.h | 2 ++ 5 files changed, 87 insertions(+), 18 deletions(-) diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index eab8a06fd..3d232eb18 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -131,7 +131,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, uint32 color, int bpp) { if (brush->bpp > 1) { - pattern = wf_create_dib(wfi, 8, 8, bpp, brush->data); + pattern = wf_create_dib(wfi, 8, 8, bpp, brush->data, NULL); lbr.lbHatch = (ULONG_PTR) pattern; } else @@ -165,13 +165,11 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, uint32 color, int bpp) 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); - + wfi->update_rect.left = x; + wfi->update_rect.top = y; + wfi->update_rect.right = x + width; + wfi->update_rect.bottom = y + height; + InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE); gdi_InvalidateRegion(wfi->hdc, x, y, width, height); } @@ -195,7 +193,7 @@ void wf_set_null_clip_rgn(wfInfo* wfi) void wf_set_clip_rgn(wfInfo* wfi, int x, int y, int width, int height) { HRGN clip; - clip = CreateRectRgn(x, y, width, height); + clip = CreateRectRgn(x, y, x + width, y + height); SelectClipRgn(wfi->drawing->hdc, clip); DeleteObject(clip); } @@ -432,7 +430,7 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits tx = message->tiles[i]->x + surface_bits_command->destLeft; ty = message->tiles[i]->y + surface_bits_command->destTop; - freerdp_image_convert(message->tiles[i]->data, wfi->tile->_bitmap.data, 64, 64, 32, 32, wfi->clrconv); + freerdp_image_convert(message->tiles[i]->data, wfi->tile->pdata, 64, 64, 32, 24, wfi->clrconv); for (j = 0; j < message->num_rects; j++) { @@ -441,11 +439,20 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits surface_bits_command->destTop + message->rects[j].y, message->rects[j].width, message->rects[j].height); - BitBlt(wfi->primary->hdc, tx, ty, 64, 64, wfi->tile->hdc, 0, 0, GDI_SRCCOPY); + BitBlt(wfi->primary->hdc, tx, ty, 64, 64, wfi->tile->hdc, 0, 0, SRCCOPY); } } wf_set_null_clip_rgn(wfi); + + /* invalidate regions */ + for (i = 0; i < message->num_rects; i++) + { + tx = surface_bits_command->destLeft + message->rects[i].x; + ty = surface_bits_command->destTop + message->rects[i].y; + wf_invalidate_region(wfi, tx, ty, message->rects[i].width, message->rects[i].height); + } + rfx_message_free(rfx_context, message); } else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) @@ -493,7 +500,7 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits } BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, - surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, GDI_SRCCOPY); + surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, SRCCOPY); } else { diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index 90486967c..0c4e57c00 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -23,7 +23,7 @@ #include "wf_gdi.h" #include "wf_graphics.h" -HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data) +HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data, uint8** pdata) { HDC hdc; int negHeight; @@ -52,6 +52,9 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data) if (data != NULL) freerdp_image_convert(data, cdata, width, height, bpp, 24, wfi->clrconv); + if (pdata != NULL) + *pdata = cdata; + ReleaseDC(NULL, hdc); GdiFlush(); @@ -70,7 +73,7 @@ wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) if (data == NULL) image->bitmap = CreateCompatibleBitmap(hdc, width, height); else - image->bitmap = wf_create_dib(wfi, width, height, bpp, data); + image->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(image->pdata)); image->org_bitmap = (HBITMAP) SelectObject(image->hdc, image->bitmap); ReleaseDC(NULL, hdc); @@ -78,6 +81,21 @@ wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) return image; } +wfBitmap* wf_bitmap_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) +{ + HDC hdc; + wfBitmap* bitmap; + + hdc = GetDC(NULL); + bitmap = (wfBitmap*) malloc(sizeof(wfBitmap)); + bitmap->hdc = CreateCompatibleDC(hdc); + bitmap->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(bitmap->pdata)); + bitmap->org_bitmap = (HBITMAP) SelectObject(bitmap->hdc, bitmap->bitmap); + ReleaseDC(NULL, hdc); + + return bitmap; +} + void wf_image_free(wfBitmap* image) { if (image != 0) @@ -105,7 +123,7 @@ void wf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) if (bitmap->data == NULL) wf_bitmap->bitmap = CreateCompatibleBitmap(hdc, bitmap->width, bitmap->height); else - wf_bitmap->bitmap = wf_create_dib(wfi, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data); + wf_bitmap->bitmap = wf_create_dib(wfi, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data, NULL); wf_bitmap->org_bitmap = (HBITMAP) SelectObject(wf_bitmap->hdc, wf_bitmap->bitmap); ReleaseDC(NULL, hdc); @@ -133,7 +151,7 @@ void wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) height = bitmap->bottom - bitmap->top + 1; BitBlt(wfi->primary->hdc, bitmap->left, bitmap->top, - width, height, wf_bitmap->hdc, 0, 0, GDI_SRCCOPY); + width, height, wf_bitmap->hdc, 0, 0, SRCCOPY); wf_invalidate_region(wfi, bitmap->left, bitmap->top, width, height); } diff --git a/client/Windows/wf_graphics.h b/client/Windows/wf_graphics.h index 65f03b260..024d3f77b 100644 --- a/client/Windows/wf_graphics.h +++ b/client/Windows/wf_graphics.h @@ -22,8 +22,9 @@ #include "wfreerdp.h" -HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data); +HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data, uint8** pdata); wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); +wfBitmap* wf_bitmap_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); void wf_image_free(wfBitmap* image); void wf_register_graphics(rdpGraphics* graphics); diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 903600ccc..f48a512e8 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -205,6 +206,37 @@ boolean wf_pre_connect(freerdp* instance) return true; } +void cpuid(unsigned info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) +{ +#ifdef __GNUC__ +#if defined(__i386__) || defined(__x86_64__) + *eax = info; + __asm volatile + ("mov %%ebx, %%edi;" /* 32bit PIC: don't clobber ebx */ + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + :"+a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) + : :"edi"); +#endif +#endif +} + +uint32 wfi_detect_cpu() +{ + uint32 cpu_opt = 0; + unsigned int eax, ebx, ecx, edx = 0; + + cpuid(1, &eax, &ebx, &ecx, &edx); + + if (edx & (1<<26)) + { + cpu_opt |= CPU_SSE2; + } + + return cpu_opt; +} + boolean wf_post_connect(freerdp* instance) { rdpGdi* gdi; @@ -251,6 +283,16 @@ boolean wf_post_connect(freerdp* instance) 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 (settings->rfx_codec) + { + wfi->tile = wf_bitmap_new(wfi, 64, 64, 24, NULL); + wfi->rfx_context = rfx_context_new(); + rfx_context_set_cpu_opt(wfi->rfx_context, wfi_detect_cpu()); + } + + if (settings->ns_codec) + wfi->nsc_context = nsc_context_new(); } if (strlen(settings->window_title) > 0) @@ -326,7 +368,6 @@ boolean wf_verify_certificate(freerdp* instance, char* subject, char* issuer, ch return true; } - int wf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size) { return freerdp_channels_data(instance, channelId, data, size, flags, total_size); diff --git a/client/Windows/wfreerdp.h b/client/Windows/wfreerdp.h index 80052e39a..2841c021f 100644 --- a/client/Windows/wfreerdp.h +++ b/client/Windows/wfreerdp.h @@ -48,6 +48,7 @@ struct wf_bitmap HDC hdc; HBITMAP bitmap; HBITMAP org_bitmap; + uint8* pdata; }; typedef struct wf_bitmap wfBitmap; @@ -85,6 +86,7 @@ struct wf_info HCURSOR cursor; HBRUSH brush; HBRUSH org_brush; + RECT update_rect; wfBitmap* tile; wfBitmap* image;