Merge branch 'cleanup' of github.com:FreeRDP/FreeRDP into cleanup

This commit is contained in:
Marc-André Moreau 2012-09-07 16:51:05 -04:00
commit 3c28058b28
9 changed files with 291 additions and 190 deletions

View File

@ -27,6 +27,7 @@
#include <winpr/windows.h>
#include "wf_info.h"
#include "wf_update.h"
#include "wf_mirage.h"
static wfInfo* wfInfoInstance = NULL;
@ -103,6 +104,12 @@ wfInfo* wf_info_init()
if (wfi != NULL)
{
HKEY hKey;
LONG status;
DWORD dwType;
DWORD dwSize;
DWORD dwValue;
wfi->mutex = CreateMutex(NULL, FALSE, NULL);
if (wfi->mutex == NULL)
@ -110,9 +117,31 @@ wfInfo* wf_info_init()
_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->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;
@ -126,28 +155,58 @@ wfInfo* wf_info_get_instance()
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)
{
if (wf_info_lock(wfi) > 0)
{
context->info = wfi;
context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (wfi->peerCount < 1)
{
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_mirror_driver_init(wfi);
wf_update_encoder_reinit(wfi);
wfi->peers[wfi->peerCount++] = context;
wf_info_unlock(wfi);
@ -158,21 +217,10 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
{
if (wf_info_lock(wfi) > 0)
{
if (wfi->peerCount <= 1)
{
wfi->peers[--(wfi->peerCount)] = NULL;
if (wfi->peerCount == 1)
wf_mirror_driver_uninit(wfi);
wf_mirror_cleanup(wfi);
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;
}
wfi->peers[--(wfi->peerCount)] = NULL;
wf_info_unlock(wfi);
}

View File

@ -31,12 +31,12 @@ struct wf_info
STREAM* s;
int width;
int height;
int bitsPerPix;
int bitsPerPixel;
HDC driverDC;
int peerCount;
int threadCount;
BOOL activated;
void* changeBuffer;
int framesPerSecond;
LPTSTR deviceKey;
TCHAR deviceName[32];
wfPeerContext** peers;
@ -45,6 +45,8 @@ struct wf_info
HANDLE mutex;
BOOL updatePending;
HANDLE updateEvent;
HANDLE updateThread;
HANDLE updateSemaphore;
RFX_CONTEXT* rfx_context;
unsigned long lastUpdate;
unsigned long nextUpdate;
@ -66,4 +68,4 @@ void wf_info_find_invalid_region(wfInfo* wfi);
void wf_info_clear_invalid_region(wfInfo* wfi);
BOOL wf_info_have_invalid_region(wfInfo* wfi);
#endif
#endif /* WF_INFO_H */

View File

@ -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
the function returns false.
*/
BOOL wf_check_disp_devices(wfInfo* context)
BOOL wf_mirror_driver_find_display_device(wfInfo* context)
{
BOOL result;
BOOL devFound;
@ -78,7 +78,7 @@ BOOL wf_check_disp_devices(wfInfo* context)
* 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;
LONG status;
@ -114,7 +114,7 @@ BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode)
return TRUE;
}
void wf_disp_change_print_status(LONG status)
void wf_mirror_driver_print_display_change_status(LONG status)
{
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.
*/
BOOL wf_update_mirror_drv(wfInfo* context, int unload)
BOOL wf_mirror_driver_update(wfInfo* context, int unload)
{
HDC dc;
BOOL status;
DWORD* extHdr;
WORD drvExtraSaved;
DEVMODE* deviceMode;
int currentScreenBPP;
int currentScreenPixHeight;
int currentScreenPixWidth;
LONG disp_change_status;
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
*/
dc = GetDC(NULL);
currentScreenPixHeight = GetDeviceCaps(dc, VERTRES);
currentScreenPixWidth = GetDeviceCaps(dc, HORZRES);
currentScreenBPP = GetDeviceCaps(dc, BITSPIXEL);
context->width = GetDeviceCaps(dc, HORZRES);
context->height = GetDeviceCaps(dc, VERTRES);
context->bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
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
{
currentScreenPixHeight = 0;
currentScreenPixWidth = 0;
currentScreenBPP = 0;
context->width = 0;
context->height = 0;
context->bitsPerPixel = 0;
}
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->dmDriverExtra = drvExtraSaved;
deviceMode->dmPelsWidth = currentScreenPixWidth;
deviceMode->dmPelsHeight = currentScreenPixHeight;
deviceMode->dmBitsPerPel = currentScreenBPP;
deviceMode->dmPelsWidth = context->width;
deviceMode->dmPelsHeight = context->height;
deviceMode->dmBitsPerPel = context->bitsPerPixel;
deviceMode->dmPosition.x = 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;
if (!status)
wf_disp_change_print_status(disp_change_status);
wf_mirror_driver_print_display_change_status(disp_change_status);
return status;
}
BOOL wf_map_mirror_mem(wfInfo* context)
BOOL wf_mirror_driver_map_memory(wfInfo* context)
{
int status;
GETCHANGESBUF* b;
@ -269,7 +260,7 @@ BOOL wf_map_mirror_mem(wfInfo* context)
/* Unmap the shared memory and release the DC */
BOOL wf_mirror_cleanup(wfInfo* context)
BOOL wf_mirror_driver_cleanup(wfInfo* context)
{
int status;

View File

@ -200,10 +200,10 @@ typedef struct
ULONG nColorBmPalEntries;
} Esc_dmf_pointer_shape_get_OUT;
BOOL wf_check_disp_devices(wfInfo* context);
BOOL wf_disp_device_set_attach_mode(wfInfo* context, DWORD mode);
BOOL wf_update_mirror_drv(wfInfo* context, int unload);
BOOL wf_map_mirror_mem(wfInfo* context);
BOOL wf_mirror_cleanup(wfInfo* context);
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);
#endif /* WF_MIRAGE_H */

View File

@ -46,93 +46,23 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* 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)
{
wfInfo* wfi;
client->context_size = sizeof(wfPeerContext);
client->ContextNew = (psPeerContextNew) wf_peer_context_new;
client->ContextFree = (psPeerContextFree) wf_peer_context_free;
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)
{
wfInfo* wfi;
rdpSettings* settings;
wfPeerContext* context = (wfPeerContext*) client->context;
wfi = context->info;
settings = client->settings;
/**
* 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.
*/
printf("Client %s is activated (osMajorType %d osMinorType %d)", client->local ? "(local)" : client->hostname,
client->settings->os_major_type, client->settings->os_minor_type);
if (client->settings->autologon)
if ((settings->width != wfi->width) || (settings->height != wfi->height))
{
printf(" and wants to login automatically as %s\\%s",
client->settings->domain ? client->settings->domain : "",
client->settings->username);
printf("Client requested resolution %dx%d, but will resize to %dx%d\n",
settings->width, settings->height, wfi->width, wfi->height);
/* 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",
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);
ResumeThread(wfi->updateThread);
return true;
}

View File

@ -21,6 +21,8 @@
#include "config.h"
#endif
#include <winpr/windows.h>
#include <freerdp/freerdp.h>
#include <freerdp/listener.h>
@ -29,6 +31,58 @@
#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)
{
long offset;
@ -69,30 +123,11 @@ void wf_update_encode(wfInfo* wfi)
cmd->height = height;
cmd->bitmapDataLength = stream_get_length(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)
{
if (wfi->updatePending)
{
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);
}
freerdp_peer* client = ((rdpContext*) context)->peer;
wfi->cmd.codecID = client->settings->rfx_codec_id;
client->update->SurfaceBits(client->update->context, &wfi->cmd);
}

View File

@ -25,4 +25,10 @@
void wf_update_encode(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 */

View File

@ -58,13 +58,16 @@ static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
memset(rfds, 0, sizeof(rfds));
context = (wfPeerContext*) client->context;
context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
context->socketSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
while (1)
{
rcount = 0;
if (client->GetFileDescriptor(client, rfds, &rcount) != true)
{
printf("Failed to get FreeRDP file descriptor\n");
printf("Failed to get peer file descriptor\n");
break;
}
@ -81,30 +84,107 @@ static DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
FD_SET(fds, &rfds_set);
}
if (max_fds == 0)
break;
select(max_fds + 1, &rfds_set, NULL, NULL, NULL);
SetEvent(context->socketEvent);
WaitForSingleObject(context->socketSemaphore, INFINITE);
if (context->socketClose)
break;
}
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)
{
wfInfo* wfi;
DWORD nCount;
DWORD status;
HANDLE handles[32];
wfPeerContext* context;
freerdp_peer* client = (freerdp_peer*) lpParam;
wf_peer_init(client);
/* Initialize the real server settings here */
client->settings->cert_file = xstrdup("server.crt");
client->settings->privatekey_file = xstrdup("server.key");
wf_peer_read_settings(client);
client->PostConnect = wf_peer_post_connect;
client->Activate = wf_peer_activate;
@ -118,29 +198,42 @@ static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
client->Initialize(client);
context = (wfPeerContext*) client->context;
context->socketEvent = CreateEvent(0, 1, 0, 0);
CreateThread(NULL, 0, wf_peer_socket_listener, client, 0, NULL);
wfi = context->info;
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);
nCount = 0;
handles[nCount++] = context->updateEvent;
handles[nCount++] = context->socketEvent;
handles[nCount++] = context->info->updateEvent;
while (1)
{
DWORD status;
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");
break;
if (client->activated)
wf_update_peer_send(wfi, context);
ResetEvent(context->updateEvent);
ReleaseSemaphore(wfi->updateSemaphore, 1, NULL);
}
if (client->activated)
wf_update_send(context->info);
if (WaitForSingleObject(context->socketEvent, 0) == 0)
{
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);

View File

@ -30,7 +30,11 @@ struct wf_peer_context
wfInfo* info;
boolean activated;
HANDLE updateEvent;
BOOL socketClose;
HANDLE socketEvent;
HANDLE socketThread;
HANDLE socketSemaphore;
};
typedef struct wf_peer_context wfPeerContext;