mfreerdp-server: merged wf_peer.c
This commit is contained in:
commit
b5d3a493aa
@ -32,14 +32,100 @@
|
|||||||
|
|
||||||
#include "wfreerdp.h"
|
#include "wfreerdp.h"
|
||||||
|
|
||||||
|
int IDcount = 0;
|
||||||
|
|
||||||
|
BOOL CALLBACK moncb(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("%d\t(%d, %d), (%d, %d)\n",
|
||||||
|
IDcount,
|
||||||
|
lprcMonitor->left,
|
||||||
|
lprcMonitor->top,
|
||||||
|
lprcMonitor->right,
|
||||||
|
lprcMonitor->bottom);
|
||||||
|
|
||||||
|
|
||||||
|
IDcount++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
int index;
|
||||||
wfServer* server;
|
wfServer* server;
|
||||||
|
|
||||||
server = wfreerdp_server_new();
|
server = wfreerdp_server_new();
|
||||||
|
|
||||||
if (argc == 2)
|
set_screen_id(0);
|
||||||
server->port = (DWORD) atoi(argv[1]);
|
|
||||||
|
//handle args
|
||||||
|
index = 1;
|
||||||
|
while (index < argc)
|
||||||
|
{
|
||||||
|
//first the args that will cause the program to terminate
|
||||||
|
if (strcmp("--list-screens", argv[index]) == 0)
|
||||||
|
{
|
||||||
|
_TCHAR name[128];
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int bpp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
_tprintf(_T("Detecting screens...\n"));
|
||||||
|
_tprintf(_T("\nID\tResolution\t\tName (Interface)\n\n"));
|
||||||
|
|
||||||
|
for (i=0; ; i++)
|
||||||
|
{
|
||||||
|
if (get_screen_info(i, name, &width, &height, &bpp) != 0)
|
||||||
|
{
|
||||||
|
if ( (width * height * bpp) == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_tprintf(_T("%d\t%dx%dx%d\t"), i, width, height, bpp);
|
||||||
|
_tprintf(_T("%s\n"), name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int vscreen_w;
|
||||||
|
int vscreen_h;
|
||||||
|
vscreen_w = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||||
|
vscreen_h = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
EnumDisplayMonitors(NULL, NULL, moncb, 0);
|
||||||
|
IDcount = 0;
|
||||||
|
printf("\nVirtual Screen = %dx%d\n", vscreen_w, vscreen_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp("--screen", argv[index]) == 0)
|
||||||
|
{
|
||||||
|
index++;
|
||||||
|
if (index == argc)
|
||||||
|
{
|
||||||
|
printf("missing screen id parameter\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_screen_id(atoi(argv[index]));
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (index == argc - 1)
|
||||||
|
{
|
||||||
|
server->port = (DWORD) atoi(argv[index]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
printf("Starting server\n");
|
printf("Starting server\n");
|
||||||
|
|
||||||
|
@ -65,26 +65,38 @@ ID3D11Texture2D* sStage;
|
|||||||
|
|
||||||
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
|
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(wfi) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wf_dxgi_getDuplication(wfi) != 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int wf_dxgi_createDevice(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
UINT dTop, i = 0;
|
|
||||||
DXGI_OUTPUT_DESC desc;
|
|
||||||
IDXGIOutput * pOutput;
|
|
||||||
UINT DriverTypeIndex;
|
UINT DriverTypeIndex;
|
||||||
IDXGIDevice* DxgiDevice = NULL;
|
|
||||||
IDXGIAdapter* DxgiAdapter = NULL;
|
|
||||||
IDXGIOutput* DxgiOutput = NULL;
|
|
||||||
IDXGIOutput1* DxgiOutput1 = NULL;
|
|
||||||
|
|
||||||
gAcquiredDesktopImage = NULL;
|
|
||||||
|
|
||||||
for (DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
|
for (DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex)
|
||||||
{
|
{
|
||||||
status = D3D11CreateDevice(NULL, DriverTypes[DriverTypeIndex], NULL, D3D11_CREATE_DEVICE_DEBUG, FeatureLevels, NumFeatureLevels,
|
status = D3D11CreateDevice(NULL, DriverTypes[DriverTypeIndex], NULL, 0, FeatureLevels, NumFeatureLevels,
|
||||||
D3D11_SDK_VERSION, &gDevice, &FeatureLevel, &gContext);
|
D3D11_SDK_VERSION, &gDevice, &FeatureLevel, &gContext);
|
||||||
if (SUCCEEDED(status))
|
if (SUCCEEDED(status))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
_tprintf(_T("D3D11CreateDevice returned [%d] for Driver Type %d\n"), status, DriverTypes[DriverTypeIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
@ -92,7 +104,21 @@ int wf_dxgi_init(wfInfo* context)
|
|||||||
_tprintf(_T("Failed to create device in InitializeDx\n"));
|
_tprintf(_T("Failed to create device in InitializeDx\n"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wf_dxgi_getDuplication(wfInfo* wfi)
|
||||||
|
{
|
||||||
|
HRESULT status;
|
||||||
|
UINT dTop, i = 0;
|
||||||
|
DXGI_OUTPUT_DESC desc;
|
||||||
|
IDXGIOutput * pOutput;
|
||||||
|
IDXGIDevice* DxgiDevice = NULL;
|
||||||
|
IDXGIAdapter* DxgiAdapter = NULL;
|
||||||
|
IDXGIOutput* DxgiOutput = NULL;
|
||||||
|
IDXGIOutput1* DxgiOutput1 = NULL;
|
||||||
|
|
||||||
status = gDevice->lpVtbl->QueryInterface(gDevice, &IID_IDXGIDevice, (void**) &DxgiDevice);
|
status = gDevice->lpVtbl->QueryInterface(gDevice, &IID_IDXGIDevice, (void**) &DxgiDevice);
|
||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
@ -135,7 +161,7 @@ int wf_dxgi_init(wfInfo* context)
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
dTop = 0;
|
dTop = wfi->screenID;
|
||||||
|
|
||||||
status = DxgiAdapter->lpVtbl->EnumOutputs(DxgiAdapter, dTop, &DxgiOutput);
|
status = DxgiAdapter->lpVtbl->EnumOutputs(DxgiAdapter, dTop, &DxgiOutput);
|
||||||
DxgiAdapter->lpVtbl->Release(DxgiAdapter);
|
DxgiAdapter->lpVtbl->Release(DxgiAdapter);
|
||||||
@ -169,13 +195,14 @@ int wf_dxgi_init(wfInfo* context)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_tprintf(_T("Failed to get duplicate output\n"));
|
_tprintf(_T("Failed to get duplicate output. Status = %#X\n"), status);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wf_dxgi_cleanup(wfInfo* wfi)
|
int wf_dxgi_cleanup(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
if (wfi->framesWaiting > 0)
|
if (wfi->framesWaiting > 0)
|
||||||
@ -212,7 +239,7 @@ int wf_dxgi_cleanup(wfInfo* wfi)
|
|||||||
|
|
||||||
int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout)
|
int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout)
|
||||||
{
|
{
|
||||||
HRESULT status;
|
HRESULT status = 0;
|
||||||
UINT i = 0;
|
UINT i = 0;
|
||||||
UINT DataBufferSize = 0;
|
UINT DataBufferSize = 0;
|
||||||
BYTE* DataBuffer = NULL;
|
BYTE* DataBuffer = NULL;
|
||||||
@ -238,16 +265,39 @@ int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout)
|
|||||||
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
//_tprintf(_T("Failed to acquire next frame\n"));
|
if (status == DXGI_ERROR_ACCESS_LOST)
|
||||||
|
|
||||||
status = gOutputDuplication->lpVtbl->ReleaseFrame(gOutputDuplication);
|
|
||||||
|
|
||||||
if (FAILED(status))
|
|
||||||
{
|
{
|
||||||
//_tprintf(_T("Failed to release frame\n"));
|
_tprintf(_T("Failed to acquire next frame with status=%#X\n"), status);
|
||||||
|
_tprintf(_T("Trying to reinitialize due to ACCESS LOST..."));
|
||||||
|
if (gAcquiredDesktopImage)
|
||||||
|
{
|
||||||
|
gAcquiredDesktopImage->lpVtbl->Release(gAcquiredDesktopImage);
|
||||||
|
gAcquiredDesktopImage = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gOutputDuplication)
|
||||||
|
{
|
||||||
|
gOutputDuplication->lpVtbl->Release(gOutputDuplication);
|
||||||
|
gOutputDuplication = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wf_dxgi_getDuplication(wfi);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_tprintf(_T("Failed to acquire next frame with status=%#X\n"), status);
|
||||||
|
|
||||||
|
status = gOutputDuplication->lpVtbl->ReleaseFrame(gOutputDuplication);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
_tprintf(_T("Failed to release frame with status=%d\n"), status);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = DesktopResource->lpVtbl->QueryInterface(DesktopResource, &IID_ID3D11Texture2D, (void**) &gAcquiredDesktopImage);
|
status = DesktopResource->lpVtbl->QueryInterface(DesktopResource, &IID_ID3D11Texture2D, (void**) &gAcquiredDesktopImage);
|
||||||
@ -261,10 +311,20 @@ int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout)
|
|||||||
|
|
||||||
wfi->framesWaiting = FrameInfo.AccumulatedFrames;
|
wfi->framesWaiting = FrameInfo.AccumulatedFrames;
|
||||||
|
|
||||||
|
if (FrameInfo.AccumulatedFrames == 0)
|
||||||
|
{
|
||||||
|
status = gOutputDuplication->lpVtbl->ReleaseFrame(gOutputDuplication);
|
||||||
|
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
_tprintf(_T("Failed to release frame with status=%d\n"), status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
HRESULT status;
|
||||||
D3D11_BOX Box;
|
D3D11_BOX Box;
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
|
|
||||||
int wf_dxgi_init(wfInfo* context);
|
int wf_dxgi_init(wfInfo* context);
|
||||||
|
|
||||||
|
int wf_dxgi_createDevice(wfInfo* context);
|
||||||
|
|
||||||
|
int wf_dxgi_getDuplication(wfInfo* context);
|
||||||
|
|
||||||
int wf_dxgi_cleanup(wfInfo* context);
|
int wf_dxgi_cleanup(wfInfo* context);
|
||||||
|
|
||||||
int wf_dxgi_nextFrame(wfInfo* context, UINT timeout);
|
int wf_dxgi_nextFrame(wfInfo* context, UINT timeout);
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "wf_dxgi.h"
|
#include "wf_dxgi.h"
|
||||||
|
|
||||||
static wfInfo* wfInfoInstance = NULL;
|
static wfInfo* wfInfoInstance = NULL;
|
||||||
|
static int _IDcount = 0;
|
||||||
|
|
||||||
int wf_info_lock(wfInfo* wfi)
|
int wf_info_lock(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
@ -215,6 +216,10 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
|
|||||||
context->info = wfi;
|
context->info = wfi;
|
||||||
context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
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
|
#ifdef WITH_WIN8
|
||||||
if (wfi->peerCount == 0)
|
if (wfi->peerCount == 0)
|
||||||
wf_dxgi_init(wfi);
|
wf_dxgi_init(wfi);
|
||||||
@ -282,7 +287,7 @@ BOOL wf_info_have_updates(wfInfo* wfi)
|
|||||||
void wf_info_update_changes(wfInfo* wfi)
|
void wf_info_update_changes(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
#ifdef WITH_WIN8
|
#ifdef WITH_WIN8
|
||||||
wf_dxgi_nextFrame(wfi, wfi->framesPerSecond / 1000);
|
wf_dxgi_nextFrame(wfi, wfi->framesPerSecond * 1000);
|
||||||
#else
|
#else
|
||||||
GETCHANGESBUF* buf;
|
GETCHANGESBUF* buf;
|
||||||
|
|
||||||
@ -303,7 +308,20 @@ void wf_info_find_invalid_region(wfInfo* wfi)
|
|||||||
|
|
||||||
for (i = wfi->lastUpdate; i != wfi->nextUpdate; i = (i + 1) % MAXCHANGES_BUF)
|
for (i = wfi->lastUpdate; i != wfi->nextUpdate; i = (i + 1) % MAXCHANGES_BUF)
|
||||||
{
|
{
|
||||||
UnionRect(&wfi->invalid, &wfi->invalid, &buf->buffer->pointrect[i].rect);
|
LPRECT lpR = &buf->buffer->pointrect[i].rect;
|
||||||
|
|
||||||
|
//need to make sure we only get updates from the selected screen
|
||||||
|
if ( (lpR->left >= wfi->servscreen_xoffset) &&
|
||||||
|
(lpR->right <= (wfi->servscreen_xoffset + wfi->servscreen_width) ) &&
|
||||||
|
(lpR->top >= wfi->servscreen_yoffset) &&
|
||||||
|
(lpR->bottom <= (wfi->servscreen_yoffset + wfi->servscreen_height) ) )
|
||||||
|
{
|
||||||
|
UnionRect(&wfi->invalid, &wfi->invalid, lpR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -313,11 +331,13 @@ void wf_info_find_invalid_region(wfInfo* wfi)
|
|||||||
if (wfi->invalid.top < 0)
|
if (wfi->invalid.top < 0)
|
||||||
wfi->invalid.top = 0;
|
wfi->invalid.top = 0;
|
||||||
|
|
||||||
if (wfi->invalid.right >= wfi->width)
|
if (wfi->invalid.right >= wfi->servscreen_width)
|
||||||
wfi->invalid.right = wfi->width - 1;
|
wfi->invalid.right = wfi->servscreen_width - 1;
|
||||||
|
|
||||||
if (wfi->invalid.bottom >= wfi->height)
|
if (wfi->invalid.bottom >= wfi->servscreen_height)
|
||||||
wfi->invalid.bottom = wfi->height - 1;
|
wfi->invalid.bottom = wfi->servscreen_height - 1;
|
||||||
|
|
||||||
|
//printf("invalid region: (%d, %d), (%d, %d)\n", wfi->invalid.left, wfi->invalid.top, wfi->invalid.right, wfi->invalid.bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wf_info_clear_invalid_region(wfInfo* wfi)
|
void wf_info_clear_invalid_region(wfInfo* wfi)
|
||||||
@ -328,7 +348,7 @@ void wf_info_clear_invalid_region(wfInfo* wfi)
|
|||||||
|
|
||||||
void wf_info_invalidate_full_screen(wfInfo* wfi)
|
void wf_info_invalidate_full_screen(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
SetRect(&wfi->invalid, 0, 0, wfi->width, wfi->height);
|
SetRect(&wfi->invalid, 0, 0, wfi->servscreen_width, wfi->servscreen_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL wf_info_have_invalid_region(wfInfo* wfi)
|
BOOL wf_info_have_invalid_region(wfInfo* wfi)
|
||||||
@ -352,9 +372,26 @@ void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits,
|
|||||||
*width += 1;
|
*width += 1;
|
||||||
*height += 1;
|
*height += 1;
|
||||||
|
|
||||||
offset = (4 * wfi->invalid.left) + (wfi->invalid.top * wfi->width * 4);
|
offset = (4 * wfi->invalid.left) + (wfi->invalid.top * wfi->virtscreen_width * 4);
|
||||||
*pBits = ((BYTE*) (changes->Userbuffer)) + offset;
|
*pBits = ((BYTE*) (changes->Userbuffer)) + offset;
|
||||||
*pitch = wfi->width * 4;
|
*pitch = wfi->virtscreen_width * 4;
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
_IDcount++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
@ -40,5 +40,6 @@ void wf_info_clear_invalid_region(wfInfo* wfi);
|
|||||||
void wf_info_invalidate_full_screen(wfInfo* wfi);
|
void wf_info_invalidate_full_screen(wfInfo* wfi);
|
||||||
BOOL wf_info_have_invalid_region(wfInfo* wfi);
|
BOOL wf_info_have_invalid_region(wfInfo* wfi);
|
||||||
void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits, int* pitch);
|
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 */
|
#endif /* WF_INFO_H */
|
@ -24,6 +24,7 @@
|
|||||||
#include <winpr/windows.h>
|
#include <winpr/windows.h>
|
||||||
|
|
||||||
#include "wf_input.h"
|
#include "wf_input.h"
|
||||||
|
#include "wf_info.h"
|
||||||
|
|
||||||
void wf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
wfInfo * wfi;
|
||||||
|
|
||||||
|
wfi = wf_info_get_instance();
|
||||||
|
|
||||||
|
//width and height of primary screen (even in multimon setups
|
||||||
width = (float) GetSystemMetrics(SM_CXSCREEN);
|
width = (float) GetSystemMetrics(SM_CXSCREEN);
|
||||||
height = (float) GetSystemMetrics(SM_CYSCREEN);
|
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.dx = (LONG) ((float) x * (65535.0f / width));
|
||||||
mouse_event.mi.dy = (LONG) ((float) y * (65535.0f / height));
|
mouse_event.mi.dy = (LONG) ((float) y * (65535.0f / height));
|
||||||
mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE;
|
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)
|
if (flags & PTR_FLAGS_MOVE)
|
||||||
{
|
{
|
||||||
mouse_event.mi.dx = x * (0xFFFF / GetSystemMetrics(SM_CXSCREEN));
|
float width, height;
|
||||||
mouse_event.mi.dy = y * (0xFFFF / GetSystemMetrics(SM_CYSCREEN));
|
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;
|
mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||||||
|
|
||||||
SendInput(1, &mouse_event, sizeof(INPUT));
|
SendInput(1, &mouse_event, sizeof(INPUT));
|
||||||
|
@ -36,6 +36,45 @@
|
|||||||
|
|
||||||
cbCallback cbEvent;
|
cbCallback cbEvent;
|
||||||
|
|
||||||
|
int get_screen_info(int id, _TCHAR* name, int* width, int* height, int* bpp)
|
||||||
|
{
|
||||||
|
DISPLAY_DEVICE dd;
|
||||||
|
|
||||||
|
memset(&dd, 0, sizeof(DISPLAY_DEVICE));
|
||||||
|
dd.cb = sizeof(DISPLAY_DEVICE);
|
||||||
|
|
||||||
|
if (EnumDisplayDevices(NULL, id, &dd, 0) != 0)
|
||||||
|
{
|
||||||
|
HDC dc;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
_stprintf(name, _T("%s (%s)"), dd.DeviceName, dd.DeviceString);
|
||||||
|
|
||||||
|
dc = CreateDC(NULL, dd.DeviceName, NULL, NULL);
|
||||||
|
*width = GetDeviceCaps(dc, HORZRES);
|
||||||
|
*height = GetDeviceCaps(dc, VERTRES);
|
||||||
|
*bpp = GetDeviceCaps(dc, BITSPIXEL);
|
||||||
|
ReleaseDC(NULL, dc);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_screen_id(int id)
|
||||||
|
{
|
||||||
|
wfInfo* wfi;
|
||||||
|
|
||||||
|
wfi = wf_info_get_instance();
|
||||||
|
wfi->screenID = id;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
|
DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
int i, fds;
|
int i, fds;
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <freerdp/codec/rfx.h>
|
#include <freerdp/codec/rfx.h>
|
||||||
|
|
||||||
#include <freerdp/server/rdpsnd.h>
|
#include <freerdp/server/rdpsnd.h>
|
||||||
|
|
||||||
#define WF_SRV_CALLBACK_EVENT_CONNECT 1
|
#define WF_SRV_CALLBACK_EVENT_CONNECT 1
|
||||||
@ -42,8 +43,18 @@ typedef struct wf_peer_context wfPeerContext;
|
|||||||
struct wf_info
|
struct wf_info
|
||||||
{
|
{
|
||||||
STREAM* s;
|
STREAM* s;
|
||||||
int width;
|
|
||||||
int height;
|
//screen and monitor info
|
||||||
|
int screenID;
|
||||||
|
int virtscreen_width;
|
||||||
|
int virtscreen_height;
|
||||||
|
int servscreen_width;
|
||||||
|
int servscreen_height;
|
||||||
|
int servscreen_xoffset;
|
||||||
|
int servscreen_yoffset;
|
||||||
|
//int width;
|
||||||
|
//int height;
|
||||||
|
|
||||||
int frame_idx;
|
int frame_idx;
|
||||||
int bitsPerPixel;
|
int bitsPerPixel;
|
||||||
HDC driverDC;
|
HDC driverDC;
|
||||||
@ -101,6 +112,9 @@ typedef struct wf_server wfServer;
|
|||||||
|
|
||||||
typedef void (__stdcall* cbCallback) (int, UINT32);
|
typedef void (__stdcall* cbCallback) (int, UINT32);
|
||||||
|
|
||||||
|
FREERDP_API int get_screen_info(int id, _TCHAR* name, int* w, int* h, int* b);
|
||||||
|
FREERDP_API void set_screen_id(int id);
|
||||||
|
|
||||||
FREERDP_API BOOL wfreerdp_server_start(wfServer* server);
|
FREERDP_API BOOL wfreerdp_server_start(wfServer* server);
|
||||||
FREERDP_API BOOL wfreerdp_server_stop(wfServer* server);
|
FREERDP_API BOOL wfreerdp_server_stop(wfServer* server);
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
/*
|
/*
|
||||||
This function will iterate over the loaded display devices until it finds
|
This function will iterate over the loaded display devices until it finds
|
||||||
the mirror device we want to load. If found, it will then copy the registry
|
the mirror device we want to load. If found, it will then copy the registry
|
||||||
key corresponding to the device to the context and returns TRUE. Otherwise
|
key corresponding to the device to the wfi and returns TRUE. Otherwise
|
||||||
the function returns FALSE.
|
the function returns FALSE.
|
||||||
*/
|
*/
|
||||||
BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
BOOL wf_mirror_driver_find_display_device(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
BOOL result;
|
BOOL result;
|
||||||
BOOL devFound;
|
BOOL devFound;
|
||||||
@ -52,13 +52,13 @@ BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
|||||||
if (_tcsncmp(deviceInfo.DeviceKey, DEVICE_KEY_PREFIX, deviceKeyPrefixLength) == 0)
|
if (_tcsncmp(deviceInfo.DeviceKey, DEVICE_KEY_PREFIX, deviceKeyPrefixLength) == 0)
|
||||||
{
|
{
|
||||||
deviceKeyLength = _tcslen(deviceInfo.DeviceKey) - deviceKeyPrefixLength;
|
deviceKeyLength = _tcslen(deviceInfo.DeviceKey) - deviceKeyPrefixLength;
|
||||||
context->deviceKey = (LPTSTR) malloc((deviceKeyLength + 1) * sizeof(TCHAR));
|
wfi->deviceKey = (LPTSTR) malloc((deviceKeyLength + 1) * sizeof(TCHAR));
|
||||||
|
|
||||||
_tcsncpy_s(context->deviceKey, deviceKeyLength + 1,
|
_tcsncpy_s(wfi->deviceKey, deviceKeyLength + 1,
|
||||||
&deviceInfo.DeviceKey[deviceKeyPrefixLength], deviceKeyLength);
|
&deviceInfo.DeviceKey[deviceKeyPrefixLength], deviceKeyLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
_tcsncpy_s(context->deviceName, 32, deviceInfo.DeviceName, _tcslen(deviceInfo.DeviceName));
|
_tcsncpy_s(wfi->deviceName, 32, deviceInfo.DeviceName, _tcslen(deviceInfo.DeviceName));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will attempt to access the the windows registry using the device
|
* This function will attempt to access the the windows registry using the device
|
||||||
* key stored in the current context. It will attempt to read the value of the
|
* key stored in the current wfi. It will attempt to read the value of the
|
||||||
* "Attach.ToDesktop" subkey and will return TRUE if the value is already set to
|
* "Attach.ToDesktop" subkey and will return TRUE if the value is already set to
|
||||||
* val. If unable to read the subkey, this function will return FALSE. If the
|
* val. If unable to read the subkey, this function will return FALSE. If the
|
||||||
* subkey is not set to val it will then attempt to set it to val and return TRUE. If
|
* subkey is not set to val it will then attempt to set it to val and return TRUE. If
|
||||||
@ -78,7 +78,7 @@ BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
|||||||
* FALSE.
|
* FALSE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode)
|
BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
LONG status;
|
LONG status;
|
||||||
@ -86,7 +86,7 @@ BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode)
|
|||||||
DWORD dwSize;
|
DWORD dwSize;
|
||||||
DWORD dwValue;
|
DWORD dwValue;
|
||||||
|
|
||||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, context->deviceKey,
|
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, wfi->deviceKey,
|
||||||
0, KEY_READ | KEY_WOW64_64KEY, &hKey);
|
0, KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||||
|
|
||||||
if (status != ERROR_SUCCESS)
|
if (status != ERROR_SUCCESS)
|
||||||
@ -170,7 +170,7 @@ void wf_mirror_driver_print_display_change_status(LONG status)
|
|||||||
* If unload is nonzero then the the driver will be asked to remove itself.
|
* If unload is nonzero then the the driver will be asked to remove itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BOOL wf_mirror_driver_update(wfInfo* context, int unload)
|
BOOL wf_mirror_driver_update(wfInfo* wfi, int unload)
|
||||||
{
|
{
|
||||||
HDC dc;
|
HDC dc;
|
||||||
BOOL status;
|
BOOL status;
|
||||||
@ -182,20 +182,25 @@ BOOL wf_mirror_driver_update(wfInfo* context, int unload)
|
|||||||
|
|
||||||
if (!unload)
|
if (!unload)
|
||||||
{
|
{
|
||||||
|
//first let's get the virtual screen dimentions
|
||||||
|
wfi->virtscreen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||||
|
wfi->virtscreen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Will have to come back to this for supporting non primary displays and multimonitor setups
|
* Will have to come back to this for supporting non primary displays and multimonitor setups
|
||||||
*/
|
*/
|
||||||
dc = GetDC(NULL);
|
/*dc = GetDC(NULL);
|
||||||
context->width = GetDeviceCaps(dc, HORZRES);
|
wfi->servscreen_width = GetDeviceCaps(dc, HORZRES);
|
||||||
context->height = GetDeviceCaps(dc, VERTRES);
|
wfi->servscreen_height = GetDeviceCaps(dc, VERTRES);
|
||||||
context->bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
|
wfi->bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
|
||||||
ReleaseDC(NULL, dc);
|
ReleaseDC(NULL, dc);*/
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context->width = 0;
|
wfi->servscreen_width = 0;
|
||||||
context->height = 0;
|
wfi->servscreen_height = 0;
|
||||||
context->bitsPerPixel = 0;
|
wfi->bitsPerPixel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceMode = (DEVMODE*) malloc(sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX);
|
deviceMode = (DEVMODE*) malloc(sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX);
|
||||||
@ -210,17 +215,17 @@ BOOL wf_mirror_driver_update(wfInfo* context, int unload)
|
|||||||
deviceMode->dmSize = sizeof(DEVMODE);
|
deviceMode->dmSize = sizeof(DEVMODE);
|
||||||
deviceMode->dmDriverExtra = drvExtraSaved;
|
deviceMode->dmDriverExtra = drvExtraSaved;
|
||||||
|
|
||||||
deviceMode->dmPelsWidth = context->width;
|
deviceMode->dmPelsWidth = wfi->virtscreen_width;
|
||||||
deviceMode->dmPelsHeight = context->height;
|
deviceMode->dmPelsHeight = wfi->virtscreen_height;
|
||||||
deviceMode->dmBitsPerPel = context->bitsPerPixel;
|
deviceMode->dmBitsPerPel = wfi->bitsPerPixel;
|
||||||
deviceMode->dmPosition.x = 0;
|
deviceMode->dmPosition.x = wfi->servscreen_xoffset;
|
||||||
deviceMode->dmPosition.y = 0;
|
deviceMode->dmPosition.y = wfi->servscreen_yoffset;
|
||||||
|
|
||||||
deviceMode->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION;
|
deviceMode->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION;
|
||||||
|
|
||||||
_tcsncpy_s(deviceMode->dmDeviceName, 32, context->deviceName, _tcslen(context->deviceName));
|
_tcsncpy_s(deviceMode->dmDeviceName, 32, wfi->deviceName, _tcslen(wfi->deviceName));
|
||||||
|
|
||||||
disp_change_status = ChangeDisplaySettingsEx(context->deviceName, deviceMode, NULL, CDS_UPDATEREGISTRY, NULL);
|
disp_change_status = ChangeDisplaySettingsEx(wfi->deviceName, deviceMode, NULL, CDS_UPDATEREGISTRY, NULL);
|
||||||
|
|
||||||
status = (disp_change_status == DISP_CHANGE_SUCCESSFUL) ? TRUE : FALSE;
|
status = (disp_change_status == DISP_CHANGE_SUCCESSFUL) ? TRUE : FALSE;
|
||||||
|
|
||||||
@ -230,50 +235,50 @@ BOOL wf_mirror_driver_update(wfInfo* context, int unload)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL wf_mirror_driver_map_memory(wfInfo* context)
|
BOOL wf_mirror_driver_map_memory(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
GETCHANGESBUF* b;
|
GETCHANGESBUF* b;
|
||||||
|
|
||||||
context->driverDC = CreateDC(context->deviceName, NULL, NULL, NULL);
|
wfi->driverDC = CreateDC(wfi->deviceName, NULL, NULL, NULL);
|
||||||
|
|
||||||
if (context->driverDC == NULL)
|
if (wfi->driverDC == NULL)
|
||||||
{
|
{
|
||||||
_tprintf(_T("Could not create device driver context!\n"));
|
_tprintf(_T("Could not create device driver wfi!\n"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->changeBuffer = malloc(sizeof(GETCHANGESBUF));
|
wfi->changeBuffer = malloc(sizeof(GETCHANGESBUF));
|
||||||
ZeroMemory(context->changeBuffer, sizeof(GETCHANGESBUF));
|
ZeroMemory(wfi->changeBuffer, sizeof(GETCHANGESBUF));
|
||||||
|
|
||||||
status = ExtEscape(context->driverDC, dmf_esc_usm_pipe_map, 0, 0, sizeof(GETCHANGESBUF), (LPSTR) context->changeBuffer);
|
status = ExtEscape(wfi->driverDC, dmf_esc_usm_pipe_map, 0, 0, sizeof(GETCHANGESBUF), (LPSTR) wfi->changeBuffer);
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
{
|
{
|
||||||
_tprintf(_T("Failed to map shared memory from the driver! code %d\n"), status);
|
_tprintf(_T("Failed to map shared memory from the driver! code %d\n"), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
b = (GETCHANGESBUF*) context->changeBuffer;
|
b = (GETCHANGESBUF*) wfi->changeBuffer;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unmap the shared memory and release the DC */
|
/* Unmap the shared memory and release the DC */
|
||||||
|
|
||||||
BOOL wf_mirror_driver_cleanup(wfInfo* context)
|
BOOL wf_mirror_driver_cleanup(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = ExtEscape(context->driverDC, dmf_esc_usm_pipe_unmap, sizeof(GETCHANGESBUF), (LPSTR) context->changeBuffer, 0, 0);
|
status = ExtEscape(wfi->driverDC, dmf_esc_usm_pipe_unmap, sizeof(GETCHANGESBUF), (LPSTR) wfi->changeBuffer, 0, 0);
|
||||||
|
|
||||||
if (status <= 0)
|
if (status <= 0)
|
||||||
{
|
{
|
||||||
_tprintf(_T("Failed to unmap shared memory from the driver! code %d\n"), status);
|
_tprintf(_T("Failed to unmap shared memory from the driver! code %d\n"), status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->driverDC != NULL)
|
if (wfi->driverDC != NULL)
|
||||||
{
|
{
|
||||||
status = DeleteDC(context->driverDC);
|
status = DeleteDC(wfi->driverDC);
|
||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
@ -281,7 +286,7 @@ BOOL wf_mirror_driver_cleanup(wfInfo* context)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(context->changeBuffer);
|
free(wfi->changeBuffer);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -200,11 +200,11 @@ typedef struct
|
|||||||
ULONG nColorBmPalEntries;
|
ULONG nColorBmPalEntries;
|
||||||
} Esc_dmf_pointer_shape_get_OUT;
|
} Esc_dmf_pointer_shape_get_OUT;
|
||||||
|
|
||||||
BOOL wf_mirror_driver_find_display_device(wfInfo* context);
|
BOOL wf_mirror_driver_find_display_device(wfInfo* wfi);
|
||||||
BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode);
|
BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode);
|
||||||
BOOL wf_mirror_driver_update(wfInfo* context, int unload);
|
BOOL wf_mirror_driver_update(wfInfo* wfi, int unload);
|
||||||
BOOL wf_mirror_driver_map_memory(wfInfo* context);
|
BOOL wf_mirror_driver_map_memory(wfInfo* wfi);
|
||||||
BOOL wf_mirror_driver_cleanup(wfInfo* context);
|
BOOL wf_mirror_driver_cleanup(wfInfo* wfi);
|
||||||
|
|
||||||
void wf_mirror_driver_activate(wfInfo* wfi);
|
void wf_mirror_driver_activate(wfInfo* wfi);
|
||||||
void wf_mirror_driver_deactivate(wfInfo* wfi);
|
void wf_mirror_driver_deactivate(wfInfo* wfi);
|
||||||
|
@ -74,7 +74,6 @@ void wf_peer_init(freerdp_peer* client)
|
|||||||
BOOL wf_peer_post_connect(freerdp_peer* client)
|
BOOL wf_peer_post_connect(freerdp_peer* client)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
HDC hdc;
|
|
||||||
wfInfo* wfi;
|
wfInfo* wfi;
|
||||||
rdpSettings* settings;
|
rdpSettings* settings;
|
||||||
wfPeerContext* context = (wfPeerContext*) client->context;
|
wfPeerContext* context = (wfPeerContext*) client->context;
|
||||||
@ -82,20 +81,24 @@ BOOL wf_peer_post_connect(freerdp_peer* client)
|
|||||||
wfi = context->info;
|
wfi = context->info;
|
||||||
settings = client->settings;
|
settings = client->settings;
|
||||||
|
|
||||||
hdc = GetDC(NULL);
|
if (
|
||||||
wfi->width = GetDeviceCaps(hdc, HORZRES);
|
(get_screen_info(wfi->screenID, NULL, &wfi->servscreen_width, &wfi->servscreen_height, &wfi->bitsPerPixel) == 0) ||
|
||||||
wfi->height = GetDeviceCaps(hdc, VERTRES);
|
(wfi->servscreen_width == 0) ||
|
||||||
wfi->bitsPerPixel = GetDeviceCaps(hdc, BITSPIXEL);
|
(wfi->servscreen_height == 0) ||
|
||||||
ReleaseDC(NULL, hdc);
|
(wfi->bitsPerPixel == 0) )
|
||||||
|
{
|
||||||
|
_tprintf(_T("postconnect: error getting screen info for screen %d\n"), wfi->screenID);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((settings->DesktopWidth != wfi->width) || (settings->DesktopHeight != wfi->height))
|
if ((settings->width != wfi->servscreen_width) || (settings->height != wfi->servscreen_height))
|
||||||
{
|
{
|
||||||
printf("Client requested resolution %dx%d, but will resize to %dx%d\n",
|
printf("Client requested resolution %dx%d, but will resize to %dx%d\n",
|
||||||
settings->DesktopWidth, settings->DesktopHeight, wfi->width, wfi->height);
|
settings->width, settings->height, wfi->servscreen_width, wfi->servscreen_height);
|
||||||
|
|
||||||
settings->DesktopWidth = wfi->width;
|
settings->width = wfi->servscreen_width;
|
||||||
settings->DesktopHeight = wfi->height;
|
settings->height = wfi->servscreen_height;
|
||||||
settings->ColorDepth = wfi->bitsPerPixel;
|
settings->color_depth = wfi->bitsPerPixel;
|
||||||
|
|
||||||
client->update->DesktopResize(client->update->context);
|
client->update->DesktopResize(client->update->context);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <winpr\windows.h>
|
#include <winpr\windows.h>
|
||||||
|
|
||||||
|
#include <InitGuid.h>
|
||||||
#define CINTERFACE
|
#define CINTERFACE
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
#include <dsound.h>
|
#include <dsound.h>
|
||||||
@ -41,7 +43,7 @@
|
|||||||
IDirectSoundCapture8 * cap;
|
IDirectSoundCapture8 * cap;
|
||||||
IDirectSoundCaptureBuffer8* capBuf;
|
IDirectSoundCaptureBuffer8* capBuf;
|
||||||
DSCBUFFERDESC dscbd;
|
DSCBUFFERDESC dscbd;
|
||||||
DWORD capturePos;
|
DWORD lastPos;
|
||||||
|
|
||||||
#define BYTESPERSEC 176400
|
#define BYTESPERSEC 176400
|
||||||
|
|
||||||
@ -107,7 +109,7 @@ static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context)
|
|||||||
|
|
||||||
context->SelectFormat(context, 4);
|
context->SelectFormat(context, 4);
|
||||||
context->SetVolume(context, 0x7FFF, 0x7FFF);
|
context->SetVolume(context, 0x7FFF, 0x7FFF);
|
||||||
capturePos = 0;
|
lastPos = 0;
|
||||||
|
|
||||||
CreateThread(NULL, 0, wf_rdpsnd_thread, latestPeer, 0, NULL);
|
CreateThread(NULL, 0, wf_rdpsnd_thread, latestPeer, 0, NULL);
|
||||||
|
|
||||||
@ -189,15 +191,24 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
|
|||||||
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
DWORD beg, end;
|
DWORD beg = 0;
|
||||||
|
DWORD end = 0;
|
||||||
DWORD diff, rate;
|
DWORD diff, rate;
|
||||||
wfPeerContext* context;
|
wfPeerContext* context;
|
||||||
wfInfo* wfi;
|
wfInfo* wfi;
|
||||||
|
|
||||||
|
VOID* pbCaptureData = NULL;
|
||||||
|
DWORD dwCaptureLength = 0;
|
||||||
|
VOID* pbCaptureData2 = NULL;
|
||||||
|
DWORD dwCaptureLength2 = 0;
|
||||||
|
VOID* pbPlayData = NULL;
|
||||||
|
DWORD dwReadPos = 0;
|
||||||
|
LONG lLockSize = 0;
|
||||||
|
|
||||||
wfi = wf_info_get_instance();
|
wfi = wf_info_get_instance();
|
||||||
|
|
||||||
context = (wfPeerContext*)lpParam;
|
context = (wfPeerContext*)lpParam;
|
||||||
rate = 1000 / 5;
|
rate = 1000 / 24;
|
||||||
|
|
||||||
_tprintf(_T("Trying to start capture\n"));
|
_tprintf(_T("Trying to start capture\n"));
|
||||||
hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
|
hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
|
||||||
@ -209,13 +220,15 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
VOID* pbCaptureData = NULL;
|
|
||||||
DWORD dwCaptureLength;
|
end = GetTickCount();
|
||||||
VOID* pbCaptureData2 = NULL;
|
diff = end - beg;
|
||||||
DWORD dwCaptureLength2;
|
|
||||||
VOID* pbPlayData = NULL;
|
if (diff < rate)
|
||||||
DWORD dwReadPos;
|
{
|
||||||
LONG lLockSize;
|
Sleep(rate - diff);
|
||||||
|
}
|
||||||
|
|
||||||
beg = GetTickCount();
|
beg = GetTickCount();
|
||||||
|
|
||||||
if (wf_rdpsnd_lock() > 0)
|
if (wf_rdpsnd_lock() > 0)
|
||||||
@ -235,9 +248,11 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lLockSize = dwReadPos - capturePos;//dscbd.dwBufferBytes;
|
lLockSize = dwReadPos - lastPos;//dscbd.dwBufferBytes;
|
||||||
if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes;
|
if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes;
|
||||||
|
|
||||||
|
//printf("Last, read, lock = [%d, %d, %d]\n", lastPos, dwReadPos, lLockSize);
|
||||||
|
|
||||||
if (lLockSize == 0)
|
if (lLockSize == 0)
|
||||||
{
|
{
|
||||||
wf_rdpsnd_unlock();
|
wf_rdpsnd_unlock();
|
||||||
@ -245,7 +260,7 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hr = capBuf->lpVtbl->Lock(capBuf, capturePos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L);
|
hr = capBuf->lpVtbl->Lock(capBuf, lastPos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
_tprintf(_T("Failed to lock sound capture buffer\n"));
|
_tprintf(_T("Failed to lock sound capture buffer\n"));
|
||||||
@ -271,21 +286,15 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO keep track of location in buffer
|
//TODO keep track of location in buffer
|
||||||
capturePos += dwCaptureLength;
|
lastPos += dwCaptureLength;
|
||||||
capturePos %= dscbd.dwBufferBytes;
|
lastPos %= dscbd.dwBufferBytes;
|
||||||
capturePos += dwCaptureLength2;
|
lastPos += dwCaptureLength2;
|
||||||
capturePos %= dscbd.dwBufferBytes;
|
lastPos %= dscbd.dwBufferBytes;
|
||||||
|
|
||||||
wf_rdpsnd_unlock();
|
wf_rdpsnd_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
end = GetTickCount();
|
|
||||||
diff = end - beg;
|
|
||||||
|
|
||||||
if (diff < rate)
|
|
||||||
{
|
|
||||||
Sleep(rate - diff);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_tprintf(_T("Trying to stop sound capture\n"));
|
_tprintf(_T("Trying to stop sound capture\n"));
|
||||||
@ -295,7 +304,10 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
|||||||
_tprintf(_T("Failed to stop capture\n"));
|
_tprintf(_T("Failed to stop capture\n"));
|
||||||
}
|
}
|
||||||
_tprintf(_T("Capture stopped\n"));
|
_tprintf(_T("Capture stopped\n"));
|
||||||
|
capBuf->lpVtbl->Release(capBuf);
|
||||||
|
cap->lpVtbl->Release(cap);
|
||||||
|
|
||||||
|
lastPos = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -199,8 +199,8 @@ void wf_update_encoder_reset(wfInfo* wfi)
|
|||||||
{
|
{
|
||||||
wfi->rfx_context = rfx_context_new();
|
wfi->rfx_context = rfx_context_new();
|
||||||
wfi->rfx_context->mode = RLGR3;
|
wfi->rfx_context->mode = RLGR3;
|
||||||
wfi->rfx_context->width = wfi->width;
|
wfi->rfx_context->width = wfi->servscreen_width;
|
||||||
wfi->rfx_context->height = wfi->height;
|
wfi->rfx_context->height = wfi->servscreen_height;
|
||||||
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||||
wfi->s = stream_new(0xFFFF);
|
wfi->s = stream_new(0xFFFF);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user