mfreerdp-server: merged wf_peer.c
This commit is contained in:
commit
b5d3a493aa
@ -32,14 +32,100 @@
|
||||
|
||||
#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 index;
|
||||
wfServer* server;
|
||||
|
||||
server = wfreerdp_server_new();
|
||||
|
||||
if (argc == 2)
|
||||
server->port = (DWORD) atoi(argv[1]);
|
||||
set_screen_id(0);
|
||||
|
||||
//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");
|
||||
|
||||
|
@ -65,26 +65,38 @@ 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(wfi) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (wf_dxgi_getDuplication(wfi) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int wf_dxgi_createDevice(wfInfo* wfi)
|
||||
{
|
||||
HRESULT status;
|
||||
UINT dTop, i = 0;
|
||||
DXGI_OUTPUT_DESC desc;
|
||||
IDXGIOutput * pOutput;
|
||||
UINT DriverTypeIndex;
|
||||
IDXGIDevice* DxgiDevice = NULL;
|
||||
IDXGIAdapter* DxgiAdapter = NULL;
|
||||
IDXGIOutput* DxgiOutput = NULL;
|
||||
IDXGIOutput1* DxgiOutput1 = NULL;
|
||||
|
||||
gAcquiredDesktopImage = NULL;
|
||||
|
||||
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);
|
||||
if (SUCCEEDED(status))
|
||||
break;
|
||||
|
||||
_tprintf(_T("D3D11CreateDevice returned [%d] for Driver Type %d\n"), status, DriverTypes[DriverTypeIndex]);
|
||||
}
|
||||
|
||||
if (FAILED(status))
|
||||
@ -92,7 +104,21 @@ int wf_dxgi_init(wfInfo* context)
|
||||
_tprintf(_T("Failed to create device in InitializeDx\n"));
|
||||
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);
|
||||
|
||||
if (FAILED(status))
|
||||
@ -135,7 +161,7 @@ int wf_dxgi_init(wfInfo* context)
|
||||
++i;
|
||||
}
|
||||
|
||||
dTop = 0;
|
||||
dTop = wfi->screenID;
|
||||
|
||||
status = DxgiAdapter->lpVtbl->EnumOutputs(DxgiAdapter, dTop, &DxgiOutput);
|
||||
DxgiAdapter->lpVtbl->Release(DxgiAdapter);
|
||||
@ -169,13 +195,14 @@ int wf_dxgi_init(wfInfo* context)
|
||||
return 1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Failed to get duplicate output\n"));
|
||||
_tprintf(_T("Failed to get duplicate output. Status = %#X\n"), status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wf_dxgi_cleanup(wfInfo* wfi)
|
||||
{
|
||||
if (wfi->framesWaiting > 0)
|
||||
@ -212,7 +239,7 @@ int wf_dxgi_cleanup(wfInfo* wfi)
|
||||
|
||||
int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout)
|
||||
{
|
||||
HRESULT status;
|
||||
HRESULT status = 0;
|
||||
UINT i = 0;
|
||||
UINT DataBufferSize = 0;
|
||||
BYTE* DataBuffer = NULL;
|
||||
@ -238,16 +265,39 @@ int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout)
|
||||
|
||||
if (FAILED(status))
|
||||
{
|
||||
//_tprintf(_T("Failed to acquire next frame\n"));
|
||||
|
||||
status = gOutputDuplication->lpVtbl->ReleaseFrame(gOutputDuplication);
|
||||
|
||||
if (FAILED(status))
|
||||
if (status == DXGI_ERROR_ACCESS_LOST)
|
||||
{
|
||||
//_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);
|
||||
@ -261,10 +311,20 @@ int wf_dxgi_nextFrame(wfInfo* wfi, UINT timeout)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -24,6 +24,10 @@
|
||||
|
||||
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_nextFrame(wfInfo* context, UINT timeout);
|
||||
|
@ -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);
|
||||
@ -282,7 +287,7 @@ BOOL wf_info_have_updates(wfInfo* wfi)
|
||||
void wf_info_update_changes(wfInfo* wfi)
|
||||
{
|
||||
#ifdef WITH_WIN8
|
||||
wf_dxgi_nextFrame(wfi, wfi->framesPerSecond / 1000);
|
||||
wf_dxgi_nextFrame(wfi, wfi->framesPerSecond * 1000);
|
||||
#else
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
@ -313,11 +331,13 @@ void wf_info_find_invalid_region(wfInfo* wfi)
|
||||
if (wfi->invalid.top < 0)
|
||||
wfi->invalid.top = 0;
|
||||
|
||||
if (wfi->invalid.right >= wfi->width)
|
||||
wfi->invalid.right = wfi->width - 1;
|
||||
if (wfi->invalid.right >= wfi->servscreen_width)
|
||||
wfi->invalid.right = wfi->servscreen_width - 1;
|
||||
|
||||
if (wfi->invalid.bottom >= wfi->height)
|
||||
wfi->invalid.bottom = wfi->height - 1;
|
||||
if (wfi->invalid.bottom >= wfi->servscreen_height)
|
||||
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)
|
||||
@ -328,7 +348,7 @@ void wf_info_clear_invalid_region(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)
|
||||
@ -352,9 +372,26 @@ void wf_info_getScreenData(wfInfo* wfi, long* width, long* height, BYTE** pBits,
|
||||
*width += 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;
|
||||
*pitch = wfi->width * 4;
|
||||
*pitch = wfi->virtscreen_width * 4;
|
||||
}
|
||||
#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);
|
||||
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 */
|
@ -24,6 +24,7 @@
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#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));
|
||||
|
@ -36,6 +36,45 @@
|
||||
|
||||
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)
|
||||
{
|
||||
int i, fds;
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/codec/rfx.h>
|
||||
|
||||
#include <freerdp/server/rdpsnd.h>
|
||||
|
||||
#define WF_SRV_CALLBACK_EVENT_CONNECT 1
|
||||
@ -42,8 +43,18 @@ typedef struct wf_peer_context wfPeerContext;
|
||||
struct wf_info
|
||||
{
|
||||
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 bitsPerPixel;
|
||||
HDC driverDC;
|
||||
@ -101,6 +112,9 @@ typedef struct wf_server wfServer;
|
||||
|
||||
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_stop(wfServer* server);
|
||||
|
||||
|
@ -26,10 +26,10 @@
|
||||
/*
|
||||
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
|
||||
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.
|
||||
*/
|
||||
BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
||||
BOOL wf_mirror_driver_find_display_device(wfInfo* wfi)
|
||||
{
|
||||
BOOL result;
|
||||
BOOL devFound;
|
||||
@ -52,13 +52,13 @@ BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
||||
if (_tcsncmp(deviceInfo.DeviceKey, DEVICE_KEY_PREFIX, deviceKeyPrefixLength) == 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
_tcsncpy_s(context->deviceName, 32, deviceInfo.DeviceName, _tcslen(deviceInfo.DeviceName));
|
||||
_tcsncpy_s(wfi->deviceName, 32, deviceInfo.DeviceName, _tcslen(deviceInfo.DeviceName));
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
@ -78,7 +78,7 @@ BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
||||
* 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;
|
||||
LONG status;
|
||||
@ -86,7 +86,7 @@ BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode)
|
||||
DWORD dwSize;
|
||||
DWORD dwValue;
|
||||
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, context->deviceKey,
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, wfi->deviceKey,
|
||||
0, KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
BOOL wf_mirror_driver_update(wfInfo* context, int unload)
|
||||
BOOL wf_mirror_driver_update(wfInfo* wfi, int unload)
|
||||
{
|
||||
HDC dc;
|
||||
BOOL status;
|
||||
@ -182,20 +182,25 @@ BOOL wf_mirror_driver_update(wfInfo* context, int 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
|
||||
*/
|
||||
dc = GetDC(NULL);
|
||||
context->width = GetDeviceCaps(dc, HORZRES);
|
||||
context->height = GetDeviceCaps(dc, VERTRES);
|
||||
context->bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
|
||||
ReleaseDC(NULL, dc);
|
||||
/*dc = GetDC(NULL);
|
||||
wfi->servscreen_width = GetDeviceCaps(dc, HORZRES);
|
||||
wfi->servscreen_height = GetDeviceCaps(dc, VERTRES);
|
||||
wfi->bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
|
||||
ReleaseDC(NULL, dc);*/
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
context->width = 0;
|
||||
context->height = 0;
|
||||
context->bitsPerPixel = 0;
|
||||
wfi->servscreen_width = 0;
|
||||
wfi->servscreen_height = 0;
|
||||
wfi->bitsPerPixel = 0;
|
||||
}
|
||||
|
||||
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->dmDriverExtra = drvExtraSaved;
|
||||
|
||||
deviceMode->dmPelsWidth = context->width;
|
||||
deviceMode->dmPelsHeight = context->height;
|
||||
deviceMode->dmBitsPerPel = context->bitsPerPixel;
|
||||
deviceMode->dmPosition.x = 0;
|
||||
deviceMode->dmPosition.y = 0;
|
||||
deviceMode->dmPelsWidth = wfi->virtscreen_width;
|
||||
deviceMode->dmPelsHeight = wfi->virtscreen_height;
|
||||
deviceMode->dmBitsPerPel = wfi->bitsPerPixel;
|
||||
deviceMode->dmPosition.x = wfi->servscreen_xoffset;
|
||||
deviceMode->dmPosition.y = wfi->servscreen_yoffset;
|
||||
|
||||
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;
|
||||
|
||||
@ -230,50 +235,50 @@ BOOL wf_mirror_driver_update(wfInfo* context, int unload)
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOL wf_mirror_driver_map_memory(wfInfo* context)
|
||||
BOOL wf_mirror_driver_map_memory(wfInfo* wfi)
|
||||
{
|
||||
int status;
|
||||
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;
|
||||
}
|
||||
|
||||
context->changeBuffer = malloc(sizeof(GETCHANGESBUF));
|
||||
ZeroMemory(context->changeBuffer, sizeof(GETCHANGESBUF));
|
||||
wfi->changeBuffer = malloc(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)
|
||||
{
|
||||
_tprintf(_T("Failed to map shared memory from the driver! code %d\n"), status);
|
||||
}
|
||||
|
||||
b = (GETCHANGESBUF*) context->changeBuffer;
|
||||
b = (GETCHANGESBUF*) wfi->changeBuffer;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Unmap the shared memory and release the DC */
|
||||
|
||||
BOOL wf_mirror_driver_cleanup(wfInfo* context)
|
||||
BOOL wf_mirror_driver_cleanup(wfInfo* wfi)
|
||||
{
|
||||
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)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
@ -281,7 +286,7 @@ BOOL wf_mirror_driver_cleanup(wfInfo* context)
|
||||
}
|
||||
}
|
||||
|
||||
free(context->changeBuffer);
|
||||
free(wfi->changeBuffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -200,11 +200,11 @@ typedef struct
|
||||
ULONG nColorBmPalEntries;
|
||||
} Esc_dmf_pointer_shape_get_OUT;
|
||||
|
||||
BOOL wf_mirror_driver_find_display_device(wfInfo* context);
|
||||
BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode);
|
||||
BOOL wf_mirror_driver_update(wfInfo* context, int unload);
|
||||
BOOL wf_mirror_driver_map_memory(wfInfo* context);
|
||||
BOOL wf_mirror_driver_cleanup(wfInfo* context);
|
||||
BOOL wf_mirror_driver_find_display_device(wfInfo* wfi);
|
||||
BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode);
|
||||
BOOL wf_mirror_driver_update(wfInfo* wfi, int unload);
|
||||
BOOL wf_mirror_driver_map_memory(wfInfo* wfi);
|
||||
BOOL wf_mirror_driver_cleanup(wfInfo* wfi);
|
||||
|
||||
void wf_mirror_driver_activate(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)
|
||||
{
|
||||
int i;
|
||||
HDC hdc;
|
||||
wfInfo* wfi;
|
||||
rdpSettings* settings;
|
||||
wfPeerContext* context = (wfPeerContext*) client->context;
|
||||
@ -82,20 +81,24 @@ BOOL wf_peer_post_connect(freerdp_peer* client)
|
||||
wfi = context->info;
|
||||
settings = client->settings;
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
wfi->width = GetDeviceCaps(hdc, HORZRES);
|
||||
wfi->height = GetDeviceCaps(hdc, VERTRES);
|
||||
wfi->bitsPerPixel = GetDeviceCaps(hdc, BITSPIXEL);
|
||||
ReleaseDC(NULL, hdc);
|
||||
if (
|
||||
(get_screen_info(wfi->screenID, NULL, &wfi->servscreen_width, &wfi->servscreen_height, &wfi->bitsPerPixel) == 0) ||
|
||||
(wfi->servscreen_width == 0) ||
|
||||
(wfi->servscreen_height == 0) ||
|
||||
(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",
|
||||
settings->DesktopWidth, settings->DesktopHeight, wfi->width, wfi->height);
|
||||
settings->width, settings->height, wfi->servscreen_width, wfi->servscreen_height);
|
||||
|
||||
settings->DesktopWidth = wfi->width;
|
||||
settings->DesktopHeight = wfi->height;
|
||||
settings->ColorDepth = wfi->bitsPerPixel;
|
||||
settings->width = wfi->servscreen_width;
|
||||
settings->height = wfi->servscreen_height;
|
||||
settings->color_depth = wfi->bitsPerPixel;
|
||||
|
||||
client->update->DesktopResize(client->update->context);
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr\windows.h>
|
||||
|
||||
#include <InitGuid.h>
|
||||
#define CINTERFACE
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
@ -41,7 +43,7 @@
|
||||
IDirectSoundCapture8 * cap;
|
||||
IDirectSoundCaptureBuffer8* capBuf;
|
||||
DSCBUFFERDESC dscbd;
|
||||
DWORD capturePos;
|
||||
DWORD lastPos;
|
||||
|
||||
#define BYTESPERSEC 176400
|
||||
|
||||
@ -107,7 +109,7 @@ static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context)
|
||||
|
||||
context->SelectFormat(context, 4);
|
||||
context->SetVolume(context, 0x7FFF, 0x7FFF);
|
||||
capturePos = 0;
|
||||
lastPos = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
HRESULT hr;
|
||||
DWORD beg, end;
|
||||
DWORD beg = 0;
|
||||
DWORD end = 0;
|
||||
DWORD diff, rate;
|
||||
wfPeerContext* context;
|
||||
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();
|
||||
|
||||
context = (wfPeerContext*)lpParam;
|
||||
rate = 1000 / 5;
|
||||
rate = 1000 / 24;
|
||||
|
||||
_tprintf(_T("Trying to start capture\n"));
|
||||
hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
|
||||
@ -209,13 +220,15 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
||||
|
||||
while (1)
|
||||
{
|
||||
VOID* pbCaptureData = NULL;
|
||||
DWORD dwCaptureLength;
|
||||
VOID* pbCaptureData2 = NULL;
|
||||
DWORD dwCaptureLength2;
|
||||
VOID* pbPlayData = NULL;
|
||||
DWORD dwReadPos;
|
||||
LONG lLockSize;
|
||||
|
||||
end = GetTickCount();
|
||||
diff = end - beg;
|
||||
|
||||
if (diff < rate)
|
||||
{
|
||||
Sleep(rate - diff);
|
||||
}
|
||||
|
||||
beg = GetTickCount();
|
||||
|
||||
if (wf_rdpsnd_lock() > 0)
|
||||
@ -235,9 +248,11 @@ DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
||||
break;
|
||||
}
|
||||
|
||||
lLockSize = dwReadPos - capturePos;//dscbd.dwBufferBytes;
|
||||
lLockSize = dwReadPos - lastPos;//dscbd.dwBufferBytes;
|
||||
if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes;
|
||||
|
||||
//printf("Last, read, lock = [%d, %d, %d]\n", lastPos, dwReadPos, lLockSize);
|
||||
|
||||
if (lLockSize == 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
_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
|
||||
capturePos += dwCaptureLength;
|
||||
capturePos %= dscbd.dwBufferBytes;
|
||||
capturePos += dwCaptureLength2;
|
||||
capturePos %= dscbd.dwBufferBytes;
|
||||
lastPos += dwCaptureLength;
|
||||
lastPos %= dscbd.dwBufferBytes;
|
||||
lastPos += dwCaptureLength2;
|
||||
lastPos %= dscbd.dwBufferBytes;
|
||||
|
||||
wf_rdpsnd_unlock();
|
||||
}
|
||||
|
||||
end = GetTickCount();
|
||||
diff = end - beg;
|
||||
|
||||
if (diff < rate)
|
||||
{
|
||||
Sleep(rate - diff);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_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("Capture stopped\n"));
|
||||
capBuf->lpVtbl->Release(capBuf);
|
||||
cap->lpVtbl->Release(cap);
|
||||
|
||||
lastPos = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -199,8 +199,8 @@ void wf_update_encoder_reset(wfInfo* wfi)
|
||||
{
|
||||
wfi->rfx_context = rfx_context_new();
|
||||
wfi->rfx_context->mode = RLGR3;
|
||||
wfi->rfx_context->width = wfi->width;
|
||||
wfi->rfx_context->height = wfi->height;
|
||||
wfi->rfx_context->width = wfi->servscreen_width;
|
||||
wfi->rfx_context->height = wfi->servscreen_height;
|
||||
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||
wfi->s = stream_new(0xFFFF);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user