mirror of https://github.com/FreeRDP/FreeRDP
Merge branch 'cleanup' of github.com:FreeRDP/FreeRDP into cleanup
This commit is contained in:
commit
3c28058b28
|
@ -27,6 +27,7 @@
|
||||||
#include <winpr/windows.h>
|
#include <winpr/windows.h>
|
||||||
|
|
||||||
#include "wf_info.h"
|
#include "wf_info.h"
|
||||||
|
#include "wf_update.h"
|
||||||
#include "wf_mirage.h"
|
#include "wf_mirage.h"
|
||||||
|
|
||||||
static wfInfo* wfInfoInstance = NULL;
|
static wfInfo* wfInfoInstance = NULL;
|
||||||
|
@ -103,6 +104,12 @@ wfInfo* wf_info_init()
|
||||||
|
|
||||||
if (wfi != NULL)
|
if (wfi != NULL)
|
||||||
{
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
LONG status;
|
||||||
|
DWORD dwType;
|
||||||
|
DWORD dwSize;
|
||||||
|
DWORD dwValue;
|
||||||
|
|
||||||
wfi->mutex = CreateMutex(NULL, FALSE, NULL);
|
wfi->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||||
|
|
||||||
if (wfi->mutex == NULL)
|
if (wfi->mutex == NULL)
|
||||||
|
@ -110,9 +117,31 @@ wfInfo* wf_info_init()
|
||||||
_tprintf(_T("CreateMutex error: %d\n"), GetLastError());
|
_tprintf(_T("CreateMutex error: %d\n"), GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
wfi->updateEvent = CreateEvent(0, 1, 0, 0);
|
wfi->updateEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
|
wfi->updateSemaphore = CreateSemaphore(NULL, 0, 32, NULL);
|
||||||
|
|
||||||
|
wfi->updateThread = CreateThread(NULL, 0, wf_update_thread, wfi, CREATE_SUSPENDED, NULL);
|
||||||
|
|
||||||
|
if (!wfi->updateThread)
|
||||||
|
{
|
||||||
|
_tprintf(_T("Failed to create update thread\n"));
|
||||||
|
}
|
||||||
|
|
||||||
wfi->peers = (wfPeerContext**) malloc(sizeof(wfPeerContext*) * 32);
|
wfi->peers = (wfPeerContext**) malloc(sizeof(wfPeerContext*) * 32);
|
||||||
|
|
||||||
|
wfi->framesPerSecond = 24;
|
||||||
|
|
||||||
|
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||||
|
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (RegQueryValueEx(hKey, _T("FramesPerSecond"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
|
||||||
|
wfi->framesPerSecond = dwValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wfi;
|
return wfi;
|
||||||
|
@ -126,28 +155,58 @@ wfInfo* wf_info_get_instance()
|
||||||
return wfInfoInstance;
|
return wfInfoInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wf_update_encoder_init(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;
|
||||||
|
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
||||||
|
wfi->s = stream_new(0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wf_update_encoder_uninit(wfInfo* wfi)
|
||||||
|
{
|
||||||
|
if (wfi->rfx_context != NULL)
|
||||||
|
{
|
||||||
|
rfx_context_free(wfi->rfx_context);
|
||||||
|
wfi->rfx_context = NULL;
|
||||||
|
stream_free(wfi->s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wf_update_encoder_reinit(wfInfo* wfi)
|
||||||
|
{
|
||||||
|
wf_update_encoder_uninit(wfi);
|
||||||
|
wf_update_encoder_init(wfi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wf_mirror_driver_init(wfInfo* wfi)
|
||||||
|
{
|
||||||
|
wf_mirror_driver_find_display_device(wfi);
|
||||||
|
wf_mirror_driver_display_device_attach(wfi, 1);
|
||||||
|
wf_mirror_driver_update(wfi, FALSE);
|
||||||
|
wf_mirror_driver_map_memory(wfi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wf_mirror_driver_uninit(wfInfo* wfi)
|
||||||
|
{
|
||||||
|
wf_mirror_driver_cleanup(wfi);
|
||||||
|
wf_mirror_driver_display_device_attach(wfi, 0);
|
||||||
|
wf_mirror_driver_update(wfi, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
|
void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
|
||||||
{
|
{
|
||||||
if (wf_info_lock(wfi) > 0)
|
if (wf_info_lock(wfi) > 0)
|
||||||
{
|
{
|
||||||
context->info = wfi;
|
context->info = wfi;
|
||||||
|
context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
|
||||||
if (wfi->peerCount < 1)
|
if (wfi->peerCount < 1)
|
||||||
{
|
wf_mirror_driver_init(wfi);
|
||||||
wf_check_disp_devices(wfi);
|
|
||||||
wf_disp_device_set_attach_mode(wfi, TRUE);
|
|
||||||
wf_update_mirror_drv(wfi, 0);
|
|
||||||
wf_map_mirror_mem(wfi);
|
|
||||||
|
|
||||||
wfi->rfx_context = rfx_context_new();
|
|
||||||
wfi->rfx_context->mode = RLGR3;
|
|
||||||
wfi->rfx_context->width = wfi->width;
|
|
||||||
wfi->rfx_context->height = wfi->height;
|
|
||||||
|
|
||||||
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
|
|
||||||
wfi->s = stream_new(65536);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
wf_update_encoder_reinit(wfi);
|
||||||
wfi->peers[wfi->peerCount++] = context;
|
wfi->peers[wfi->peerCount++] = context;
|
||||||
|
|
||||||
wf_info_unlock(wfi);
|
wf_info_unlock(wfi);
|
||||||
|
@ -158,21 +217,10 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
|
||||||
{
|
{
|
||||||
if (wf_info_lock(wfi) > 0)
|
if (wf_info_lock(wfi) > 0)
|
||||||
{
|
{
|
||||||
if (wfi->peerCount <= 1)
|
if (wfi->peerCount == 1)
|
||||||
{
|
wf_mirror_driver_uninit(wfi);
|
||||||
wfi->peers[--(wfi->peerCount)] = NULL;
|
|
||||||
|
|
||||||
wf_mirror_cleanup(wfi);
|
wfi->peers[--(wfi->peerCount)] = NULL;
|
||||||
wf_disp_device_set_attach_mode(context->info, FALSE);
|
|
||||||
wf_update_mirror_drv(wfi, 1);
|
|
||||||
|
|
||||||
stream_free(wfi->s);
|
|
||||||
rfx_context_free(wfi->rfx_context);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wfi->peers[--(wfi->peerCount)] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wf_info_unlock(wfi);
|
wf_info_unlock(wfi);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,12 @@ struct wf_info
|
||||||
STREAM* s;
|
STREAM* s;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int bitsPerPix;
|
int bitsPerPixel;
|
||||||
HDC driverDC;
|
HDC driverDC;
|
||||||
int peerCount;
|
int peerCount;
|
||||||
int threadCount;
|
|
||||||
BOOL activated;
|
BOOL activated;
|
||||||
void* changeBuffer;
|
void* changeBuffer;
|
||||||
|
int framesPerSecond;
|
||||||
LPTSTR deviceKey;
|
LPTSTR deviceKey;
|
||||||
TCHAR deviceName[32];
|
TCHAR deviceName[32];
|
||||||
wfPeerContext** peers;
|
wfPeerContext** peers;
|
||||||
|
@ -45,6 +45,8 @@ struct wf_info
|
||||||
HANDLE mutex;
|
HANDLE mutex;
|
||||||
BOOL updatePending;
|
BOOL updatePending;
|
||||||
HANDLE updateEvent;
|
HANDLE updateEvent;
|
||||||
|
HANDLE updateThread;
|
||||||
|
HANDLE updateSemaphore;
|
||||||
RFX_CONTEXT* rfx_context;
|
RFX_CONTEXT* rfx_context;
|
||||||
unsigned long lastUpdate;
|
unsigned long lastUpdate;
|
||||||
unsigned long nextUpdate;
|
unsigned long nextUpdate;
|
||||||
|
@ -66,4 +68,4 @@ void wf_info_find_invalid_region(wfInfo* wfi);
|
||||||
void wf_info_clear_invalid_region(wfInfo* wfi);
|
void wf_info_clear_invalid_region(wfInfo* wfi);
|
||||||
BOOL wf_info_have_invalid_region(wfInfo* wfi);
|
BOOL wf_info_have_invalid_region(wfInfo* wfi);
|
||||||
|
|
||||||
#endif
|
#endif /* WF_INFO_H */
|
||||||
|
|
|
@ -29,7 +29,7 @@ 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 context and returns true. Otherwise
|
||||||
the function returns false.
|
the function returns false.
|
||||||
*/
|
*/
|
||||||
BOOL wf_check_disp_devices(wfInfo* context)
|
BOOL wf_mirror_driver_find_display_device(wfInfo* context)
|
||||||
{
|
{
|
||||||
BOOL result;
|
BOOL result;
|
||||||
BOOL devFound;
|
BOOL devFound;
|
||||||
|
@ -78,7 +78,7 @@ BOOL wf_check_disp_devices(wfInfo* context)
|
||||||
* false.
|
* false.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode)
|
BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
LONG status;
|
LONG status;
|
||||||
|
@ -114,7 +114,7 @@ BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wf_disp_change_print_status(LONG status)
|
void wf_mirror_driver_print_display_change_status(LONG status)
|
||||||
{
|
{
|
||||||
TCHAR disp_change[64];
|
TCHAR disp_change[64];
|
||||||
|
|
||||||
|
@ -170,16 +170,13 @@ void wf_disp_change_print_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_update_mirror_drv(wfInfo* context, int unload)
|
BOOL wf_mirror_driver_update(wfInfo* context, int unload)
|
||||||
{
|
{
|
||||||
HDC dc;
|
HDC dc;
|
||||||
BOOL status;
|
BOOL status;
|
||||||
DWORD* extHdr;
|
DWORD* extHdr;
|
||||||
WORD drvExtraSaved;
|
WORD drvExtraSaved;
|
||||||
DEVMODE* deviceMode;
|
DEVMODE* deviceMode;
|
||||||
int currentScreenBPP;
|
|
||||||
int currentScreenPixHeight;
|
|
||||||
int currentScreenPixWidth;
|
|
||||||
LONG disp_change_status;
|
LONG disp_change_status;
|
||||||
DWORD dmf_devmodewext_magic_sig = 0xDF20C0DE;
|
DWORD dmf_devmodewext_magic_sig = 0xDF20C0DE;
|
||||||
|
|
||||||
|
@ -189,22 +186,16 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload)
|
||||||
* 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);
|
||||||
currentScreenPixHeight = GetDeviceCaps(dc, VERTRES);
|
context->width = GetDeviceCaps(dc, HORZRES);
|
||||||
currentScreenPixWidth = GetDeviceCaps(dc, HORZRES);
|
context->height = GetDeviceCaps(dc, VERTRES);
|
||||||
currentScreenBPP = GetDeviceCaps(dc, BITSPIXEL);
|
context->bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
|
||||||
ReleaseDC(NULL, dc);
|
ReleaseDC(NULL, dc);
|
||||||
|
|
||||||
context->height = currentScreenPixHeight;
|
|
||||||
context->width = currentScreenPixWidth;
|
|
||||||
context->bitsPerPix = currentScreenBPP;
|
|
||||||
|
|
||||||
_tprintf(_T("Detected current screen settings: %dx%dx%d\n"), currentScreenPixHeight, currentScreenPixWidth, currentScreenBPP);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentScreenPixHeight = 0;
|
context->width = 0;
|
||||||
currentScreenPixWidth = 0;
|
context->height = 0;
|
||||||
currentScreenBPP = 0;
|
context->bitsPerPixel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceMode = (DEVMODE*) malloc(sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX);
|
deviceMode = (DEVMODE*) malloc(sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX);
|
||||||
|
@ -219,9 +210,9 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload)
|
||||||
deviceMode->dmSize = sizeof(DEVMODE);
|
deviceMode->dmSize = sizeof(DEVMODE);
|
||||||
deviceMode->dmDriverExtra = drvExtraSaved;
|
deviceMode->dmDriverExtra = drvExtraSaved;
|
||||||
|
|
||||||
deviceMode->dmPelsWidth = currentScreenPixWidth;
|
deviceMode->dmPelsWidth = context->width;
|
||||||
deviceMode->dmPelsHeight = currentScreenPixHeight;
|
deviceMode->dmPelsHeight = context->height;
|
||||||
deviceMode->dmBitsPerPel = currentScreenBPP;
|
deviceMode->dmBitsPerPel = context->bitsPerPixel;
|
||||||
deviceMode->dmPosition.x = 0;
|
deviceMode->dmPosition.x = 0;
|
||||||
deviceMode->dmPosition.y = 0;
|
deviceMode->dmPosition.y = 0;
|
||||||
|
|
||||||
|
@ -234,12 +225,12 @@ BOOL wf_update_mirror_drv(wfInfo* context, int unload)
|
||||||
status = (disp_change_status == DISP_CHANGE_SUCCESSFUL) ? TRUE : FALSE;
|
status = (disp_change_status == DISP_CHANGE_SUCCESSFUL) ? TRUE : FALSE;
|
||||||
|
|
||||||
if (!status)
|
if (!status)
|
||||||
wf_disp_change_print_status(disp_change_status);
|
wf_mirror_driver_print_display_change_status(disp_change_status);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL wf_map_mirror_mem(wfInfo* context)
|
BOOL wf_mirror_driver_map_memory(wfInfo* context)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
GETCHANGESBUF* b;
|
GETCHANGESBUF* b;
|
||||||
|
@ -269,7 +260,7 @@ BOOL wf_map_mirror_mem(wfInfo* context)
|
||||||
|
|
||||||
/* Unmap the shared memory and release the DC */
|
/* Unmap the shared memory and release the DC */
|
||||||
|
|
||||||
BOOL wf_mirror_cleanup(wfInfo* context)
|
BOOL wf_mirror_driver_cleanup(wfInfo* context)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
|
|
@ -200,10 +200,10 @@ typedef struct
|
||||||
ULONG nColorBmPalEntries;
|
ULONG nColorBmPalEntries;
|
||||||
} Esc_dmf_pointer_shape_get_OUT;
|
} Esc_dmf_pointer_shape_get_OUT;
|
||||||
|
|
||||||
BOOL wf_check_disp_devices(wfInfo* context);
|
BOOL wf_mirror_driver_find_display_device(wfInfo* context);
|
||||||
BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode);
|
BOOL wf_mirror_driver_display_device_attach(wfInfo* context, DWORD mode);
|
||||||
BOOL wf_update_mirror_drv(wfInfo* context, int unload);
|
BOOL wf_mirror_driver_update(wfInfo* context, int unload);
|
||||||
BOOL wf_map_mirror_mem(wfInfo* context);
|
BOOL wf_mirror_driver_map_memory(wfInfo* context);
|
||||||
BOOL wf_mirror_cleanup(wfInfo* context);
|
BOOL wf_mirror_driver_cleanup(wfInfo* context);
|
||||||
|
|
||||||
#endif /* WF_MIRAGE_H */
|
#endif /* WF_MIRAGE_H */
|
||||||
|
|
|
@ -46,93 +46,23 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
|
||||||
wf_info_peer_unregister(context->info, context);
|
wf_info_peer_unregister(context->info, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD WINAPI wf_peer_mirror_monitor(LPVOID lpParam)
|
|
||||||
{
|
|
||||||
DWORD fps;
|
|
||||||
wfInfo* wfi;
|
|
||||||
DWORD beg, end;
|
|
||||||
DWORD diff, rate;
|
|
||||||
freerdp_peer* client;
|
|
||||||
wfPeerContext* context;
|
|
||||||
|
|
||||||
fps = 24;
|
|
||||||
rate = 1000 / fps;
|
|
||||||
client = (freerdp_peer*) lpParam;
|
|
||||||
context = (wfPeerContext*) client->context;
|
|
||||||
wfi = context->info;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
beg = GetTickCount();
|
|
||||||
|
|
||||||
if (wf_info_lock(wfi) > 0)
|
|
||||||
{
|
|
||||||
if (wfi->peerCount > 0)
|
|
||||||
{
|
|
||||||
wf_info_update_changes(wfi);
|
|
||||||
|
|
||||||
if (wf_info_have_updates(wfi))
|
|
||||||
{
|
|
||||||
wf_update_encode(wfi);
|
|
||||||
SetEvent(wfi->updateEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wf_info_unlock(wfi);
|
|
||||||
}
|
|
||||||
|
|
||||||
end = GetTickCount();
|
|
||||||
diff = end - beg;
|
|
||||||
|
|
||||||
if (diff < rate)
|
|
||||||
{
|
|
||||||
Sleep(rate - diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wf_info_lock(wfi);
|
|
||||||
wfi->threadCount--;
|
|
||||||
wf_info_unlock(wfi);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wf_peer_init(freerdp_peer* client)
|
void wf_peer_init(freerdp_peer* client)
|
||||||
{
|
{
|
||||||
wfInfo* wfi;
|
|
||||||
|
|
||||||
client->context_size = sizeof(wfPeerContext);
|
client->context_size = sizeof(wfPeerContext);
|
||||||
client->ContextNew = (psPeerContextNew) wf_peer_context_new;
|
client->ContextNew = (psPeerContextNew) wf_peer_context_new;
|
||||||
client->ContextFree = (psPeerContextFree) wf_peer_context_free;
|
client->ContextFree = (psPeerContextFree) wf_peer_context_free;
|
||||||
|
|
||||||
freerdp_peer_context_new(client);
|
freerdp_peer_context_new(client);
|
||||||
|
|
||||||
wfi = ((wfPeerContext*) client->context)->info;
|
|
||||||
|
|
||||||
wf_info_lock(wfi);
|
|
||||||
|
|
||||||
if (wfi->threadCount < 1)
|
|
||||||
{
|
|
||||||
if (CreateThread(NULL, 0, wf_peer_mirror_monitor, client, 0, NULL) != 0)
|
|
||||||
{
|
|
||||||
wfi->threadCount++;
|
|
||||||
printf("started monitor thread\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_tprintf(_T("failed to create monitor thread\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wf_info_unlock(wfi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean wf_peer_post_connect(freerdp_peer* client)
|
boolean wf_peer_post_connect(freerdp_peer* client)
|
||||||
{
|
{
|
||||||
wfInfo* wfi;
|
wfInfo* wfi;
|
||||||
|
rdpSettings* settings;
|
||||||
wfPeerContext* context = (wfPeerContext*) client->context;
|
wfPeerContext* context = (wfPeerContext*) client->context;
|
||||||
|
|
||||||
wfi = context->info;
|
wfi = context->info;
|
||||||
|
settings = client->settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback is called when the entire connection sequence is done, i.e. we've received the
|
* This callback is called when the entire connection sequence is done, i.e. we've received the
|
||||||
|
@ -141,28 +71,20 @@ boolean wf_peer_post_connect(freerdp_peer* client)
|
||||||
* callback returns.
|
* callback returns.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname,
|
if ((settings->width != wfi->width) || (settings->height != wfi->height))
|
||||||
client->settings->os_major_type, client->settings->os_minor_type);
|
|
||||||
|
|
||||||
if (client->settings->autologon)
|
|
||||||
{
|
{
|
||||||
printf(" and wants to login automatically as %s\\%s",
|
printf("Client requested resolution %dx%d, but will resize to %dx%d\n",
|
||||||
client->settings->domain ? client->settings->domain : "",
|
settings->width, settings->height, wfi->width, wfi->height);
|
||||||
client->settings->username);
|
|
||||||
|
|
||||||
/* A real server may perform OS login here if NLA is not executed previously. */
|
settings->width = wfi->width;
|
||||||
|
settings->height = wfi->height;
|
||||||
|
settings->color_depth = wfi->bitsPerPixel;
|
||||||
|
|
||||||
|
client->update->DesktopResize(client->update->context);
|
||||||
|
client->activated = false;
|
||||||
}
|
}
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
printf("Client requested desktop: %dx%dx%d\n",
|
ResumeThread(wfi->updateThread);
|
||||||
client->settings->width, client->settings->height, client->settings->color_depth);
|
|
||||||
|
|
||||||
printf("But we will try resizing to %dx%d\n", wfi->width, wfi->height);
|
|
||||||
|
|
||||||
client->settings->width = wfi->width;
|
|
||||||
client->settings->height = wfi->height;
|
|
||||||
|
|
||||||
client->update->DesktopResize(client->update->context);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <winpr/windows.h>
|
||||||
|
|
||||||
#include <freerdp/freerdp.h>
|
#include <freerdp/freerdp.h>
|
||||||
#include <freerdp/listener.h>
|
#include <freerdp/listener.h>
|
||||||
|
|
||||||
|
@ -29,6 +31,58 @@
|
||||||
|
|
||||||
#include "wf_update.h"
|
#include "wf_update.h"
|
||||||
|
|
||||||
|
DWORD WINAPI wf_update_thread(LPVOID lpParam)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
DWORD fps;
|
||||||
|
wfInfo* wfi;
|
||||||
|
DWORD beg, end;
|
||||||
|
DWORD diff, rate;
|
||||||
|
|
||||||
|
wfi = (wfInfo*) lpParam;
|
||||||
|
|
||||||
|
fps = wfi->framesPerSecond;
|
||||||
|
rate = 1000 / fps;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
beg = GetTickCount();
|
||||||
|
|
||||||
|
if (wf_info_lock(wfi) > 0)
|
||||||
|
{
|
||||||
|
if (wfi->peerCount > 0)
|
||||||
|
{
|
||||||
|
wf_info_update_changes(wfi);
|
||||||
|
|
||||||
|
if (wf_info_have_updates(wfi))
|
||||||
|
{
|
||||||
|
wf_update_encode(wfi);
|
||||||
|
|
||||||
|
for (index = 0; index < wfi->peerCount; index++)
|
||||||
|
SetEvent(wfi->peers[index]->updateEvent);
|
||||||
|
|
||||||
|
for (index = 0; index < wfi->peerCount; index++)
|
||||||
|
WaitForSingleObject(wfi->updateSemaphore, INFINITE);
|
||||||
|
|
||||||
|
wfi->lastUpdate = wfi->nextUpdate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wf_info_unlock(wfi);
|
||||||
|
}
|
||||||
|
|
||||||
|
end = GetTickCount();
|
||||||
|
diff = end - beg;
|
||||||
|
|
||||||
|
if (diff < rate)
|
||||||
|
{
|
||||||
|
Sleep(rate - diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void wf_update_encode(wfInfo* wfi)
|
void wf_update_encode(wfInfo* wfi)
|
||||||
{
|
{
|
||||||
long offset;
|
long offset;
|
||||||
|
@ -69,30 +123,11 @@ void wf_update_encode(wfInfo* wfi)
|
||||||
cmd->height = height;
|
cmd->height = height;
|
||||||
cmd->bitmapDataLength = stream_get_length(wfi->s);
|
cmd->bitmapDataLength = stream_get_length(wfi->s);
|
||||||
cmd->bitmapData = stream_get_head(wfi->s);
|
cmd->bitmapData = stream_get_head(wfi->s);
|
||||||
|
|
||||||
wfi->updatePending = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wf_update_send(wfInfo* wfi)
|
void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context)
|
||||||
{
|
{
|
||||||
if (wf_info_lock(wfi) > 0)
|
freerdp_peer* client = ((rdpContext*) context)->peer;
|
||||||
{
|
wfi->cmd.codecID = client->settings->rfx_codec_id;
|
||||||
if (wfi->updatePending)
|
client->update->SurfaceBits(client->update->context, &wfi->cmd);
|
||||||
{
|
|
||||||
int index;
|
|
||||||
freerdp_peer* client;
|
|
||||||
|
|
||||||
for (index = 0; index < wfi->peerCount; index++)
|
|
||||||
{
|
|
||||||
client = ((rdpContext*) wfi->peers[index])->peer;
|
|
||||||
wfi->cmd.codecID = client->settings->rfx_codec_id;
|
|
||||||
client->update->SurfaceBits(client->update->context, &wfi->cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
wfi->lastUpdate = wfi->nextUpdate;
|
|
||||||
wfi->updatePending = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
wf_info_unlock(wfi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,4 +25,10 @@
|
||||||
void wf_update_encode(wfInfo* wfi);
|
void wf_update_encode(wfInfo* wfi);
|
||||||
void wf_update_send(wfInfo* wfi);
|
void wf_update_send(wfInfo* wfi);
|
||||||
|
|
||||||
|
DWORD WINAPI wf_update_thread(LPVOID lpParam);
|
||||||
|
|
||||||
|
void wf_update_begin(wfInfo* wfi);
|
||||||
|
void wf_update_peer_send(wfInfo* wfi, wfPeerContext* context);
|
||||||
|
void wf_update_end(wfInfo* wfi);
|
||||||
|
|
||||||
#endif /* WF_UPDATE_H */
|
#endif /* WF_UPDATE_H */
|
||||||
|
|
|
@ -58,13 +58,16 @@ static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
|
||||||
memset(rfds, 0, sizeof(rfds));
|
memset(rfds, 0, sizeof(rfds));
|
||||||
context = (wfPeerContext*) client->context;
|
context = (wfPeerContext*) client->context;
|
||||||
|
|
||||||
|
context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rcount = 0;
|
rcount = 0;
|
||||||
|
|
||||||
if (client->GetFileDescriptor(client, rfds, &rcount) != true)
|
if (client->GetFileDescriptor(client, rfds, &rcount) != true)
|
||||||
{
|
{
|
||||||
printf("Failed to get FreeRDP file descriptor\n");
|
printf("Failed to get peer file descriptor\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,30 +84,107 @@ static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
|
||||||
FD_SET(fds, &rfds_set);
|
FD_SET(fds, &rfds_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (max_fds == 0)
|
if (max_fds == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
select(max_fds + 1, &rfds_set, NULL, NULL, NULL);
|
select(max_fds + 1, &rfds_set, NULL, NULL, NULL);
|
||||||
|
|
||||||
SetEvent(context->socketEvent);
|
SetEvent(context->socketEvent);
|
||||||
|
WaitForSingleObject(context->socketSemaphore, INFINITE);
|
||||||
|
|
||||||
|
if (context->socketClose)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wf_peer_read_settings(freerdp_peer* client)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
int length;
|
||||||
|
LONG status;
|
||||||
|
DWORD dwType;
|
||||||
|
DWORD dwSize;
|
||||||
|
TCHAR* PrivateKeyFile;
|
||||||
|
TCHAR* CertificateFile;
|
||||||
|
char* PrivateKeyFileA;
|
||||||
|
char* CertificateFileA;
|
||||||
|
|
||||||
|
PrivateKeyFile = CertificateFile = NULL;
|
||||||
|
|
||||||
|
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||||
|
|
||||||
|
if (status != ERROR_SUCCESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
status = RegQueryValueEx(hKey, _T("CertificateFile"), NULL, &dwType, NULL, &dwSize);
|
||||||
|
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
CertificateFile = (LPTSTR) malloc(dwSize + sizeof(TCHAR));
|
||||||
|
status = RegQueryValueEx(hKey, _T("CertificateFile"), NULL, &dwType, (BYTE*) CertificateFile, &dwSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = RegQueryValueEx(hKey, _T("PrivateKeyFile"), NULL, &dwType, NULL, &dwSize);
|
||||||
|
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
PrivateKeyFile = (LPTSTR) malloc(dwSize + sizeof(TCHAR));
|
||||||
|
status = RegQueryValueEx(hKey, _T("PrivateKeyFile"), NULL, &dwType, (BYTE*) PrivateKeyFile, &dwSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CertificateFile)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
length = WideCharToMultiByte(CP_UTF8, 0, CertificateFile, lstrlenW(CertificateFile), NULL, 0, NULL, NULL);
|
||||||
|
CertificateFileA = (char*) malloc(length + 1);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, CertificateFile, lstrlenW(CertificateFile), CertificateFileA, length, NULL, NULL);
|
||||||
|
CertificateFileA[length] = '\0';
|
||||||
|
free(CertificateFile);
|
||||||
|
#else
|
||||||
|
CertificateFileA = (char*) CertificateFile;
|
||||||
|
#endif
|
||||||
|
client->settings->cert_file = CertificateFileA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client->settings->cert_file = _strdup("server.crt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PrivateKeyFile)
|
||||||
|
{
|
||||||
|
#ifdef UNICODE
|
||||||
|
length = WideCharToMultiByte(CP_UTF8, 0, PrivateKeyFile, lstrlenW(PrivateKeyFile), NULL, 0, NULL, NULL);
|
||||||
|
PrivateKeyFileA = (char*) malloc(length + 1);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, PrivateKeyFile, lstrlenW(PrivateKeyFile), PrivateKeyFileA, length, NULL, NULL);
|
||||||
|
PrivateKeyFileA[length] = '\0';
|
||||||
|
free(PrivateKeyFile);
|
||||||
|
#else
|
||||||
|
PrivateKeyFileA = (char*) PrivateKeyFile;
|
||||||
|
#endif
|
||||||
|
client->settings->privatekey_file = PrivateKeyFileA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client->settings->privatekey_file = _strdup("server.key");
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
|
wfInfo* wfi;
|
||||||
DWORD nCount;
|
DWORD nCount;
|
||||||
|
DWORD status;
|
||||||
HANDLE handles[32];
|
HANDLE handles[32];
|
||||||
wfPeerContext* context;
|
wfPeerContext* context;
|
||||||
freerdp_peer* client = (freerdp_peer*) lpParam;
|
freerdp_peer* client = (freerdp_peer*) lpParam;
|
||||||
|
|
||||||
wf_peer_init(client);
|
wf_peer_init(client);
|
||||||
|
|
||||||
/* Initialize the real server settings here */
|
wf_peer_read_settings(client);
|
||||||
client->settings->cert_file = xstrdup("server.crt");
|
|
||||||
client->settings->privatekey_file = xstrdup("server.key");
|
|
||||||
|
|
||||||
client->PostConnect = wf_peer_post_connect;
|
client->PostConnect = wf_peer_post_connect;
|
||||||
client->Activate = wf_peer_activate;
|
client->Activate = wf_peer_activate;
|
||||||
|
@ -118,29 +198,42 @@ static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||||
client->Initialize(client);
|
client->Initialize(client);
|
||||||
context = (wfPeerContext*) client->context;
|
context = (wfPeerContext*) client->context;
|
||||||
|
|
||||||
context->socketEvent = CreateEvent(0, 1, 0, 0);
|
wfi = context->info;
|
||||||
CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL);
|
context->socketThread = CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL);
|
||||||
|
|
||||||
printf("We've got a client %s\n", client->local ? "(local)" : client->hostname);
|
printf("We've got a client %s\n", client->local ? "(local)" : client->hostname);
|
||||||
|
|
||||||
nCount = 0;
|
nCount = 0;
|
||||||
|
handles[nCount++] = context->updateEvent;
|
||||||
handles[nCount++] = context->socketEvent;
|
handles[nCount++] = context->socketEvent;
|
||||||
handles[nCount++] = context->info->updateEvent;
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
DWORD status;
|
|
||||||
|
|
||||||
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
status = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
|
||||||
|
|
||||||
if (client->CheckFileDescriptor(client) != true)
|
if (WaitForSingleObject(context->updateEvent, 0) == 0)
|
||||||
{
|
{
|
||||||
printf("Failed to check FreeRDP file descriptor\n");
|
if (client->activated)
|
||||||
break;
|
wf_update_peer_send(wfi, context);
|
||||||
|
|
||||||
|
ResetEvent(context->updateEvent);
|
||||||
|
ReleaseSemaphore(wfi->updateSemaphore, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->activated)
|
if (WaitForSingleObject(context->socketEvent, 0) == 0)
|
||||||
wf_update_send(context->info);
|
{
|
||||||
|
if (client->CheckFileDescriptor(client) != true)
|
||||||
|
{
|
||||||
|
printf("Failed to check peer file descriptor\n");
|
||||||
|
context->socketClose = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetEvent(context->socketEvent);
|
||||||
|
ReleaseSemaphore(context->socketSemaphore, 1, NULL);
|
||||||
|
|
||||||
|
if (context->socketClose)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);
|
printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);
|
||||||
|
|
|
@ -30,7 +30,11 @@ struct wf_peer_context
|
||||||
|
|
||||||
wfInfo* info;
|
wfInfo* info;
|
||||||
boolean activated;
|
boolean activated;
|
||||||
|
HANDLE updateEvent;
|
||||||
|
BOOL socketClose;
|
||||||
HANDLE socketEvent;
|
HANDLE socketEvent;
|
||||||
|
HANDLE socketThread;
|
||||||
|
HANDLE socketSemaphore;
|
||||||
};
|
};
|
||||||
typedef struct wf_peer_context wfPeerContext;
|
typedef struct wf_peer_context wfPeerContext;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue