From ac4cb24a68801dfe79e1321221d068614bca1342 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 18 Mar 2013 21:54:50 -0400 Subject: [PATCH] wfreerdp: clean separation of client core and controlling code --- client/Windows/wf_event.c | 9 ++- client/Windows/wf_graphics.c | 2 - client/Windows/wf_interface.c | 176 +++++++++++++++++++++++++++++++++--------- client/Windows/wf_interface.h | 41 +++++----- client/Windows/wf_window.h | 1 + client/Windows/wfreerdp.c | 107 +++---------------------- client/Windows/wfreerdp.h | 74 +----------------- 7 files changed, 177 insertions(+), 233 deletions(-) diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index 0c7fd8b..1ab6953 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -33,10 +33,9 @@ #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; diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index 53b2d92..5071495 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -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; diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 17eaed4..a0db3c3 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -55,15 +55,17 @@ #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; +} diff --git a/client/Windows/wf_interface.h b/client/Windows/wf_interface.h index 3e6bcf5..2385fc0 100644 --- a/client/Windows/wf_interface.h +++ b/client/Windows/wf_interface.h @@ -19,11 +19,12 @@ * limitations under the License. */ -#ifndef __WFREERDP_H -#define __WFREERDP_H +#ifndef __WF_INTERFACE_H +#define __WF_INTERFACE_H #include +#include #include #include #include @@ -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 diff --git a/client/Windows/wf_window.h b/client/Windows/wf_window.h index f3c0f95..feddf7e 100644 --- a/client/Windows/wf_window.h +++ b/client/Windows/wf_window.h @@ -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 diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 38326b4..a625a86 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -40,114 +40,29 @@ #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; } diff --git a/client/Windows/wfreerdp.h b/client/Windows/wfreerdp.h index 8ff88ba..913d5d6 100644 --- a/client/Windows/wfreerdp.h +++ b/client/Windows/wfreerdp.h @@ -22,78 +22,6 @@ #ifndef __WFREERDP_H #define __WFREERDP_H -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 -- 2.7.4