wfreerdp: fix RemoteFX
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 16 Dec 2011 19:43:14 +0000 (14:43 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 16 Dec 2011 19:43:14 +0000 (14:43 -0500)
client/Windows/wf_gdi.c
client/Windows/wf_graphics.c
client/Windows/wf_graphics.h
client/Windows/wfreerdp.c
client/Windows/wfreerdp.h

index eab8a06..3d232eb 100644 (file)
@@ -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
        {
index 9048696..0c4e57c 100644 (file)
@@ -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);
 }
index 65f03b2..024d3f7 100644 (file)
@@ -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);
index 903600c..f48a512 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 
 #include <freerdp/freerdp.h>
+#include <freerdp/constants.h>
 #include <freerdp/utils/args.h>
 #include <freerdp/utils/event.h>
 #include <freerdp/utils/memory.h>
@@ -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);
index 80052e3..2841c02 100644 (file)
@@ -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;