wfreerdp-server: merging Corey's sound support with C# binding improvements
This commit is contained in:
commit
e87df0b7cc
@ -72,6 +72,7 @@ struct rdp_freerdp_peer
|
||||
psPeerSendChannelData SendChannelData;
|
||||
psPeerReceiveChannelData ReceiveChannelData;
|
||||
|
||||
int pId;
|
||||
UINT32 ack_frame_id;
|
||||
BOOL local;
|
||||
BOOL connected;
|
||||
|
@ -48,10 +48,13 @@ else()
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
endif()
|
||||
|
||||
|
||||
if(WITH_WIN8)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} d3d11 dxgi dxguid)
|
||||
endif()
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} dsound)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-server)
|
||||
|
||||
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* FreeRDP Windows Server
|
||||
*
|
||||
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
|
||||
@ -136,19 +136,32 @@ wfInfo* wf_info_init()
|
||||
_tprintf(_T("Failed to create update thread\n"));
|
||||
}
|
||||
|
||||
wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * 32);
|
||||
wfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * WF_INFO_MAXPEERS);
|
||||
memset(wfi->peers, 0, sizeof(freerdp_peer*) * WF_INFO_MAXPEERS);
|
||||
|
||||
wfi->framesPerSecond = 24;
|
||||
//Set FPS
|
||||
wfi->framesPerSecond = WF_INFO_DEFAULT_FPS;
|
||||
|
||||
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);
|
||||
|
||||
//Set input toggle
|
||||
wfi->input_disabled = FALSE;
|
||||
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
|
||||
if (status == ERROR_SUCCESS)
|
||||
{
|
||||
if (RegQueryValueEx(hKey, _T("DisableInput"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
if (dwValue != 0)
|
||||
wfi->input_disabled = TRUE;
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
|
||||
//detect windows version
|
||||
@ -190,6 +203,15 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
|
||||
{
|
||||
if (wf_info_lock(wfi) > 0)
|
||||
{
|
||||
int i;
|
||||
int peerId;
|
||||
if (wfi->peerCount == WF_INFO_MAXPEERS)
|
||||
{
|
||||
context->socketClose = TRUE;
|
||||
wf_info_unlock(wfi);
|
||||
return;
|
||||
}
|
||||
|
||||
context->info = wfi;
|
||||
context->updateEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
@ -199,12 +221,25 @@ void wf_info_peer_register(wfInfo* wfi, wfPeerContext* context)
|
||||
#else
|
||||
wf_mirror_driver_activate(wfi);
|
||||
#endif
|
||||
//look trhough the array of peers until an empty slot
|
||||
for(i=0; i<WF_INFO_MAXPEERS; ++i)
|
||||
{
|
||||
//empty index will be our peer id
|
||||
if (wfi->peers[i] == NULL)
|
||||
{
|
||||
peerId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wfi->peers[wfi->peerCount++] = ((rdpContext*) context)->peer;
|
||||
|
||||
printf("Registering Peer: %d\n", wfi->peerCount);
|
||||
wfi->peers[peerId] = ((rdpContext*) context)->peer;
|
||||
wfi->peers[peerId]->pId = peerId;
|
||||
wfi->peerCount++;
|
||||
printf("Registering Peer: id=%d #=%d\n", peerId, wfi->peerCount);
|
||||
|
||||
wf_info_unlock(wfi);
|
||||
|
||||
wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_CONNECT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,10 +247,14 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
|
||||
{
|
||||
if (wf_info_lock(wfi) > 0)
|
||||
{
|
||||
wfi->peers[--(wfi->peerCount)] = NULL;
|
||||
int peerId;
|
||||
|
||||
peerId = ((rdpContext*) context)->peer->pId;
|
||||
wfi->peers[peerId] = NULL;
|
||||
wfi->peerCount--;
|
||||
CloseHandle(context->updateEvent);
|
||||
|
||||
printf("Unregistering Peer: %d\n", wfi->peerCount);
|
||||
printf("Unregistering Peer: id=%d, #=%d\n", peerId, wfi->peerCount);
|
||||
|
||||
#ifdef WITH_WIN8
|
||||
if (wfi->peerCount == 0)
|
||||
@ -223,6 +262,8 @@ void wf_info_peer_unregister(wfInfo* wfi, wfPeerContext* context)
|
||||
#endif
|
||||
|
||||
wf_info_unlock(wfi);
|
||||
|
||||
wfreerdp_server_peer_callback_event(peerId, WF_SRV_CALLBACK_EVENT_DISCONNECT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
#include "wf_interface.h"
|
||||
|
||||
#define WF_INFO_DEFAULT_FPS 24
|
||||
#define WF_INFO_MAXPEERS 32
|
||||
|
||||
int wf_info_lock(wfInfo* wfi);
|
||||
int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds);
|
||||
int wf_info_unlock(wfInfo* wfi);
|
||||
|
@ -164,3 +164,20 @@ void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1
|
||||
wf_peer_mouse_event(input, flags, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wf_peer_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
{
|
||||
}
|
||||
|
||||
void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
|
||||
{
|
||||
}
|
||||
|
||||
void wf_peer_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
}
|
||||
|
||||
void wf_peer_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
|
||||
{
|
||||
}
|
||||
|
@ -27,4 +27,10 @@ void wf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
|
||||
void wf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
|
||||
void wf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
|
||||
|
||||
//dummy versions
|
||||
void wf_peer_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code);
|
||||
void wf_peer_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code);
|
||||
void wf_peer_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
|
||||
void wf_peer_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
|
||||
|
||||
#endif /* WF_INPUT_H */
|
||||
|
@ -3,6 +3,7 @@
|
||||
* FreeRDP Windows Server
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -21,15 +22,20 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/windows.h>
|
||||
#include <freerdp/utils/tcp.h>
|
||||
#include <freerdp\listener.h>
|
||||
|
||||
#include "wf_peer.h"
|
||||
#include "wf_settings.h"
|
||||
#include "wf_info.h"
|
||||
|
||||
#include "wf_interface.h"
|
||||
|
||||
cbCallback cbEvent;
|
||||
|
||||
DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
|
||||
{
|
||||
int i, fds;
|
||||
@ -38,11 +44,15 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
|
||||
void* rfds[32];
|
||||
fd_set rfds_set;
|
||||
freerdp_listener* instance;
|
||||
wfInfo* wfi;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
wfi->force_all_disconnect = FALSE;
|
||||
|
||||
ZeroMemory(rfds, sizeof(rfds));
|
||||
instance = (freerdp_listener*) lpParam;
|
||||
|
||||
while (1)
|
||||
while(wfi->force_all_disconnect == FALSE)
|
||||
{
|
||||
rcount = 0;
|
||||
|
||||
@ -68,6 +78,7 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
|
||||
if (max_fds == 0)
|
||||
break;
|
||||
|
||||
|
||||
select(max_fds + 1, &rfds_set, NULL, NULL, NULL);
|
||||
|
||||
if (instance->CheckFileDescriptor(instance) != TRUE)
|
||||
@ -77,6 +88,8 @@ DWORD WINAPI wf_server_main_loop(LPVOID lpParam)
|
||||
}
|
||||
}
|
||||
|
||||
printf("wf_server_main_loop terminating\n");
|
||||
|
||||
instance->Close(instance);
|
||||
|
||||
return 0;
|
||||
@ -103,6 +116,13 @@ BOOL wfreerdp_server_start(wfServer* server)
|
||||
|
||||
BOOL wfreerdp_server_stop(wfServer* server)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
|
||||
printf("Stopping server\n");
|
||||
wfi->force_all_disconnect = TRUE;
|
||||
server->instance->Close(server->instance);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -120,6 +140,8 @@ wfServer* wfreerdp_server_new()
|
||||
server->port = 3389;
|
||||
}
|
||||
|
||||
cbEvent = NULL;
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
@ -132,3 +154,141 @@ void wfreerdp_server_free(wfServer* server)
|
||||
|
||||
freerdp_wsa_cleanup();
|
||||
}
|
||||
|
||||
|
||||
FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server)
|
||||
{
|
||||
DWORD tStatus;
|
||||
BOOL bRet;
|
||||
|
||||
bRet = GetExitCodeThread(server->thread, &tStatus);
|
||||
if (bRet == 0)
|
||||
{
|
||||
printf("Error in call to GetExitCodeThread\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (tStatus == STILL_ACTIVE)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FREERDP_API UINT32 wfreerdp_server_num_peers()
|
||||
{
|
||||
wfInfo* wfi;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
return wfi->peerCount;
|
||||
}
|
||||
|
||||
FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
freerdp_peer* peer;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
peer = wfi->peers[pId];
|
||||
|
||||
|
||||
if (peer)
|
||||
{
|
||||
UINT32 sLen;
|
||||
|
||||
sLen = strnlen_s(peer->hostname, 50);
|
||||
swprintf(dstStr, 50, L"%hs", peer->hostname);
|
||||
return sLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("nonexistent peer id=%d\n", pId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_local(int pId)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
freerdp_peer* peer;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
peer = wfi->peers[pId];
|
||||
|
||||
|
||||
if (peer)
|
||||
{
|
||||
return peer->local;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
freerdp_peer* peer;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
peer = wfi->peers[pId];
|
||||
|
||||
|
||||
if (peer)
|
||||
{
|
||||
return peer->connected;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
freerdp_peer* peer;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
peer = wfi->peers[pId];
|
||||
|
||||
|
||||
if (peer)
|
||||
{
|
||||
return peer->activated;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
freerdp_peer* peer;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
peer = wfi->peers[pId];
|
||||
|
||||
|
||||
if (peer)
|
||||
{
|
||||
return peer->authenticated;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
FREERDP_API void wfreerdp_server_register_callback_event(cbCallback cb)
|
||||
{
|
||||
cbEvent = cb;
|
||||
}
|
||||
|
||||
void wfreerdp_server_peer_callback_event(int pId, UINT32 eType)
|
||||
{
|
||||
if (cbEvent)
|
||||
cbEvent(pId, eType);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* FreeRDP Windows Server
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -30,6 +31,11 @@
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/server/rdpsnd.h>
|
||||
|
||||
#define WF_SRV_CALLBACK_EVENT_CONNECT 1
|
||||
#define WF_SRV_CALLBACK_EVENT_DISCONNECT 2
|
||||
#define WF_SRV_CALLBACK_EVENT_ACTIVATE 4
|
||||
#define WF_SRV_CALLBACK_EVENT_AUTH 8
|
||||
|
||||
typedef struct wf_info wfInfo;
|
||||
typedef struct wf_peer_context wfPeerContext;
|
||||
|
||||
@ -51,6 +57,9 @@ struct wf_info
|
||||
BOOL mirrorDriverActive;
|
||||
UINT framesWaiting;
|
||||
|
||||
HANDLE snd_mutex;
|
||||
BOOL snd_stop;
|
||||
|
||||
RECT invalid;
|
||||
HANDLE mutex;
|
||||
BOOL updatePending;
|
||||
@ -61,6 +70,9 @@ struct wf_info
|
||||
unsigned long lastUpdate;
|
||||
unsigned long nextUpdate;
|
||||
SURFACE_BITS_COMMAND cmd;
|
||||
|
||||
BOOL input_disabled;
|
||||
BOOL force_all_disconnect;
|
||||
};
|
||||
|
||||
struct wf_peer_context
|
||||
@ -87,10 +99,25 @@ struct wf_server
|
||||
};
|
||||
typedef struct wf_server wfServer;
|
||||
|
||||
typedef void (__stdcall* cbCallback) (int, UINT32);
|
||||
|
||||
FREERDP_API BOOL wfreerdp_server_start(wfServer* server);
|
||||
FREERDP_API BOOL wfreerdp_server_stop(wfServer* server);
|
||||
|
||||
FREERDP_API wfServer* wfreerdp_server_new();
|
||||
FREERDP_API void wfreerdp_server_free(wfServer* server);
|
||||
|
||||
FREERDP_API BOOL wfreerdp_server_is_running(wfServer* server);
|
||||
|
||||
FREERDP_API UINT32 wfreerdp_server_num_peers();
|
||||
FREERDP_API UINT32 wfreerdp_server_get_peer_hostname(int pId, wchar_t * dstStr);
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_local(int pId);
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_connected(int pId);
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_activated(int pId);
|
||||
FREERDP_API BOOL wfreerdp_server_peer_is_authenticated(int pId);
|
||||
|
||||
FREERDP_API void wfreerdp_server_register_callback_event(cbCallback cb);
|
||||
|
||||
void wfreerdp_server_peer_callback_event(int pId, UINT32 eType);
|
||||
|
||||
#endif /* WF_INTERFACE_H */
|
||||
|
@ -1,8 +1,9 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* FreeRDP Windows Server
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -50,7 +51,13 @@ void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context)
|
||||
wf_info_peer_unregister(context->info, context);
|
||||
|
||||
if (context->rdpsnd)
|
||||
{
|
||||
printf("snd_free\n");
|
||||
wf_rdpsnd_lock();
|
||||
context->info->snd_stop = TRUE;
|
||||
rdpsnd_server_context_free(context->rdpsnd);
|
||||
wf_rdpsnd_unlock();
|
||||
}
|
||||
|
||||
WTSDestroyVirtualChannelManager(context->vcm);
|
||||
}
|
||||
@ -118,6 +125,8 @@ BOOL wf_peer_activate(freerdp_peer* client)
|
||||
client->activated = TRUE;
|
||||
wf_update_peer_activate(wfi, context);
|
||||
|
||||
wfreerdp_server_peer_callback_event(((rdpContext*) context)->peer->pId, WF_SRV_CALLBACK_EVENT_ACTIVATE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -131,6 +140,8 @@ BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL
|
||||
identity->User, identity->Domain, identity->Password);
|
||||
}
|
||||
|
||||
|
||||
wfreerdp_server_peer_callback_event(((rdpContext*) client->context)->peer->pId, WF_SRV_CALLBACK_EVENT_AUTH);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -239,7 +250,20 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||
client->Initialize(client);
|
||||
context = (wfPeerContext*) client->context;
|
||||
|
||||
if (context->socketClose)
|
||||
return 0;
|
||||
|
||||
wfi = context->info;
|
||||
|
||||
if (wfi->input_disabled == TRUE)
|
||||
{
|
||||
printf("client input is disabled\n");
|
||||
client->input->KeyboardEvent = wf_peer_keyboard_event_dummy;
|
||||
client->input->UnicodeKeyboardEvent = wf_peer_unicode_keyboard_event_dummy;
|
||||
client->input->MouseEvent = wf_peer_mouse_event_dummy;
|
||||
client->input->ExtendedMouseEvent = wf_peer_extended_mouse_event_dummy;
|
||||
}
|
||||
|
||||
context->socketEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
printf("socketEvent created\n");
|
||||
|
||||
@ -288,6 +312,13 @@ DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
||||
break;
|
||||
}
|
||||
|
||||
//force disconnect
|
||||
if(wfi->force_all_disconnect == TRUE)
|
||||
{
|
||||
printf("Forcing Disconnect -> ");
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME: we should wait on this, instead of calling it every time */
|
||||
if (WTSVirtualChannelManagerCheckFileDescriptor(context->vcm) != TRUE)
|
||||
break;
|
||||
|
@ -24,9 +24,29 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <winpr\windows.h>
|
||||
#define CINTERFACE
|
||||
#include <mmsystem.h>
|
||||
#include <dsound.h>
|
||||
|
||||
#include <freerdp/server/rdpsnd.h>
|
||||
|
||||
#include "wf_rdpsnd.h"
|
||||
#include "wf_info.h"
|
||||
|
||||
/*
|
||||
* Here are some temp things that shall be moved
|
||||
*
|
||||
*/
|
||||
IDirectSoundCapture8 * cap;
|
||||
IDirectSoundCaptureBuffer8* capBuf;
|
||||
DSCBUFFERDESC dscbd;
|
||||
DWORD capturePos;
|
||||
|
||||
#define BYTESPERSEC 176400
|
||||
|
||||
//FIXME support multiple clients
|
||||
wfPeerContext* latestPeer;
|
||||
|
||||
static const rdpsndFormat test_audio_formats[] =
|
||||
{
|
||||
@ -44,11 +64,107 @@ static const rdpsndFormat test_audio_formats[] =
|
||||
|
||||
static void wf_peer_rdpsnd_activated(rdpsnd_server_context* context)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
|
||||
WAVEFORMATEX wfx = {WAVE_FORMAT_PCM, 2, 44100, BYTESPERSEC, 4, 16, 0};
|
||||
|
||||
|
||||
printf("RDPSND Activated\n");
|
||||
|
||||
hr = DirectSoundCaptureCreate8(NULL, &cap, NULL);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to create sound capture device\n"));
|
||||
return;
|
||||
}
|
||||
_tprintf(_T("Created sound capture device\n"));
|
||||
|
||||
dscbd.dwSize = sizeof(DSCBUFFERDESC);
|
||||
dscbd.dwFlags = 0;
|
||||
dscbd.dwBufferBytes = BYTESPERSEC;
|
||||
dscbd.dwReserved = 0;
|
||||
dscbd.lpwfxFormat = &wfx;
|
||||
dscbd.dwFXCount = 0;
|
||||
dscbd.lpDSCFXDesc = NULL;
|
||||
|
||||
hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to create capture buffer\n"));
|
||||
}
|
||||
_tprintf(_T("Created capture buffer"));
|
||||
|
||||
hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to QI capture buffer\n"));
|
||||
}
|
||||
_tprintf(_T("Created IDirectSoundCaptureBuffer8\n"));
|
||||
pDSCB->lpVtbl->Release(pDSCB);
|
||||
|
||||
context->SelectFormat(context, 4);
|
||||
context->SetVolume(context, 0x7FFF, 0x7FFF);
|
||||
capturePos = 0;
|
||||
|
||||
CreateThread(NULL, 0, wf_rdpsnd_thread, latestPeer, 0, NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int wf_rdpsnd_lock()
|
||||
{
|
||||
DWORD dRes;
|
||||
wfInfo* wfi;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
|
||||
dRes = WaitForSingleObject(wfi->snd_mutex, INFINITE);
|
||||
|
||||
switch (dRes)
|
||||
{
|
||||
case WAIT_ABANDONED:
|
||||
case WAIT_OBJECT_0:
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case WAIT_FAILED:
|
||||
printf("wf_rdpsnd_lock failed with 0x%08X\n", GetLastError());
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int wf_rdpsnd_unlock()
|
||||
{
|
||||
wfInfo* wfi;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
|
||||
if (ReleaseMutex(wfi->snd_mutex) == 0)
|
||||
{
|
||||
printf("wf_rdpsnd_unlock failed with 0x%08X\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
|
||||
{
|
||||
wfInfo* wfi;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
|
||||
wfi->snd_mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
context->rdpsnd = rdpsnd_server_context_new(context->vcm);
|
||||
context->rdpsnd->data = context;
|
||||
|
||||
@ -65,5 +181,121 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
|
||||
|
||||
context->rdpsnd->Initialize(context->rdpsnd);
|
||||
|
||||
latestPeer = context;
|
||||
wfi->snd_stop = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam)
|
||||
{
|
||||
HRESULT hr;
|
||||
DWORD beg, end;
|
||||
DWORD diff, rate;
|
||||
wfPeerContext* context;
|
||||
wfInfo* wfi;
|
||||
|
||||
wfi = wf_info_get_instance();
|
||||
|
||||
context = (wfPeerContext*)lpParam;
|
||||
rate = 1000 / 5;
|
||||
|
||||
_tprintf(_T("Trying to start capture\n"));
|
||||
hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to start capture\n"));
|
||||
}
|
||||
_tprintf(_T("Capture started\n"));
|
||||
|
||||
while (1)
|
||||
{
|
||||
VOID* pbCaptureData = NULL;
|
||||
DWORD dwCaptureLength;
|
||||
VOID* pbCaptureData2 = NULL;
|
||||
DWORD dwCaptureLength2;
|
||||
VOID* pbPlayData = NULL;
|
||||
DWORD dwReadPos;
|
||||
LONG lLockSize;
|
||||
beg = GetTickCount();
|
||||
|
||||
if (wf_rdpsnd_lock() > 0)
|
||||
{
|
||||
//check for main exit condition
|
||||
if (wfi->snd_stop == TRUE)
|
||||
{
|
||||
wf_rdpsnd_unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to get read pos\n"));
|
||||
wf_rdpsnd_unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
lLockSize = dwReadPos - capturePos;//dscbd.dwBufferBytes;
|
||||
if (lLockSize < 0) lLockSize += dscbd.dwBufferBytes;
|
||||
|
||||
if (lLockSize == 0)
|
||||
{
|
||||
wf_rdpsnd_unlock();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
hr = capBuf->lpVtbl->Lock(capBuf, capturePos, lLockSize, &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 0L);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to lock sound capture buffer\n"));
|
||||
wf_rdpsnd_unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
//fwrite(pbCaptureData, 1, dwCaptureLength, pFile);
|
||||
//fwrite(pbCaptureData2, 1, dwCaptureLength2, pFile);
|
||||
|
||||
//FIXME: frames = bytes/(bytespersample * channels)
|
||||
|
||||
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData, dwCaptureLength/4);
|
||||
context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData2, dwCaptureLength2/4);
|
||||
|
||||
|
||||
hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2, dwCaptureLength2);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to unlock sound capture buffer\n"));
|
||||
wf_rdpsnd_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO keep track of location in buffer
|
||||
capturePos += dwCaptureLength;
|
||||
capturePos %= dscbd.dwBufferBytes;
|
||||
capturePos += dwCaptureLength2;
|
||||
capturePos %= dscbd.dwBufferBytes;
|
||||
|
||||
wf_rdpsnd_unlock();
|
||||
}
|
||||
|
||||
end = GetTickCount();
|
||||
diff = end - beg;
|
||||
|
||||
if (diff < rate)
|
||||
{
|
||||
Sleep(rate - diff);
|
||||
}
|
||||
}
|
||||
|
||||
_tprintf(_T("Trying to stop sound capture\n"));
|
||||
hr = capBuf->lpVtbl->Stop(capBuf);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
_tprintf(_T("Failed to stop capture\n"));
|
||||
}
|
||||
_tprintf(_T("Capture stopped\n"));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,7 +26,11 @@
|
||||
|
||||
#include "wf_interface.h"
|
||||
|
||||
int wf_rdpsnd_lock();
|
||||
int wf_rdpsnd_unlock();
|
||||
BOOL wf_peer_rdpsnd_init(wfPeerContext* context);
|
||||
|
||||
DWORD WINAPI wf_rdpsnd_thread(LPVOID lpParam);
|
||||
|
||||
#endif /* WF_RDPSND_H */
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* FreeRDP Windows Server
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -37,6 +38,7 @@
|
||||
DWORD WINAPI wf_update_thread(LPVOID lpParam)
|
||||
{
|
||||
int index;
|
||||
int peerindex;
|
||||
DWORD fps;
|
||||
wfInfo* wfi;
|
||||
DWORD beg, end;
|
||||
@ -62,16 +64,20 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam)
|
||||
wf_update_encode(wfi);
|
||||
|
||||
//printf("Start of parallel sending\n");
|
||||
|
||||
for (index = 0; index < wfi->peerCount; index++)
|
||||
index = 0;
|
||||
for (peerindex = 0; peerindex < wfi->peerCount; peerindex++)
|
||||
{
|
||||
if (wfi->peers[index]->activated)
|
||||
for (; index < WF_INFO_MAXPEERS; index++)
|
||||
{
|
||||
if (wfi->peers[index] && wfi->peers[index]->activated)
|
||||
{
|
||||
//printf("Setting event for %d of %d\n", index + 1, wfi->activePeerCount);
|
||||
SetEvent(((wfPeerContext*) wfi->peers[index]->context)->updateEvent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (index = 0; index < wfi->activePeerCount; index++)
|
||||
{
|
||||
//printf("Waiting for %d of %d\n", index + 1, wfi->activePeerCount);
|
||||
|
Loading…
Reference in New Issue
Block a user