diff --git a/server/Windows/cli/wfreerdp.c b/server/Windows/cli/wfreerdp.c index 0b855becd..441ba516a 100644 --- a/server/Windows/cli/wfreerdp.c +++ b/server/Windows/cli/wfreerdp.c @@ -46,6 +46,8 @@ BOOL CALLBACK moncb(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARA IDcount++; + + return TRUE; } int main(int argc, char* argv[]) @@ -88,8 +90,15 @@ int main(int argc, char* argv[]) } { + int vscreen_w; + int vscreen_h; + vscreen_w = GetSystemMetrics(SM_CXVIRTUALSCREEN); + vscreen_h = GetSystemMetrics(SM_CYVIRTUALSCREEN); + printf("\n"); - EnumDisplayMonitors(NULL, NULL, moncb, NULL); + EnumDisplayMonitors(NULL, NULL, moncb, 0); + IDcount = 0; + printf("\nVirtual Screen = %dx%d\n", vscreen_w, vscreen_h); } return 0; diff --git a/server/Windows/wf_dxgi.c b/server/Windows/wf_dxgi.c index ac9b4b907..dd5ac3421 100644 --- a/server/Windows/wf_dxgi.c +++ b/server/Windows/wf_dxgi.c @@ -65,17 +65,17 @@ ID3D11Texture2D* sStage; DXGI_OUTDUPL_FRAME_INFO FrameInfo; -int wf_dxgi_init(wfInfo* context) +int wf_dxgi_init(wfInfo* wfi) { //not sure if needed gAcquiredDesktopImage = NULL; - if (wf_dxgi_createDevice(context) != 0) + if (wf_dxgi_createDevice(wfi) != 0) { return 1; } - if (wf_dxgi_getDuplication(context) != 0) + if (wf_dxgi_getDuplication(wfi) != 0) { return 1; } @@ -84,7 +84,7 @@ int wf_dxgi_init(wfInfo* context) } -int wf_dxgi_createDevice(wfInfo* context) +int wf_dxgi_createDevice(wfInfo* wfi) { HRESULT status; UINT DriverTypeIndex; @@ -108,7 +108,7 @@ int wf_dxgi_createDevice(wfInfo* context) return 0; } -int wf_dxgi_getDuplication(wfInfo* context) +int wf_dxgi_getDuplication(wfInfo* wfi) { HRESULT status; UINT dTop, i = 0; @@ -161,7 +161,7 @@ int wf_dxgi_getDuplication(wfInfo* context) ++i; } - dTop = context->screenID; + dTop = wfi->screenID; status = DxgiAdapter->lpVtbl->EnumOutputs(DxgiAdapter, dTop, &DxgiOutput); DxgiAdapter->lpVtbl->Release(DxgiAdapter); @@ -324,7 +324,7 @@ int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout) return 0; } -int wf_dxgi_getPixelData(wfInfo* context, BYTE** data, int* pitch, RECT* invalid) +int wf_dxgi_getPixelData(wfInfo* wfi, BYTE** data, int* pitch, RECT* invalid) { HRESULT status; D3D11_BOX Box; diff --git a/server/Windows/wf_info.c b/server/Windows/wf_info.c index e36a9f222..92543d7f6 100644 --- a/server/Windows/wf_info.c +++ b/server/Windows/wf_info.c @@ -32,6 +32,7 @@ #include "wf_dxgi.h" static wfInfo* wfInfoInstance = NULL; +static int _IDcount = 0; int wf_info_lock(wfInfo* wfi) { @@ -215,6 +216,10 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context) context->info = wfi; context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + //get the offset of the top left corner of selected screen + EnumDisplayMonitors(NULL, NULL, wf_info_monEnumCB, 0); + _IDcount = 0; + #ifdef WITH_WIN8 if (wfi->peerCount == 0) wf_dxgi_init(wfi); @@ -358,3 +363,22 @@ void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, } #endif } + +BOOL CALLBACK wf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) +{ + wfInfo * wfi; + + wfi = wf_info_get_instance(); + + if(_IDcount == wfi->screenID) + { + wfi->servscreen_xoffset = lprcMonitor->left; + wfi->servscreen_yoffset = lprcMonitor->top; + } + else + { + _IDcount++; + } + + return TRUE; +} diff --git a/server/Windows/wf_info.h b/server/Windows/wf_info.h index 3a2e8015c..8c1b6ae3f 100644 --- a/server/Windows/wf_info.h +++ b/server/Windows/wf_info.h @@ -40,5 +40,6 @@ void wf_info_clear_invalid_region(wfInfo* wfi); void wf_info_invalidate_full_screen(wfInfo* wfi); BOOL wf_info_have_invalid_region(wfInfo* wfi); void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, int* pitch); +BOOL CALLBACK wf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); #endif /* WF_INFO_H */ \ No newline at end of file diff --git a/server/Windows/wf_input.c b/server/Windows/wf_input.c index 7124f2049..06b9f5350 100644 --- a/server/Windows/wf_input.c +++ b/server/Windows/wf_input.c @@ -24,6 +24,7 @@ #include #include "wf_input.h" +#include "wf_info.h" void wf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) { @@ -82,9 +83,17 @@ void wf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) } else { + wfInfo * wfi; + + wfi = wf_info_get_instance(); + + //width and height of primary screen (even in multimon setups width = (float) GetSystemMetrics(SM_CXSCREEN); height = (float) GetSystemMetrics(SM_CYSCREEN); + x += wfi->servscreen_xoffset; + y += wfi->servscreen_yoffset; + mouse_event.mi.dx = (LONG) ((float) x * (65535.0f / width)); mouse_event.mi.dy = (LONG) ((float) y * (65535.0f / height)); mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE; @@ -138,8 +147,21 @@ void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1 if (flags & PTR_FLAGS_MOVE) { - mouse_event.mi.dx = x * (0xFFFF / GetSystemMetrics(SM_CXSCREEN)); - mouse_event.mi.dy = y * (0xFFFF / GetSystemMetrics(SM_CYSCREEN)); + float width, height; + wfInfo * wfi; + + wfi = wf_info_get_instance(); + //width and height of primary screen (even in multimon setups + width = (float) GetSystemMetrics(SM_CXSCREEN); + height = (float) GetSystemMetrics(SM_CYSCREEN); + + x += wfi->servscreen_xoffset; + y += wfi->servscreen_yoffset; + + //mouse_event.mi.dx = x * (0xFFFF / width); + //mouse_event.mi.dy = y * (0xFFFF / height); + mouse_event.mi.dx = (LONG) ((float) x * (65535.0f / width)); + mouse_event.mi.dy = (LONG) ((float) y * (65535.0f / height)); mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; SendInput(1, &mouse_event, sizeof(INPUT));