diff --git a/client/Windows/cli/wfreerdp.c b/client/Windows/cli/wfreerdp.c index 87601279f..ac8d6f665 100644 --- a/client/Windows/cli/wfreerdp.c +++ b/client/Windows/cli/wfreerdp.c @@ -44,27 +44,53 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + int index; int status; - wfInfo* wfi; + HANDLE thread; + wfContext* wfc; + DWORD dwExitCode; + rdpContext* context; + rdpSettings* settings; + RDP_CLIENT_ENTRY_POINTS clientEntryPoints; - freerdp_client_global_init(); + ZeroMemory(&clientEntryPoints, sizeof(RDP_CLIENT_ENTRY_POINTS)); + clientEntryPoints.Size = sizeof(RDP_CLIENT_ENTRY_POINTS); + clientEntryPoints.Version = RDP_CLIENT_INTERFACE_VERSION; - wfi = freerdp_client_new(__argc, __argv); + RdpClientEntry(&clientEntryPoints); - status = freerdp_client_start(wfi); + context = freerdp_client_context_new(&clientEntryPoints); - if (status < 0) + settings = context->settings; + wfc = (wfContext*) context; + + context->argc = __argc; + context->argv = (char**) malloc(sizeof(char*) * __argc); + + for (index = 0; index < context->argc; index++) + context->argv[index] = _strdup(__argv[index]); + + status = freerdp_client_parse_command_line(context, context->argc, context->argv); + + status = freerdp_client_command_line_status_print(context->argc, context->argv, settings, status); + + if (status) { - MessageBox(GetConsoleWindow(), - _T("Failed to start wfreerdp.\n\nPlease check the debug output."), - _T("FreeRDP Error"), MB_ICONSTOP); - } - else - { - WaitForSingleObject(wfi->thread, INFINITE); + freerdp_client_context_free(context); + return 0; } - freerdp_client_free(wfi); + freerdp_client_start(context); + + thread = freerdp_client_get_thread(context); + + WaitForSingleObject(thread, INFINITE); + + GetExitCodeThread(thread, &dwExitCode); + + freerdp_client_stop(context); + + freerdp_client_context_free(context); return 0; } diff --git a/client/Windows/wf_cliprdr.c b/client/Windows/wf_cliprdr.c index cfaa2e21e..78bb02dd4 100644 --- a/client/Windows/wf_cliprdr.c +++ b/client/Windows/wf_cliprdr.c @@ -29,54 +29,54 @@ #include "wf_cliprdr.h" -void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman) +void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels) { } -void wf_cliprdr_uninit(wfInfo* wfi) +void wf_cliprdr_uninit(wfContext* wfc) { } -static void wf_cliprdr_process_cb_monitor_ready_event(wfInfo* wfi) +static void wf_cliprdr_process_cb_monitor_ready_event(wfContext* wfc) { } -static void wf_cliprdr_process_cb_data_request_event(wfInfo* wfi, RDP_CB_DATA_REQUEST_EVENT* event) +static void wf_cliprdr_process_cb_data_request_event(wfContext* wfc, RDP_CB_DATA_REQUEST_EVENT* event) { } -static void wf_cliprdr_process_cb_format_list_event(wfInfo* wfi, RDP_CB_FORMAT_LIST_EVENT* event) +static void wf_cliprdr_process_cb_format_list_event(wfContext* wfc, RDP_CB_FORMAT_LIST_EVENT* event) { } -static void wf_cliprdr_process_cb_data_response_event(wfInfo* wfi, RDP_CB_DATA_RESPONSE_EVENT* event) +static void wf_cliprdr_process_cb_data_response_event(wfContext* wfc, RDP_CB_DATA_RESPONSE_EVENT* event) { } -void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event) +void wf_process_cliprdr_event(wfContext* wfc, wMessage* event) { switch (GetMessageType(event->id)) { case CliprdrChannel_MonitorReady: - wf_cliprdr_process_cb_monitor_ready_event(wfi); + wf_cliprdr_process_cb_monitor_ready_event(wfc); break; case CliprdrChannel_FormatList: - wf_cliprdr_process_cb_format_list_event(wfi, (RDP_CB_FORMAT_LIST_EVENT*) event); + wf_cliprdr_process_cb_format_list_event(wfc, (RDP_CB_FORMAT_LIST_EVENT*) event); break; case CliprdrChannel_DataRequest: - wf_cliprdr_process_cb_data_request_event(wfi, (RDP_CB_DATA_REQUEST_EVENT*) event); + wf_cliprdr_process_cb_data_request_event(wfc, (RDP_CB_DATA_REQUEST_EVENT*) event); break; case CliprdrChannel_DataResponse: - wf_cliprdr_process_cb_data_response_event(wfi, (RDP_CB_DATA_RESPONSE_EVENT*) event); + wf_cliprdr_process_cb_data_response_event(wfc, (RDP_CB_DATA_RESPONSE_EVENT*) event); break; default: @@ -84,27 +84,27 @@ void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event) } } -BOOL wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +BOOL wf_cliprdr_process_selection_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return TRUE; } -BOOL wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +BOOL wf_cliprdr_process_selection_request(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return TRUE; } -BOOL wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +BOOL wf_cliprdr_process_selection_clear(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return TRUE; } -BOOL wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +BOOL wf_cliprdr_process_property_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return TRUE; } -void wf_cliprdr_check_owner(wfInfo* wfi) +void wf_cliprdr_check_owner(wfContext* wfc) { } diff --git a/client/Windows/wf_cliprdr.h b/client/Windows/wf_cliprdr.h index 2239a5d79..96a26e1be 100644 --- a/client/Windows/wf_cliprdr.h +++ b/client/Windows/wf_cliprdr.h @@ -21,13 +21,13 @@ #include "wf_interface.h" -void wf_cliprdr_init(wfInfo* wfi, rdpChannels* chanman); -void wf_cliprdr_uninit(wfInfo* wfi); -void wf_process_cliprdr_event(wfInfo* wfi, wMessage* event); -BOOL wf_cliprdr_process_selection_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -BOOL wf_cliprdr_process_selection_request(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -BOOL wf_cliprdr_process_selection_clear(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -BOOL wf_cliprdr_process_property_notify(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -void wf_cliprdr_check_owner(wfInfo* wfi); +void wf_cliprdr_init(wfContext* wfc, rdpChannels* channels); +void wf_cliprdr_uninit(wfContext* wfc); +void wf_process_cliprdr_event(wfContext* wfc, wMessage* event); +BOOL wf_cliprdr_process_selection_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +BOOL wf_cliprdr_process_selection_request(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +BOOL wf_cliprdr_process_selection_clear(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +BOOL wf_cliprdr_process_property_notify(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +void wf_cliprdr_check_owner(wfContext* wfc); #endif /* __WF_CLIPRDR_H */ diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index 279414583..c243d35da 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -37,12 +37,12 @@ static HWND g_focus_hWnd; #define X_POS(lParam) (lParam & 0xFFFF) #define Y_POS(lParam) ((lParam >> 16) & 0xFFFF) -BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop); -void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); +BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop); +void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y); LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) { - wfInfo* wfi; + wfContext* wfc; DWORD rdp_scancode; rdpInput* input; PKBDLLHOOKSTRUCT p; @@ -57,26 +57,26 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: - wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA); + wfc = (wfContext*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA); p = (PKBDLLHOOKSTRUCT) lParam; - if (!wfi || !p) + if (!wfc || !p) return 1; - input = wfi->instance->input; + input = wfc->instance->input; rdp_scancode = MAKE_RDP_SCANCODE((BYTE) p->scanCode, p->flags & LLKHF_EXTENDED); DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X", (wParam == WM_KEYDOWN), (BYTE) p->scanCode, p->flags, p->vkCode); - if (wfi->fs_toggle && + if (wfc->fs_toggle && ((p->vkCode == VK_RETURN) || (p->vkCode == VK_CANCEL)) && (GetAsyncKeyState(VK_CONTROL) & 0x8000) && (GetAsyncKeyState(VK_MENU) & 0x8000)) /* could also use flags & LLKHF_ALTDOWN */ { if (wParam == WM_KEYDOWN) { - wf_toggle_fullscreen(wfi); + wf_toggle_fullscreen(wfc); return 1; } } @@ -126,14 +126,14 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) return CallNextHookEx(NULL, nCode, wParam, lParam); } -static int wf_event_process_WM_MOUSEWHEEL(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +static int wf_event_process_WM_MOUSEWHEEL(wfContext* wfc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { int delta; int flags; rdpInput* input; DefWindowProc(hWnd, Msg, wParam, lParam); - input = wfi->instance->input; + input = wfc->instance->input; delta = ((signed short) HIWORD(wParam)); /* GET_WHEEL_DELTA_WPARAM(wParam); */ if (delta > 0) @@ -150,11 +150,12 @@ static int wf_event_process_WM_MOUSEWHEEL(wfInfo* wfi, HWND hWnd, UINT Msg, WPAR return 0; } -void wf_sizing(wfInfo* wfi, WPARAM wParam, LPARAM lParam) +void wf_sizing(wfContext* wfc, WPARAM wParam, LPARAM lParam) { // Holding the CTRL key down while resizing the window will force the desktop aspect ratio. LPRECT rect; - if (wfi->instance->settings->SmartSizing && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) + + if (wfc->instance->settings->SmartSizing && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) { rect = (LPRECT) wParam; @@ -164,20 +165,20 @@ void wf_sizing(wfInfo* wfi, WPARAM wParam, LPARAM lParam) case WMSZ_RIGHT: case WMSZ_BOTTOMRIGHT: // Adjust height - rect->bottom = rect->top + wfi->height * (rect->right - rect->left) / wfi->instance->settings->DesktopWidth; + rect->bottom = rect->top + wfc->height * (rect->right - rect->left) / wfc->instance->settings->DesktopWidth; break; case WMSZ_TOP: case WMSZ_BOTTOM: case WMSZ_TOPRIGHT: // Adjust width - rect->right = rect->left + wfi->width * (rect->bottom - rect->top) / wfi->instance->settings->DesktopHeight; + rect->right = rect->left + wfc->width * (rect->bottom - rect->top) / wfc->instance->settings->DesktopHeight; break; case WMSZ_BOTTOMLEFT: case WMSZ_TOPLEFT: // adjust width - rect->left = rect->right - (wfi->width * (rect->bottom - rect->top) / wfi->instance->settings->DesktopHeight); + rect->left = rect->right - (wfc->width * (rect->bottom - rect->top) / wfc->instance->settings->DesktopHeight); break; } @@ -189,38 +190,38 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam { HDC hdc; LONG ptr; - wfInfo* wfi; + wfContext* wfc; int x, y, w, h; PAINTSTRUCT ps; rdpInput* input; BOOL processed; - - RECT windowRect, clientRect; - MINMAXINFO *minmax; + RECT windowRect; + RECT clientRect; + MINMAXINFO* minmax; SCROLLINFO si; processed = TRUE; ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA); - wfi = (wfInfo*) ptr; + wfc = (wfContext*) ptr; - if (wfi != NULL) + if (wfc != NULL) { - input = wfi->instance->input; + input = wfc->instance->input; switch (Msg) { case WM_MOVE: - if (!wfi->disablewindowtracking) + if (!wfc->disablewindowtracking) { int x = (int)(short) LOWORD(lParam); int y = (int)(short) HIWORD(lParam); - ((wfContext*) wfi->instance->context)->wfi->client_x = x; - ((wfContext*) wfi->instance->context)->wfi->client_y = y; + wfc->client_x = x; + wfc->client_y = y; } break; case WM_GETMINMAXINFO: - if (wfi->instance->settings->SmartSizing) + if (wfc->instance->settings->SmartSizing) { processed = FALSE; } @@ -229,41 +230,42 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam // Set maximum window size for resizing minmax = (MINMAXINFO*) lParam; - wf_update_canvas_diff(wfi); - if (!wfi->fullscreen) + wf_update_canvas_diff(wfc); + + if (!wfc->fullscreen) { // add window decoration - minmax->ptMaxTrackSize.x = wfi->width + wfi->diff.x; - minmax->ptMaxTrackSize.y = wfi->height + wfi->diff.y; + minmax->ptMaxTrackSize.x = wfc->width + wfc->diff.x; + minmax->ptMaxTrackSize.y = wfc->height + wfc->diff.y; } } break; case WM_SIZING: - wf_sizing(wfi, lParam, wParam); + wf_sizing(wfc, lParam, wParam); break; case WM_SIZE: - GetWindowRect(wfi->hwnd, &windowRect); + GetWindowRect(wfc->hwnd, &windowRect); - if (!wfi->fullscreen) + if (!wfc->fullscreen) { - wfi->client_width = LOWORD(lParam); - wfi->client_height = HIWORD(lParam); - wfi->client_x = windowRect.left; - wfi->client_y = windowRect.top; + wfc->client_width = LOWORD(lParam); + wfc->client_height = HIWORD(lParam); + wfc->client_x = windowRect.left; + wfc->client_y = windowRect.top; } - wf_size_scrollbars(wfi, LOWORD(lParam), HIWORD(lParam)); + wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam)); // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect. - if (wParam == SIZE_MAXIMIZED && !wfi->fullscreen) - SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED); + if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen) + SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED); break; case WM_EXITSIZEMOVE: - wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height); + wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height); break; case WM_ERASEBKGND: @@ -278,38 +280,38 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam w = ps.rcPaint.right - ps.rcPaint.left + 1; h = ps.rcPaint.bottom - ps.rcPaint.top + 1; - wf_scale_blt(wfi, hdc, x, y, w, h, wfi->primary->hdc, x - wfi->offset_x + wfi->xCurrentScroll, y - wfi->offset_y + wfi->yCurrentScroll, SRCCOPY); + wf_scale_blt(wfc, hdc, x, y, w, h, wfc->primary->hdc, x - wfc->offset_x + wfc->xCurrentScroll, y - wfc->offset_y + wfc->yCurrentScroll, SRCCOPY); EndPaint(hWnd, &ps); break; case WM_LBUTTONDOWN: - wf_scale_mouse_event(wfi, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); + wf_scale_mouse_event(wfc, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_LBUTTONUP: - wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); + wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_RBUTTONDOWN: - wf_scale_mouse_event(wfi, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); + wf_scale_mouse_event(wfc, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_RBUTTONUP: - wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); + wf_scale_mouse_event(wfc, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_MOUSEMOVE: - wf_scale_mouse_event(wfi, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y); + wf_scale_mouse_event(wfc, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfc->offset_x, Y_POS(lParam) - wfc->offset_y); break; case WM_MOUSEWHEEL: - wf_event_process_WM_MOUSEWHEEL(wfi, hWnd, Msg, wParam, lParam); + wf_event_process_WM_MOUSEWHEEL(wfc, hWnd, Msg, wParam, lParam); break; case WM_SETCURSOR: if (LOWORD(lParam) == HTCLIENT) - SetCursor(wfi->cursor); + SetCursor(wfc->cursor); else DefWindowProc(hWnd, Msg, wParam, lParam); break; @@ -324,22 +326,22 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam { // User clicked the scroll bar shaft left of the scroll box. case SB_PAGEUP: - xNewPos = wfi->xCurrentScroll - 50; + xNewPos = wfc->xCurrentScroll - 50; break; // User clicked the scroll bar shaft right of the scroll box. case SB_PAGEDOWN: - xNewPos = wfi->xCurrentScroll + 50; + xNewPos = wfc->xCurrentScroll + 50; break; // User clicked the left arrow. case SB_LINEUP: - xNewPos = wfi->xCurrentScroll - 5; + xNewPos = wfc->xCurrentScroll - 5; break; // User clicked the right arrow. case SB_LINEDOWN: - xNewPos = wfi->xCurrentScroll + 5; + xNewPos = wfc->xCurrentScroll + 5; break; // User dragged the scroll box. @@ -352,37 +354,37 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam break; default: - xNewPos = wfi->xCurrentScroll; + xNewPos = wfc->xCurrentScroll; } // New position must be between 0 and the screen width. xNewPos = MAX(0, xNewPos); - xNewPos = MIN(wfi->xMaxScroll, xNewPos); + xNewPos = MIN(wfc->xMaxScroll, xNewPos); // If the current position does not change, do not scroll. - if (xNewPos == wfi->xCurrentScroll) + if (xNewPos == wfc->xCurrentScroll) break; // Determine the amount scrolled (in pixels). - xDelta = xNewPos - wfi->xCurrentScroll; + xDelta = xNewPos - wfc->xCurrentScroll; // Reset the current scroll position. - wfi->xCurrentScroll = xNewPos; + wfc->xCurrentScroll = xNewPos; // Scroll the window. (The system repaints most of the // client area when ScrollWindowEx is called; however, it is // necessary to call UpdateWindow in order to repaint the // rectangle of pixels that were invalidated.) - ScrollWindowEx(wfi->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, + ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL, SW_INVALIDATE); - UpdateWindow(wfi->hwnd); + UpdateWindow(wfc->hwnd); // Reset the scroll bar. si.cbSize = sizeof(si); si.fMask = SIF_POS; - si.nPos = wfi->xCurrentScroll; - SetScrollInfo(wfi->hwnd, SB_HORZ, &si, TRUE); + si.nPos = wfc->xCurrentScroll; + SetScrollInfo(wfc->hwnd, SB_HORZ, &si, TRUE); } break; @@ -396,22 +398,22 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam { // User clicked the scroll bar shaft above the scroll box. case SB_PAGEUP: - yNewPos = wfi->yCurrentScroll - 50; + yNewPos = wfc->yCurrentScroll - 50; break; // User clicked the scroll bar shaft below the scroll box. case SB_PAGEDOWN: - yNewPos = wfi->yCurrentScroll + 50; + yNewPos = wfc->yCurrentScroll + 50; break; // User clicked the top arrow. case SB_LINEUP: - yNewPos = wfi->yCurrentScroll - 5; + yNewPos = wfc->yCurrentScroll - 5; break; // User clicked the bottom arrow. case SB_LINEDOWN: - yNewPos = wfi->yCurrentScroll + 5; + yNewPos = wfc->yCurrentScroll + 5; break; // User dragged the scroll box. @@ -425,37 +427,37 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam break; default: - yNewPos = wfi->yCurrentScroll; + yNewPos = wfc->yCurrentScroll; } // New position must be between 0 and the screen height. yNewPos = MAX(0, yNewPos); - yNewPos = MIN(wfi->yMaxScroll, yNewPos); + yNewPos = MIN(wfc->yMaxScroll, yNewPos); // If the current position does not change, do not scroll. - if (yNewPos == wfi->yCurrentScroll) + if (yNewPos == wfc->yCurrentScroll) break; // Determine the amount scrolled (in pixels). - yDelta = yNewPos - wfi->yCurrentScroll; + yDelta = yNewPos - wfc->yCurrentScroll; // Reset the current scroll position. - wfi->yCurrentScroll = yNewPos; + wfc->yCurrentScroll = yNewPos; // Scroll the window. (The system repaints most of the // client area when ScrollWindowEx is called; however, it is // necessary to call UpdateWindow in order to repaint the // rectangle of pixels that were invalidated.) - ScrollWindowEx(wfi->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, + ScrollWindowEx(wfc->hwnd, -xDelta, -yDelta, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL, SW_INVALIDATE); - UpdateWindow(wfi->hwnd); + UpdateWindow(wfc->hwnd); // Reset the scroll bar. si.cbSize = sizeof(si); si.fMask = SIF_POS; - si.nPos = wfi->yCurrentScroll; - SetScrollInfo(wfi->hwnd, SB_VERT, &si, TRUE); + si.nPos = wfc->yCurrentScroll; + SetScrollInfo(wfc->hwnd, SB_VERT, &si, TRUE); } break; @@ -463,9 +465,9 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam { if (wParam == SYSCOMMAND_ID_SMARTSIZING) { - HMENU hMenu = GetSystemMenu(wfi->hwnd, FALSE); - freerdp_set_param_bool(wfi->instance->settings, FreeRDP_SmartSizing, !wfi->instance->settings->SmartSizing); - CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, wfi->instance->settings->SmartSizing ? MF_CHECKED : MF_UNCHECKED); + HMENU hMenu = GetSystemMenu(wfc->hwnd, FALSE); + freerdp_set_param_bool(wfc->instance->settings, FreeRDP_SmartSizing, !wfc->instance->settings->SmartSizing); + CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, wfc->instance->settings->SmartSizing ? MF_CHECKED : MF_UNCHECKED); } else @@ -496,7 +498,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam case WM_SETCURSOR: if (LOWORD(lParam) == HTCLIENT) - SetCursor(wfi->hDefaultCursor); + SetCursor(wfc->hDefaultCursor); else DefWindowProc(hWnd, Msg, wParam, lParam); break; @@ -507,7 +509,7 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam break; case WM_KILLFOCUS: - if (g_focus_hWnd == hWnd && wfi && !wfi->fullscreen) + if (g_focus_hWnd == hWnd && wfc && !wfc->fullscreen) { DEBUG_KBD("loosing focus %X", hWnd); g_focus_hWnd = NULL; @@ -535,20 +537,20 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam return 0; } -BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop) +BOOL wf_scale_blt(wfContext* wfc, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, int x1, int y1, DWORD rop) { int ww, wh, dw, dh; - if (!wfi->client_width) - wfi->client_width = wfi->width; + if (!wfc->client_width) + wfc->client_width = wfc->width; - if (!wfi->client_height) - wfi->client_height = wfi->height; + if (!wfc->client_height) + wfc->client_height = wfc->height; - ww = wfi->client_width; - wh = wfi->client_height; - dw = wfi->instance->settings->DesktopWidth; - dh = wfi->instance->settings->DesktopHeight; + ww = wfc->client_width; + wh = wfc->client_height; + dw = wfc->instance->settings->DesktopWidth; + dh = wfc->instance->settings->DesktopHeight; if (!ww) ww = dw; @@ -556,38 +558,38 @@ BOOL wf_scale_blt(wfInfo* wfi, HDC hdc, int x, int y, int w, int h, HDC hdcSrc, if (!wh) wh = dh; - if (wfi->fullscreen || !wfi->instance->settings->SmartSizing || (ww == dw && wh == dh)) + if (wfc->fullscreen || !wfc->instance->settings->SmartSizing || (ww == dw && wh == dh)) { - return BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x1, y1, SRCCOPY); + return BitBlt(hdc, x, y, w, h, wfc->primary->hdc, x1, y1, SRCCOPY); } else { SetStretchBltMode(hdc, HALFTONE); SetBrushOrgEx(hdc, 0, 0, NULL); - return StretchBlt(hdc, 0, 0, ww, wh, wfi->primary->hdc, 0, 0, dw, dh, SRCCOPY); + return StretchBlt(hdc, 0, 0, ww, wh, wfc->primary->hdc, 0, 0, dw, dh, SRCCOPY); } return TRUE; } -void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) +void wf_scale_mouse_event(wfContext* wfc, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) { int ww, wh, dw, dh; - if (!wfi->client_width) - wfi->client_width = wfi->width; + if (!wfc->client_width) + wfc->client_width = wfc->width; - if (!wfi->client_height) - wfi->client_height = wfi->height; + if (!wfc->client_height) + wfc->client_height = wfc->height; - ww = wfi->client_width; - wh = wfi->client_height; - dw = wfi->instance->settings->DesktopWidth; - dh = wfi->instance->settings->DesktopHeight; + ww = wfc->client_width; + wh = wfc->client_height; + dw = wfc->instance->settings->DesktopWidth; + dh = wfc->instance->settings->DesktopHeight; - if (!wfi->instance->settings->SmartSizing || (ww == dw) && (wh == dh)) - input->MouseEvent(input, flags, x + wfi->xCurrentScroll, y + wfi->yCurrentScroll); + if (!wfc->instance->settings->SmartSizing || (ww == dw) && (wh == dh)) + input->MouseEvent(input, flags, x + wfc->xCurrentScroll, y + wfc->yCurrentScroll); else - input->MouseEvent(input, flags, x * dw / ww + wfi->xCurrentScroll, y * dh / wh + wfi->yCurrentScroll); + input->MouseEvent(input, flags, x * dw / ww + wfc->xCurrentScroll, y * dh / wh + wfc->yCurrentScroll); } diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c index a6736e539..41fae28d0 100644 --- a/client/Windows/wf_gdi.c +++ b/client/Windows/wf_gdi.c @@ -72,10 +72,10 @@ BOOL wf_set_rop2(HDC hdc, int rop2) return TRUE; } -wfBitmap* wf_glyph_new(wfInfo* wfi, GLYPH_DATA* glyph) +wfBitmap* wf_glyph_new(wfContext* wfc, GLYPH_DATA* glyph) { wfBitmap* glyph_bmp; - glyph_bmp = wf_image_new(wfi, glyph->cx, glyph->cy, 1, glyph->aj); + glyph_bmp = wf_image_new(wfc, glyph->cx, glyph->cy, 1, glyph->aj); return glyph_bmp; } @@ -84,7 +84,7 @@ void wf_glyph_free(wfBitmap* glyph) wf_image_free(glyph); } -BYTE* wf_glyph_convert(wfInfo* wfi, int width, int height, BYTE* data) +BYTE* wf_glyph_convert(wfContext* wfc, int width, int height, BYTE* data) { int indexx; int indexy; @@ -115,7 +115,7 @@ BYTE* wf_glyph_convert(wfInfo* wfi, int width, int height, BYTE* data) return cdata; } -HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp) +HBRUSH wf_create_brush(wfContext* wfc, rdpBrush* brush, UINT32 color, int bpp) { int i; HBRUSH br; @@ -135,7 +135,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, NULL); + pattern = wf_create_dib(wfc, 8, 8, bpp, brush->data, NULL); lbr.lbHatch = (ULONG_PTR) pattern; } else @@ -143,7 +143,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp) for (i = 0; i != 8; i++) ipattern[7 - i] = brush->data[i]; - cdata = wf_glyph_convert(wfi, 8, 8, ipattern); + cdata = wf_glyph_convert(wfc, 8, 8, ipattern); pattern = CreateBitmap(8, 8, 1, 1, cdata); lbr.lbHatch = (ULONG_PTR) pattern; free(cdata); @@ -159,7 +159,7 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp) } br = CreateBrushIndirect(&lbr); - SetBrushOrgEx(wfi->drawing->hdc, brush->x, brush->y, NULL); + SetBrushOrgEx(wfc->drawing->hdc, brush->x, brush->y, NULL); if (pattern != NULL) DeleteObject(pattern); @@ -167,20 +167,20 @@ HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, UINT32 color, int bpp) return br; } -void wf_scale_rect(wfInfo* wfi, RECT* source) +void wf_scale_rect(wfContext* wfc, RECT* source) { int ww, wh, dw, dh; - if (!wfi->client_width) - wfi->client_width = wfi->width; + if (!wfc->client_width) + wfc->client_width = wfc->width; - if (!wfi->client_height) - wfi->client_height = wfi->height; + if (!wfc->client_height) + wfc->client_height = wfc->height; - ww = wfi->client_width; - wh = wfi->client_height; - dw = wfi->instance->settings->DesktopWidth; - dh = wfi->instance->settings->DesktopHeight; + ww = wfc->client_width; + wh = wfc->client_height; + dw = wfc->instance->settings->DesktopWidth; + dh = wfc->instance->settings->DesktopHeight; if (!ww) ww = dw; @@ -188,7 +188,7 @@ void wf_scale_rect(wfInfo* wfi, RECT* source) if (!wh) wh = dh; - if (wfi->instance->settings->SmartSizing && (ww != dw || wh != dh)) + if (wfc->instance->settings->SmartSizing && (ww != dw || wh != dh)) { source->bottom = source->bottom * wh / dh + 20; source->top = source->top * wh / dh - 20; @@ -196,197 +196,194 @@ void wf_scale_rect(wfInfo* wfi, RECT* source) source->right = source->right * ww / dw + 20; } - source->bottom -= wfi->yCurrentScroll; - source->top -= wfi->yCurrentScroll; - source->left -= wfi->xCurrentScroll; - source->right -= wfi->xCurrentScroll; + source->bottom -= wfc->yCurrentScroll; + source->top -= wfc->yCurrentScroll; + source->left -= wfc->xCurrentScroll; + source->right -= wfc->xCurrentScroll; } -void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height) +void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height) { RECT rect; - wfi->update_rect.left = x + wfi->offset_x; - wfi->update_rect.top = y + wfi->offset_y; - wfi->update_rect.right = wfi->update_rect.left + width; - wfi->update_rect.bottom = wfi->update_rect.top + height; + wfc->update_rect.left = x + wfc->offset_x; + wfc->update_rect.top = y + wfc->offset_y; + wfc->update_rect.right = wfc->update_rect.left + width; + wfc->update_rect.bottom = wfc->update_rect.top + height; - wf_scale_rect(wfi, &(wfi->update_rect)); - InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE); + wf_scale_rect(wfc, &(wfc->update_rect)); + InvalidateRect(wfc->hwnd, &(wfc->update_rect), FALSE); rect.left = x; rect.right = width; rect.top = y; rect.bottom = height; - wf_scale_rect(wfi, &rect); - gdi_InvalidateRegion(wfi->hdc, rect.left, rect.top, rect.right, rect.bottom); + wf_scale_rect(wfc, &rect); + gdi_InvalidateRegion(wfc->hdc, rect.left, rect.top, rect.right, rect.bottom); } -void wf_update_offset(wfInfo* wfi) +void wf_update_offset(wfContext* wfc) { - if (wfi->fullscreen) + if (wfc->fullscreen) { - if (wfi->instance->settings->UseMultimon) + if (wfc->instance->settings->UseMultimon) { int x = GetSystemMetrics(SM_XVIRTUALSCREEN); int y = GetSystemMetrics(SM_YVIRTUALSCREEN); int w = GetSystemMetrics(SM_CXVIRTUALSCREEN); int h = GetSystemMetrics(SM_CYVIRTUALSCREEN); - wfi->offset_x = (w - wfi->width) / 2; - if (wfi->offset_x < x) - wfi->offset_x = x; - wfi->offset_y = (h - wfi->height) / 2; - if (wfi->offset_y < y) - wfi->offset_y = y; + wfc->offset_x = (w - wfc->width) / 2; + if (wfc->offset_x < x) + wfc->offset_x = x; + wfc->offset_y = (h - wfc->height) / 2; + if (wfc->offset_y < y) + wfc->offset_y = y; } else { - wfi->offset_x = (GetSystemMetrics(SM_CXSCREEN) - wfi->width) / 2; - if (wfi->offset_x < 0) - wfi->offset_x = 0; - wfi->offset_y = (GetSystemMetrics(SM_CYSCREEN) - wfi->height) / 2; - if (wfi->offset_y < 0) - wfi->offset_y = 0; + wfc->offset_x = (GetSystemMetrics(SM_CXSCREEN) - wfc->width) / 2; + if (wfc->offset_x < 0) + wfc->offset_x = 0; + wfc->offset_y = (GetSystemMetrics(SM_CYSCREEN) - wfc->height) / 2; + if (wfc->offset_y < 0) + wfc->offset_y = 0; } } else { - wfi->offset_x = 0; - wfi->offset_y = 0; + wfc->offset_x = 0; + wfc->offset_y = 0; } } -void wf_resize_window(wfInfo* wfi) +void wf_resize_window(wfContext* wfc) { - if (wfi->fullscreen) + if (wfc->fullscreen) { - if(wfi->instance->settings->UseMultimon) + if(wfc->instance->settings->UseMultimon) { int x = GetSystemMetrics(SM_XVIRTUALSCREEN); int y = GetSystemMetrics(SM_YVIRTUALSCREEN); int w = GetSystemMetrics(SM_CXVIRTUALSCREEN); int h = GetSystemMetrics(SM_CYVIRTUALSCREEN); - SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP); - SetWindowPos(wfi->hwnd, HWND_TOP, x, y, w, h, SWP_FRAMECHANGED); + SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP); + SetWindowPos(wfc->hwnd, HWND_TOP, x, y, w, h, SWP_FRAMECHANGED); } else { - SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP); - SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED); + SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_POPUP); + SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED); } } - else if (!wfi->instance->settings->Decorations) + else if (!wfc->instance->settings->Decorations) { RECT rc_wnd; RECT rc_client; - SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CHILD); + SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CHILD); /* Now resize to get full canvas size and room for caption and borders */ - SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, wfi->width, wfi->height, SWP_FRAMECHANGED); + SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, wfc->width, wfc->height, SWP_FRAMECHANGED); - wf_update_canvas_diff(wfi); - SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, wfi->width + wfi->diff.x, wfi->height + wfi->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); + wf_update_canvas_diff(wfc); + SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, wfc->width + wfc->diff.x, wfc->height + wfc->diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); } else { RECT rc_wnd; RECT rc_client; - SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX); + SetWindowLongPtr(wfc->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX); - if (!wfi->client_height) - wfi->client_height = wfi->height; + if (!wfc->client_height) + wfc->client_height = wfc->height; - if (!wfi->client_width) - wfi->client_width = wfi->width; + if (!wfc->client_width) + wfc->client_width = wfc->width; - if (!wfi->client_x) - wfi->client_x = 10; + if (!wfc->client_x) + wfc->client_x = 10; - if (!wfi->client_y) - wfi->client_y = 10; + if (!wfc->client_y) + wfc->client_y = 10; - wf_update_canvas_diff(wfi); + wf_update_canvas_diff(wfc); /* Now resize to get full canvas size and room for caption and borders */ - SetWindowPos(wfi->hwnd, HWND_TOP, wfi->client_x, wfi->client_y, wfi->client_width + wfi->diff.x, wfi->client_height + wfi->diff.y, 0 /*SWP_FRAMECHANGED*/); - //wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height); + SetWindowPos(wfc->hwnd, HWND_TOP, wfc->client_x, wfc->client_y, wfc->client_width + wfc->diff.x, wfc->client_height + wfc->diff.y, 0 /*SWP_FRAMECHANGED*/); + //wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height); } - wf_update_offset(wfi); + wf_update_offset(wfc); } -void wf_toggle_fullscreen(wfInfo* wfi) +void wf_toggle_fullscreen(wfContext* wfc) { - ShowWindow(wfi->hwnd, SW_HIDE); - wfi->fullscreen = !wfi->fullscreen; + ShowWindow(wfc->hwnd, SW_HIDE); + wfc->fullscreen = !wfc->fullscreen; - if (wfi->fullscreen) + if (wfc->fullscreen) { - wfi->disablewindowtracking = TRUE; + wfc->disablewindowtracking = TRUE; } - SetParent(wfi->hwnd, wfi->fullscreen ? NULL : wfi->hWndParent); - wf_resize_window(wfi); - ShowWindow(wfi->hwnd, SW_SHOW); - SetForegroundWindow(wfi->hwnd); + SetParent(wfc->hwnd, wfc->fullscreen ? NULL : wfc->hWndParent); + wf_resize_window(wfc); + ShowWindow(wfc->hwnd, SW_SHOW); + SetForegroundWindow(wfc->hwnd); - if (!wfi->fullscreen) + if (!wfc->fullscreen) { // Reenable window tracking AFTER resizing it back, otherwise it can lean to repositioning errors. - wfi->disablewindowtracking = FALSE; + wfc->disablewindowtracking = FALSE; } } -void wf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) +void wf_gdi_palette_update(wfContext* wfc, PALETTE_UPDATE* palette) { } -void wf_set_null_clip_rgn(wfInfo* wfi) +void wf_set_null_clip_rgn(wfContext* wfc) { - SelectClipRgn(wfi->drawing->hdc, NULL); + SelectClipRgn(wfc->drawing->hdc, NULL); } -void wf_set_clip_rgn(wfInfo* wfi, int x, int y, int width, int height) +void wf_set_clip_rgn(wfContext* wfc, int x, int y, int width, int height) { HRGN clip; clip = CreateRectRgn(x, y, x + width, y + height); - SelectClipRgn(wfi->drawing->hdc, clip); + SelectClipRgn(wfc->drawing->hdc, clip); DeleteObject(clip); } -void wf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds) +void wf_gdi_set_bounds(wfContext* wfc, rdpBounds* bounds) { HRGN hrgn; - wfInfo* wfi = ((wfContext*) context)->wfi; if (bounds != NULL) { hrgn = CreateRectRgn(bounds->left, bounds->top, bounds->right + 1, bounds->bottom + 1); - SelectClipRgn(wfi->drawing->hdc, hrgn); + SelectClipRgn(wfc->drawing->hdc, hrgn); DeleteObject(hrgn); } else { - SelectClipRgn(wfi->drawing->hdc, NULL); + SelectClipRgn(wfc->drawing->hdc, NULL); } } -void wf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) +void wf_gdi_dstblt(wfContext* wfc, DSTBLT_ORDER* dstblt) { - wfInfo* wfi = ((wfContext*) context)->wfi; - - BitBlt(wfi->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect, + BitBlt(wfc->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop)); - wf_invalidate_region(wfi, dstblt->nLeftRect, dstblt->nTopRect, + wf_invalidate_region(wfc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight); } -void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) +void wf_gdi_patblt(wfContext* wfc, PATBLT_ORDER* patblt) { HBRUSH brush; HBRUSH org_brush; @@ -395,78 +392,73 @@ void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) UINT32 bgcolor; COLORREF org_bkcolor; COLORREF org_textcolor; - wfInfo* wfi = ((wfContext*) context)->wfi; - fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); - bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv); + bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv); - brush = wf_create_brush(wfi, &patblt->brush, fgcolor, wfi->srcBpp); - org_bkmode = SetBkMode(wfi->drawing->hdc, OPAQUE); - org_bkcolor = SetBkColor(wfi->drawing->hdc, bgcolor); - org_textcolor = SetTextColor(wfi->drawing->hdc, fgcolor); - org_brush = (HBRUSH)SelectObject(wfi->drawing->hdc, brush); + brush = wf_create_brush(wfc, &patblt->brush, fgcolor, wfc->srcBpp); + org_bkmode = SetBkMode(wfc->drawing->hdc, OPAQUE); + org_bkcolor = SetBkColor(wfc->drawing->hdc, bgcolor); + org_textcolor = SetTextColor(wfc->drawing->hdc, fgcolor); + org_brush = (HBRUSH)SelectObject(wfc->drawing->hdc, brush); - PatBlt(wfi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, + PatBlt(wfc->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)); - SelectObject(wfi->drawing->hdc, org_brush); + SelectObject(wfc->drawing->hdc, org_brush); DeleteObject(brush); - SetBkMode(wfi->drawing->hdc, org_bkmode); - SetBkColor(wfi->drawing->hdc, org_bkcolor); - SetTextColor(wfi->drawing->hdc, org_textcolor); + SetBkMode(wfc->drawing->hdc, org_bkmode); + SetBkColor(wfc->drawing->hdc, org_bkcolor); + SetTextColor(wfc->drawing->hdc, org_textcolor); - if (wfi->drawing == wfi->primary) - wf_invalidate_region(wfi, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + if (wfc->drawing == wfc->primary) + wf_invalidate_region(wfc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); } -void wf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) +void wf_gdi_scrblt(wfContext* wfc, SCRBLT_ORDER* scrblt) { - wfInfo* wfi = ((wfContext*) context)->wfi; - - BitBlt(wfi->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect, - scrblt->nWidth, scrblt->nHeight, wfi->primary->hdc, + BitBlt(wfc->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight, wfc->primary->hdc, scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop)); - wf_invalidate_region(wfi, scrblt->nLeftRect, scrblt->nTopRect, + wf_invalidate_region(wfc, scrblt->nLeftRect, scrblt->nTopRect, scrblt->nWidth, scrblt->nHeight); } -void wf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +void wf_gdi_opaque_rect(wfContext* wfc, OPAQUE_RECT_ORDER* opaque_rect) { RECT rect; HBRUSH brush; UINT32 brush_color; - wfInfo* wfi = ((wfContext*) context)->wfi; - brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfc->srcBpp, wfc->dstBpp, wfc->clrconv); rect.left = opaque_rect->nLeftRect; rect.top = opaque_rect->nTopRect; rect.right = opaque_rect->nLeftRect + opaque_rect->nWidth; rect.bottom = opaque_rect->nTopRect + opaque_rect->nHeight; brush = CreateSolidBrush(brush_color); - FillRect(wfi->drawing->hdc, &rect, brush); + FillRect(wfc->drawing->hdc, &rect, brush); DeleteObject(brush); - if (wfi->drawing == wfi->primary) - wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1); + if (wfc->drawing == wfc->primary) + wf_invalidate_region(wfc, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1); } -void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +void wf_gdi_multi_opaque_rect(wfContext* wfc, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) { int i; RECT rect; HBRUSH brush; UINT32 brush_color; DELTA_RECT* rectangle; - wfInfo* wfi = ((wfContext*) context)->wfi; 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, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + 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; @@ -475,46 +467,45 @@ void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult brush = CreateSolidBrush(brush_color); brush = CreateSolidBrush(brush_color); - FillRect(wfi->drawing->hdc, &rect, brush); + FillRect(wfc->drawing->hdc, &rect, brush); - if (wfi->drawing == wfi->primary) - wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1); + if (wfc->drawing == wfc->primary) + wf_invalidate_region(wfc, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1); DeleteObject(brush); } } -void wf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) +void wf_gdi_line_to(wfContext* wfc, LINE_TO_ORDER* line_to) { HPEN pen; HPEN org_pen; int x, y, w, h; UINT32 pen_color; - wfInfo* wfi = ((wfContext*) context)->wfi; - pen_color = freerdp_color_convert_bgr(line_to->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + pen_color = freerdp_color_convert_bgr(line_to->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv); pen = CreatePen(line_to->penStyle, line_to->penWidth, pen_color); - wf_set_rop2(wfi->drawing->hdc, line_to->bRop2); - org_pen = (HPEN) SelectObject(wfi->drawing->hdc, pen); + wf_set_rop2(wfc->drawing->hdc, line_to->bRop2); + org_pen = (HPEN) SelectObject(wfc->drawing->hdc, pen); - MoveToEx(wfi->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL); - LineTo(wfi->drawing->hdc, line_to->nXEnd, line_to->nYEnd); + MoveToEx(wfc->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL); + LineTo(wfc->drawing->hdc, line_to->nXEnd, line_to->nYEnd); x = (line_to->nXStart < line_to->nXEnd) ? line_to->nXStart : line_to->nXEnd; y = (line_to->nYStart < line_to->nYEnd) ? line_to->nYStart : line_to->nYEnd; w = (line_to->nXStart < line_to->nXEnd) ? (line_to->nXEnd - line_to->nXStart) : (line_to->nXStart - line_to->nXEnd); h = (line_to->nYStart < line_to->nYEnd) ? (line_to->nYEnd - line_to->nYStart) : (line_to->nYStart - line_to->nYEnd); - if (wfi->drawing == wfi->primary) - wf_invalidate_region(wfi, x, y, w, h); + if (wfc->drawing == wfc->primary) + wf_invalidate_region(wfc, x, y, w, h); - SelectObject(wfi->drawing->hdc, org_pen); + SelectObject(wfc->drawing->hdc, org_pen); DeleteObject(pen); } -void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) +void wf_gdi_polyline(wfContext* wfc, POLYLINE_ORDER* polyline) { int i; POINT* pts; @@ -522,13 +513,12 @@ void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) HPEN hpen; HPEN org_hpen; UINT32 pen_color; - wfInfo* wfi = ((wfContext*) context)->wfi; - pen_color = freerdp_color_convert_bgr(polyline->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + pen_color = freerdp_color_convert_bgr(polyline->penColor, wfc->srcBpp, wfc->dstBpp, wfc->clrconv); hpen = CreatePen(0, 1, pen_color); - org_rop2 = wf_set_rop2(wfi->drawing->hdc, polyline->bRop2); - org_hpen = (HPEN) SelectObject(wfi->drawing->hdc, hpen); + org_rop2 = wf_set_rop2(wfc->drawing->hdc, polyline->bRop2); + org_hpen = (HPEN) SelectObject(wfc->drawing->hdc, hpen); if (polyline->numPoints > 0) { @@ -539,45 +529,43 @@ void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) pts[i].x = polyline->points[i].x; pts[i].y = polyline->points[i].y; - if (wfi->drawing == wfi->primary) - wf_invalidate_region(wfi, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1); + if (wfc->drawing == wfc->primary) + wf_invalidate_region(wfc, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1); } - Polyline(wfi->drawing->hdc, pts, polyline->numPoints); + Polyline(wfc->drawing->hdc, pts, polyline->numPoints); free(pts); } - SelectObject(wfi->drawing->hdc, org_hpen); - wf_set_rop2(wfi->drawing->hdc, org_rop2); + SelectObject(wfc->drawing->hdc, org_hpen); + wf_set_rop2(wfc->drawing->hdc, org_rop2); DeleteObject(hpen); } -void wf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +void wf_gdi_memblt(wfContext* wfc, MEMBLT_ORDER* memblt) { wfBitmap* bitmap; - wfInfo* wfi = ((wfContext*) context)->wfi; bitmap = (wfBitmap*) memblt->bitmap; - BitBlt(wfi->drawing->hdc, memblt->nLeftRect, memblt->nTopRect, + BitBlt(wfc->drawing->hdc, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight, bitmap->hdc, memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop)); - if (wfi->drawing == wfi->primary) - wf_invalidate_region(wfi, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight); + if (wfc->drawing == wfc->primary) + wf_invalidate_region(wfc, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight); } -void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) +void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_command) { int i, j; int tx, ty; char* tile_bitmap; RFX_MESSAGE* message; BITMAPINFO bitmap_info; - wfInfo* wfi = ((wfContext*) context)->wfi; - RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfi->rfx_context; - NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfi->nsc_context; + RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfc->rfx_context; + NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfc->nsc_context; tile_bitmap = (char*) malloc(32); ZeroMemory(tile_bitmap, 32); @@ -592,27 +580,27 @@ 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->pdata, 64, 64, 32, 32, wfi->clrconv); + freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv); for (j = 0; j < message->num_rects; j++) { - wf_set_clip_rgn(wfi, + wf_set_clip_rgn(wfc, surface_bits_command->destLeft + message->rects[j].x, 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, SRCCOPY); + BitBlt(wfc->primary->hdc, tx, ty, 64, 64, wfc->tile->hdc, 0, 0, SRCCOPY); } } - wf_set_null_clip_rgn(wfi); + wf_set_null_clip_rgn(wfc); /* 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); + wf_invalidate_region(wfc, tx, ty, message->rects[i].width, message->rects[i].height); } rfx_message_free(rfx_context, message); @@ -628,10 +616,10 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits bitmap_info.bmiHeader.biPlanes = 1; bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp; bitmap_info.bmiHeader.biCompression = BI_RGB; - SetDIBitsToDevice(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, + SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height, nsc_context->bmpdata, &bitmap_info, DIB_RGB_COLORS); - wf_invalidate_region(wfi, surface_bits_command->destLeft, surface_bits_command->destTop, + wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); } else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE) @@ -643,10 +631,10 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits bitmap_info.bmiHeader.biPlanes = 1; bitmap_info.bmiHeader.biBitCount = surface_bits_command->bpp; bitmap_info.bmiHeader.biCompression = BI_RGB; - SetDIBitsToDevice(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, + SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height, surface_bits_command->bitmapData, &bitmap_info, DIB_RGB_COLORS); - wf_invalidate_region(wfi, surface_bits_command->destLeft, surface_bits_command->destTop, + wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height); } else @@ -658,16 +646,17 @@ void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits free(tile_bitmap); } -void wf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) +void wf_gdi_surface_frame_marker(wfContext* wfc, SURFACE_FRAME_MARKER* surface_frame_marker) { - wfInfo* wfi; + rdpContext* context; rdpSettings* settings; - wfi = ((wfContext*) context)->wfi; - settings = wfi->instance->settings; + context = (rdpContext*) wfc; + settings = wfc->instance->settings; + if (surface_frame_marker->frameAction == SURFACECMD_FRAMEACTION_END && settings->FrameAcknowledge > 0) { - IFCALL(wfi->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId); + IFCALL(context->instance->update->SurfaceFrameAcknowledge, context, surface_frame_marker->frameId); } } @@ -678,19 +667,19 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update) update->Palette = wf_gdi_palette_update; update->SetBounds = wf_gdi_set_bounds; - primary->DstBlt = wf_gdi_dstblt; - primary->PatBlt = wf_gdi_patblt; - primary->ScrBlt = wf_gdi_scrblt; - primary->OpaqueRect = wf_gdi_opaque_rect; + primary->DstBlt = (pDstBlt) wf_gdi_dstblt; + primary->PatBlt = (pPatBlt) wf_gdi_patblt; + primary->ScrBlt = (pScrBlt) wf_gdi_scrblt; + primary->OpaqueRect = (pOpaqueRect) wf_gdi_opaque_rect; primary->DrawNineGrid = NULL; primary->MultiDstBlt = NULL; primary->MultiPatBlt = NULL; primary->MultiScrBlt = NULL; - primary->MultiOpaqueRect = wf_gdi_multi_opaque_rect; + primary->MultiOpaqueRect = (pMultiOpaqueRect) wf_gdi_multi_opaque_rect; primary->MultiDrawNineGrid = NULL; - primary->LineTo = wf_gdi_line_to; - primary->Polyline = wf_gdi_polyline; - primary->MemBlt = wf_gdi_memblt; + primary->LineTo = (pLineTo) wf_gdi_line_to; + primary->Polyline = (pPolyline) wf_gdi_polyline; + primary->MemBlt = (pMemBlt) wf_gdi_memblt; primary->Mem3Blt = NULL; primary->SaveBitmap = NULL; primary->GlyphIndex = NULL; @@ -705,20 +694,20 @@ void wf_gdi_register_update_callbacks(rdpUpdate* update) update->SurfaceFrameMarker = wf_gdi_surface_frame_marker; } -void wf_update_canvas_diff(wfInfo* wfi) +void wf_update_canvas_diff(wfContext* wfc) { RECT rc_client, rc_wnd; int dx, dy; - GetClientRect(wfi->hwnd, &rc_client); - GetWindowRect(wfi->hwnd, &rc_wnd); + GetClientRect(wfc->hwnd, &rc_client); + GetWindowRect(wfc->hwnd, &rc_wnd); dx = (rc_wnd.right - rc_wnd.left) - rc_client.right; dy = (rc_wnd.bottom - rc_wnd.top) - rc_client.bottom; - if (!wfi->disablewindowtracking) + if (!wfc->disablewindowtracking) { - wfi->diff.x = dx; - wfi->diff.y = dy; + wfc->diff.x = dx; + wfc->diff.y = dy; } -} \ No newline at end of file +} diff --git a/client/Windows/wf_gdi.h b/client/Windows/wf_gdi.h index b5cfa0721..b7ab1cfda 100644 --- a/client/Windows/wf_gdi.h +++ b/client/Windows/wf_gdi.h @@ -24,15 +24,15 @@ #include "wf_interface.h" -void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height); -wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data); +void wf_invalidate_region(wfContext* wfc, int x, int y, int width, int height); +wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data); void wf_image_free(wfBitmap* image); -void wf_update_offset(wfInfo* wfi); -void wf_resize_window(wfInfo* wfi); -void wf_toggle_fullscreen(wfInfo* wfi); +void wf_update_offset(wfContext* wfc); +void wf_resize_window(wfContext* wfc); +void wf_toggle_fullscreen(wfContext* wfc); void wf_gdi_register_update_callbacks(rdpUpdate* update); -void wf_update_canvas_diff(wfInfo* wfi); +void wf_update_canvas_diff(wfContext* wfc); #endif /* __WF_GDI_H */ diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index 9a7937215..98c42b468 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -21,12 +21,14 @@ #include "config.h" #endif +#include + #include #include "wf_gdi.h" #include "wf_graphics.h" -HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, BYTE** pdata) +HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data, BYTE** pdata) { HDC hdc; int negHeight; @@ -48,12 +50,12 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, B bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = negHeight; bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = wfi->dstBpp; + bmi.bmiHeader.biBitCount = wfc->dstBpp; bmi.bmiHeader.biCompression = BI_RGB; bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); if (data != NULL) - freerdp_image_convert(data, cdata, width, height, bpp, wfi->dstBpp, wfi->clrconv); + freerdp_image_convert(data, cdata, width, height, bpp, wfc->dstBpp, wfc->clrconv); if (pdata != NULL) *pdata = cdata; @@ -64,7 +66,7 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, B return bitmap; } -wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data) +wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data) { HDC hdc; wfBitmap* image; @@ -73,7 +75,7 @@ wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data) image = (wfBitmap*) malloc(sizeof(wfBitmap)); image->hdc = CreateCompatibleDC(hdc); - image->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(image->pdata)); + image->bitmap = wf_create_dib(wfc, width, height, bpp, data, &(image->pdata)); image->org_bitmap = (HBITMAP) SelectObject(image->hdc, image->bitmap); ReleaseDC(NULL, hdc); @@ -94,27 +96,26 @@ void wf_image_free(wfBitmap* image) /* Bitmap Class */ -void wf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) +void wf_Bitmap_New(wfContext* wfc, rdpBitmap* bitmap) { HDC hdc; wfBitmap* wf_bitmap = (wfBitmap*) bitmap; - wfInfo* wfi = ((wfContext*) context)->wfi; wf_bitmap = (wfBitmap*) bitmap; hdc = GetDC(NULL); wf_bitmap->hdc = CreateCompatibleDC(hdc); - if (bitmap->data == NULL) + if (!bitmap->data) 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, NULL); + wf_bitmap->bitmap = wf_create_dib(wfc, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data, NULL); wf_bitmap->org_bitmap = (HBITMAP) SelectObject(wf_bitmap->hdc, wf_bitmap->bitmap); ReleaseDC(NULL, hdc); } -void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) +void wf_Bitmap_Free(wfContext* wfc, rdpBitmap* bitmap) { wfBitmap* wf_bitmap = (wfBitmap*) bitmap; @@ -126,22 +127,21 @@ void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) } } -void wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) +void wf_Bitmap_Paint(wfContext* wfc, rdpBitmap* bitmap) { int width, height; wfBitmap* wf_bitmap = (wfBitmap*) bitmap; - wfInfo* wfi = ((wfContext*) context)->wfi; width = bitmap->right - bitmap->left + 1; height = bitmap->bottom - bitmap->top + 1; - BitBlt(wfi->primary->hdc, bitmap->left, bitmap->top, + BitBlt(wfc->primary->hdc, bitmap->left, bitmap->top, width, height, wf_bitmap->hdc, 0, 0, SRCCOPY); - wf_invalidate_region(wfi, bitmap->left, bitmap->top, width, height); + wf_invalidate_region(wfc, bitmap->left, bitmap->top, width, height); } -void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, +void wf_Bitmap_Decompress(wfContext* wfc, rdpBitmap* bitmap, BYTE* data, int width, int height, int bpp, int length, BOOL compressed, int codec_id) { UINT16 size; @@ -174,19 +174,17 @@ void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, bitmap->bpp = bpp; } -void wf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL primary) +void wf_Bitmap_SetSurface(wfContext* wfc, rdpBitmap* bitmap, BOOL primary) { - wfInfo* wfi = ((wfContext*) context)->wfi; - if (primary) - wfi->drawing = wfi->primary; + wfc->drawing = wfc->primary; else - wfi->drawing = (wfBitmap*) bitmap; + wfc->drawing = (wfBitmap*) bitmap; } /* Pointer Class */ -void wf_Pointer_New(rdpContext* context, rdpPointer* pointer) +void wf_Pointer_New(wfContext* wfc, rdpPointer* pointer) { HCURSOR hCur; ICONINFO info; @@ -223,35 +221,35 @@ void wf_Pointer_New(rdpContext* context, rdpPointer* pointer) DeleteObject(info.hbmColor); } -void wf_Pointer_Free(rdpContext* context, rdpPointer* pointer) +void wf_Pointer_Free(wfContext* wfc, rdpPointer* pointer) { HCURSOR hCur; hCur = ((wfPointer*) pointer)->cursor; + if (hCur != 0) DestroyIcon(hCur); } -void wf_Pointer_Set(rdpContext* context, rdpPointer* pointer) +void wf_Pointer_Set(wfContext* wfc, rdpPointer* pointer) { - wfInfo* wfi; HCURSOR hCur; - wfi = ((wfContext*) context)->wfi; hCur = ((wfPointer*) pointer)->cursor; + if (hCur != NULL) { SetCursor(hCur); - wfi->cursor = hCur; + wfc->cursor = hCur; } } -void wf_Pointer_SetNull(rdpContext* context) +void wf_Pointer_SetNull(wfContext* wfc) { } -void wf_Pointer_SetDefault(rdpContext* context) +void wf_Pointer_SetDefault(wfContext* wfc) { } @@ -263,21 +261,21 @@ void wf_register_graphics(rdpGraphics* graphics) rdpBitmap bitmap; rdpPointer pointer; - memset(&bitmap, 0, sizeof(rdpBitmap)); + ZeroMemory(&bitmap, sizeof(rdpBitmap)); bitmap.size = sizeof(wfBitmap); - bitmap.New = wf_Bitmap_New; - bitmap.Free = wf_Bitmap_Free; - bitmap.Paint = wf_Bitmap_Paint; - bitmap.Decompress = wf_Bitmap_Decompress; - bitmap.SetSurface = wf_Bitmap_SetSurface; + 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; - memset(&pointer, 0, sizeof(rdpPointer)); + ZeroMemory(&pointer, sizeof(rdpPointer)); pointer.size = sizeof(wfPointer); - pointer.New = wf_Pointer_New; - pointer.Free = wf_Pointer_Free; - pointer.Set = wf_Pointer_Set; - pointer.SetNull = wf_Pointer_SetNull; - pointer.SetDefault = wf_Pointer_SetDefault; + pointer.New = (pPointer_New) wf_Pointer_New; + pointer.Free = (pPointer_Free) wf_Pointer_Free; + pointer.Set = (pPointer_Set) wf_Pointer_Set; + pointer.SetNull = (pPointer_SetNull) wf_Pointer_SetNull; + pointer.SetDefault = (pPointer_SetDefault) wf_Pointer_SetDefault; graphics_register_bitmap(graphics, &bitmap); graphics_register_pointer(graphics, &pointer); diff --git a/client/Windows/wf_graphics.h b/client/Windows/wf_graphics.h index 0a4c6cded..a27c6a679 100644 --- a/client/Windows/wf_graphics.h +++ b/client/Windows/wf_graphics.h @@ -22,8 +22,8 @@ #include "wf_interface.h" -HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, BYTE* data, BYTE** pdata); -wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, BYTE* data); +HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data, BYTE** pdata); +wfBitmap* wf_image_new(wfContext* wfc, int width, int height, int bpp, BYTE* data); void wf_image_free(wfBitmap* image); void wf_register_graphics(rdpGraphics* graphics); diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 31555ad44..9ae2de7df 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -57,48 +57,7 @@ #include "resource.h" -wfInfo* wf_wfi_new() -{ - wfInfo* wfi; - - wfi = (wfInfo*) malloc(sizeof(wfInfo)); - ZeroMemory(wfi, sizeof(wfInfo)); - - return wfi; -} - -void wf_wfi_free(wfInfo* wfi) -{ - free(wfi); -} - -int wf_context_new(freerdp* instance, rdpContext* context) -{ - wfInfo* wfi; - - context->channels = freerdp_channels_new(); - - wfi = wf_wfi_new(); - - ((wfContext*) context)->wfi = wfi; - wfi->instance = instance; - - // Register callbacks - instance->context->client->OnParamChange = wf_on_param_change; - - return 0; -} - -void wf_context_free(freerdp* instance, rdpContext* context) -{ - if (context->cache) - cache_free(context->cache); - - freerdp_channels_free(context->channels); - - wf_wfi_free(((wfContext*) context)->wfi); - ((wfContext*) context)->wfi = NULL; -} +void wf_size_scrollbars(wfContext* wfc, int client_width, int client_height); int wf_create_console(void) { @@ -111,26 +70,24 @@ int wf_create_console(void) return 0; } -void wf_sw_begin_paint(rdpContext* context) +void wf_sw_begin_paint(wfContext* wfc) { - rdpGdi* gdi = context->gdi; + rdpGdi* gdi = ((rdpContext*) wfc)->gdi; gdi->primary->hdc->hwnd->invalid->null = 1; gdi->primary->hdc->hwnd->ninvalid = 0; } -void wf_sw_end_paint(rdpContext* context) +void wf_sw_end_paint(wfContext* wfc) { int i; rdpGdi* gdi; - wfInfo* wfi; INT32 x, y; UINT32 w, h; int ninvalid; RECT update_rect; HGDI_RGN cinvalid; - gdi = context->gdi; - wfi = ((wfContext*) context)->wfi; + gdi = ((rdpContext*) wfc)->gdi; if (gdi->primary->hdc->hwnd->ninvalid < 1) return; @@ -150,108 +107,105 @@ void wf_sw_end_paint(rdpContext* context) update_rect.right = x + w - 1; update_rect.bottom = y + h - 1; - InvalidateRect(wfi->hwnd, &update_rect, FALSE); + InvalidateRect(wfc->hwnd, &update_rect, FALSE); } } -void wf_sw_desktop_resize(rdpContext* context) +void wf_sw_desktop_resize(wfContext* wfc) { - wfInfo* wfi; rdpGdi* gdi; + rdpContext* context; rdpSettings* settings; - wfi = ((wfContext*) context)->wfi; - settings = wfi->instance->settings; + context = (rdpContext*) wfc; + settings = wfc->instance->settings; gdi = context->gdi; - wfi->width = settings->DesktopWidth; - wfi->height = settings->DesktopHeight; - gdi_resize(gdi, wfi->width, wfi->height); + wfc->width = settings->DesktopWidth; + wfc->height = settings->DesktopHeight; + gdi_resize(gdi, wfc->width, wfc->height); - if (wfi->primary) + if (wfc->primary) { - wf_image_free(wfi->primary); - wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, gdi->primary_buffer); + wf_image_free(wfc->primary); + wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, gdi->primary_buffer); } } -void wf_hw_begin_paint(rdpContext* context) +void wf_hw_begin_paint(wfContext* wfc) { - wfInfo* wfi = ((wfContext*) context)->wfi; - wfi->hdc->hwnd->invalid->null = 1; - wfi->hdc->hwnd->ninvalid = 0; + wfc->hdc->hwnd->invalid->null = 1; + wfc->hdc->hwnd->ninvalid = 0; } -void wf_hw_end_paint(rdpContext* context) +void wf_hw_end_paint(wfContext* wfc) { } -void wf_hw_desktop_resize(rdpContext* context) +void wf_hw_desktop_resize(wfContext* wfc) { - wfInfo* wfi; BOOL same; RECT rect; rdpSettings* settings; - wfi = ((wfContext*) context)->wfi; - settings = wfi->instance->settings; + settings = wfc->instance->settings; - wfi->width = settings->DesktopWidth; - wfi->height = settings->DesktopHeight; + wfc->width = settings->DesktopWidth; + wfc->height = settings->DesktopHeight; - if (wfi->primary) + if (wfc->primary) { - same = (wfi->primary == wfi->drawing) ? TRUE : FALSE; + same = (wfc->primary == wfc->drawing) ? TRUE : FALSE; - wf_image_free(wfi->primary); + wf_image_free(wfc->primary); - wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, NULL); + wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL); if (same) - wfi->drawing = wfi->primary; + wfc->drawing = wfc->primary; } - if (wfi->fullscreen != TRUE) + if (wfc->fullscreen != TRUE) { - if (wfi->hwnd) - SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, wfi->width + wfi->diff.x, wfi->height + wfi->diff.y, SWP_NOMOVE); + if (wfc->hwnd) + SetWindowPos(wfc->hwnd, HWND_TOP, -1, -1, wfc->width + wfc->diff.x, wfc->height + wfc->diff.y, SWP_NOMOVE); } else { - wf_update_offset(wfi); - GetWindowRect(wfi->hwnd, &rect); - InvalidateRect(wfi->hwnd, &rect, TRUE); + wf_update_offset(wfc); + GetWindowRect(wfc->hwnd, &rect); + InvalidateRect(wfc->hwnd, &rect, TRUE); } } BOOL wf_pre_connect(freerdp* instance) { - int desktopWidth, desktopHeight; - wfInfo* wfi; - wfContext* context; + wfContext* wfc; + int desktopWidth; + int desktopHeight; + rdpContext* context; rdpSettings* settings; - context = (wfContext*) instance->context; - - wfi = context->wfi; - wfi->instance = instance; + context = instance->context; + wfc = (wfContext*) instance->context; + wfc->instance = instance; settings = instance->settings; if (settings->ConnectionFile) { - if (wfi->connectionRdpFile) + if (wfc->connectionRdpFile) { - freerdp_client_rdp_file_free(wfi->connectionRdpFile); + freerdp_client_rdp_file_free(wfc->connectionRdpFile); } - wfi->connectionRdpFile = freerdp_client_rdp_file_new(); + wfc->connectionRdpFile = freerdp_client_rdp_file_new(); fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile); - freerdp_client_parse_rdp_file(wfi->connectionRdpFile, settings->ConnectionFile); - freerdp_client_populate_settings_from_rdp_file(wfi->connectionRdpFile, settings); + freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile); + freerdp_client_populate_settings_from_rdp_file(wfc->connectionRdpFile, settings); } settings->OsMajorType = OSMAJORTYPE_WINDOWS; @@ -281,31 +235,31 @@ BOOL wf_pre_connect(freerdp* instance) settings->GlyphSupportLevel = GLYPH_SUPPORT_NONE; - wfi->fullscreen = settings->Fullscreen; - wfi->fs_toggle = 1; - wfi->sw_gdi = settings->SoftwareGdi; + wfc->fullscreen = settings->Fullscreen; + wfc->fs_toggle = 1; + wfc->sw_gdi = settings->SoftwareGdi; - wfi->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); - ZeroMemory(wfi->clrconv, sizeof(CLRCONV)); + wfc->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); + ZeroMemory(wfc->clrconv, sizeof(CLRCONV)); - wfi->clrconv->palette = NULL; - wfi->clrconv->alpha = FALSE; + wfc->clrconv->palette = NULL; + wfc->clrconv->alpha = FALSE; instance->context->cache = cache_new(settings); desktopWidth = settings->DesktopWidth; desktopHeight = settings->DesktopHeight; - if (wfi->percentscreen > 0) + if (wfc->percentscreen > 0) { - desktopWidth = (GetSystemMetrics(SM_CXSCREEN) * wfi->percentscreen) / 100; + desktopWidth = (GetSystemMetrics(SM_CXSCREEN) * wfc->percentscreen) / 100; settings->DesktopWidth = desktopWidth; - desktopHeight = (GetSystemMetrics(SM_CYSCREEN) * wfi->percentscreen) / 100; + desktopHeight = (GetSystemMetrics(SM_CYSCREEN) * wfc->percentscreen) / 100; settings->DesktopHeight = desktopHeight; } - if (wfi->fullscreen) + if (wfc->fullscreen) { if (settings->UseMultimon) { @@ -344,9 +298,9 @@ BOOL wf_pre_connect(freerdp* instance) return TRUE; } -void wf_add_system_menu(wfInfo* wfi) +void wf_add_system_menu(wfContext* wfc) { - HMENU hMenu = GetSystemMenu(wfi->hwnd, FALSE); + HMENU hMenu = GetSystemMenu(wfc->hwnd, FALSE); MENUITEMINFO item_info; ZeroMemory(&item_info, sizeof(MENUITEMINFO)); @@ -357,11 +311,11 @@ void wf_add_system_menu(wfInfo* wfi) item_info.fType = MFT_STRING; item_info.dwTypeData = _wcsdup(_T("Smart sizing")); item_info.cch = _wcslen(_T("Smart sizing")); - item_info.dwItemData = (ULONG_PTR) wfi; + item_info.dwItemData = (ULONG_PTR) wfc; InsertMenuItem(hMenu, 6, TRUE, &item_info); - if (wfi->instance->settings->SmartSizing) + if (wfc->instance->settings->SmartSizing) { CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, MF_CHECKED); } @@ -370,59 +324,59 @@ void wf_add_system_menu(wfInfo* wfi) BOOL wf_post_connect(freerdp* instance) { rdpGdi* gdi; - wfInfo* wfi; DWORD dwStyle; rdpCache* cache; - wfContext* context; + wfContext* wfc; + rdpContext* context; WCHAR lpWindowName[64]; rdpSettings* settings; settings = instance->settings; - context = (wfContext*) instance->context; + context = instance->context; + wfc = (wfContext*) instance->context; cache = instance->context->cache; - wfi = context->wfi; - wfi->dstBpp = 32; - wfi->width = settings->DesktopWidth; - wfi->height = settings->DesktopHeight; + wfc->dstBpp = 32; + wfc->width = settings->DesktopWidth; + wfc->height = settings->DesktopHeight; - if (wfi->sw_gdi) + if (wfc->sw_gdi) { gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_32BPP, NULL); gdi = instance->context->gdi; - wfi->hdc = gdi->primary->hdc; - wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, gdi->primary_buffer); + wfc->hdc = gdi->primary->hdc; + wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, gdi->primary_buffer); } else { wf_gdi_register_update_callbacks(instance->update); - wfi->srcBpp = instance->settings->ColorDepth; - wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, NULL); + wfc->srcBpp = instance->settings->ColorDepth; + wfc->primary = wf_image_new(wfc, wfc->width, wfc->height, wfc->dstBpp, NULL); - wfi->hdc = gdi_GetDC(); - wfi->hdc->bitsPerPixel = wfi->dstBpp; - wfi->hdc->bytesPerPixel = wfi->dstBpp / 8; + wfc->hdc = gdi_GetDC(); + wfc->hdc->bitsPerPixel = wfc->dstBpp; + wfc->hdc->bytesPerPixel = wfc->dstBpp / 8; - wfi->hdc->alpha = wfi->clrconv->alpha; - wfi->hdc->invert = wfi->clrconv->invert; + wfc->hdc->alpha = wfc->clrconv->alpha; + wfc->hdc->invert = wfc->clrconv->invert; - wfi->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); - wfi->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); - wfi->hdc->hwnd->invalid->null = 1; + wfc->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); + wfc->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + wfc->hdc->hwnd->invalid->null = 1; - wfi->hdc->hwnd->count = 32; - wfi->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * wfi->hdc->hwnd->count); - wfi->hdc->hwnd->ninvalid = 0; + wfc->hdc->hwnd->count = 32; + wfc->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * wfc->hdc->hwnd->count); + wfc->hdc->hwnd->ninvalid = 0; if (settings->RemoteFxCodec) { - wfi->tile = wf_image_new(wfi, 64, 64, 32, NULL); - wfi->rfx_context = rfx_context_new(); + wfc->tile = wf_image_new(wfc, 64, 64, 32, NULL); + wfc->rfx_context = rfx_context_new(); } if (settings->NSCodec) { - wfi->nsc_context = nsc_context_new(); + wfc->nsc_context = nsc_context_new(); } } @@ -438,40 +392,40 @@ BOOL wf_post_connect(freerdp* instance) else dwStyle = 0; - if (!wfi->hwnd) + if (!wfc->hwnd) { - wfi->hwnd = CreateWindowEx((DWORD) NULL, wfi->wndClassName, lpWindowName, dwStyle, - 0, 0, 0, 0, wfi->hWndParent, NULL, wfi->hInstance, NULL); + wfc->hwnd = CreateWindowEx((DWORD) NULL, wfc->wndClassName, lpWindowName, dwStyle, + 0, 0, 0, 0, wfc->hWndParent, NULL, wfc->hInstance, NULL); - SetWindowLongPtr(wfi->hwnd, GWLP_USERDATA, (LONG_PTR) wfi); + SetWindowLongPtr(wfc->hwnd, GWLP_USERDATA, (LONG_PTR) wfc); } - wf_resize_window(wfi); + wf_resize_window(wfc); - wf_add_system_menu(wfi); + wf_add_system_menu(wfc); - BitBlt(wfi->primary->hdc, 0, 0, wfi->width, wfi->height, NULL, 0, 0, BLACKNESS); - wfi->drawing = wfi->primary; + BitBlt(wfc->primary->hdc, 0, 0, wfc->width, wfc->height, NULL, 0, 0, BLACKNESS); + wfc->drawing = wfc->primary; - ShowWindow(wfi->hwnd, SW_SHOWNORMAL); - UpdateWindow(wfi->hwnd); + ShowWindow(wfc->hwnd, SW_SHOWNORMAL); + UpdateWindow(wfc->hwnd); - if (wfi->sw_gdi) + if (wfc->sw_gdi) { - instance->update->BeginPaint = wf_sw_begin_paint; - instance->update->EndPaint = wf_sw_end_paint; - instance->update->DesktopResize = wf_sw_desktop_resize; + instance->update->BeginPaint = (pBeginPaint) wf_sw_begin_paint; + instance->update->EndPaint = (pEndPaint) wf_sw_end_paint; + instance->update->DesktopResize = (pDesktopResize) wf_sw_desktop_resize; } else { - instance->update->BeginPaint = wf_hw_begin_paint; - instance->update->EndPaint = wf_hw_end_paint; - instance->update->DesktopResize = wf_hw_desktop_resize; + instance->update->BeginPaint = (pBeginPaint) wf_hw_begin_paint; + instance->update->EndPaint = (pEndPaint) wf_hw_end_paint; + instance->update->DesktopResize = (pDesktopResize) wf_hw_desktop_resize; } pointer_cache_register_callbacks(instance->update); - if (wfi->sw_gdi != TRUE) + if (wfc->sw_gdi != TRUE) { brush_cache_register_callbacks(instance->update); bitmap_cache_register_callbacks(instance->update); @@ -482,13 +436,7 @@ BOOL wf_post_connect(freerdp* instance) freerdp_channels_post_connect(instance->context->channels, instance); - wf_cliprdr_init(wfi, instance->context->channels); - - // Callback - if (wfi->client_callback_func != NULL) - { - wfi->client_callback_func(wfi, CALLBACK_TYPE_CONNECTED, 0, 0); - } + wf_cliprdr_init(wfc, instance->context->channels); return TRUE; } @@ -602,7 +550,7 @@ BOOL wf_check_fds(freerdp* instance) return TRUE; } -DWORD WINAPI wf_thread(LPVOID lpParam) +DWORD WINAPI wf_client_thread(LPVOID lpParam) { MSG msg; int index; @@ -616,10 +564,12 @@ DWORD WINAPI wf_thread(LPVOID lpParam) void* wfds[32]; int fds_count; HANDLE fds[64]; + wfContext* wfc; freerdp* instance; rdpChannels* channels; instance = (freerdp*) lpParam; + wfc = (wfContext*) instance->context; ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(wfds, sizeof(wfds)); @@ -706,11 +656,11 @@ DWORD WINAPI wf_thread(LPVOID lpParam) { if ((msg.message == WM_SETFOCUS) && (msg.lParam == 1)) { - PostMessage(((wfContext*) instance->context)->wfi->hwnd, WM_SETFOCUS, 0, 0); + PostMessage(wfc->hwnd, WM_SETFOCUS, 0, 0); } else if ((msg.message == WM_KILLFOCUS) && (msg.lParam == 1)) { - PostMessage(((wfContext*) instance->context)->wfi->hwnd, WM_KILLFOCUS, 0, 0); + PostMessage(wfc->hwnd, WM_KILLFOCUS, 0, 0); } } @@ -719,10 +669,10 @@ DWORD WINAPI wf_thread(LPVOID lpParam) width = LOWORD(msg.lParam); height = HIWORD(msg.lParam); - //((wfContext*) instance->context)->wfi->client_width = width; - //((wfContext*) instance->context)->wfi->client_height = height; + //wfc->client_width = width; + //wfc->client_height = height; - SetWindowPos(((wfContext*) instance->context)->wfi->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED); + SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED); } if ((msg_ret == 0) || (msg_ret == -1)) @@ -740,16 +690,12 @@ DWORD WINAPI wf_thread(LPVOID lpParam) } /* cleanup */ - ((wfContext*) instance->context)->wfi->mainThreadId = 0; + wfc->mainThreadId = 0; freerdp_channels_close(channels, instance); - freerdp_disconnect(instance); + freerdp_disconnect(instance); - // Callback - if (((wfContext*) instance->context)->wfi->client_callback_func != NULL) - { - ((wfContext*) instance->context)->wfi->client_callback_func(((wfContext*) instance->context)->wfi, CALLBACK_TYPE_DISCONNECTED, 12, 34); - } + printf("Main thread exited.\n"); return 0; } @@ -758,12 +704,12 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam) { MSG msg; BOOL status; - wfInfo* wfi; + wfContext* wfc; HHOOK hook_handle; - wfi = (wfInfo*) lpParam; + wfc = (wfContext*) lpParam; - hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfi->hInstance, 0); + hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, wfc->hInstance, 0); if (hook_handle) { @@ -788,12 +734,247 @@ DWORD WINAPI wf_keyboard_thread(LPVOID lpParam) fprintf(stderr, "failed to install keyboard hook\n"); } - wfi->keyboardThreadId = 0; + wfc->keyboardThreadId = 0; printf("Keyboard thread exited.\n"); + return (DWORD) NULL; } -int freerdp_client_global_init() +rdpSettings* freerdp_client_get_settings(wfContext* wfc) +{ + return wfc->instance->settings; +} + +int freerdp_client_focus_in(wfContext* wfc) +{ + PostThreadMessage(wfc->mainThreadId, WM_SETFOCUS, 0, 1); + return 0; +} + +int freerdp_client_focus_out(wfContext* wfc) +{ + PostThreadMessage(wfc->mainThreadId, WM_KILLFOCUS, 0, 1); + return 0; +} + +int freerdp_client_set_window_size(wfContext* wfc, int width, int height) +{ + if ((width != wfc->client_width) || (height != wfc->client_height)) + { + PostThreadMessage(wfc->mainThreadId, WM_SIZE, SIZE_RESTORED, ((UINT) height << 16) | (UINT) width); + } + + return 0; +} + +void wf_on_param_change(freerdp* instance, int id) +{ + RECT rect; + HMENU hMenu; + wfContext* wfc = (wfContext*) instance->context; + + // specific processing here + switch (id) + { + case FreeRDP_SmartSizing: + fprintf(stderr, "SmartSizing changed.\n"); + + if (!instance->settings->SmartSizing && (wfc->client_width > instance->settings->DesktopWidth || wfc->client_height > instance->settings->DesktopHeight)) + { + GetWindowRect(wfc->hwnd, &rect); + SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, MIN(wfc->client_width + wfc->offset_x, rect.right - rect.left), MIN(wfc->client_height + wfc->offset_y, rect.bottom - rect.top), SWP_NOMOVE | SWP_FRAMECHANGED); + wf_update_canvas_diff(wfc); + } + + hMenu = GetSystemMenu(wfc->hwnd, FALSE); + CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, instance->settings->SmartSizing); + wf_size_scrollbars(wfc, wfc->client_width, wfc->client_height); + GetClientRect(wfc->hwnd, &rect); + InvalidateRect(wfc->hwnd, &rect, TRUE); + break; + + case FreeRDP_ConnectionType: + fprintf(stderr, "ConnectionType changed.\n"); + freerdp_set_connection_type(wfc->instance->settings, wfc->instance->settings->ConnectionType); + break; + } +} + +// TODO: Some of that code is a duplicate of wf_pre_connect. Refactor? +int freerdp_client_load_settings_from_rdp_file(wfContext* wfc, char* filename) +{ + rdpSettings* settings; + + settings = wfc->instance->settings; + + if (filename) + { + settings->ConnectionFile = _strdup(filename); + + // free old settings file + freerdp_client_rdp_file_free(wfc->connectionRdpFile); + wfc->connectionRdpFile = freerdp_client_rdp_file_new(); + + fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile); + + if (!freerdp_client_parse_rdp_file(wfc->connectionRdpFile, settings->ConnectionFile)) + { + return 1; + } + + if (!freerdp_client_populate_settings_from_rdp_file(wfc->connectionRdpFile, settings)) + { + return 2; + } + } + + return 0; +} + +int freerdp_client_save_settings_to_rdp_file(wfContext* wfc, char* filename) +{ + if (!filename) + return 1; + + if (wfc->instance->settings->ConnectionFile) + { + free(wfc->instance->settings->ConnectionFile); + } + + wfc->instance->settings->ConnectionFile = _strdup(filename); + + // Reuse existing rdpFile structure if available, to preserve unsupported settings when saving to disk. + if (wfc->connectionRdpFile == NULL) + { + wfc->connectionRdpFile = freerdp_client_rdp_file_new(); + } + + if (!freerdp_client_populate_rdp_file_from_settings(wfc->connectionRdpFile, wfc->instance->settings)) + { + return 1; + } + + if (!freerdp_client_write_rdp_file(wfc->connectionRdpFile, filename, UNICODE)); + { + return 2; + } + + return 0; +} + +void wf_size_scrollbars(wfContext* wfc, int client_width, int client_height) +{ + BOOL rc; + + if (wfc->disablewindowtracking == TRUE) + { + return; + } + + // prevent infinite message loop + wfc->disablewindowtracking = TRUE; + + if (wfc->instance->settings->SmartSizing) + { + wfc->xCurrentScroll = 0; + wfc->yCurrentScroll = 0; + + if (wfc->xScrollVisible || wfc->yScrollVisible) + { + if (ShowScrollBar(wfc->hwnd, SB_BOTH, FALSE)) + { + wfc->xScrollVisible = FALSE; + wfc->yScrollVisible = FALSE; + } + } + } + else + { + SCROLLINFO si; + BOOL horiz = wfc->xScrollVisible; + BOOL vert = wfc->yScrollVisible;; + + if (!horiz && client_width < wfc->instance->settings->DesktopWidth) + { + horiz = TRUE; + } + else if (horiz && client_width >= wfc->instance->settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/) + { + horiz = FALSE; + } + + if (!vert && client_height < wfc->instance->settings->DesktopHeight) + { + vert = TRUE; + } + else if (vert && client_height >= wfc->instance->settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/) + { + vert = FALSE; + } + + if (horiz == vert && (horiz != wfc->xScrollVisible && vert != wfc->yScrollVisible)) + { + if (ShowScrollBar(wfc->hwnd, SB_BOTH, horiz)) + { + wfc->xScrollVisible = horiz; + wfc->yScrollVisible = vert; + } + } + + if (horiz != wfc->xScrollVisible) + { + if (ShowScrollBar(wfc->hwnd, SB_HORZ, horiz)) + { + wfc->xScrollVisible = horiz; + } + } + + if (vert != wfc->yScrollVisible) + { + if (ShowScrollBar(wfc->hwnd, SB_VERT, vert)) + { + wfc->yScrollVisible = vert; + } + } + + if (horiz) + { + // The horizontal scrolling range is defined by + // (bitmap_width) - (client_width). The current horizontal + // scroll value remains within the horizontal scrolling range. + wfc->xMaxScroll = MAX(wfc->instance->settings->DesktopWidth - client_width, 0); + wfc->xCurrentScroll = MIN(wfc->xCurrentScroll, wfc->xMaxScroll); + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + si.nMin = wfc->xMinScroll; + si.nMax = wfc->instance->settings->DesktopWidth; + si.nPage = client_width; + si.nPos = wfc->xCurrentScroll; + SetScrollInfo(wfc->hwnd, SB_HORZ, &si, TRUE); + } + + if (vert) + { + // The vertical scrolling range is defined by + // (bitmap_height) - (client_height). The current vertical + // scroll value remains within the vertical scrolling range. + wfc->yMaxScroll = MAX(wfc->instance->settings->DesktopHeight - client_height, 0); + wfc->yCurrentScroll = MIN(wfc->yCurrentScroll, wfc->yMaxScroll); + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + si.nMin = wfc->yMinScroll; + si.nMax = wfc->instance->settings->DesktopHeight; + si.nPage = client_height; + si.nPos = wfc->yCurrentScroll; + SetScrollInfo(wfc->hwnd, SB_VERT, &si, TRUE); + } + } + + wfc->disablewindowtracking = FALSE; + wf_update_canvas_diff(wfc); +} + +void wfreerdp_client_global_init(void) { WSADATA wsaData; @@ -805,8 +986,7 @@ int freerdp_client_global_init() _putenv(home); } - if (WSAStartup(0x101, &wsaData) != 0) - return 1; + WSAStartup(0x101, &wsaData); #if defined(WITH_DEBUG) || defined(_DEBUG) wf_create_console(); @@ -815,378 +995,112 @@ int freerdp_client_global_init() freerdp_channels_global_init(); freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); - - return 0; } -int freerdp_client_global_uninit() +void wfreerdp_client_global_uninit(void) { WSACleanup(); - - return 0; } -wfInfo* freerdp_client_new(int argc, char** argv) +int wfreerdp_client_new(freerdp* instance, rdpContext* context) { - int index; - int status; - wfInfo* wfi; - freerdp* instance; + wfContext* wfc = (wfContext*) context; + + wfreerdp_client_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->ContextSize = sizeof(wfContext); - instance->ContextNew = wf_context_new; - instance->ContextFree = wf_context_free; - freerdp_context_new(instance); + wfc->instance = instance; + context->channels = freerdp_channels_new(); - wfi = ((wfContext*) (instance->context))->wfi; - - wfi->instance = instance; - wfi->client = instance->context->client; - - instance->context->argc = argc; - instance->context->argv = (char**) malloc(sizeof(char*) * argc); - - for (index = 0; index < argc; index++) - instance->context->argv[index] = _strdup(argv[index]); - - status = freerdp_client_parse_command_line_arguments(instance->context->argc, instance->context->argv, instance->settings); - - return wfi; + return 0; } -rdpSettings* freerdp_client_get_settings(wfInfo* wfi) +void wfreerdp_client_free(freerdp* instance, rdpContext* context) { - return wfi->instance->settings; + if (context->cache) + cache_free(context->cache); + + freerdp_channels_free(context->channels); } -int freerdp_client_start(wfInfo* wfi) +int wfreerdp_client_start(rdpContext* context) { HWND hWndParent; HINSTANCE hInstance; - freerdp* instance = wfi->instance; + wfContext* wfc = (wfContext*) context; + freerdp* instance = context->instance; hInstance = GetModuleHandle(NULL); hWndParent = (HWND) instance->settings->ParentWindowId; instance->settings->EmbeddedWindow = (hWndParent) ? TRUE : FALSE; - wfi->hWndParent = hWndParent; - wfi->hInstance = hInstance; - wfi->cursor = LoadCursor(NULL, IDC_ARROW); - wfi->icon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)); - wfi->wndClassName = _tcsdup(_T("FreeRDP")); + wfc->hWndParent = hWndParent; + wfc->hInstance = hInstance; + wfc->cursor = LoadCursor(NULL, IDC_ARROW); + wfc->icon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)); + wfc->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.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.hIcon = wfi->icon; - wfi->wndClass.hIconSm = wfi->icon; - RegisterClassEx(&(wfi->wndClass)); + wfc->wndClass.cbSize = sizeof(WNDCLASSEX); + wfc->wndClass.style = CS_HREDRAW | CS_VREDRAW; + wfc->wndClass.lpfnWndProc = wf_event_proc; + wfc->wndClass.cbClsExtra = 0; + wfc->wndClass.cbWndExtra = 0; + wfc->wndClass.hCursor = wfc->cursor; + wfc->wndClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); + wfc->wndClass.lpszMenuName = NULL; + wfc->wndClass.lpszClassName = wfc->wndClassName; + wfc->wndClass.hInstance = hInstance; + wfc->wndClass.hIcon = wfc->icon; + wfc->wndClass.hIconSm = wfc->icon; + RegisterClassEx(&(wfc->wndClass)); - wfi->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfi, 0, &wfi->keyboardThreadId); + wfc->keyboardThread = CreateThread(NULL, 0, wf_keyboard_thread, (void*) wfc, 0, &wfc->keyboardThreadId); - if (!wfi->keyboardThread) + if (!wfc->keyboardThread) return -1; - freerdp_client_load_addins(instance->context->channels, instance->settings); + freerdp_client_load_addins(context->channels, instance->settings); - wfi->thread = CreateThread(NULL, 0, wf_thread, (void*) instance, 0, &wfi->mainThreadId); + wfc->thread = CreateThread(NULL, 0, wf_client_thread, (void*) instance, 0, &wfc->mainThreadId); - if (!wfi->thread) + if (!wfc->thread) return -1; - printf("Main thread exited.\n"); return 0; } -int freerdp_client_stop(wfInfo* wfi) +int wfreerdp_client_stop(rdpContext* context) { - if (wfi->mainThreadId) - PostThreadMessage(wfi->mainThreadId, WM_QUIT, 0, 0); + wfContext* wfc = (wfContext*) context; - if (wfi->keyboardThreadId) - PostThreadMessage(wfi->keyboardThreadId, WM_QUIT, 0, 0); - return 0; -} + if (wfc->mainThreadId) + PostThreadMessage(wfc->mainThreadId, WM_QUIT, 0, 0); -HANDLE freerdp_client_get_thread(wfInfo* cfi) -{ - return cfi->thread; -} - -freerdp* freerdp_client_get_instance(wfInfo* cfi) -{ - return cfi->instance; -} - -rdpClient* freerdp_client_get_interface(wfInfo* cfi) -{ - return cfi->client; -} - -int freerdp_client_focus_in(wfInfo* wfi) -{ - PostThreadMessage(wfi->mainThreadId, WM_SETFOCUS, 0, 1); - return 0; -} - -int freerdp_client_focus_out(wfInfo* wfi) -{ - PostThreadMessage(wfi->mainThreadId, WM_KILLFOCUS, 0, 1); - return 0; -} - -int freerdp_client_set_window_size(wfInfo* wfi, int width, int height) -{ - if ((width != wfi->client_width) || (height != wfi->client_height)) - { - PostThreadMessage(wfi->mainThreadId, WM_SIZE, SIZE_RESTORED, ((UINT) height << 16) | (UINT) width); - } + if (wfc->keyboardThreadId) + PostThreadMessage(wfc->keyboardThreadId, WM_QUIT, 0, 0); return 0; } -int freerdp_client_free(wfInfo* wfi) +int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) { - freerdp* instance = wfi->instance; + pEntryPoints->Version = 1; + pEntryPoints->Size = sizeof(RDP_CLIENT_ENTRY_POINTS_V1); - freerdp_context_free(instance); - freerdp_free(instance); + pEntryPoints->GlobalInit = wfreerdp_client_global_init; + pEntryPoints->GlobalUninit = wfreerdp_client_global_uninit; + + pEntryPoints->ContextSize = sizeof(wfContext); + pEntryPoints->ClientNew = wfreerdp_client_new; + pEntryPoints->ClientFree = wfreerdp_client_free; + + pEntryPoints->ClientStart = wfreerdp_client_start; + pEntryPoints->ClientStop = wfreerdp_client_stop; return 0; } - -void wf_on_param_change(freerdp* instance, int id) -{ - wfInfo* cfi = ((wfContext*) instance->context)->wfi; - RECT rect; - HMENU hMenu; - - // specific processing here - switch(id) - { - case FreeRDP_SmartSizing: - fprintf(stderr, "SmartSizing changed.\n"); - - if (!instance->settings->SmartSizing && (cfi->client_width > instance->settings->DesktopWidth || cfi->client_height > instance->settings->DesktopHeight)) - { - GetWindowRect(cfi->hwnd, &rect); - SetWindowPos(cfi->hwnd, HWND_TOP, 0, 0, MIN(cfi->client_width + cfi->offset_x, rect.right - rect.left), MIN(cfi->client_height + cfi->offset_y, rect.bottom - rect.top), SWP_NOMOVE | SWP_FRAMECHANGED); - wf_update_canvas_diff(cfi); - } - - hMenu = GetSystemMenu(cfi->hwnd, FALSE); - CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, instance->settings->SmartSizing); - wf_size_scrollbars(cfi, cfi->client_width, cfi->client_height); - GetClientRect(cfi->hwnd, &rect); - InvalidateRect(cfi->hwnd, &rect, TRUE); - break; - - case FreeRDP_ConnectionType: - fprintf(stderr, "ConnectionType changed.\n"); - freerdp_set_connection_type(cfi->instance->settings, cfi->instance->settings->ConnectionType); - break; - } - - // trigger callback to client - - if (cfi->client_callback_func != NULL) - { - fprintf(stderr, "Notifying client..."); - cfi->client_callback_func(cfi, CALLBACK_TYPE_PARAM_CHANGE, id, 0); - } -} - -int freerdp_client_set_client_callback_function(wfInfo* cfi, callbackFunc callbackFunc) -{ - cfi->client_callback_func = callbackFunc; - return 0; -} - -// TODO: Some of that code is a duplicate of wf_pre_connect. Refactor? -int freerdp_client_load_settings_from_rdp_file(wfInfo* cfi, char* filename) -{ - rdpSettings* settings; - - settings = cfi->instance->settings; - - if (filename) - { - settings->ConnectionFile = _strdup(filename); - - // free old settings file - freerdp_client_rdp_file_free(cfi->connectionRdpFile); - cfi->connectionRdpFile = freerdp_client_rdp_file_new(); - - fprintf(stderr, "Using connection file: %s\n", settings->ConnectionFile); - - if (!freerdp_client_parse_rdp_file(cfi->connectionRdpFile, settings->ConnectionFile)) - { - return 1; - } - - if (!freerdp_client_populate_settings_from_rdp_file(cfi->connectionRdpFile, settings)) - { - return 2; - } - } - - return 0; -} - -int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename) -{ - if (filename == NULL) - return 1; - - if (cfi->instance->settings->ConnectionFile) - { - free(cfi->instance->settings->ConnectionFile); - } - - cfi->instance->settings->ConnectionFile = _strdup(filename); - - // Reuse existing rdpFile structure if available, to preserve unsupported settings when saving to disk. - if (cfi->connectionRdpFile == NULL) - { - cfi->connectionRdpFile = freerdp_client_rdp_file_new(); - } - - if (!freerdp_client_populate_rdp_file_from_settings(cfi->connectionRdpFile, cfi->instance->settings)) - { - return 1; - } - - if (!freerdp_client_write_rdp_file(cfi->connectionRdpFile, filename, UNICODE)); - { - return 2; - } - - return 0; -} - - -void wf_size_scrollbars(wfInfo* wfi, int client_width, int client_height) -{ - BOOL rc; - if (wfi->disablewindowtracking == TRUE) - { - return; - } - - - // prevent infinite message loop - wfi->disablewindowtracking = TRUE; - - if (wfi->instance->settings->SmartSizing) - { - wfi->xCurrentScroll = 0; - wfi->yCurrentScroll = 0; - - if (wfi->xScrollVisible || wfi->yScrollVisible) - { - if (ShowScrollBar(wfi->hwnd, SB_BOTH, FALSE)) - { - wfi->xScrollVisible = FALSE; - wfi->yScrollVisible = FALSE; - } - } - } - else - { - SCROLLINFO si; - BOOL horiz = wfi->xScrollVisible; - BOOL vert = wfi->yScrollVisible;; - - if (!horiz && client_width < wfi->instance->settings->DesktopWidth) - { - horiz = TRUE; - } - else if (horiz && client_width >= wfi->instance->settings->DesktopWidth/* - GetSystemMetrics(SM_CXVSCROLL)*/) - { - horiz = FALSE; - } - - if (!vert && client_height < wfi->instance->settings->DesktopHeight) - { - vert = TRUE; - } - else if (vert && client_height >= wfi->instance->settings->DesktopHeight/* - GetSystemMetrics(SM_CYHSCROLL)*/) - { - vert = FALSE; - } - - if (horiz == vert && (horiz != wfi->xScrollVisible && vert != wfi->yScrollVisible)) - { - if (ShowScrollBar(wfi->hwnd, SB_BOTH, horiz)) - { - wfi->xScrollVisible = horiz; - wfi->yScrollVisible = vert; - } - } - - if (horiz != wfi->xScrollVisible) - { - if (ShowScrollBar(wfi->hwnd, SB_HORZ, horiz)) - { - wfi->xScrollVisible = horiz; - } - } - - if (vert != wfi->yScrollVisible) - { - if (ShowScrollBar(wfi->hwnd, SB_VERT, vert)) - { - wfi->yScrollVisible = vert; - } - } - - if (horiz) - { - // The horizontal scrolling range is defined by - // (bitmap_width) - (client_width). The current horizontal - // scroll value remains within the horizontal scrolling range. - wfi->xMaxScroll = MAX(wfi->instance->settings->DesktopWidth - client_width, 0); - wfi->xCurrentScroll = MIN(wfi->xCurrentScroll, wfi->xMaxScroll); - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = wfi->xMinScroll; - si.nMax = wfi->instance->settings->DesktopWidth; - si.nPage = client_width; - si.nPos = wfi->xCurrentScroll; - SetScrollInfo(wfi->hwnd, SB_HORZ, &si, TRUE); - } - - if (vert) - { - // The vertical scrolling range is defined by - // (bitmap_height) - (client_height). The current vertical - // scroll value remains within the vertical scrolling range. - wfi->yMaxScroll = MAX(wfi->instance->settings->DesktopHeight - client_height, 0); - wfi->yCurrentScroll = MIN(wfi->yCurrentScroll, wfi->yMaxScroll); - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = wfi->yMinScroll; - si.nMax = wfi->instance->settings->DesktopHeight; - si.nPage = client_height; - si.nPos = wfi->yCurrentScroll; - SetScrollInfo(wfi->hwnd, SB_VERT, &si, TRUE); - } - } - - wfi->disablewindowtracking = FALSE; - wf_update_canvas_diff(wfi); -} diff --git a/client/Windows/wf_interface.h b/client/Windows/wf_interface.h index 669e606f2..028e1a853 100644 --- a/client/Windows/wf_interface.h +++ b/client/Windows/wf_interface.h @@ -43,11 +43,6 @@ extern "C" { #endif -// Callback type codes. Move elsewhere? -#define CALLBACK_TYPE_PARAM_CHANGE 0x01 -#define CALLBACK_TYPE_CONNECTED 0x02 -#define CALLBACK_TYPE_DISCONNECTED 0x03 - // System menu constants #define SYSCOMMAND_ID_SMARTSIZING 1000 @@ -68,21 +63,10 @@ struct wf_pointer }; typedef struct wf_pointer wfPointer; -typedef struct wf_info wfInfo; - struct wf_context { - rdpContext _p; - - wfInfo* wfi; -}; -typedef struct wf_context wfContext; - -typedef void (CALLBACK * callbackFunc)(wfInfo* wfi, int callback_type, DWORD param1, DWORD param2); - -struct wf_info -{ - rdpClient* client; + rdpContext context; + DEFINE_RDP_CLIENT_COMMON(); int width; int height; @@ -97,7 +81,6 @@ struct wf_info int client_width; int client_height; - HANDLE thread; HANDLE keyboardThread; HICON icon; @@ -129,61 +112,33 @@ struct wf_info NSC_CONTEXT* nsc_context; BOOL sw_gdi; - callbackFunc client_callback_func; rdpFile* connectionRdpFile; // Keep track of window size and position, disable when in fullscreen mode. - BOOL disablewindowtracking; + BOOL disablewindowtracking; - // These variables are required for horizontal scrolling. + // These variables are required for horizontal scrolling. BOOL updating_scrollbars; BOOL xScrollVisible; - int xMinScroll; // minimum horizontal scroll value - int xCurrentScroll; // current horizontal scroll value - int xMaxScroll; // maximum horizontal scroll value - - // These variables are required for vertical scrolling. + int xMinScroll; // minimum horizontal scroll value + int xCurrentScroll; // current horizontal scroll value + int xMaxScroll; // maximum horizontal scroll value + + // These variables are required for vertical scrolling. BOOL yScrollVisible; - int yMinScroll; // minimum vertical scroll value - int yCurrentScroll; // current vertical scroll value - int yMaxScroll; // maximum vertical scroll value + int yMinScroll; // minimum vertical scroll value + int yCurrentScroll; // current vertical scroll value + int yMaxScroll; // maximum vertical scroll value }; +typedef struct wf_context wfContext; /** * Client Interface */ -#define cfInfo wfInfo +FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints); -void wf_on_param_change(freerdp* instance, int id); -void wf_size_scrollbars(wfInfo* wfi, int client_width, int client_height); - -FREERDP_API int freerdp_client_global_init(); -FREERDP_API int freerdp_client_global_uninit(); - -FREERDP_API int freerdp_client_start(wfInfo* cfi); -FREERDP_API int freerdp_client_stop(wfInfo* cfi); - -FREERDP_API HANDLE freerdp_client_get_thread(wfInfo* cfi); -FREERDP_API freerdp* freerdp_client_get_instance(wfInfo* cfi); -FREERDP_API rdpClient* freerdp_client_get_interface(wfInfo* cfi); - -FREERDP_API int freerdp_client_focus_in(wfInfo* cfi); -FREERDP_API int freerdp_client_focus_out(wfInfo* cfi); - -FREERDP_API int freerdp_client_set_window_size(wfInfo* cfi, int width, int height); - -FREERDP_API cfInfo* freerdp_client_new(int argc, char** argv); -FREERDP_API int freerdp_client_free(wfInfo* cfi); - -FREERDP_API int freerdp_client_set_client_callback_function(wfInfo* cfi, callbackFunc callbackFunc); - -FREERDP_API rdpSettings* freerdp_client_get_settings(wfInfo* wfi); - -FREERDP_API int freerdp_client_load_settings_from_rdp_file(wfInfo* cfi, char* filename); -FREERDP_API int freerdp_client_save_settings_to_rdp_file(wfInfo* cfi, char* filename); - #ifdef __cplusplus } #endif diff --git a/client/Windows/wf_rail.c b/client/Windows/wf_rail.c index 5cc3c09fe..a776828fc 100644 --- a/client/Windows/wf_rail.c +++ b/client/Windows/wf_rail.c @@ -29,30 +29,30 @@ #include "wf_window.h" #include "wf_rail.h" -void wf_rail_paint(wfInfo* wfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom) +void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom) { } -void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail) +void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail) { } -void wf_rail_send_client_system_command(wfInfo* wfi, UINT32 windowId, UINT16 command) +void wf_rail_send_client_system_command(wfContext* wfc, UINT32 windowId, UINT16 command) { } -void wf_rail_send_activate(wfInfo* wfi, HWND window, BOOL enabled) +void wf_rail_send_activate(wfContext* wfc, HWND window, BOOL enabled) { } -void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, wMessage* event) +void wf_process_rail_event(wfContext* wfc, rdpChannels* channels, wMessage* event) { } -void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window) +void wf_rail_adjust_position(wfContext* wfc, rdpWindow* window) { } -void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window) +void wf_rail_end_local_move(wfContext* wfc, rdpWindow* window) { } diff --git a/client/Windows/wf_rail.h b/client/Windows/wf_rail.h index 171733706..e4cbcec4a 100644 --- a/client/Windows/wf_rail.h +++ b/client/Windows/wf_rail.h @@ -21,12 +21,12 @@ #include "wf_interface.h" -void wf_rail_paint(wfInfo* wfi, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom); -void wf_rail_register_callbacks(wfInfo* wfi, rdpRail* rail); -void wf_rail_send_client_system_command(wfInfo* wfi, UINT32 windowId, UINT16 command); -void wf_rail_send_activate(wfInfo* wfi, HWND window, BOOL enabled); -void wf_process_rail_event(wfInfo* wfi, rdpChannels* chanman, wMessage* event); -void wf_rail_adjust_position(wfInfo* wfi, rdpWindow *window); -void wf_rail_end_local_move(wfInfo* wfi, rdpWindow *window); +void wf_rail_paint(wfContext* wfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom); +void wf_rail_register_callbacks(wfContext* wfc, rdpRail* rail); +void wf_rail_send_client_system_command(wfContext* wfc, UINT32 windowId, UINT16 command); +void wf_rail_send_activate(wfContext* wfc, HWND window, BOOL enabled); +void wf_process_rail_event(wfContext* wfc, rdpChannels* channels, wMessage* event); +void wf_rail_adjust_position(wfContext* wfc, rdpWindow* window); +void wf_rail_end_local_move(wfContext* wfc, rdpWindow* window); #endif diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt index f1d8ba08f..56dd96bdb 100644 --- a/client/X11/CMakeLists.txt +++ b/client/X11/CMakeLists.txt @@ -44,8 +44,8 @@ set(${MODULE_PREFIX}_SRCS xf_keyboard.h xf_window.c xf_window.h - xf_interface.c - xf_interface.h) + xf_client.c + xf_client.h) if(WITH_CLIENT_INTERFACE) if(CLIENT_INTERFACE_SHARED) diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c index a919c5360..8e39158c2 100644 --- a/client/X11/cli/xfreerdp.c +++ b/client/X11/cli/xfreerdp.c @@ -27,13 +27,14 @@ #include #include +#include -#include "xf_interface.h" - +#include "xf_client.h" #include "xfreerdp.h" int main(int argc, char* argv[]) { + int status; HANDLE thread; xfContext* xfc; DWORD dwExitCode; @@ -52,20 +53,17 @@ int main(int argc, char* argv[]) settings = context->settings; xfc = (xfContext*) context; - if (freerdp_client_parse_command_line(context, argc, argv) < 0) - { - if (settings->ConnectionFile) - { - freerdp_client_parse_connection_file(context, settings->ConnectionFile); - } - else - { - if (settings->ListMonitors) - xf_list_monitors(xfc); + status = freerdp_client_parse_command_line(context, argc, argv); - freerdp_client_context_free(context); - return 0; - } + status = freerdp_client_command_line_status_print(argc, argv, settings, status); + + if (status) + { + if (settings->ListMonitors) + xf_list_monitors(xfc); + + freerdp_client_context_free(context); + return 0; } freerdp_client_start(context); diff --git a/client/X11/xf_channels.c b/client/X11/xf_channels.c index dd2136fd5..91dda0b8e 100644 --- a/client/X11/xf_channels.c +++ b/client/X11/xf_channels.c @@ -23,7 +23,7 @@ #include "xf_channels.h" -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" int xf_on_channel_connected(freerdp* instance, const char* name, void* pInterface) diff --git a/client/X11/xf_interface.c b/client/X11/xf_client.c similarity index 98% rename from client/X11/xf_interface.c rename to client/X11/xf_client.c index 67f49f250..d63771c02 100644 --- a/client/X11/xf_interface.c +++ b/client/X11/xf_client.c @@ -480,6 +480,7 @@ void xf_create_window(xfContext* xfc) void xf_toggle_fullscreen(xfContext* xfc) { Pixmap contents = 0; + WindowStateChangeEventArgs e; xf_lock_x11(xfc, TRUE); @@ -495,8 +496,9 @@ void xf_toggle_fullscreen(xfContext* xfc) xf_unlock_x11(xfc, TRUE); - IFCALL(xfc->client->OnWindowStateChange, xfc->instance, - xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0); + e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0; + + PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "WindowStateChange", xfc, (wEventArgs*) &e); } void xf_lock_x11(xfContext* xfc, BOOL display) @@ -667,9 +669,6 @@ BOOL xf_pre_connect(freerdp* instance) instance->OnChannelConnected = xf_on_channel_connected; instance->OnChannelDisconnected = xf_on_channel_disconnected; - //if (status < 0) - // exit(XF_EXIT_PARSE_ARGUMENTS); - freerdp_client_load_addins(channels, instance->settings); freerdp_channels_pre_connect(channels, instance); @@ -774,6 +773,7 @@ BOOL xf_post_connect(freerdp* instance) rdpCache* cache; rdpChannels* channels; rdpSettings* settings; + ResizeWindowEventArgs e; RFX_CONTEXT* rfx_context = NULL; NSC_CONTEXT* nsc_context = NULL; xfContext* xfc = (xfContext*) instance->context; @@ -894,7 +894,10 @@ BOOL xf_post_connect(freerdp* instance) xf_cliprdr_init(xfc, channels); - IFCALL(xfc->client->OnResizeWindow, instance, settings->DesktopWidth, settings->DesktopHeight); + e.width = settings->DesktopWidth; + e.height = settings->DesktopHeight; + + PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e); return TRUE; } @@ -1550,11 +1553,6 @@ int xfreerdp_client_stop(rdpContext* context) return 0; } -rdpClient* freerdp_client_get_interface(rdpContext* context) -{ - return context->client; -} - double freerdp_client_get_scale(rdpContext* context) { xfContext* xfc = (xfContext*) context; @@ -1563,11 +1561,16 @@ double freerdp_client_get_scale(rdpContext* context) void freerdp_client_reset_scale(rdpContext* context) { + ResizeWindowEventArgs e; xfContext* xfc = (xfContext*) context; xfc->scale = 1.0; XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale); - IFCALL(xfc->client->OnResizeWindow, xfc->instance, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale); + + e.width = (int) xfc->originalWidth * xfc->scale; + e.height = (int) xfc->originalHeight * xfc->scale; + PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e); + xf_draw_screen_scaled(xfc); } @@ -1588,7 +1591,6 @@ int xfreerdp_client_new(freerdp* instance, rdpContext* context) context->channels = freerdp_channels_new(); settings = instance->settings; - xfc->client = instance->context->client; xfc->settings = instance->context->settings; settings->OsMajorType = OSMAJORTYPE_UNIX; diff --git a/client/X11/xf_interface.h b/client/X11/xf_client.h similarity index 90% rename from client/X11/xf_interface.h rename to client/X11/xf_client.h index 6710ca37b..604e46700 100644 --- a/client/X11/xf_interface.h +++ b/client/X11/xf_client.h @@ -17,11 +17,12 @@ * limitations under the License. */ -#ifndef __XF_INTERFACE_H -#define __XF_INTERFACE_H +#ifndef __XF_CLIENT_H +#define __XF_CLIENT_H #include #include +#include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -48,4 +50,4 @@ FREERDP_API int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints); } #endif -#endif /* __XF_INTERFACE_H */ +#endif /* __XF_CLIENT_H */ diff --git a/client/X11/xf_cliprdr.h b/client/X11/xf_cliprdr.h index 3f62e3268..3e3d680ee 100644 --- a/client/X11/xf_cliprdr.h +++ b/client/X11/xf_cliprdr.h @@ -20,7 +20,7 @@ #ifndef __XF_CLIPRDR_H #define __XF_CLIPRDR_H -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels); diff --git a/client/X11/xf_event.h b/client/X11/xf_event.h index 8ed250e83..4a6492f37 100644 --- a/client/X11/xf_event.h +++ b/client/X11/xf_event.h @@ -22,7 +22,7 @@ #include "xf_keyboard.h" -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" BOOL xf_event_process(freerdp* instance, XEvent* event); diff --git a/client/X11/xf_gdi.h b/client/X11/xf_gdi.h index 64e98d0cb..413f1c6e7 100644 --- a/client/X11/xf_gdi.h +++ b/client/X11/xf_gdi.h @@ -22,7 +22,7 @@ #include -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" void xf_gdi_register_update_callbacks(rdpUpdate* update); diff --git a/client/X11/xf_graphics.h b/client/X11/xf_graphics.h index 60bbba6bf..8363bf553 100644 --- a/client/X11/xf_graphics.h +++ b/client/X11/xf_graphics.h @@ -20,7 +20,7 @@ #ifndef __XF_GRAPHICS_H #define __XF_GRAPHICS_H -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" void xf_register_graphics(rdpGraphics* graphics); diff --git a/client/X11/xf_input.c b/client/X11/xf_input.c index c61defc8b..2cfffd922 100644 --- a/client/X11/xf_input.c +++ b/client/X11/xf_input.c @@ -156,6 +156,7 @@ void xf_input_detect_pinch(xfContext* xfc) double dist; double zoom; double delta; + ResizeWindowEventArgs e; if (active_contacts != 2) { @@ -195,7 +196,10 @@ void xf_input_detect_pinch(xfContext* xfc) xfc->scale = 0.5; XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale); - IFCALL(xfc->client->OnResizeWindow, xfc->instance, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale); + + e.width = (int) xfc->originalWidth * xfc->scale; + e.height = (int) xfc->originalHeight * xfc->scale; + PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e); z_vector = 0; } @@ -208,7 +212,10 @@ void xf_input_detect_pinch(xfContext* xfc) xfc->scale = 1.5; XResizeWindow(xfc->display, xfc->window->handle, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale); - IFCALL(xfc->client->OnResizeWindow, xfc->instance, xfc->originalWidth * xfc->scale, xfc->originalHeight * xfc->scale); + + e.width = (int) xfc->originalWidth * xfc->scale; + e.height = (int) xfc->originalHeight * xfc->scale; + PubSub_OnEvent(((rdpContext*) xfc)->pubSub, "ResizeWindow", xfc, (wEventArgs*) &e); z_vector = 0; } diff --git a/client/X11/xf_input.h b/client/X11/xf_input.h index 26498505b..367c7da23 100644 --- a/client/X11/xf_input.h +++ b/client/X11/xf_input.h @@ -20,7 +20,7 @@ #ifndef __XF_INPUT_H #define __XF_INPUT_H -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" #ifdef WITH_XI diff --git a/client/X11/xf_keyboard.h b/client/X11/xf_keyboard.h index 65732ced8..0b84efa43 100644 --- a/client/X11/xf_keyboard.h +++ b/client/X11/xf_keyboard.h @@ -22,7 +22,7 @@ #include -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" void xf_kbd_init(xfContext* xfc); diff --git a/client/X11/xf_monitor.h b/client/X11/xf_monitor.h index 58d465024..ed4bd21a8 100644 --- a/client/X11/xf_monitor.h +++ b/client/X11/xf_monitor.h @@ -40,7 +40,7 @@ struct _VIRTUAL_SCREEN }; typedef struct _VIRTUAL_SCREEN VIRTUAL_SCREEN; -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" int xf_list_monitors(xfContext* xfc); diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h index 3518e0388..d10bb03e5 100644 --- a/client/X11/xf_rail.h +++ b/client/X11/xf_rail.h @@ -20,7 +20,7 @@ #ifndef __XF_RAIL_H #define __XF_RAIL_H -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom); diff --git a/client/X11/xf_tsmf.h b/client/X11/xf_tsmf.h index a8cf8cdae..eb7981851 100644 --- a/client/X11/xf_tsmf.h +++ b/client/X11/xf_tsmf.h @@ -20,7 +20,7 @@ #ifndef __XF_TSMF_H #define __XF_TSMF_H -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" void xf_tsmf_init(xfContext* xfc, long xv_port); diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index c501b8224..e80023981 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -27,7 +27,7 @@ typedef struct xf_localmove xfLocalMove; typedef struct xf_window xfWindow; -#include "xf_interface.h" +#include "xf_client.h" #include "xfreerdp.h" // Extended ICCM flags http://standards.freedesktop.org/wm-spec/wm-spec-latest.html diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index fc1563ec4..802c9732f 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -62,7 +62,6 @@ struct xf_context DEFINE_RDP_CLIENT_COMMON(); freerdp* instance; - rdpClient* client; rdpSettings* settings; GC gc; diff --git a/client/common/client.c b/client/common/client.c index 629c9c6f3..7454e19f3 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -26,6 +26,18 @@ #include #include +int freerdp_client_common_new(freerdp* instance, rdpContext* context) +{ + RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints; + return pEntryPoints->ClientNew(instance, context); +} + +void freerdp_client_common_free(freerdp* instance, rdpContext* context) +{ + RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints; + pEntryPoints->ClientFree(instance, context); +} + /* Common API */ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) @@ -37,15 +49,14 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints) instance = freerdp_new(); instance->ContextSize = pEntryPoints->ContextSize; - instance->ContextNew = pEntryPoints->ClientNew; - instance->ContextFree = pEntryPoints->ClientFree; + instance->ContextNew = freerdp_client_common_new; + instance->ContextFree = freerdp_client_common_free; + instance->pClientEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc(pEntryPoints->Size); + CopyMemory(instance->pClientEntryPoints, pEntryPoints, pEntryPoints->Size); freerdp_context_new(instance); context = instance->context; - context->client->pEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc(pEntryPoints->Size); - CopyMemory(context->client->pEntryPoints, pEntryPoints, pEntryPoints->Size); - return context; } @@ -59,14 +70,14 @@ void freerdp_client_context_free(rdpContext* context) int freerdp_client_start(rdpContext* context) { - rdpClient* client = context->client; - return client->pEntryPoints->ClientStart(context); + RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints; + return pEntryPoints->ClientStart(context); } int freerdp_client_stop(rdpContext* context) { - rdpClient* client = context->client; - return client->pEntryPoints->ClientStop(context); + RDP_CLIENT_ENTRY_POINTS* pEntryPoints = context->instance->pClientEntryPoints; + return pEntryPoints->ClientStop(context); } freerdp* freerdp_client_get_instance(rdpContext* context) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 77353ff81..06514b59a 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -949,32 +949,10 @@ BOOL freerdp_client_detect_command_line(int argc, char** argv, DWORD* flags) return compatibility; } -int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings) +int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* settings, int status) { - char* p; - char* str; - int length; - int status; - DWORD flags; - BOOL compatibility; COMMAND_LINE_ARGUMENT_A* arg; - freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); - - compatibility = freerdp_client_detect_command_line(argc, argv, &flags); - - if (compatibility) - { - fprintf(stderr, "WARNING: Using deprecated command-line interface!\n"); - return freerdp_client_parse_old_command_line_arguments(argc, argv, settings); - } - else - { - CommandLineClearArgumentsA(args); - status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings, - freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter); - } - if (status == COMMAND_LINE_STATUS_PRINT_HELP) { freerdp_client_print_command_line_help(argc, argv); @@ -1025,13 +1003,36 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin return COMMAND_LINE_STATUS_PRINT; } - arg = CommandLineFindArgumentA(args, "v"); + return 0; +} - if (!settings->ConnectionFile && !(arg->Flags & COMMAND_LINE_VALUE_PRESENT)) +int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings) +{ + char* p; + char* str; + int length; + int status; + DWORD flags; + BOOL compatibility; + COMMAND_LINE_ARGUMENT_A* arg; + + freerdp_register_addin_provider(freerdp_channels_load_static_addin_entry, 0); + + compatibility = freerdp_client_detect_command_line(argc, argv, &flags); + + if (compatibility) { - //fprintf(stderr, "error: server hostname was not specified with /v:[:port]\n"); - //return COMMAND_LINE_ERROR_MISSING_ARGUMENT; + fprintf(stderr, "WARNING: Using deprecated command-line interface!\n"); + return freerdp_client_parse_old_command_line_arguments(argc, argv, settings); } + else + { + CommandLineClearArgumentsA(args); + status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, settings, + freerdp_client_command_line_pre_filter, freerdp_client_command_line_post_filter); + } + + arg = CommandLineFindArgumentA(args, "v"); arg = args; diff --git a/include/freerdp/client.h b/include/freerdp/client.h index fe62a5208..5edd4fc12 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -55,37 +55,14 @@ struct rdp_client_entry_points_v1 pRdpClientStart ClientStart; pRdpClientStop ClientStop; }; -typedef struct rdp_client_entry_points_v1 RDP_CLIENT_ENTRY_POINTS_V1; #define RDP_CLIENT_INTERFACE_VERSION 1 #define RDP_CLIENT_ENTRY_POINT_NAME "RdpClientEntry" -typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS; typedef int (*pRdpClientEntry)(RDP_CLIENT_ENTRY_POINTS* pEntryPoints); /* Common Client Interface */ -#define FREERDP_WINDOW_STATE_NORMAL 0 -#define FREERDP_WINDOW_STATE_MINIMIZED 1 -#define FREERDP_WINDOW_STATE_MAXIMIZED 2 -#define FREERDP_WINDOW_STATE_FULLSCREEN 3 -#define FREERDP_WINDOW_STATE_ACTIVE 4 - -typedef void (*pOnResizeWindow)(freerdp* instance, int width, int height); -typedef void (*pOnWindowStateChange)(freerdp* instance, int state); -typedef void (*pOnErrorInfo)(freerdp* instance, UINT32 code); -typedef void (*pOnParamChange)(freerdp* instance, int id); - -struct rdp_client -{ - RDP_CLIENT_ENTRY_POINTS* pEntryPoints; - - pOnResizeWindow OnResizeWindow; - pOnWindowStateChange OnWindowStateChange; - pOnErrorInfo OnErrorInfo; - pOnParamChange OnParamChange; -}; - #define DEFINE_RDP_CLIENT_COMMON() \ HANDLE thread diff --git a/include/freerdp/client/cmdline.h b/include/freerdp/client/cmdline.h index e0a424e7e..8e4ab21ed 100644 --- a/include/freerdp/client/cmdline.h +++ b/include/freerdp/client/cmdline.h @@ -28,6 +28,7 @@ extern "C" { #endif FREERDP_API int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettings* settings); +FREERDP_API int freerdp_client_command_line_status_print(int argc, char** argv, rdpSettings* settings, int status); FREERDP_API int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings); FREERDP_API int freerdp_client_print_version(void); diff --git a/include/freerdp/event.h b/include/freerdp/event.h new file mode 100644 index 000000000..1680c9126 --- /dev/null +++ b/include/freerdp/event.h @@ -0,0 +1,57 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * Event Definitions + * + * Copyright 2013 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_EVENT_H +#define FREERDP_EVENT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FREERDP_WINDOW_STATE_NORMAL 0 +#define FREERDP_WINDOW_STATE_MINIMIZED 1 +#define FREERDP_WINDOW_STATE_MAXIMIZED 2 +#define FREERDP_WINDOW_STATE_FULLSCREEN 3 +#define FREERDP_WINDOW_STATE_ACTIVE 4 + +DEFINE_EVENT_BEGIN(WindowStateChange) + int state; +DEFINE_EVENT_END(WindowStateChange) + +DEFINE_EVENT_BEGIN(ResizeWindow) + int width; + int height; +DEFINE_EVENT_END(ResizeWindow) + +DEFINE_EVENT_BEGIN(ErrorInfo) + UINT32 code; +DEFINE_EVENT_END(ErrorInfo) + +DEFINE_EVENT_BEGIN(ParamChange) + int id; +DEFINE_EVENT_END(ParamChange) + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_EVENT_H */ diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index c6438c5e6..214c2f719 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -26,16 +26,19 @@ typedef struct rdp_rail rdpRail; typedef struct rdp_cache rdpCache; typedef struct rdp_channels rdpChannels; typedef struct rdp_graphics rdpGraphics; -typedef struct rdp_client rdpClient; typedef struct rdp_freerdp freerdp; typedef struct rdp_context rdpContext; typedef struct rdp_freerdp_peer freerdp_peer; + typedef struct rdp_client_context rdpClientContext; +typedef struct rdp_client_entry_points_v1 RDP_CLIENT_ENTRY_POINTS_V1; +typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS; #include #include #include +#include #include #include @@ -92,7 +95,9 @@ struct rdp_context Used to keep this data available and used later on, typically just before connection initialization. @see freerdp_parse_args() */ - UINT64 paddingB[32 - 18]; /* 18 */ + ALIGN64 wPubSub* pubSub; /* (offset 18) */ + + UINT64 paddingB[32 - 19]; /* 19 */ ALIGN64 rdpRdp* rdp; /**< (offset 32) Pointer to a rdp_rdp structure used to keep the connection's parameters. @@ -109,8 +114,7 @@ struct rdp_context ALIGN64 rdpInput* input; /* 38 */ ALIGN64 rdpUpdate* update; /* 39 */ ALIGN64 rdpSettings* settings; /* 40 */ - ALIGN64 rdpClient* client; /* 41 */ - UINT64 paddingC[64 - 42]; /* 42 */ + UINT64 paddingC[64 - 41]; /* 41 */ UINT64 paddingD[96 - 64]; /* 64 */ UINT64 paddingE[128 - 96]; /* 96 */ @@ -135,7 +139,9 @@ struct rdp_freerdp Can be allocated by a call to freerdp_context_new(). Must be deallocated by a call to freerdp_context_free() before deallocating the current instance. */ - UINT64 paddingA[16 - 1]; /* 1 */ + ALIGN64 RDP_CLIENT_ENTRY_POINTS* pClientEntryPoints; + + UINT64 paddingA[16 - 2]; /* 2 */ ALIGN64 rdpInput* input; /* (offset 16) Input handle for the connection. diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 6bda2092e..70ab66706 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -744,6 +744,9 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) { + ParamChangeEventArgs e; + rdpContext* context = ((freerdp*) settings->instance)->context; + switch (id) { case FreeRDP_ServerMode: @@ -1185,7 +1188,9 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + + e.id = id; + PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e); return -1; } @@ -1508,6 +1513,9 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id) int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) { + ParamChangeEventArgs e; + rdpContext* context = ((freerdp*) settings->instance)->context; + switch (id) { case FreeRDP_ShareId: @@ -1821,7 +1829,9 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + + e.id = id; + PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e); return 0; } @@ -1844,6 +1854,9 @@ UINT64 freerdp_get_param_uint64(rdpSettings* settings, int id) int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) { + ParamChangeEventArgs e; + rdpContext* context = ((freerdp*) settings->instance)->context; + switch (id) { case FreeRDP_ParentWindowId: @@ -1857,7 +1870,9 @@ int freerdp_set_param_uint64(rdpSettings* settings, int id, UINT64 param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + + e.id = id; + PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e); return 0; } @@ -2028,6 +2043,9 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) int freerdp_set_param_string(rdpSettings* settings, int id, char* param) { + ParamChangeEventArgs e; + rdpContext* context = ((freerdp*) settings->instance)->context; + switch (id) { case FreeRDP_ServerHostname: @@ -2189,7 +2207,9 @@ int freerdp_set_param_string(rdpSettings* settings, int id, char* param) // Mark field as modified settings->settings_modified[id] = 1; - IFCALL(((freerdp*) settings->instance)->context->client->OnParamChange, ((freerdp*) settings->instance), id); + + e.id = id; + PubSub_OnEvent(context->pubSub, "ParamChange", context->instance, (wEventArgs*) &e); return 0; } diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 83128d9a4..b0e4f1754 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -308,6 +308,14 @@ void freerdp_get_version(int* major, int* minor, int* revision) *revision = FREERDP_VERSION_REVISION; } +static wEvent FreeRDP_Events[] = +{ + DEFINE_EVENT_ENTRY(WindowStateChange) + DEFINE_EVENT_ENTRY(ResizeWindow) + DEFINE_EVENT_ENTRY(ErrorInfo) + DEFINE_EVENT_ENTRY(ParamChange) +}; + /** Allocator function for a rdp context. * The function will allocate a rdpRdp structure using rdp_new(), then copy * its contents to the appropriate fields in the rdp_freerdp structure given in parameters. @@ -339,8 +347,8 @@ int freerdp_context_new(freerdp* instance) context->update = instance->update; context->settings = instance->settings; - context->client = (rdpClient*) malloc(sizeof(rdpClient)); - ZeroMemory(context->client, sizeof(rdpClient)); + context->pubSub = PubSub_New(TRUE); + PubSub_Publish(context->pubSub, FreeRDP_Events, sizeof(FreeRDP_Events) / sizeof(wEvent)); instance->update->context = instance->context; instance->update->pointer->context = instance->context; @@ -375,11 +383,7 @@ void freerdp_context_free(freerdp* instance) rdp_free(instance->context->rdp); graphics_free(instance->context->graphics); - if (instance->context->client) - { - free(instance->context->client->pEntryPoints); - free(instance->context->client); - } + PubSub_Free(instance->context->pubSub); free(instance->context); instance->context = NULL; diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 2f23b895a..3d82652ea 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -502,11 +502,13 @@ BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s) if (rdp->errorInfo != ERRINFO_SUCCESS) { - rdpClient* client = rdp->instance->context->client; + ErrorInfoEventArgs e; + rdpContext* context = rdp->instance->context; rdp_print_errinfo(rdp->errorInfo); - IFCALL(client->OnErrorInfo, rdp->instance, rdp->errorInfo); + e.code = rdp->errorInfo; + PubSub_OnEvent(context->pubSub, "ErrorInfo", context, (wEventArgs*) &e); } return TRUE; diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index a8ed0765e..9a028fd87 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -339,6 +339,72 @@ WINPR_API void MessagePipe_PostQuit(wMessagePipe* pipe, int nExitCode); WINPR_API wMessagePipe* MessagePipe_New(void); WINPR_API void MessagePipe_Free(wMessagePipe* pipe); +/* Publisher/Subscriber Pattern */ + +struct _wEventArgs +{ + DWORD size; +}; +typedef struct _wEventArgs wEventArgs; + +typedef void (*pEventHandler)(void* context, wEventArgs* e); + +#define MAX_EVENT_HANDLERS 32 + +struct _wEvent +{ + const char* EventName; + wEventArgs EventArgs; + int EventHandlerCount; + pEventHandler EventHandlers[MAX_EVENT_HANDLERS]; +}; +typedef struct _wEvent wEvent; + +#define DEFINE_EVENT_HANDLER(_name) \ + typedef void (*p ## _name ## EventHandler)(void* context, _name ## EventArgs* e) + +#define DEFINE_EVENT_BEGIN(_name) \ + typedef struct _ ## _name ## EventArgs { \ + wEventArgs e; + +#define DEFINE_EVENT_END(_name) \ + } _name ## EventArgs; \ + DEFINE_EVENT_HANDLER(_name); + +#define DEFINE_EVENT_ENTRY(_name) \ + { #_name, { sizeof( _name ## EventArgs) }, 0, { \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }, + +struct _wPubSub +{ + HANDLE mutex; + BOOL synchronized; + + int size; + int count; + wEvent* events; +}; +typedef struct _wPubSub wPubSub; + +WINPR_API BOOL PubSub_Lock(wPubSub* pubSub); +WINPR_API BOOL PubSub_Unlock(wPubSub* pubSub); + +WINPR_API wEvent* PubSub_Events(wPubSub* pubSub, int* count); +WINPR_API wEvent* PubSub_FindEvent(wPubSub* pubSub, const char* EventName); + +WINPR_API void PubSub_Publish(wPubSub* pubSub, wEvent* events, int count); + +WINPR_API int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler); +WINPR_API int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler); + +WINPR_API int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e); + +WINPR_API wPubSub* PubSub_New(BOOL synchronized); +WINPR_API void PubSub_Free(wPubSub* pubSub); + #ifdef __cplusplus } #endif diff --git a/winpr/libwinpr/handle/handle.h b/winpr/libwinpr/handle/handle.h index 5011e826d..9e9e44a25 100644 --- a/winpr/libwinpr/handle/handle.h +++ b/winpr/libwinpr/handle/handle.h @@ -32,7 +32,7 @@ #define HANDLE_TYPE_ANONYMOUS_PIPE 7 #define WINPR_HANDLE_DEF() \ - ULONG Type; + ULONG Type struct winpr_handle { diff --git a/winpr/libwinpr/pipe/pipe.c b/winpr/libwinpr/pipe/pipe.c index 8b2ee59e9..1363763ee 100644 --- a/winpr/libwinpr/pipe/pipe.c +++ b/winpr/libwinpr/pipe/pipe.c @@ -38,8 +38,6 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize) { - void* ptr; - HANDLE handle; int pipe_fd[2]; WINPR_PIPE* pReadPipe; WINPR_PIPE* pWritePipe; diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index 50c6eaad7..2a8c53afe 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -21,6 +21,7 @@ set(MODULE_PREFIX "WINPR_UTILS") set(${MODULE_PREFIX}_COLLECTIONS_SRCS collections/Queue.c collections/Stack.c + collections/PubSub.c collections/Reference.c collections/ArrayList.c collections/Dictionary.c diff --git a/winpr/libwinpr/utils/cmdline.c b/winpr/libwinpr/utils/cmdline.c index 7ba1822c5..0c998ea4c 100644 --- a/winpr/libwinpr/utils/cmdline.c +++ b/winpr/libwinpr/utils/cmdline.c @@ -49,6 +49,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* void* context, COMMAND_LINE_PRE_FILTER_FN_A preFilter, COMMAND_LINE_POST_FILTER_FN_A postFilter) { int i, j; + int status; int count; int length; int index; @@ -67,11 +68,16 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* int value_index; int toggle; + status = 0; + if (!argv) - return 0; + return status; if (argc == 1) - return COMMAND_LINE_STATUS_PRINT_HELP; + { + status = COMMAND_LINE_STATUS_PRINT_HELP; + return status; + } for (i = 1; i < argc; i++) { @@ -82,7 +88,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* count = preFilter(context, i, argc, argv); if (count < 0) - return COMMAND_LINE_ERROR; + { + status = COMMAND_LINE_ERROR; + return status; + } if (count > 0) { @@ -257,7 +266,10 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* } if (!value && (options[j].Flags & COMMAND_LINE_VALUE_REQUIRED)) - return COMMAND_LINE_ERROR_MISSING_VALUE; + { + status = COMMAND_LINE_ERROR_MISSING_VALUE; + return status; + } options[j].Flags |= COMMAND_LINE_ARGUMENT_PRESENT; @@ -311,7 +323,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A* } } - return 0; + return status; } int CommandLineParseArgumentsW(int argc, LPCWSTR* argv, COMMAND_LINE_ARGUMENT_W* options, DWORD flags, diff --git a/winpr/libwinpr/utils/collections/PubSub.c b/winpr/libwinpr/utils/collections/PubSub.c new file mode 100644 index 000000000..9c4358263 --- /dev/null +++ b/winpr/libwinpr/utils/collections/PubSub.c @@ -0,0 +1,224 @@ +/** + * WinPR: Windows Portable Runtime + * Publisher/Subscriber Pattern + * + * Copyright 2012 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +/** + * Properties + */ + +wEvent* PubSub_Events(wPubSub* pubSub, int* count) +{ + if (count) + *count = pubSub->count; + + return pubSub->events; +} + +/** + * Methods + */ + +BOOL PubSub_Lock(wPubSub* pubSub) +{ + return (WaitForSingleObject(pubSub->mutex, INFINITE) == WAIT_OBJECT_0) ? TRUE : FALSE; +} + +BOOL PubSub_Unlock(wPubSub* pubSub) +{ + return ReleaseMutex(pubSub->mutex); +} + +wEvent* PubSub_FindEvent(wPubSub* pubSub, const char* EventName) +{ + int index; + wEvent* event = NULL; + + for (index = 0; pubSub->count; index++) + { + if (strcmp(pubSub->events[index].EventName, EventName) == 0) + { + event = &(pubSub->events[index]); + break; + } + } + + return event; +} + +void PubSub_Publish(wPubSub* pubSub, wEvent* events, int count) +{ + if (pubSub->synchronized) + PubSub_Lock(pubSub); + + while (pubSub->count + count >= pubSub->size) + { + pubSub->size *= 2; + pubSub->events = (wEvent*) realloc(pubSub->events, pubSub->size); + } + + CopyMemory(&pubSub->events[pubSub->count], events, count * sizeof(wEvent)); + pubSub->count += count; + + if (pubSub->synchronized) + PubSub_Unlock(pubSub); +} + +int PubSub_Subscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler) +{ + wEvent* event; + int status = -1; + + if (pubSub->synchronized) + PubSub_Lock(pubSub); + + event = PubSub_FindEvent(pubSub, EventName); + + if (event) + { + status = 0; + + if (event->EventHandlerCount <= MAX_EVENT_HANDLERS) + { + event->EventHandlers[event->EventHandlerCount] = EventHandler; + event->EventHandlerCount++; + } + else + { + status = -1; + } + } + + if (pubSub->synchronized) + PubSub_Unlock(pubSub); + + return status; +} + +int PubSub_Unsubscribe(wPubSub* pubSub, const char* EventName, pEventHandler EventHandler) +{ + int index; + wEvent* event; + int status = -1; + + if (pubSub->synchronized) + PubSub_Lock(pubSub); + + event = PubSub_FindEvent(pubSub, EventName); + + if (event) + { + status = 0; + + for (index = 0; index < event->EventHandlerCount; index++) + { + if (event->EventHandlers[index] == EventHandler) + { + event->EventHandlers[index] = NULL; + event->EventHandlerCount--; + MoveMemory(&event->EventHandlers[index], &event->EventHandlers[index + 1], + (MAX_EVENT_HANDLERS - index - 1) * sizeof(wEvent)); + status = 1; + } + } + } + + if (pubSub->synchronized) + PubSub_Unlock(pubSub); + + return status; +} + +int PubSub_OnEvent(wPubSub* pubSub, const char* EventName, void* context, wEventArgs* e) +{ + int index; + wEvent* event; + int status = -1; + + if (pubSub->synchronized) + PubSub_Lock(pubSub); + + event = PubSub_FindEvent(pubSub, EventName); + + if (event) + { + status = 0; + + for (index = 0; index < event->EventHandlerCount; index++) + { + if (event->EventHandlers[index]) + { + event->EventHandlers[index](context, e); + status = 1; + } + } + } + + if (pubSub->synchronized) + PubSub_Unlock(pubSub); + + return status; +} + +/** + * Construction, Destruction + */ + +wPubSub* PubSub_New(BOOL synchronized) +{ + wPubSub* pubSub = NULL; + + pubSub = (wPubSub*) malloc(sizeof(wPubSub)); + + if (pubSub) + { + pubSub->synchronized = synchronized; + + if (pubSub->synchronized) + pubSub->mutex = CreateMutex(NULL, FALSE, NULL); + + pubSub->count = 0; + pubSub->size = 64; + + pubSub->events = (wEvent*) malloc(sizeof(wEvent) * pubSub->size); + ZeroMemory(pubSub->events, sizeof(wEvent) * pubSub->size); + } + + return pubSub; +} + +void PubSub_Free(wPubSub* pubSub) +{ + if (pubSub) + { + if (pubSub->synchronized) + CloseHandle(pubSub->mutex); + + if (pubSub->events) + free(pubSub->events); + + free(pubSub); + } +} diff --git a/winpr/libwinpr/utils/test/CMakeLists.txt b/winpr/libwinpr/utils/test/CMakeLists.txt index 307aae204..2656109b0 100644 --- a/winpr/libwinpr/utils/test/CMakeLists.txt +++ b/winpr/libwinpr/utils/test/CMakeLists.txt @@ -7,6 +7,7 @@ set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS TestQueue.c TestPrint.c + TestPubSub.c TestArrayList.c TestCmdLine.c TestStreamPool.c diff --git a/winpr/libwinpr/utils/test/TestPubSub.c b/winpr/libwinpr/utils/test/TestPubSub.c new file mode 100644 index 000000000..68e4cb3cc --- /dev/null +++ b/winpr/libwinpr/utils/test/TestPubSub.c @@ -0,0 +1,86 @@ + +#include +#include +#include + +DEFINE_EVENT_BEGIN(MouseMotion) + int x; + int y; +DEFINE_EVENT_END(MouseMotion) + +DEFINE_EVENT_BEGIN(MouseButton) + int x; + int y; + int flags; + int button; +DEFINE_EVENT_END(MouseButton) + +void MouseMotionEventHandler(void* context, MouseMotionEventArgs* e) +{ + printf("MouseMotionEvent: x: %d y: %d\n", e->x, e->y); +} + +void MouseButtonEventHandler(void* context, MouseButtonEventArgs* e) +{ + printf("MouseButtonEvent: x: %d y: %d flags: %d button: %d\n", e->x, e->y, e->flags, e->button); +} + +static wEvent Node_Events[] = +{ + DEFINE_EVENT_ENTRY(MouseMotion) + DEFINE_EVENT_ENTRY(MouseButton) +}; + +#define NODE_EVENT_COUNT (sizeof(Node_Events) / sizeof(wEvent)) + +/* strongly-typed wrappers could be automatically defined using a macro */ + +static INLINE int PubSub_SubscribeMouseMotion(wPubSub* pubSub, pMouseMotionEventHandler MouseMotionEventHandler) +{ + return PubSub_Subscribe(pubSub, "MouseMotion", (pEventHandler) MouseMotionEventHandler); +} + +static INLINE int PubSub_OnMouseMotion(wPubSub* pubSub, void* context, MouseMotionEventArgs* e) +{ + return PubSub_OnEvent(pubSub, "MouseMotion", context, (wEventArgs*) e); +} + +int TestPubSub(int argc, char* argv[]) +{ + wPubSub* node; + + node = PubSub_New(TRUE); + + PubSub_Publish(node, Node_Events, NODE_EVENT_COUNT); + + /* Register Event Handler */ + + PubSub_SubscribeMouseMotion(node, MouseMotionEventHandler); + PubSub_Subscribe(node, "MouseButton", (pEventHandler) MouseButtonEventHandler); + + /* Call Event Handler */ + { + MouseMotionEventArgs e; + + e.x = 64; + e.y = 128; + + PubSub_OnMouseMotion(node, NULL, &e); + } + + { + MouseButtonEventArgs e; + + e.x = 23; + e.y = 56; + e.flags = 7; + e.button = 1; + + PubSub_OnEvent(node, "MouseButton", NULL, (wEventArgs*) &e); + } + + PubSub_Free(node); + + return 0; +} +