wfreerdp: clean separation of client core and controlling code
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 19 Mar 2013 01:54:50 +0000 (21:54 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 19 Mar 2013 01:54:50 +0000 (21:54 -0400)
client/Windows/wf_event.c
client/Windows/wf_graphics.c
client/Windows/wf_interface.c
client/Windows/wf_interface.h
client/Windows/wf_window.h
client/Windows/wfreerdp.c
client/Windows/wfreerdp.h

index 0c7fd8b..1ab6953 100644 (file)
 #include "wf_event.h"
 
 static HWND g_focus_hWnd;
-extern HCURSOR g_default_cursor;
 
-#define X_POS(lParam) (lParam & 0xffff)
-#define Y_POS(lParam) ((lParam >> 16) & 0xffff)
+#define X_POS(lParam) (lParam & 0xFFFF)
+#define Y_POS(lParam) ((lParam >> 16) & 0xFFFF)
 
 LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
 {
@@ -57,8 +56,10 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
                        case WM_SYSKEYUP:
                                wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
                                p = (PKBDLLHOOKSTRUCT) lParam;
+
                                if (!wfi || !p)
                                        return 1;
+                               
                                input = wfi->instance->input;
                                rdp_scancode = MAKE_RDP_SCANCODE((BYTE) p->scanCode, p->flags & LLKHF_EXTENDED);
 
@@ -233,7 +234,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam
 
                case WM_SETCURSOR:
                        if (LOWORD(lParam) == HTCLIENT)
-                               SetCursor(g_default_cursor);
+                               SetCursor(wfi->hDefaultCursor);
                        else
                                DefWindowProc(hWnd, Msg, wParam, lParam);
                        break;
index 53b2d92..5071495 100644 (file)
@@ -26,8 +26,6 @@
 #include "wf_gdi.h"
 #include "wf_graphics.h"
 
-extern HINSTANCE g_hInstance; /* in wfreerdp.c */
-
 HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, BYTE** pdata)
 {
        HDC hdc;
index 17eaed4..a0db3c3 100644 (file)
 
 #include "wfreerdp.h"
 
-extern HANDLE g_done_event;
-extern HINSTANCE g_hInstance;
-extern HCURSOR g_default_cursor;
-extern int g_thread_count;
-extern LPCTSTR g_wnd_class_name;
-
 void wf_context_new(freerdp* instance, rdpContext* context)
 {
+       wfInfo* wfi;
+
        context->channels = freerdp_channels_new();
+
+       wfi = (wfInfo*) malloc(sizeof(wfInfo));
+       ZeroMemory(wfi, sizeof(wfInfo));
+
+       ((wfContext*) context)->wfi = wfi;
+       wfi->instance = instance;
 }
 
 void wf_context_free(freerdp* instance, rdpContext* context)
@@ -173,6 +175,7 @@ void wf_hw_desktop_resize(rdpContext* context)
 
        wfi->width = settings->DesktopWidth;
        wfi->height = settings->DesktopHeight;
+
        if (wfi->primary)
        {
                same = (wfi->primary == wfi->drawing) ? TRUE : FALSE;
@@ -205,14 +208,10 @@ BOOL wf_pre_connect(freerdp* instance)
        wfContext* context;
        rdpSettings* settings;
 
-       wfi = (wfInfo*) malloc(sizeof(wfInfo));
-       ZeroMemory(wfi, sizeof(wfInfo));
-
        context = (wfContext*) instance->context;
-       wfi->instance = instance;
-       context->wfi = wfi;
 
-       settings = instance->settings;
+       wfi = context->wfi;
+       wfi->instance = instance;
 
        settings = instance->settings;
 
@@ -255,8 +254,6 @@ BOOL wf_pre_connect(freerdp* instance)
 
        settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE;
 
-       wfi->cursor = g_default_cursor;
-
        wfi->fullscreen = settings->Fullscreen;
        wfi->fs_toggle = 1;
        wfi->sw_gdi = settings->SoftwareGdi;
@@ -307,7 +304,7 @@ BOOL wf_post_connect(freerdp* instance)
        wfInfo* wfi;
        rdpCache* cache;
        wfContext* context;
-       wchar_t win_title[64];
+       WCHAR win_title[64];
        rdpSettings* settings;
 
        settings = instance->settings;
@@ -364,10 +361,10 @@ BOOL wf_post_connect(freerdp* instance)
        else
                _snwprintf(win_title, ARRAYSIZE(win_title), L"FreeRDP: %S:%d", settings->ServerHostname, settings->ServerPort);
 
-       if (wfi->hwnd == 0)
+       if (!wfi->hwnd)
        {
-               wfi->hwnd = CreateWindowEx((DWORD) NULL, g_wnd_class_name, win_title,
-                               0, 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL);
+               wfi->hwnd = CreateWindowEx((DWORD) NULL, wfi->wndClassName, win_title,
+                       0, 0, 0, 0, 0, NULL, NULL, wfi->hInstance, NULL);
 
                SetWindowLongPtr(wfi->hwnd, GWLP_USERDATA, (LONG_PTR) wfi);
        }
@@ -534,8 +531,8 @@ int wfreerdp_run(freerdp* instance)
        HANDLE fds[64];
        rdpChannels* channels;
 
-       memset(rfds, 0, sizeof(rfds));
-       memset(wfds, 0, sizeof(wfds));
+       ZeroMemory(rfds, sizeof(rfds));
+       ZeroMemory(wfds, sizeof(wfds));
 
        if (freerdp_connect(instance) != TRUE)
                return 0;
@@ -610,6 +607,7 @@ int wfreerdp_run(freerdp* instance)
                wf_process_channel_event(channels, instance);
 
                quit_msg = FALSE;
+
                while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
                {
                        msg_ret = GetMessage(&msg, NULL, 0, 0);
@@ -636,40 +634,32 @@ int wfreerdp_run(freerdp* instance)
        return 0;
 }
 
-DWORD WINAPI thread_func(LPVOID lpParam)
+DWORD WINAPI wf_thread(LPVOID lpParam)
 {
        wfInfo* wfi;
        freerdp* instance;
 
        instance = (freerdp*) lpParam;
 
-       wfi = (wfInfo*) malloc(sizeof(wfInfo));
-       ZeroMemory(wfi, sizeof(wfInfo));
-
-       ((wfContext*) instance->context)->wfi = wfi;
-       wfi->instance = instance;
-
        wfreerdp_run(instance);
 
-       g_thread_count--;
-
-       if (g_thread_count < 1)
-               SetEvent(g_done_event);
-
        return (DWORD) NULL;
 }
 
-DWORD WINAPI kbd_thread_func(LPVOID lpParam)
+DWORD WINAPI wf_keyboard_thread(LPVOID lpParam)
 {
        MSG msg;
        BOOL status;
+       wfInfo* wfi;
        HHOOK hook_handle;
 
-       hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, g_hInstance, 0);
+       wfi = (wfInfo*) lpParam;
+
+       hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfi->hInstance, 0);
 
        if (hook_handle)
        {
-               while ((status = GetMessage( &msg, NULL, 0, 0 )) != 0)
+               while ((status = GetMessage(&msg, NULL, 0, 0)) != 0)
                {
                        if (status == -1)
                        {
@@ -682,6 +672,7 @@ DWORD WINAPI kbd_thread_func(LPVOID lpParam)
                                DispatchMessage(&msg);
                        }
                }
+
                UnhookWindowsHookEx(hook_handle);
        }
        else
@@ -691,3 +682,118 @@ DWORD WINAPI kbd_thread_func(LPVOID lpParam)
 
        return (DWORD) NULL;
 }
+
+int wf_global_init()
+{
+       WSADATA wsaData;
+
+       if (!getenv("HOME"))
+       {
+               char home[MAX_PATH * 2] = "HOME=";
+               strcat(home, getenv("HOMEDRIVE"));
+               strcat(home, getenv("HOMEPATH"));
+               _putenv(home);
+       }
+
+       if (WSAStartup(0x101, &wsaData) != 0)
+               return 1;
+
+#if defined(WITH_DEBUG) || defined(_DEBUG)
+       wf_create_console();
+#endif
+
+       freerdp_channels_global_init();
+
+       freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
+
+       return 0;
+}
+
+int wf_global_uninit()
+{
+       WSACleanup();
+
+       return 0;
+}
+
+wfInfo* wf_new(HINSTANCE hInstance, int argc, char** argv)
+{
+       wfInfo* wfi;
+       freerdp* instance;
+
+       instance = freerdp_new();
+       instance->PreConnect = wf_pre_connect;
+       instance->PostConnect = wf_post_connect;
+       instance->Authenticate = wf_authenticate;
+       instance->VerifyCertificate = wf_verify_certificate;
+       instance->ReceiveChannelData = wf_receive_channel_data;
+
+       instance->context_size = sizeof(wfContext);
+       instance->ContextNew = wf_context_new;
+       instance->ContextFree = wf_context_free;
+       freerdp_context_new(instance);
+
+       wfi = ((wfContext*) (instance->context))->wfi;
+       wfi->instance = instance;
+
+       instance->context->argc = argc;
+       instance->context->argv = argv;
+
+       wfi->hInstance = hInstance;
+       wfi->cursor = LoadCursor(NULL, IDC_ARROW);
+       wfi->icon = LoadIcon(NULL, IDI_APPLICATION);
+       wfi->wndClassName = _tcsdup(_T("FreeRDP"));
+
+       wfi->wndClass.cbSize = sizeof(WNDCLASSEX);
+       wfi->wndClass.style = CS_HREDRAW | CS_VREDRAW;
+       wfi->wndClass.lpfnWndProc = wf_event_proc;
+       wfi->wndClass.cbClsExtra = 0;
+       wfi->wndClass.cbWndExtra = 0;
+       wfi->wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+       wfi->wndClass.hCursor = wfi->cursor;
+       wfi->wndClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
+       wfi->wndClass.lpszMenuName = NULL;
+       wfi->wndClass.lpszClassName = wfi->wndClassName;
+       wfi->wndClass.hInstance = hInstance;
+       wfi->wndClass.hIconSm = wfi->icon;
+       RegisterClassEx(&(wfi->wndClass));
+
+       return wfi;
+}
+
+int wf_start(wfInfo* wfi)
+{
+       int status;
+       freerdp* instance = wfi->instance;
+
+       wfi->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfi, 0, NULL);
+
+       if (!wfi->keyboardThread)
+               return -1;
+
+       status = freerdp_client_parse_command_line_arguments(instance->context->argc, instance->context->argv, instance->settings);
+
+       freerdp_client_load_addins(instance->context->channels, instance->settings);
+
+       wfi->thread = CreateThread(NULL, 0, wf_thread, (void*) instance, 0, NULL);
+
+       if (!wfi->thread)
+               return -1;
+
+       return 0;
+}
+
+int wf_stop(wfInfo* wfi)
+{
+       return 0;
+}
+
+int wf_free(wfInfo* wfi)
+{
+       freerdp* instance = wfi->instance;
+
+       freerdp_context_free(instance);
+       freerdp_free(instance);
+
+       return 0;
+}
index 3e6bcf5..2385fc0 100644 (file)
  * limitations under the License.
  */
 
-#ifndef __WFREERDP_H
-#define __WFREERDP_H
+#ifndef __WF_INTERFACE_H
+#define __WF_INTERFACE_H
 
 #include <winpr/windows.h>
 
+#include <freerdp/api.h>
 #include <freerdp/freerdp.h>
 #include <freerdp/gdi/gdi.h>
 #include <freerdp/gdi/dc.h>
@@ -75,6 +76,15 @@ struct wf_info
        int percentscreen;
        char window_title[64];
 
+       HANDLE thread;
+       HANDLE keyboardThread;
+
+       HICON icon;
+       HINSTANCE hInstance;
+       WNDCLASSEX wndClass;
+       LPCTSTR wndClassName;
+       HCURSOR hDefaultCursor;
+
        HWND hwnd;
        POINT diff;
        HGDI_DC hdc;
@@ -96,28 +106,13 @@ struct wf_info
        BOOL sw_gdi;
 };
 
-int wf_create_console(void);
-
-void wf_context_new(freerdp* instance, rdpContext* context);
-void wf_context_free(freerdp* instance, rdpContext* context);
-
-void wf_sw_begin_paint(rdpContext* context);
-void wf_sw_end_paint(rdpContext* context);
-void wf_sw_desktop_resize(rdpContext* context);
-
-void wf_hw_begin_paint(rdpContext* context);
-void wf_hw_end_paint(rdpContext* context);
-void wf_hw_desktop_resize(rdpContext* context);
-
-BOOL wf_pre_connect(freerdp* instance);
-BOOL wf_post_connect(freerdp* instance);
-
-BOOL wf_authenticate(freerdp* instance, char** username, char** password, char** domain);
-BOOL wf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint);
+FREERDP_API int wf_global_init();
+FREERDP_API int wf_global_uninit();
 
-int wf_receive_channel_data(freerdp* instance, int channelId, BYTE* data, int size, int flags, int total_size);
+FREERDP_API int wf_start(wfInfo* wfi);
+FREERDP_API int wf_stop(wfInfo* wfi);
 
-DWORD WINAPI kbd_thread_func(LPVOID lpParam);
-DWORD WINAPI thread_func(LPVOID lpParam);
+FREERDP_API wfInfo* wf_new(HINSTANCE hInstance, int argc, char** argv);
+FREERDP_API int wf_free(wfInfo* wfi);
 
 #endif
index f3c0f95..feddf7e 100644 (file)
@@ -16,6 +16,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #ifndef __WF_WINDOW_H
 #define __WF_WINDOW_H
 
index 38326b4..a625a86 100644 (file)
 
 #include "wf_interface.h"
 
-HANDLE g_done_event;
-HINSTANCE g_hInstance;
-HCURSOR g_default_cursor;
-int g_thread_count = 0;
-LPCTSTR g_wnd_class_name = L"wfreerdp";
-
 INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 {
-       freerdp* instance;
-       WSADATA wsa_data;
-       WNDCLASSEX wnd_cls;
-
-       if (!getenv("HOME"))
-       {
-               char home[MAX_PATH * 2] = "HOME=";
-               strcat(home, getenv("HOMEDRIVE"));
-               strcat(home, getenv("HOMEPATH"));
-               _putenv(home);
-       }
-
-       if (WSAStartup(0x101, &wsa_data) != 0)
-               return 1;
-
-       g_done_event = CreateEvent(0, 1, 0, 0);
-
-#if defined(WITH_DEBUG) || defined(_DEBUG)
-       wf_create_console();
-#endif
-
-       g_default_cursor = LoadCursor(NULL, IDC_ARROW);
-
-       wnd_cls.cbSize        = sizeof(WNDCLASSEX);
-       wnd_cls.style         = CS_HREDRAW | CS_VREDRAW;
-       wnd_cls.lpfnWndProc   = wf_event_proc;
-       wnd_cls.cbClsExtra    = 0;
-       wnd_cls.cbWndExtra    = 0;
-       wnd_cls.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
-       wnd_cls.hCursor       = g_default_cursor;
-       wnd_cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
-       wnd_cls.lpszMenuName  = NULL;
-       wnd_cls.lpszClassName = g_wnd_class_name;
-       wnd_cls.hInstance     = hInstance;
-       wnd_cls.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
-       RegisterClassEx(&wnd_cls);
-
-       g_hInstance = hInstance;
-       freerdp_channels_global_init();
-
-       instance = freerdp_new();
-       instance->PreConnect = wf_pre_connect;
-       instance->PostConnect = wf_post_connect;
-       instance->Authenticate = wf_authenticate;
-       instance->VerifyCertificate = wf_verify_certificate;
-       instance->ReceiveChannelData = wf_receive_channel_data;
-
-       instance->context_size = sizeof(wfContext);
-       instance->ContextNew = wf_context_new;
-       instance->ContextFree = wf_context_free;
-       freerdp_context_new(instance);
+       int status;
+       wfInfo* wfi;
 
-       instance->context->argc = __argc;
-       instance->context->argv = __argv;
+       wf_global_init();
 
-        if (!CreateThread(NULL, 0, kbd_thread_func, NULL, 0, NULL))
-               printf("error creating keyboard handler thread");
+       wfi = wf_new(hInstance, __argc, __argv);
 
-       //while (1)
-       {
-               int status;
-
-               freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0);
-
-               status = freerdp_client_parse_command_line_arguments(__argc, __argv, instance->settings);
-
-               freerdp_client_load_addins(instance->context->channels, instance->settings);
+       status = wf_start(wfi);
 
-               if (status < 0)
-               {
-                       printf("failed to parse arguments.\n");
-#ifdef _DEBUG
-                       system("pause");
-#endif
-                       exit(-1);
-               }
-
-               if (CreateThread(NULL, 0, thread_func, instance, 0, NULL) != 0)
-                       g_thread_count++;
-       }
-
-       if (g_thread_count > 0)
+       if (status < 0)
        {
-               WaitForSingleObject(g_done_event, INFINITE);
+               MessageBox(GetConsoleWindow(),
+                       _T("Failed to start wfreerdp.\n\nPlease check the debug output."),
+                       _T("FreeRDP Error"), MB_ICONSTOP);
        }
        else
        {
-               MessageBox(GetConsoleWindow(),
-                       L"Failed to start wfreerdp.\n\nPlease check the debug output.",
-                       L"FreeRDP Error", MB_ICONSTOP);
+               WaitForSingleObject(wfi->thread, INFINITE);
        }
 
-       freerdp_context_free(instance);
-       freerdp_free(instance);
-
-       WSACleanup();
-
-#ifdef _DEBUG
-       system("pause");
-#endif
+       wf_free(wfi);
 
        return 0;
 }
index 8ff88ba..913d5d6 100644 (file)
 #ifndef __WFREERDP_H
 #define __WFREERDP_H
 
-#include <winpr/windows.h>
-
-#include <freerdp/freerdp.h>
-#include <freerdp/gdi/gdi.h>
-#include <freerdp/gdi/dc.h>
-#include <freerdp/gdi/region.h>
-#include <freerdp/cache/cache.h>
-#include <freerdp/codec/color.h>
-#include <freerdp/utils/debug.h>
-#include <freerdp/channels/channels.h>
-#include <freerdp/codec/rfx.h>
-#include <freerdp/codec/nsc.h>
-
-#include "wf_event.h"
-
-struct wf_bitmap
-{
-       rdpBitmap _bitmap;
-       HDC hdc;
-       HBITMAP bitmap;
-       HBITMAP org_bitmap;
-       BYTE* pdata;
-};
-typedef struct wf_bitmap wfBitmap;
-
-struct wf_pointer
-{
-       rdpPointer pointer;
-       HCURSOR cursor;
-};
-typedef struct wf_pointer wfPointer;
-
-typedef struct wf_info wfInfo;
-
-struct wf_context
-{
-       rdpContext _p;
-
-       wfInfo* wfi;
-};
-typedef struct wf_context wfContext;
-
-struct wf_info
-{
-       int width;
-       int height;
-       int offset_x;
-       int offset_y;
-       int fs_toggle;
-       int fullscreen;
-       int percentscreen;
-       char window_title[64];
-
-       HWND hwnd;
-       POINT diff;
-       HGDI_DC hdc;
-       UINT16 srcBpp;
-       UINT16 dstBpp;
-       freerdp* instance;
-       wfBitmap* primary;
-       wfBitmap* drawing;
-       HCLRCONV clrconv;
-       HCURSOR cursor;
-       HBRUSH brush;
-       HBRUSH org_brush;
-       RECT update_rect;
-
-       wfBitmap* tile;
-       RFX_CONTEXT* rfx_context;
-       NSC_CONTEXT* nsc_context;
-
-       BOOL sw_gdi;
-};
+#include "wf_interface.h"
 
 #endif