2011-09-26 00:30:20 +04:00
|
|
|
/**
|
2012-10-09 07:02:04 +04:00
|
|
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
2011-09-26 00:30:20 +04:00
|
|
|
* Event Handling
|
|
|
|
*
|
|
|
|
* Copyright 2009-2011 Jay Sorg
|
|
|
|
* Copyright 2010-2011 Vic Lee
|
|
|
|
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2012-08-15 01:20:53 +04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2011-09-26 00:30:20 +04:00
|
|
|
#include <stdio.h>
|
2012-08-15 01:20:53 +04:00
|
|
|
|
2011-09-26 00:30:20 +04:00
|
|
|
#include <freerdp/freerdp.h>
|
2012-08-15 01:20:53 +04:00
|
|
|
|
2013-03-19 06:09:52 +04:00
|
|
|
#include "wf_interface.h"
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2012-12-25 08:10:24 +04:00
|
|
|
#include "wf_gdi.h"
|
2011-09-26 00:30:20 +04:00
|
|
|
#include "wf_event.h"
|
|
|
|
|
|
|
|
static HWND g_focus_hWnd;
|
|
|
|
|
2013-03-19 05:54:50 +04:00
|
|
|
#define X_POS(lParam) (lParam & 0xFFFF)
|
|
|
|
#define Y_POS(lParam) ((lParam >> 16) & 0xFFFF)
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2013-04-11 00:58:14 +04:00
|
|
|
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);
|
|
|
|
|
2011-09-26 00:30:20 +04:00
|
|
|
LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
wfInfo* wfi;
|
2013-03-06 21:50:25 +04:00
|
|
|
DWORD rdp_scancode;
|
2011-09-26 00:30:20 +04:00
|
|
|
rdpInput* input;
|
|
|
|
PKBDLLHOOKSTRUCT p;
|
|
|
|
|
2012-02-22 02:22:01 +04:00
|
|
|
DEBUG_KBD("Low-level keyboard hook, hWnd %X nCode %X wParam %X", g_focus_hWnd, nCode, wParam);
|
2011-09-26 00:30:20 +04:00
|
|
|
|
|
|
|
if (g_focus_hWnd && (nCode == HC_ACTION))
|
|
|
|
{
|
|
|
|
switch (wParam)
|
|
|
|
{
|
|
|
|
case WM_KEYDOWN:
|
|
|
|
case WM_SYSKEYDOWN:
|
|
|
|
case WM_KEYUP:
|
|
|
|
case WM_SYSKEYUP:
|
|
|
|
wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
|
|
|
|
p = (PKBDLLHOOKSTRUCT) lParam;
|
2013-03-19 05:54:50 +04:00
|
|
|
|
2012-10-02 11:04:58 +04:00
|
|
|
if (!wfi || !p)
|
|
|
|
return 1;
|
2013-03-19 05:54:50 +04:00
|
|
|
|
2011-09-26 00:30:20 +04:00
|
|
|
input = wfi->instance->input;
|
2012-10-09 11:01:37 +04:00
|
|
|
rdp_scancode = MAKE_RDP_SCANCODE((BYTE) p->scanCode, p->flags & LLKHF_EXTENDED);
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2012-02-22 02:22:01 +04:00
|
|
|
DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X",
|
2012-10-09 11:01:37 +04:00
|
|
|
(wParam == WM_KEYDOWN), (BYTE) p->scanCode, p->flags, p->vkCode);
|
2011-09-26 00:30:20 +04:00
|
|
|
|
|
|
|
if (wfi->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)
|
2012-12-25 08:10:24 +04:00
|
|
|
{
|
|
|
|
wf_toggle_fullscreen(wfi);
|
|
|
|
return 1;
|
|
|
|
}
|
2011-09-26 00:30:20 +04:00
|
|
|
}
|
|
|
|
|
2012-03-29 03:12:48 +04:00
|
|
|
if (rdp_scancode == RDP_SCANCODE_NUMLOCK_EXTENDED)
|
2011-09-26 00:30:20 +04:00
|
|
|
{
|
2012-03-29 03:12:48 +04:00
|
|
|
/* Windows sends NumLock as extended - rdp doesn't */
|
|
|
|
DEBUG_KBD("hack: NumLock (x45) should not be extended");
|
|
|
|
rdp_scancode = RDP_SCANCODE_NUMLOCK;
|
|
|
|
}
|
|
|
|
else if (rdp_scancode == RDP_SCANCODE_NUMLOCK)
|
|
|
|
{
|
|
|
|
/* Windows sends Pause as if it was a RDP NumLock (handled above).
|
|
|
|
* It must however be sent as a one-shot Ctrl+NumLock */
|
|
|
|
if (wParam == WM_KEYDOWN)
|
2011-09-26 00:30:20 +04:00
|
|
|
{
|
2012-03-29 03:12:48 +04:00
|
|
|
DEBUG_KBD("Pause, sent as Ctrl+NumLock");
|
2012-10-09 10:31:28 +04:00
|
|
|
freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_LCONTROL);
|
|
|
|
freerdp_input_send_keyboard_event_ex(input, TRUE, RDP_SCANCODE_NUMLOCK);
|
|
|
|
freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_LCONTROL);
|
|
|
|
freerdp_input_send_keyboard_event_ex(input, FALSE, RDP_SCANCODE_NUMLOCK);
|
2011-09-26 00:30:20 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-03-29 03:12:48 +04:00
|
|
|
DEBUG_KBD("Pause up");
|
2011-09-26 00:30:20 +04:00
|
|
|
}
|
|
|
|
|
2012-03-29 03:12:48 +04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (rdp_scancode == RDP_SCANCODE_RSHIFT_EXTENDED)
|
2011-09-26 00:30:20 +04:00
|
|
|
{
|
2012-03-29 03:12:48 +04:00
|
|
|
DEBUG_KBD("right shift (x36) should not be extended");
|
|
|
|
rdp_scancode = RDP_SCANCODE_RSHIFT;
|
2011-09-26 00:30:20 +04:00
|
|
|
}
|
|
|
|
|
2012-09-22 22:27:30 +04:00
|
|
|
freerdp_input_send_keyboard_event_ex(input, !(p->flags & LLKHF_UP), rdp_scancode);
|
2011-09-26 00:30:20 +04:00
|
|
|
|
|
|
|
if (p->vkCode == VK_CAPITAL)
|
2012-02-22 02:22:01 +04:00
|
|
|
DEBUG_KBD("caps lock is processed on client side too to toggle caps lock indicator");
|
2011-09-26 00:30:20 +04:00
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
2012-10-17 15:48:24 +04:00
|
|
|
static int wf_event_process_WM_MOUSEWHEEL(wfInfo* wfi, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
2012-10-16 20:57:12 +04:00
|
|
|
{
|
|
|
|
int delta;
|
|
|
|
int flags;
|
|
|
|
rdpInput* input;
|
|
|
|
|
|
|
|
DefWindowProc(hWnd, Msg, wParam, lParam);
|
|
|
|
input = wfi->instance->input;
|
2012-10-17 15:48:24 +04:00
|
|
|
delta = ((signed short) HIWORD(wParam)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
|
|
|
|
|
2012-10-16 20:57:12 +04:00
|
|
|
if (delta > 0)
|
|
|
|
{
|
|
|
|
flags = PTR_FLAGS_WHEEL | 0x0078;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
|
|
|
|
}
|
2012-10-17 15:48:24 +04:00
|
|
|
|
2012-10-16 20:57:12 +04:00
|
|
|
input->MouseEvent(input, flags, 0, 0);
|
2012-10-17 15:48:24 +04:00
|
|
|
|
2012-10-16 20:57:12 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-04-26 23:46:36 +04:00
|
|
|
void wf_sizing(wfInfo* wfi, 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))
|
|
|
|
{
|
|
|
|
rect = (LPRECT) wParam;
|
|
|
|
|
|
|
|
switch(lParam)
|
|
|
|
{
|
|
|
|
case WMSZ_LEFT:
|
|
|
|
case WMSZ_RIGHT:
|
|
|
|
case WMSZ_BOTTOMRIGHT:
|
|
|
|
// Adjust height
|
|
|
|
rect->bottom = rect->top + wfi->height * (rect->right - rect->left) / wfi->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;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WMSZ_BOTTOMLEFT:
|
|
|
|
case WMSZ_TOPLEFT:
|
|
|
|
// adjust width
|
|
|
|
rect->left = rect->right - (wfi->width * (rect->bottom - rect->top) / wfi->instance->settings->DesktopHeight);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-09-26 00:30:20 +04:00
|
|
|
LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
HDC hdc;
|
|
|
|
LONG ptr;
|
|
|
|
wfInfo* wfi;
|
2011-10-07 22:55:07 +04:00
|
|
|
int x, y, w, h;
|
2011-09-26 00:30:20 +04:00
|
|
|
PAINTSTRUCT ps;
|
|
|
|
rdpInput* input;
|
2012-10-09 10:38:39 +04:00
|
|
|
BOOL processed;
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2013-04-26 01:18:14 +04:00
|
|
|
RECT windowRect, clientRect;
|
|
|
|
MINMAXINFO *minmax;
|
2013-04-26 23:46:36 +04:00
|
|
|
SCROLLINFO si;
|
2013-04-26 01:18:14 +04:00
|
|
|
|
2012-10-09 10:31:28 +04:00
|
|
|
processed = TRUE;
|
2011-09-26 00:30:20 +04:00
|
|
|
ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
|
|
|
wfi = (wfInfo*) ptr;
|
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
if (wfi != NULL)
|
2011-09-26 00:30:20 +04:00
|
|
|
{
|
2011-09-26 01:47:40 +04:00
|
|
|
input = wfi->instance->input;
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
switch (Msg)
|
|
|
|
{
|
2013-04-25 23:42:40 +04:00
|
|
|
case WM_MOVE:
|
2013-04-26 01:18:14 +04:00
|
|
|
if (!wfi->disablewindowtracking)
|
2013-04-25 23:42:40 +04:00
|
|
|
{
|
2013-04-26 23:46:36 +04:00
|
|
|
int x = (int)(short) LOWORD(lParam);
|
|
|
|
int y = (int)(short) HIWORD(lParam);
|
2013-04-25 23:42:40 +04:00
|
|
|
((wfContext*) wfi->instance->context)->wfi->client_x = x;
|
|
|
|
((wfContext*) wfi->instance->context)->wfi->client_y = y;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-04-26 01:18:14 +04:00
|
|
|
case WM_GETMINMAXINFO:
|
2013-04-26 23:46:36 +04:00
|
|
|
if (wfi->instance->settings->SmartSizing)
|
2013-04-26 01:18:14 +04:00
|
|
|
{
|
2013-04-26 23:46:36 +04:00
|
|
|
processed = FALSE;
|
2013-04-26 01:18:14 +04:00
|
|
|
}
|
2013-04-26 23:46:36 +04:00
|
|
|
else
|
2013-04-25 23:42:40 +04:00
|
|
|
{
|
2013-04-26 23:46:36 +04:00
|
|
|
// Set maximum window size for resizing
|
2013-04-25 23:42:40 +04:00
|
|
|
|
2013-04-26 23:46:36 +04:00
|
|
|
minmax = (MINMAXINFO*) lParam;
|
|
|
|
wf_update_canvas_diff(wfi);
|
2013-04-25 23:42:40 +04:00
|
|
|
if (!wfi->fullscreen)
|
|
|
|
{
|
2013-04-26 23:46:36 +04:00
|
|
|
// add window decoration
|
|
|
|
minmax->ptMaxTrackSize.x = wfi->width + wfi->diff.x;
|
|
|
|
minmax->ptMaxTrackSize.y = wfi->height + wfi->diff.y;
|
2013-04-25 23:42:40 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-04-26 23:46:36 +04:00
|
|
|
case WM_SIZING:
|
|
|
|
wf_sizing(wfi, lParam, wParam);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_SIZE:
|
2013-04-30 19:15:04 +04:00
|
|
|
GetWindowRect(wfi->hwnd, &windowRect);
|
|
|
|
|
2013-04-26 23:46:36 +04:00
|
|
|
if (!wfi->fullscreen)
|
|
|
|
{
|
|
|
|
wfi->client_width = LOWORD(lParam);
|
|
|
|
wfi->client_height = HIWORD(lParam);
|
|
|
|
wfi->client_x = windowRect.left;
|
|
|
|
wfi->client_y = windowRect.top;
|
|
|
|
}
|
|
|
|
|
|
|
|
wf_size_scrollbars(wfi, LOWORD(lParam), HIWORD(lParam));
|
2013-04-30 19:15:04 +04:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
2013-04-26 23:46:36 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_EXITSIZEMOVE:
|
|
|
|
wf_size_scrollbars(wfi, wfi->client_width, wfi->client_height);
|
|
|
|
break;
|
|
|
|
|
2013-04-11 00:58:14 +04:00
|
|
|
case WM_ERASEBKGND:
|
|
|
|
/* Say we handled it - prevents flickering */
|
|
|
|
return (LRESULT) 1;
|
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
case WM_PAINT:
|
2011-09-26 00:30:20 +04:00
|
|
|
hdc = BeginPaint(hWnd, &ps);
|
2012-10-16 22:20:04 +04:00
|
|
|
|
2011-10-07 22:55:07 +04:00
|
|
|
x = ps.rcPaint.left;
|
|
|
|
y = ps.rcPaint.top;
|
|
|
|
w = ps.rcPaint.right - ps.rcPaint.left + 1;
|
|
|
|
h = ps.rcPaint.bottom - ps.rcPaint.top + 1;
|
|
|
|
|
2013-04-26 23:46:36 +04:00
|
|
|
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);
|
2011-10-07 22:55:07 +04:00
|
|
|
|
2011-09-26 00:30:20 +04:00
|
|
|
EndPaint(hWnd, &ps);
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
case WM_LBUTTONDOWN:
|
2013-04-11 00:58:14 +04:00
|
|
|
wf_scale_mouse_event(wfi, input,PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
case WM_LBUTTONUP:
|
2013-04-11 00:58:14 +04:00
|
|
|
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON1, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
case WM_RBUTTONDOWN:
|
2013-04-11 00:58:14 +04:00
|
|
|
wf_scale_mouse_event(wfi, input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
case WM_RBUTTONUP:
|
2013-04-11 00:58:14 +04:00
|
|
|
wf_scale_mouse_event(wfi, input, PTR_FLAGS_BUTTON2, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
2011-09-26 00:30:20 +04:00
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
case WM_MOUSEMOVE:
|
2013-04-11 00:58:14 +04:00
|
|
|
wf_scale_mouse_event(wfi, input, PTR_FLAGS_MOVE, X_POS(lParam) - wfi->offset_x, Y_POS(lParam) - wfi->offset_y);
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
2012-10-16 22:20:04 +04:00
|
|
|
|
2012-10-16 20:57:12 +04:00
|
|
|
case WM_MOUSEWHEEL:
|
2012-10-17 15:48:24 +04:00
|
|
|
wf_event_process_WM_MOUSEWHEEL(wfi, hWnd, Msg, wParam, lParam);
|
2012-10-16 20:57:12 +04:00
|
|
|
break;
|
2011-09-26 01:47:40 +04:00
|
|
|
|
|
|
|
case WM_SETCURSOR:
|
2012-10-16 22:06:23 +04:00
|
|
|
if (LOWORD(lParam) == HTCLIENT)
|
|
|
|
SetCursor(wfi->cursor);
|
|
|
|
else
|
|
|
|
DefWindowProc(hWnd, Msg, wParam, lParam);
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
|
|
|
|
2013-04-26 23:46:36 +04:00
|
|
|
case WM_HSCROLL:
|
|
|
|
{
|
|
|
|
int xDelta; // xDelta = new_pos - current_pos
|
|
|
|
int xNewPos; // new position
|
|
|
|
int yDelta = 0;
|
|
|
|
|
|
|
|
switch (LOWORD(wParam))
|
|
|
|
{
|
|
|
|
// User clicked the scroll bar shaft left of the scroll box.
|
|
|
|
case SB_PAGEUP:
|
|
|
|
xNewPos = wfi->xCurrentScroll - 50;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User clicked the scroll bar shaft right of the scroll box.
|
|
|
|
case SB_PAGEDOWN:
|
|
|
|
xNewPos = wfi->xCurrentScroll + 50;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User clicked the left arrow.
|
|
|
|
case SB_LINEUP:
|
|
|
|
xNewPos = wfi->xCurrentScroll - 5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User clicked the right arrow.
|
|
|
|
case SB_LINEDOWN:
|
|
|
|
xNewPos = wfi->xCurrentScroll + 5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User dragged the scroll box.
|
|
|
|
case SB_THUMBPOSITION:
|
|
|
|
xNewPos = HIWORD(wParam);
|
|
|
|
|
|
|
|
// user is dragging the scrollbar
|
|
|
|
case SB_THUMBTRACK :
|
|
|
|
xNewPos = HIWORD(wParam);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
xNewPos = wfi->xCurrentScroll;
|
|
|
|
}
|
|
|
|
|
|
|
|
// New position must be between 0 and the screen width.
|
|
|
|
xNewPos = MAX(0, xNewPos);
|
|
|
|
xNewPos = MIN(wfi->xMaxScroll, xNewPos);
|
|
|
|
|
|
|
|
// If the current position does not change, do not scroll.
|
|
|
|
if (xNewPos == wfi->xCurrentScroll)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Determine the amount scrolled (in pixels).
|
|
|
|
xDelta = xNewPos - wfi->xCurrentScroll;
|
|
|
|
|
|
|
|
// Reset the current scroll position.
|
|
|
|
wfi->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,
|
|
|
|
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
|
|
|
|
SW_INVALIDATE);
|
|
|
|
UpdateWindow(wfi->hwnd);
|
|
|
|
|
|
|
|
// Reset the scroll bar.
|
|
|
|
si.cbSize = sizeof(si);
|
|
|
|
si.fMask = SIF_POS;
|
|
|
|
si.nPos = wfi->xCurrentScroll;
|
|
|
|
SetScrollInfo(wfi->hwnd, SB_HORZ, &si, TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_VSCROLL:
|
|
|
|
{
|
|
|
|
int xDelta = 0;
|
|
|
|
int yDelta; // yDelta = new_pos - current_pos
|
|
|
|
int yNewPos; // new position
|
|
|
|
|
|
|
|
switch (LOWORD(wParam))
|
|
|
|
{
|
|
|
|
// User clicked the scroll bar shaft above the scroll box.
|
|
|
|
case SB_PAGEUP:
|
|
|
|
yNewPos = wfi->yCurrentScroll - 50;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User clicked the scroll bar shaft below the scroll box.
|
|
|
|
case SB_PAGEDOWN:
|
|
|
|
yNewPos = wfi->yCurrentScroll + 50;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User clicked the top arrow.
|
|
|
|
case SB_LINEUP:
|
|
|
|
yNewPos = wfi->yCurrentScroll - 5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User clicked the bottom arrow.
|
|
|
|
case SB_LINEDOWN:
|
|
|
|
yNewPos = wfi->yCurrentScroll + 5;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// User dragged the scroll box.
|
|
|
|
case SB_THUMBPOSITION:
|
|
|
|
yNewPos = HIWORD(wParam);
|
|
|
|
break;
|
|
|
|
|
|
|
|
// user is dragging the scrollbar
|
|
|
|
case SB_THUMBTRACK :
|
|
|
|
yNewPos = HIWORD(wParam);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
yNewPos = wfi->yCurrentScroll;
|
|
|
|
}
|
|
|
|
|
|
|
|
// New position must be between 0 and the screen height.
|
|
|
|
yNewPos = MAX(0, yNewPos);
|
|
|
|
yNewPos = MIN(wfi->yMaxScroll, yNewPos);
|
|
|
|
|
|
|
|
// If the current position does not change, do not scroll.
|
|
|
|
if (yNewPos == wfi->yCurrentScroll)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Determine the amount scrolled (in pixels).
|
|
|
|
yDelta = yNewPos - wfi->yCurrentScroll;
|
|
|
|
|
|
|
|
// Reset the current scroll position.
|
|
|
|
wfi->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,
|
|
|
|
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
|
|
|
|
SW_INVALIDATE);
|
|
|
|
UpdateWindow(wfi->hwnd);
|
|
|
|
|
|
|
|
// Reset the scroll bar.
|
|
|
|
si.cbSize = sizeof(si);
|
|
|
|
si.fMask = SIF_POS;
|
|
|
|
si.nPos = wfi->yCurrentScroll;
|
|
|
|
SetScrollInfo(wfi->hwnd, SB_VERT, &si, TRUE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-04-30 19:15:04 +04:00
|
|
|
case WM_SYSCOMMAND:
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
processed = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2011-09-26 01:47:40 +04:00
|
|
|
default:
|
2012-10-09 10:31:28 +04:00
|
|
|
processed = FALSE;
|
2011-09-26 01:47:40 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-09 10:31:28 +04:00
|
|
|
processed = FALSE;
|
2011-09-26 01:47:40 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (processed)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (Msg)
|
|
|
|
{
|
|
|
|
case WM_DESTROY:
|
|
|
|
PostQuitMessage(WM_QUIT);
|
2011-09-26 00:30:20 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_SETCURSOR:
|
2012-10-16 22:06:23 +04:00
|
|
|
if (LOWORD(lParam) == HTCLIENT)
|
2013-03-19 05:54:50 +04:00
|
|
|
SetCursor(wfi->hDefaultCursor);
|
2012-10-16 22:06:23 +04:00
|
|
|
else
|
|
|
|
DefWindowProc(hWnd, Msg, wParam, lParam);
|
2011-09-26 00:30:20 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_SETFOCUS:
|
2012-02-22 02:22:01 +04:00
|
|
|
DEBUG_KBD("getting focus %X", hWnd);
|
2011-09-26 00:30:20 +04:00
|
|
|
g_focus_hWnd = hWnd;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_KILLFOCUS:
|
2013-04-25 00:47:32 +04:00
|
|
|
if (g_focus_hWnd == hWnd && wfi && !wfi->fullscreen)
|
|
|
|
{
|
|
|
|
DEBUG_KBD("loosing focus %X", hWnd);
|
2011-09-26 00:30:20 +04:00
|
|
|
g_focus_hWnd = NULL;
|
2013-04-25 00:47:32 +04:00
|
|
|
}
|
2011-09-26 00:30:20 +04:00
|
|
|
break;
|
|
|
|
|
2013-05-31 22:20:43 +04:00
|
|
|
case WM_ACTIVATE:
|
|
|
|
{
|
|
|
|
int activate = (int)(short) LOWORD(lParam);
|
|
|
|
if (activate != WA_INACTIVE)
|
|
|
|
{
|
|
|
|
g_focus_hWnd = hWnd;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_focus_hWnd = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-26 00:30:20 +04:00
|
|
|
default:
|
|
|
|
return DefWindowProc(hWnd, Msg, wParam, lParam);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2013-04-11 00:58:14 +04:00
|
|
|
|
|
|
|
BOOL wf_scale_blt(wfInfo* wfi, 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 (!wfi->client_height)
|
|
|
|
wfi->client_height = wfi->height;
|
|
|
|
|
|
|
|
ww = wfi->client_width;
|
|
|
|
wh = wfi->client_height;
|
|
|
|
dw = wfi->instance->settings->DesktopWidth;
|
|
|
|
dh = wfi->instance->settings->DesktopHeight;
|
|
|
|
|
|
|
|
if (!ww)
|
|
|
|
ww = dw;
|
|
|
|
|
|
|
|
if (!wh)
|
|
|
|
wh = dh;
|
|
|
|
|
2013-04-30 20:56:16 +04:00
|
|
|
if (wfi->fullscreen || !wfi->instance->settings->SmartSizing || (ww == dw && wh == dh))
|
2013-04-11 00:58:14 +04:00
|
|
|
{
|
|
|
|
return BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x1, y1, SRCCOPY);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetStretchBltMode(hdc, HALFTONE);
|
|
|
|
SetBrushOrgEx(hdc, 0, 0, NULL);
|
|
|
|
|
2013-04-30 20:56:16 +04:00
|
|
|
return StretchBlt(hdc, 0, 0, ww, wh, wfi->primary->hdc, 0, 0, dw, dh, SRCCOPY);
|
2013-04-11 00:58:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void wf_scale_mouse_event(wfInfo* wfi, rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
|
|
|
{
|
|
|
|
int ww, wh, dw, dh;
|
|
|
|
|
|
|
|
if (!wfi->client_width)
|
|
|
|
wfi->client_width = wfi->width;
|
|
|
|
|
|
|
|
if (!wfi->client_height)
|
|
|
|
wfi->client_height = wfi->height;
|
|
|
|
|
|
|
|
ww = wfi->client_width;
|
|
|
|
wh = wfi->client_height;
|
|
|
|
dw = wfi->instance->settings->DesktopWidth;
|
|
|
|
dh = wfi->instance->settings->DesktopHeight;
|
|
|
|
|
2013-04-30 20:56:16 +04:00
|
|
|
if (!wfi->instance->settings->SmartSizing || (ww == dw) && (wh == dh))
|
2013-04-26 23:46:36 +04:00
|
|
|
input->MouseEvent(input, flags, x + wfi->xCurrentScroll, y + wfi->yCurrentScroll);
|
2013-04-11 00:58:14 +04:00
|
|
|
else
|
2013-04-30 20:56:16 +04:00
|
|
|
input->MouseEvent(input, flags, x * dw / ww + wfi->xCurrentScroll, y * dh / wh + wfi->yCurrentScroll);
|
2013-04-11 00:58:14 +04:00
|
|
|
}
|