mfreerdp-server: formatting

This commit is contained in:
C-o-r-E 2013-02-19 15:06:42 -05:00
parent 26989e0cd2
commit 2bd632d077
11 changed files with 906 additions and 904 deletions

View File

@ -3,6 +3,7 @@
# #
# Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@gmail.com> # Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> # Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
# Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -37,8 +38,6 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MODULE freerdp MODULE freerdp
MODULES freerdp-utils) MODULES freerdp-utils)
#set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${MAC_AUDIOTOOLBOX_LIBRARY_PATH})
#set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${MAC_COREFOUNDATION_LIBRARY_PATH})
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
${AUDIO_TOOL} ${AUDIO_TOOL}
${CORE_AUDIO} ${CORE_AUDIO}

View File

@ -97,16 +97,17 @@ static void rdpsnd_audio_open(rdpsndDevicePlugin* device, rdpsndFormat* format,
aq_plugin_p->data_format.mChannelsPerFrame = 2; aq_plugin_p->data_format.mChannelsPerFrame = 2;
aq_plugin_p->data_format.mBitsPerChannel = 16; aq_plugin_p->data_format.mBitsPerChannel = 16;
rv = AudioQueueNewOutput(&aq_plugin_p->data_format, // audio stream basic desc rv = AudioQueueNewOutput(
aq_playback_cb, // callback when more data is required &aq_plugin_p->data_format, // audio stream basic desc
aq_plugin_p, // data to pass to callback aq_playback_cb, // callback when more data is required
CFRunLoopGetCurrent(), // The current run loop, and the one on aq_plugin_p, // data to pass to callback
// which the audio queue playback callback CFRunLoopGetCurrent(), // The current run loop, and the one on
// will be invoked // which the audio queue playback callback
kCFRunLoopCommonModes, // run loop modes in which callbacks can // will be invoked
// be invoked kCFRunLoopCommonModes, // run loop modes in which callbacks can
0, // flags - reserved // be invoked
&aq_plugin_p->aq_ref 0, // flags - reserved
&aq_plugin_p->aq_ref
); );
if (rv != 0) { if (rv != 0) {
printf("rdpsnd_audio_open: AudioQueueNewOutput() failed with error %d\n", rv); printf("rdpsnd_audio_open: AudioQueueNewOutput() failed with error %d\n", rv);
@ -204,6 +205,8 @@ static void aq_playback_cb(void* user_data, AudioQueueRef aq_ref, AudioQueueBuff
int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints)
{ {
printf("freerdp_rdpsnd_client_subsystem_entry()\n\n");
ADDIN_ARGV* args; ADDIN_ARGV* args;
rdpsndAudioQPlugin* aqPlugin; rdpsndAudioQPlugin* aqPlugin;

View File

@ -60,15 +60,15 @@ void mf_peer_audin_init(mfPeerContext* context)
{ {
context->audin = audin_server_context_new(context->vcm); context->audin = audin_server_context_new(context->vcm);
context->audin->data = context; context->audin->data = context;
context->audin->server_formats = audio_formats; context->audin->server_formats = audio_formats;
context->audin->num_server_formats = sizeof(audio_formats) / sizeof(audio_formats[0]); context->audin->num_server_formats = sizeof(audio_formats) / sizeof(audio_formats[0]);
context->audin->dst_format.wFormatTag = 1; context->audin->dst_format.wFormatTag = 1;
context->audin->dst_format.nChannels = 2; context->audin->dst_format.nChannels = 2;
context->audin->dst_format.nSamplesPerSec = 44100; context->audin->dst_format.nSamplesPerSec = 44100;
context->audin->dst_format.wBitsPerSample = 16; context->audin->dst_format.wBitsPerSample = 16;
context->audin->Opening = mf_peer_audin_opening; context->audin->Opening = mf_peer_audin_opening;
context->audin->OpenResult = mf_peer_audin_open_result; context->audin->OpenResult = mf_peer_audin_open_result;
context->audin->ReceiveSamples = mf_peer_audin_receive_samples; context->audin->ReceiveSamples = mf_peer_audin_receive_samples;

View File

@ -35,21 +35,21 @@ int mf_is_event_set(mfEventQueue* event_queue)
fd_set rfds; fd_set rfds;
int num_set; int num_set;
struct timeval time; struct timeval time;
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_SET(event_queue->pipe_fd[0], &rfds); FD_SET(event_queue->pipe_fd[0], &rfds);
memset(&time, 0, sizeof(time)); memset(&time, 0, sizeof(time));
num_set = select(event_queue->pipe_fd[0] + 1, &rfds, 0, 0, &time); num_set = select(event_queue->pipe_fd[0] + 1, &rfds, 0, 0, &time);
return (num_set == 1); return (num_set == 1);
} }
void mf_signal_event(mfEventQueue* event_queue) void mf_signal_event(mfEventQueue* event_queue)
{ {
int length; int length;
length = write(event_queue->pipe_fd[1], "sig", 4); length = write(event_queue->pipe_fd[1], "sig", 4);
if (length != 4) if (length != 4)
printf("mf_signal_event: error\n"); printf("mf_signal_event: error\n");
} }
@ -57,9 +57,9 @@ void mf_signal_event(mfEventQueue* event_queue)
void mf_set_event(mfEventQueue* event_queue) void mf_set_event(mfEventQueue* event_queue)
{ {
int length; int length;
length = write(event_queue->pipe_fd[1], "sig", 4); length = write(event_queue->pipe_fd[1], "sig", 4);
if (length != 4) if (length != 4)
printf("mf_set_event: error\n"); printf("mf_set_event: error\n");
} }
@ -67,11 +67,11 @@ void mf_set_event(mfEventQueue* event_queue)
void mf_clear_events(mfEventQueue* event_queue) void mf_clear_events(mfEventQueue* event_queue)
{ {
int length; int length;
while (mf_is_event_set(event_queue)) while (mf_is_event_set(event_queue))
{ {
length = read(event_queue->pipe_fd[0], &length, 4); length = read(event_queue->pipe_fd[0], &length, 4);
if (length != 4) if (length != 4)
printf("mf_clear_event: error\n"); printf("mf_clear_event: error\n");
} }
@ -80,9 +80,9 @@ void mf_clear_events(mfEventQueue* event_queue)
void mf_clear_event(mfEventQueue* event_queue) void mf_clear_event(mfEventQueue* event_queue)
{ {
int length; int length;
length = read(event_queue->pipe_fd[0], &length, 4); length = read(event_queue->pipe_fd[0], &length, 4);
if (length != 4) if (length != 4)
printf("mf_clear_event: error\n"); printf("mf_clear_event: error\n");
} }
@ -90,62 +90,62 @@ void mf_clear_event(mfEventQueue* event_queue)
void mf_event_push(mfEventQueue* event_queue, mfEvent* event) void mf_event_push(mfEventQueue* event_queue, mfEvent* event)
{ {
pthread_mutex_lock(&(event_queue->mutex)); pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count >= event_queue->size) if (event_queue->count >= event_queue->size)
{ {
event_queue->size *= 2; event_queue->size *= 2;
event_queue->events = (mfEvent**) realloc((void*) event_queue->events, sizeof(mfEvent*) * event_queue->size); event_queue->events = (mfEvent**) realloc((void*) event_queue->events, sizeof(mfEvent*) * event_queue->size);
} }
event_queue->events[(event_queue->count)++] = event; event_queue->events[(event_queue->count)++] = event;
pthread_mutex_unlock(&(event_queue->mutex)); pthread_mutex_unlock(&(event_queue->mutex));
mf_set_event(event_queue); mf_set_event(event_queue);
} }
mfEvent* mf_event_peek(mfEventQueue* event_queue) mfEvent* mf_event_peek(mfEventQueue* event_queue)
{ {
mfEvent* event; mfEvent* event;
pthread_mutex_lock(&(event_queue->mutex)); pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count < 1) if (event_queue->count < 1)
event = NULL; event = NULL;
else else
event = event_queue->events[0]; event = event_queue->events[0];
pthread_mutex_unlock(&(event_queue->mutex)); pthread_mutex_unlock(&(event_queue->mutex));
return event; return event;
} }
mfEvent* mf_event_pop(mfEventQueue* event_queue) mfEvent* mf_event_pop(mfEventQueue* event_queue)
{ {
mfEvent* event; mfEvent* event;
pthread_mutex_lock(&(event_queue->mutex)); pthread_mutex_lock(&(event_queue->mutex));
if (event_queue->count < 1) if (event_queue->count < 1)
return NULL; return NULL;
/* remove event signal */ /* remove event signal */
mf_clear_event(event_queue); mf_clear_event(event_queue);
event = event_queue->events[0]; event = event_queue->events[0];
(event_queue->count)--; (event_queue->count)--;
memmove(&event_queue->events[0], &event_queue->events[1], event_queue->count * sizeof(void*)); memmove(&event_queue->events[0], &event_queue->events[1], event_queue->count * sizeof(void*));
pthread_mutex_unlock(&(event_queue->mutex)); pthread_mutex_unlock(&(event_queue->mutex));
return event; return event;
} }
mfEventRegion* mf_event_region_new(int x, int y, int width, int height) mfEventRegion* mf_event_region_new(int x, int y, int width, int height)
{ {
mfEventRegion* event_region = malloc(sizeof(mfEventRegion)); mfEventRegion* event_region = malloc(sizeof(mfEventRegion));
if (event_region != NULL) if (event_region != NULL)
{ {
event_region->x = x; event_region->x = x;
@ -153,7 +153,7 @@ mfEventRegion* mf_event_region_new(int x, int y, int width, int height)
event_region->width = width; event_region->width = width;
event_region->height = height; event_region->height = height;
} }
return event_region; return event_region;
} }
@ -177,22 +177,22 @@ void mf_event_free(mfEvent* event)
mfEventQueue* mf_event_queue_new() mfEventQueue* mf_event_queue_new()
{ {
mfEventQueue* event_queue = malloc(sizeof(mfEventQueue)); mfEventQueue* event_queue = malloc(sizeof(mfEventQueue));
if (event_queue != NULL) if (event_queue != NULL)
{ {
event_queue->pipe_fd[0] = -1; event_queue->pipe_fd[0] = -1;
event_queue->pipe_fd[1] = -1; event_queue->pipe_fd[1] = -1;
event_queue->size = 16; event_queue->size = 16;
event_queue->count = 0; event_queue->count = 0;
event_queue->events = (mfEvent**) malloc(sizeof(mfEvent*) * event_queue->size); event_queue->events = (mfEvent**) malloc(sizeof(mfEvent*) * event_queue->size);
if (pipe(event_queue->pipe_fd) < 0) if (pipe(event_queue->pipe_fd) < 0)
printf("mf_event_queue_new: pipe failed\n"); printf("mf_event_queue_new: pipe failed\n");
pthread_mutex_init(&(event_queue->mutex), NULL); pthread_mutex_init(&(event_queue->mutex), NULL);
} }
return event_queue; return event_queue;
} }
@ -203,12 +203,12 @@ void mf_event_queue_free(mfEventQueue* event_queue)
close(event_queue->pipe_fd[0]); close(event_queue->pipe_fd[0]);
event_queue->pipe_fd[0] = -1; event_queue->pipe_fd[0] = -1;
} }
if (event_queue->pipe_fd[1] != -1) if (event_queue->pipe_fd[1] != -1)
{ {
close(event_queue->pipe_fd[1]); close(event_queue->pipe_fd[1]);
event_queue->pipe_fd[1] = -1; event_queue->pipe_fd[1] = -1;
} }
pthread_mutex_destroy(&(event_queue->mutex)); pthread_mutex_destroy(&(event_queue->mutex));
} }

View File

@ -52,7 +52,7 @@ struct mf_event_queue
struct mf_event_region struct mf_event_region
{ {
int type; int type;
int x; int x;
int y; int y;
int width; int width;

View File

@ -1,21 +1,21 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Mac OS X Server * FreeRDP Mac OS X Server
* *
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com> * Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -34,116 +34,116 @@ static mfInfo* mfInfoInstance = NULL;
int mf_info_lock(mfInfo* mfi) int mf_info_lock(mfInfo* mfi)
{ {
int status = pthread_mutex_lock(&mfi->mutex); int status = pthread_mutex_lock(&mfi->mutex);
switch (status) { switch (status) {
case 0: case 0:
return TRUE; return TRUE;
break; break;
default: default:
printf("mf_info_lock failed with %#X\n", status); printf("mf_info_lock failed with %#X\n", status);
return -1; return -1;
break; break;
} }
} }
int mf_info_try_lock(mfInfo* mfi, UINT32 ms) int mf_info_try_lock(mfInfo* mfi, UINT32 ms)
{ {
int status = pthread_mutex_trylock(&mfi->mutex); int status = pthread_mutex_trylock(&mfi->mutex);
switch (status) { switch (status) {
case 0: case 0:
return TRUE; return TRUE;
break; break;
case EBUSY: case EBUSY:
return FALSE; return FALSE;
break; break;
default: default:
printf("mf_info_try_lock failed with %#X\n", status); printf("mf_info_try_lock failed with %#X\n", status);
return -1; return -1;
break; break;
} }
} }
int mf_info_unlock(mfInfo* mfi) int mf_info_unlock(mfInfo* mfi)
{ {
int status = pthread_mutex_unlock(&mfi->mutex); int status = pthread_mutex_unlock(&mfi->mutex);
switch (status) { switch (status) {
case 0: case 0:
return TRUE; return TRUE;
break; break;
default: default:
printf("mf_info_unlock failed with %#X\n", status); printf("mf_info_unlock failed with %#X\n", status);
return -1; return -1;
break; break;
} }
} }
mfInfo* mf_info_init() mfInfo* mf_info_init()
{ {
mfInfo* mfi; mfInfo* mfi;
mfi = (mfInfo*) malloc(sizeof(mfInfo));
memset(mfi, 0, sizeof(mfInfo));
mfi = (mfInfo*) malloc(sizeof(mfInfo));
memset(mfi, 0, sizeof(mfInfo));
if (mfi != NULL) if (mfi != NULL)
{ {
/* HKEY hKey; /* HKEY hKey;
LONG status; LONG status;
DWORD dwType; DWORD dwType;
DWORD dwSize; DWORD dwSize;
DWORD dwValue; DWORD dwValue;
*/ */
int mutexInitStatus = pthread_mutex_init(&mfi->mutex, NULL); int mutexInitStatus = pthread_mutex_init(&mfi->mutex, NULL);
if (mutexInitStatus != 0) if (mutexInitStatus != 0)
{ {
printf(_T("CreateMutex error: %#X\n"), mutexInitStatus); printf(_T("CreateMutex error: %#X\n"), mutexInitStatus);
} }
mfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * MF_INFO_MAXPEERS); mfi->peers = (freerdp_peer**) malloc(sizeof(freerdp_peer*) * MF_INFO_MAXPEERS);
memset(mfi->peers, 0, sizeof(freerdp_peer*) * MF_INFO_MAXPEERS); memset(mfi->peers, 0, sizeof(freerdp_peer*) * MF_INFO_MAXPEERS);
//Set FPS //Set FPS
mfi->framesPerSecond = MF_INFO_DEFAULT_FPS; mfi->framesPerSecond = MF_INFO_DEFAULT_FPS;
/*status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); /*status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS) if (status == ERROR_SUCCESS)
{ {
if (RegQueryValueEx(hKey, _T("FramesPerSecond"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) if (RegQueryValueEx(hKey, _T("FramesPerSecond"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
mfi->framesPerSecond = dwValue; mfi->framesPerSecond = dwValue;
} }
RegCloseKey(hKey);*/ RegCloseKey(hKey);*/
//Set input toggle //Set input toggle
mfi->input_disabled = FALSE; mfi->input_disabled = FALSE;
/*status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); /*status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS) if (status == ERROR_SUCCESS)
{ {
if (RegQueryValueEx(hKey, _T("DisableInput"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) if (RegQueryValueEx(hKey, _T("DisableInput"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS)
{ {
if (dwValue != 0) if (dwValue != 0)
mfi->input_disabled = TRUE; mfi->input_disabled = TRUE;
} }
} }
RegCloseKey(hKey);*/ RegCloseKey(hKey);*/
} }
return mfi; return mfi;
} }
@ -151,7 +151,7 @@ mfInfo* mf_info_get_instance()
{ {
if (mfInfoInstance == NULL) if (mfInfoInstance == NULL)
mfInfoInstance = mf_info_init(); mfInfoInstance = mf_info_init();
return mfInfoInstance; return mfInfoInstance;
} }
@ -163,26 +163,26 @@ void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context)
int peerId; int peerId;
if (mfi->peerCount == MF_INFO_MAXPEERS) if (mfi->peerCount == MF_INFO_MAXPEERS)
{ {
printf("TODO: socketClose on OS X\n"); printf("TODO: socketClose on OS X\n");
//context->socketClose = TRUE; //context->socketClose = TRUE;
mf_info_unlock(mfi); mf_info_unlock(mfi);
return; return;
} }
context->info = mfi; context->info = mfi;
//get the offset of the top left corner of selected screen //get the offset of the top left corner of selected screen
//EnumDisplayMonitors(NULL, NULL, mf_info_monEnumCB, 0); //EnumDisplayMonitors(NULL, NULL, mf_info_monEnumCB, 0);
//_IDcount = 0; //_IDcount = 0;
//initialize screen capture //initialize screen capture
if (mfi->peerCount == 0) if (mfi->peerCount == 0)
{ {
mf_mlion_display_info(&mfi->servscreen_width, &mfi->servscreen_height, &mfi->scale); mf_mlion_display_info(&mfi->servscreen_width, &mfi->servscreen_height, &mfi->scale);
mf_mlion_screen_updates_init(); mf_mlion_screen_updates_init();
mf_mlion_start_getting_screen_updates(); mf_mlion_start_getting_screen_updates();
} }
//look trhough the array of peers until an empty slot //look trhough the array of peers until an empty slot
for(i=0; i<MF_INFO_MAXPEERS; ++i) for(i=0; i<MF_INFO_MAXPEERS; ++i)
{ {
@ -193,14 +193,14 @@ void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context)
break; break;
} }
} }
mfi->peers[peerId] = ((rdpContext*) context)->peer; mfi->peers[peerId] = ((rdpContext*) context)->peer;
mfi->peers[peerId]->pId = peerId; mfi->peers[peerId]->pId = peerId;
mfi->peerCount++; mfi->peerCount++;
printf("Registering Peer: id=%d #=%d\n", peerId, mfi->peerCount); printf("Registering Peer: id=%d #=%d\n", peerId, mfi->peerCount);
mf_info_unlock(mfi); mf_info_unlock(mfi);
//mfreerdp_server_peer_callback_event(peerId, MF_SRV_CALLBACK_EVENT_CONNECT); //mfreerdp_server_peer_callback_event(peerId, MF_SRV_CALLBACK_EVENT_CONNECT);
} }
} }
@ -210,20 +210,20 @@ void mf_info_peer_unregister(mfInfo* mfi, mfPeerContext* context)
if (mf_info_lock(mfi) > 0) if (mf_info_lock(mfi) > 0)
{ {
int peerId; int peerId;
peerId = ((rdpContext*) context)->peer->pId; peerId = ((rdpContext*) context)->peer->pId;
mfi->peers[peerId] = NULL; mfi->peers[peerId] = NULL;
mfi->peerCount--; mfi->peerCount--;
printf("Unregistering Peer: id=%d, #=%d\n", peerId, mfi->peerCount); printf("Unregistering Peer: id=%d, #=%d\n", peerId, mfi->peerCount);
//screen capture cleanup //screen capture cleanup
if (mfi->peerCount == 0) if (mfi->peerCount == 0)
{ {
mf_mlion_stop_getting_screen_updates(); mf_mlion_stop_getting_screen_updates();
} }
mf_info_unlock(mfi); mf_info_unlock(mfi);
//mfreerdp_server_peer_callback_event(peerId, MF_SRV_CALLBACK_EVENT_DISCONNECT); //mfreerdp_server_peer_callback_event(peerId, MF_SRV_CALLBACK_EVENT_DISCONNECT);
} }
} }
@ -232,77 +232,77 @@ BOOL mf_info_have_updates(mfInfo* mfi)
{ {
if(mfi->framesWaiting == 0) if(mfi->framesWaiting == 0)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
void mf_info_update_changes(mfInfo* mfi) void mf_info_update_changes(mfInfo* mfi)
{ {
/*#ifdef WITH_WIN8 /*#ifdef WITH_WIN8
mf_dxgi_nextFrame(mfi, mfi->framesPerSecond * 1000); mf_dxgi_nextFrame(mfi, mfi->framesPerSecond * 1000);
#else #else
GETCHANGESBUF* buf; GETCHANGESBUF* buf;
buf = (GETCHANGESBUF*) mfi->changeBuffer; buf = (GETCHANGESBUF*) mfi->changeBuffer;
mfi->nextUpdate = buf->buffer->counter; mfi->nextUpdate = buf->buffer->counter;
#endif*/ #endif*/
} }
void mf_info_find_invalid_region(mfInfo* mfi) void mf_info_find_invalid_region(mfInfo* mfi)
{ {
mf_mlion_get_dirty_region(&mfi->invalid); mf_mlion_get_dirty_region(&mfi->invalid);
} }
void mf_info_clear_invalid_region(mfInfo* mfi) void mf_info_clear_invalid_region(mfInfo* mfi)
{ {
mf_mlion_clear_dirty_region(); mf_mlion_clear_dirty_region();
mfi->invalid.height = 0; mfi->invalid.height = 0;
mfi->invalid.width = 0; mfi->invalid.width = 0;
} }
void mf_info_invalidate_full_screen(mfInfo* mfi) void mf_info_invalidate_full_screen(mfInfo* mfi)
{ {
mfi->invalid.x = 0; mfi->invalid.x = 0;
mfi->invalid.y = 0; mfi->invalid.y = 0;
mfi->invalid.height = mfi->servscreen_height; mfi->invalid.height = mfi->servscreen_height;
mfi->invalid.height = mfi->servscreen_width; mfi->invalid.height = mfi->servscreen_width;
} }
BOOL mf_info_have_invalid_region(mfInfo* mfi) BOOL mf_info_have_invalid_region(mfInfo* mfi)
{ {
if (mfi->invalid.width * mfi->invalid.height == 0) { if (mfi->invalid.width * mfi->invalid.height == 0) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch) void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch)
{ {
*width = mfi->invalid.width / mfi->scale; *width = mfi->invalid.width / mfi->scale;
*height = mfi->invalid.height / mfi->scale; *height = mfi->invalid.height / mfi->scale;
*pitch = mfi->servscreen_width * mfi->scale * 4; *pitch = mfi->servscreen_width * mfi->scale * 4;
mf_mlion_get_pixelData(mfi->invalid.x / mfi->scale, mfi->invalid.y / mfi->scale, *width, *height, pBits); mf_mlion_get_pixelData(mfi->invalid.x / mfi->scale, mfi->invalid.y / mfi->scale, *width, *height, pBits);
*pBits = *pBits + (mfi->invalid.x * 4) + (*pitch * mfi->invalid.y); *pBits = *pBits + (mfi->invalid.x * 4) + (*pitch * mfi->invalid.y);
} }
/* /*
BOOL CALLBACK mf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) BOOL CALLBACK mf_info_monEnumCB(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{ {
mfInfo * mfi; mfInfo * mfi;
mfi = mf_info_get_instance(); mfi = mf_info_get_instance();
if(_IDcount == mfi->screenID) if(_IDcount == mfi->screenID)
{ {
mfi->servscreen_xoffset = lprcMonitor->left; mfi->servscreen_xoffset = lprcMonitor->left;
mfi->servscreen_yoffset = lprcMonitor->top; mfi->servscreen_yoffset = lprcMonitor->top;
} }
_IDcount++; _IDcount++;
return TRUE; return TRUE;
} }
*/ */

View File

@ -48,32 +48,32 @@ typedef struct mf_peer_context mfPeerContext;
struct mf_peer_context struct mf_peer_context
{ {
rdpContext _p; rdpContext _p;
mfInfo* info; mfInfo* info;
STREAM* s; STREAM* s;
BOOL activated; BOOL activated;
UINT32 frame_id; UINT32 frame_id;
BOOL audin_open; BOOL audin_open;
RFX_CONTEXT* rfx_context; RFX_CONTEXT* rfx_context;
NSC_CONTEXT* nsc_context; NSC_CONTEXT* nsc_context;
//#ifdef WITH_SERVER_CHANNELS //#ifdef WITH_SERVER_CHANNELS
WTSVirtualChannelManager* vcm; WTSVirtualChannelManager* vcm;
//#endif //#endif
//#ifdef CHANNEL_AUDIN_SERVER //#ifdef CHANNEL_AUDIN_SERVER
audin_server_context* audin; audin_server_context* audin;
//#endif //#endif
//#ifdef CHANNEL_RDPSND_SERVER //#ifdef CHANNEL_RDPSND_SERVER
rdpsnd_server_context* rdpsnd; rdpsnd_server_context* rdpsnd;
//#endif //#endif
}; };
struct mf_info struct mf_info
{ {
//STREAM* s; //STREAM* s;
//screen and monitor info //screen and monitor info
UINT32 screenID; UINT32 screenID;
UINT32 virtscreen_width; UINT32 virtscreen_width;
@ -82,7 +82,7 @@ struct mf_info
UINT32 servscreen_height; UINT32 servscreen_height;
UINT32 servscreen_xoffset; UINT32 servscreen_xoffset;
UINT32 servscreen_yoffset; UINT32 servscreen_yoffset;
//int frame_idx; //int frame_idx;
int bitsPerPixel; int bitsPerPixel;
//HDC driverDC; //HDC driverDC;
@ -95,11 +95,11 @@ struct mf_info
freerdp_peer** peers; freerdp_peer** peers;
//BOOL mirrorDriverActive; //BOOL mirrorDriverActive;
unsigned int framesWaiting; unsigned int framesWaiting;
UINT32 scale; UINT32 scale;
//HANDLE snd_mutex; //HANDLE snd_mutex;
//BOOL snd_stop; //BOOL snd_stop;
RFX_RECT invalid; RFX_RECT invalid;
pthread_mutex_t mutex; pthread_mutex_t mutex;
//BOOL updatePending; //BOOL updatePending;
@ -110,7 +110,7 @@ struct mf_info
//unsigned long lastUpdate; //unsigned long lastUpdate;
//unsigned long nextUpdate; //unsigned long nextUpdate;
//SURFACE_BITS_COMMAND cmd; //SURFACE_BITS_COMMAND cmd;
BOOL input_disabled; BOOL input_disabled;
BOOL force_all_disconnect; BOOL force_all_disconnect;
}; };

View File

@ -45,262 +45,262 @@ BOOL ready = FALSE;
void (^streamHandler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisplayStreamUpdateRef) = ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) void (^streamHandler)(CGDisplayStreamFrameStatus, uint64_t, IOSurfaceRef, CGDisplayStreamUpdateRef) = ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef)
{ {
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
//may need to move this down //may need to move this down
if(ready == TRUE) if(ready == TRUE)
{ {
RFX_RECT rect; RFX_RECT rect;
unsigned long offset_beg; unsigned long offset_beg;
unsigned long stride; unsigned long stride;
rect.x = 0; rect.x = 0;
rect.y = 0; rect.y = 0;
rect.width = 0; rect.width = 0;
rect.height = 0; rect.height = 0;
mf_mlion_peek_dirty_region(&rect); mf_mlion_peek_dirty_region(&rect);
//lock surface //lock surface
IOSurfaceLock(frameSurface, kIOSurfaceLockReadOnly, NULL); IOSurfaceLock(frameSurface, kIOSurfaceLockReadOnly, NULL);
//get pointer //get pointer
void* baseAddress = IOSurfaceGetBaseAddress(frameSurface); void* baseAddress = IOSurfaceGetBaseAddress(frameSurface);
//copy region //copy region
stride = IOSurfaceGetBytesPerRow(frameSurface); stride = IOSurfaceGetBytesPerRow(frameSurface);
//memcpy(localBuf, baseAddress + offset_beg, surflen); //memcpy(localBuf, baseAddress + offset_beg, surflen);
for(int i = 0; i < rect.height; i++) for(int i = 0; i < rect.height; i++)
{ {
offset_beg = (stride * (rect.y + i) + (rect.x * 4)); offset_beg = (stride * (rect.y + i) + (rect.x * 4));
memcpy(localBuf + offset_beg, memcpy(localBuf + offset_beg,
baseAddress + offset_beg, baseAddress + offset_beg,
rect.width * 4); rect.width * 4);
} }
//unlock surface //unlock surface
IOSurfaceUnlock(frameSurface, kIOSurfaceLockReadOnly, NULL); IOSurfaceUnlock(frameSurface, kIOSurfaceLockReadOnly, NULL);
ready = FALSE; ready = FALSE;
dispatch_semaphore_signal(data_sem); dispatch_semaphore_signal(data_sem);
} }
if (status != kCGDisplayStreamFrameStatusFrameComplete) if (status != kCGDisplayStreamFrameStatusFrameComplete)
{ {
//unhandled //unhandled
switch(status) switch(status)
{ {
case kCGDisplayStreamFrameStatusFrameIdle: case kCGDisplayStreamFrameStatusFrameIdle:
printf("kCGDisplayStreamFrameStatusFrameIdle\n"); printf("kCGDisplayStreamFrameStatusFrameIdle\n");
break; break;
case kCGDisplayStreamFrameStatusStopped: case kCGDisplayStreamFrameStatusStopped:
printf("kCGDisplayStreamFrameStatusStopped\n"); printf("kCGDisplayStreamFrameStatusStopped\n");
break; break;
case kCGDisplayStreamFrameStatusFrameBlank: case kCGDisplayStreamFrameStatusFrameBlank:
printf("kCGDisplayStreamFrameStatusFrameBlank\n"); printf("kCGDisplayStreamFrameStatusFrameBlank\n");
break; break;
default: default:
printf("Unhandled Frame Status!!!\n"); printf("Unhandled Frame Status!!!\n");
} }
} }
else if (lastUpdate == NULL) else if (lastUpdate == NULL)
{ {
CFRetain(updateRef); CFRetain(updateRef);
lastUpdate = updateRef; lastUpdate = updateRef;
} }
else else
{ {
CGDisplayStreamUpdateRef tmpRef; CGDisplayStreamUpdateRef tmpRef;
tmpRef = lastUpdate; tmpRef = lastUpdate;
lastUpdate = CGDisplayStreamUpdateCreateMergedUpdate(tmpRef, updateRef); lastUpdate = CGDisplayStreamUpdateCreateMergedUpdate(tmpRef, updateRef);
CFRelease(tmpRef); CFRelease(tmpRef);
} }
dispatch_semaphore_signal(region_sem); dispatch_semaphore_signal(region_sem);
}; };
int mf_mlion_display_info(UINT32* disp_width, UINT32* disp_height, UINT32* scale) int mf_mlion_display_info(UINT32* disp_width, UINT32* disp_height, UINT32* scale)
{ {
CGDirectDisplayID display_id; CGDirectDisplayID display_id;
display_id = CGMainDisplayID(); display_id = CGMainDisplayID();
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display_id); CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display_id);
size_t pixelWidth = CGDisplayModeGetPixelWidth(mode); size_t pixelWidth = CGDisplayModeGetPixelWidth(mode);
//size_t pixelHeight = CGDisplayModeGetPixelHeight(mode); //size_t pixelHeight = CGDisplayModeGetPixelHeight(mode);
size_t wide = CGDisplayPixelsWide(display_id); size_t wide = CGDisplayPixelsWide(display_id);
size_t high = CGDisplayPixelsHigh(display_id); size_t high = CGDisplayPixelsHigh(display_id);
CGDisplayModeRelease(mode); CGDisplayModeRelease(mode);
*disp_width = wide;//pixelWidth; *disp_width = wide;//pixelWidth;
*disp_height = high;//pixelHeight; *disp_height = high;//pixelHeight;
*scale = pixelWidth / wide; *scale = pixelWidth / wide;
return 0; return 0;
} }
int mf_mlion_screen_updates_init() int mf_mlion_screen_updates_init()
{ {
printf("mf_mlion_screen_updates_init()\n"); printf("mf_mlion_screen_updates_init()\n");
CGDirectDisplayID display_id; CGDirectDisplayID display_id;
display_id = CGMainDisplayID(); display_id = CGMainDisplayID();
screen_update_q = dispatch_queue_create("mfreerdp.server.screenUpdate", NULL); screen_update_q = dispatch_queue_create("mfreerdp.server.screenUpdate", NULL);
region_sem = dispatch_semaphore_create(1); region_sem = dispatch_semaphore_create(1);
data_sem = dispatch_semaphore_create(1); data_sem = dispatch_semaphore_create(1);
UINT32 pixelWidth; UINT32 pixelWidth;
UINT32 pixelHeight; UINT32 pixelHeight;
UINT32 scale; UINT32 scale;
mf_mlion_display_info(&pixelWidth, &pixelHeight, &scale); mf_mlion_display_info(&pixelWidth, &pixelHeight, &scale);
localBuf = malloc(pixelWidth * pixelHeight * 4); localBuf = malloc(pixelWidth * pixelHeight * 4);
stream = CGDisplayStreamCreateWithDispatchQueue(display_id, stream = CGDisplayStreamCreateWithDispatchQueue(display_id,
pixelWidth, pixelWidth,
pixelHeight, pixelHeight,
'BGRA', 'BGRA',
NULL, NULL,
screen_update_q, screen_update_q,
streamHandler); streamHandler);
return 0; return 0;
} }
int mf_mlion_start_getting_screen_updates() int mf_mlion_start_getting_screen_updates()
{ {
CGError err; CGError err;
err = CGDisplayStreamStart(stream); err = CGDisplayStreamStart(stream);
if(err != kCGErrorSuccess) if(err != kCGErrorSuccess)
{ {
printf("Failed to start displaystream!! err = %d\n", err); printf("Failed to start displaystream!! err = %d\n", err);
return 1; return 1;
} }
return 0; return 0;
} }
int mf_mlion_stop_getting_screen_updates() int mf_mlion_stop_getting_screen_updates()
{ {
CGError err; CGError err;
err = CGDisplayStreamStop(stream); err = CGDisplayStreamStop(stream);
if(err != kCGErrorSuccess) if(err != kCGErrorSuccess)
{ {
printf("Failed to stop displaystream!! err = %d\n", err); printf("Failed to stop displaystream!! err = %d\n", err);
return 1; return 1;
} }
return 0; return 0;
return 0; return 0;
} }
int mf_mlion_get_dirty_region(RFX_RECT* invalid) int mf_mlion_get_dirty_region(RFX_RECT* invalid)
{ {
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
if (lastUpdate != NULL) if (lastUpdate != NULL)
{ {
mf_mlion_peek_dirty_region(invalid); mf_mlion_peek_dirty_region(invalid);
//CFRelease(lastUpdate); //CFRelease(lastUpdate);
//lastUpdate = NULL; //lastUpdate = NULL;
} }
dispatch_semaphore_signal(region_sem); dispatch_semaphore_signal(region_sem);
return 0; return 0;
} }
int mf_mlion_peek_dirty_region(RFX_RECT* invalid) int mf_mlion_peek_dirty_region(RFX_RECT* invalid)
{ {
size_t num_rects; size_t num_rects;
CGRect dirtyRegion; CGRect dirtyRegion;
const CGRect * rects = CGDisplayStreamUpdateGetRects(lastUpdate, kCGDisplayStreamUpdateDirtyRects, &num_rects); const CGRect * rects = CGDisplayStreamUpdateGetRects(lastUpdate, kCGDisplayStreamUpdateDirtyRects, &num_rects);
//printf("\trectangles: %zd\n", num_rects); //printf("\trectangles: %zd\n", num_rects);
if (num_rects == 0) { if (num_rects == 0) {
//dispatch_semaphore_signal(region_sem); //dispatch_semaphore_signal(region_sem);
return 0; return 0;
} }
dirtyRegion = *rects; dirtyRegion = *rects;
for (size_t i = 0; i < num_rects; i++) for (size_t i = 0; i < num_rects; i++)
{ {
dirtyRegion = CGRectUnion(dirtyRegion, *(rects+i)); dirtyRegion = CGRectUnion(dirtyRegion, *(rects+i));
} }
invalid->x = dirtyRegion.origin.x; invalid->x = dirtyRegion.origin.x;
invalid->y = dirtyRegion.origin.y; invalid->y = dirtyRegion.origin.y;
invalid->height = dirtyRegion.size.height; invalid->height = dirtyRegion.size.height;
invalid->width = dirtyRegion.size.width; invalid->width = dirtyRegion.size.width;
return 0; return 0;
} }
int mf_mlion_clear_dirty_region() int mf_mlion_clear_dirty_region()
{ {
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
CFRelease(lastUpdate); CFRelease(lastUpdate);
lastUpdate = NULL; lastUpdate = NULL;
dispatch_semaphore_signal(region_sem); dispatch_semaphore_signal(region_sem);
return 0; return 0;
} }
int mf_mlion_get_pixelData(long x, long y, long width, long height, BYTE** pxData) int mf_mlion_get_pixelData(long x, long y, long width, long height, BYTE** pxData)
{ {
dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(region_sem, DISPATCH_TIME_FOREVER);
ready = TRUE; ready = TRUE;
dispatch_semaphore_wait(data_sem, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(data_sem, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(region_sem); dispatch_semaphore_signal(region_sem);
//this second wait allows us to block until data is copied... more on this later //this second wait allows us to block until data is copied... more on this later
dispatch_semaphore_wait(data_sem, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(data_sem, DISPATCH_TIME_FOREVER);
*pxData = localBuf; *pxData = localBuf;
dispatch_semaphore_signal(data_sem); dispatch_semaphore_signal(data_sem);
/* /*
if (image != NULL) { if (image != NULL) {
CGImageRelease(image); CGImageRelease(image);
} }
image = CGDisplayCreateImageForRect( image = CGDisplayCreateImageForRect(
kCGDirectMainDisplay, kCGDirectMainDisplay,
CGRectMake(x, y, width, height) ); CGRectMake(x, y, width, height) );
CGContextDrawImage( CGContextDrawImage(
bitmapcontext, bitmapcontext,
CGRectMake(0, 1800 - height, width, height), CGRectMake(0, 1800 - height, width, height),
image); image);
*pxData = baseAddress; *pxData = baseAddress;
*/ */
return 0; return 0;
} }

View File

@ -1,21 +1,21 @@
/** /**
* FreeRDP: A Remote Desktop Protocol Client * FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Mac OS X Server * FreeRDP Mac OS X Server
* *
* Copyright 2012 Corey Clayton <can.of.tuna@gmail.com> * Copyright 2012 Corey Clayton <can.of.tuna@gmail.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@ -61,151 +61,151 @@ BOOL mf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
{ {
if (info_event_queue->pipe_fd[0] == -1) if (info_event_queue->pipe_fd[0] == -1)
return TRUE; return TRUE;
rfds[*rcount] = (void *)(long) info_event_queue->pipe_fd[0]; rfds[*rcount] = (void *)(long) info_event_queue->pipe_fd[0];
(*rcount)++; (*rcount)++;
return TRUE; return TRUE;
} }
BOOL mf_peer_check_fds(freerdp_peer* client) BOOL mf_peer_check_fds(freerdp_peer* client)
{ {
mfPeerContext* context = (mfPeerContext*) client->context; mfPeerContext* context = (mfPeerContext*) client->context;
mfEvent* event; mfEvent* event;
//HGDI_RGN invalid_region; //HGDI_RGN invalid_region;
if (context->activated == FALSE) if (context->activated == FALSE)
return TRUE; return TRUE;
event = mf_event_peek(info_event_queue); event = mf_event_peek(info_event_queue);
if (event != NULL) if (event != NULL)
{ {
if (event->type == MF_EVENT_TYPE_REGION) if (event->type == MF_EVENT_TYPE_REGION)
{ {
printf("unhandled event\n"); printf("unhandled event\n");
/*mfEventRegion* region = (mfEventRegion*) mf_event_pop(info_event_queue); /*mfEventRegion* region = (mfEventRegion*) mf_event_pop(info_event_queue);
gdi_InvalidateRegion(xfp->hdc, region->x, region->y, region->width, region->height); gdi_InvalidateRegion(xfp->hdc, region->x, region->y, region->width, region->height);
xf_event_region_free(region);*/ xf_event_region_free(region);*/
} }
else if (event->type == MF_EVENT_TYPE_FRAME_TICK) else if (event->type == MF_EVENT_TYPE_FRAME_TICK)
{ {
event = mf_event_pop(info_event_queue); event = mf_event_pop(info_event_queue);
mf_peer_rfx_update(client); mf_peer_rfx_update(client);
mf_event_free(event); mf_event_free(event);
} }
} }
return TRUE; return TRUE;
} }
void mf_peer_rfx_update(freerdp_peer* client) void mf_peer_rfx_update(freerdp_peer* client)
{ {
//check //check
mfInfo* mfi = mf_info_get_instance(); mfInfo* mfi = mf_info_get_instance();
mf_info_find_invalid_region(mfi); mf_info_find_invalid_region(mfi);
if (mf_info_have_invalid_region(mfi) == false) { if (mf_info_have_invalid_region(mfi) == false) {
return; return;
} }
long width; long width;
long height; long height;
int pitch; int pitch;
BYTE* dataBits = NULL; BYTE* dataBits = NULL;
mf_info_getScreenData(mfi, &width, &height, &dataBits, &pitch); mf_info_getScreenData(mfi, &width, &height, &dataBits, &pitch);
mf_info_clear_invalid_region(mfi); mf_info_clear_invalid_region(mfi);
//encode //encode
STREAM* s; STREAM* s;
RFX_RECT rect; RFX_RECT rect;
rdpUpdate* update; rdpUpdate* update;
mfPeerContext* mfp; mfPeerContext* mfp;
SURFACE_BITS_COMMAND* cmd; SURFACE_BITS_COMMAND* cmd;
update = client->update; update = client->update;
mfp = (mfPeerContext*) client->context; mfp = (mfPeerContext*) client->context;
cmd = &update->surface_bits_command; cmd = &update->surface_bits_command;
s = mfp->s; s = mfp->s;
stream_clear(s); stream_clear(s);
stream_set_pos(s, 0); stream_set_pos(s, 0);
UINT32 x = mfi->invalid.x / mfi->scale; UINT32 x = mfi->invalid.x / mfi->scale;
UINT32 y = mfi->invalid.y / mfi->scale; UINT32 y = mfi->invalid.y / mfi->scale;
rect.x = 0; rect.x = 0;
rect.y = 0; rect.y = 0;
rect.width = width; rect.width = width;
rect.height = height; rect.height = height;
mfp->rfx_context->width = mfi->servscreen_width; mfp->rfx_context->width = mfi->servscreen_width;
mfp->rfx_context->height = mfi->servscreen_height; mfp->rfx_context->height = mfi->servscreen_height;
rfx_compose_message(mfp->rfx_context, s, &rect, 1, rfx_compose_message(mfp->rfx_context, s, &rect, 1,
(BYTE*) dataBits, rect.width, rect.height, pitch); (BYTE*) dataBits, rect.width, rect.height, pitch);
cmd->destLeft = x; cmd->destLeft = x;
cmd->destTop = y; cmd->destTop = y;
cmd->destRight = x + rect.width; cmd->destRight = x + rect.width;
cmd->destBottom = y + rect.height; cmd->destBottom = y + rect.height;
cmd->bpp = 32; cmd->bpp = 32;
cmd->codecID = 3; cmd->codecID = 3;
cmd->width = rect.width; cmd->width = rect.width;
cmd->height = rect.height; cmd->height = rect.height;
cmd->bitmapDataLength = stream_get_length(s); cmd->bitmapDataLength = stream_get_length(s);
cmd->bitmapData = stream_get_head(s); cmd->bitmapData = stream_get_head(s);
//send //send
update->SurfaceBits(update->context, cmd); update->SurfaceBits(update->context, cmd);
//clean up //clean up
// note: need to stop getting new dirty rects until here // note: need to stop getting new dirty rects until here
/* /*
CGColorSpaceRelease(rgbColorSpace); CGColorSpaceRelease(rgbColorSpace);
CGImageRelease(image); CGImageRelease(image);
CGContextRelease(context); CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0); CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
CVPixelBufferRelease(pxbuffer); CVPixelBufferRelease(pxbuffer);
*/ */
} }
/* Called when we have a new peer connecting */ /* Called when we have a new peer connecting */
void mf_peer_context_new(freerdp_peer* client, mfPeerContext* context) void mf_peer_context_new(freerdp_peer* client, mfPeerContext* context)
{ {
context->info = mf_info_get_instance(); context->info = mf_info_get_instance();
context->rfx_context = rfx_context_new(); context->rfx_context = rfx_context_new();
context->rfx_context->mode = RLGR3; context->rfx_context->mode = RLGR3;
context->rfx_context->width = client->settings->DesktopWidth; context->rfx_context->width = client->settings->DesktopWidth;
context->rfx_context->height = client->settings->DesktopHeight; context->rfx_context->height = client->settings->DesktopHeight;
rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); rfx_context_set_pixel_format(context->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
rfx_context_set_cpu_opt(context->rfx_context, CPU_SSE2); rfx_context_set_cpu_opt(context->rfx_context, CPU_SSE2);
//context->nsc_context = nsc_context_new(); //context->nsc_context = nsc_context_new();
//nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_B8G8R8A8); //nsc_context_set_pixel_format(context->nsc_context, RDP_PIXEL_FORMAT_B8G8R8A8);
context->s = stream_new(0xFFFF); context->s = stream_new(0xFFFF);
//#ifdef WITH_SERVER_CHANNELS //#ifdef WITH_SERVER_CHANNELS
context->vcm = WTSCreateVirtualChannelManager(client); context->vcm = WTSCreateVirtualChannelManager(client);
//#endif //#endif
mf_info_peer_register(context->info, context); mf_info_peer_register(context->info, context);
} }
@ -214,29 +214,29 @@ void mf_peer_context_free(freerdp_peer* client, mfPeerContext* context)
{ {
if (context) if (context)
{ {
mf_info_peer_unregister(context->info, context); mf_info_peer_unregister(context->info, context);
dispatch_suspend(info_timer); dispatch_suspend(info_timer);
stream_free(context->s); stream_free(context->s);
rfx_context_free(context->rfx_context); rfx_context_free(context->rfx_context);
//nsc_context_free(context->nsc_context); //nsc_context_free(context->nsc_context);
#ifdef CHANNEL_AUDIN_SERVER #ifdef CHANNEL_AUDIN_SERVER
if (context->audin) if (context->audin)
audin_server_context_free(context->audin); audin_server_context_free(context->audin);
#endif #endif
//#ifdef CHANNEL_RDPSND_SERVER //#ifdef CHANNEL_RDPSND_SERVER
mf_peer_rdpsnd_stop(); mf_peer_rdpsnd_stop();
if (context->rdpsnd) if (context->rdpsnd)
rdpsnd_server_context_free(context->rdpsnd); rdpsnd_server_context_free(context->rdpsnd);
//#endif //#endif
//#ifdef WITH_SERVER_CHANNELS //#ifdef WITH_SERVER_CHANNELS
WTSDestroyVirtualChannelManager(context->vcm); WTSDestroyVirtualChannelManager(context->vcm);
//#endif //#endif
} }
} }
@ -247,86 +247,86 @@ void mf_peer_init(freerdp_peer* client)
client->ContextNew = (psPeerContextNew) mf_peer_context_new; client->ContextNew = (psPeerContextNew) mf_peer_context_new;
client->ContextFree = (psPeerContextFree) mf_peer_context_free; client->ContextFree = (psPeerContextFree) mf_peer_context_free;
freerdp_peer_context_new(client); freerdp_peer_context_new(client);
info_event_queue = mf_event_queue_new(); info_event_queue = mf_event_queue_new();
info_queue = dispatch_queue_create("testing.101", DISPATCH_QUEUE_SERIAL); info_queue = dispatch_queue_create("testing.101", DISPATCH_QUEUE_SERIAL);
info_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, info_queue); info_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, info_queue);
if(info_timer) if(info_timer)
{ {
//printf("created timer\n"); //printf("created timer\n");
dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 42ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC); dispatch_source_set_timer(info_timer, DISPATCH_TIME_NOW, 42ull * NSEC_PER_MSEC, 100ull * NSEC_PER_MSEC);
dispatch_source_set_event_handler(info_timer, ^{ dispatch_source_set_event_handler(info_timer, ^{
//printf("dispatch\n"); //printf("dispatch\n");
mfEvent* event = mf_event_new(MF_EVENT_TYPE_FRAME_TICK); mfEvent* event = mf_event_new(MF_EVENT_TYPE_FRAME_TICK);
mf_event_push(info_event_queue, (mfEvent*) event);} mf_event_push(info_event_queue, (mfEvent*) event);}
); );
dispatch_resume(info_timer); dispatch_resume(info_timer);
} }
} }
BOOL mf_peer_post_connect(freerdp_peer* client) BOOL mf_peer_post_connect(freerdp_peer* client)
{ {
mfPeerContext* context = (mfPeerContext*) client->context; mfPeerContext* context = (mfPeerContext*) client->context;
rdpSettings* settings = client->settings; rdpSettings* settings = client->settings;
printf("Client %s post connect\n", client->hostname); printf("Client %s post connect\n", client->hostname);
if (client->settings->AutoLogonEnabled) if (client->settings->AutoLogonEnabled)
{ {
printf(" and wants to login automatically as %s\\%s", printf(" and wants to login automatically as %s\\%s",
client->settings->Domain ? client->settings->Domain : "", client->settings->Domain ? client->settings->Domain : "",
client->settings->Username); client->settings->Username);
/* A real server may perform OS login here if NLA is not executed previously. */ /* A real server may perform OS login here if NLA is not executed previously. */
} }
printf("\n"); printf("\n");
mfInfo* mfi = mf_info_get_instance(); mfInfo* mfi = mf_info_get_instance();
mfi->scale = 1; mfi->scale = 1;
//mfi->servscreen_width = 2880 / mfi->scale; //mfi->servscreen_width = 2880 / mfi->scale;
//mfi->servscreen_height = 1800 / mfi->scale; //mfi->servscreen_height = 1800 / mfi->scale;
UINT32 bitsPerPixel = 32; UINT32 bitsPerPixel = 32;
if ((settings->DesktopWidth != mfi->servscreen_width) || (settings->DesktopHeight != mfi->servscreen_height)) if ((settings->DesktopWidth != mfi->servscreen_width) || (settings->DesktopHeight != mfi->servscreen_height))
{ {
printf("Client requested resolution %dx%d, but will resize to %dx%d\n", printf("Client requested resolution %dx%d, but will resize to %dx%d\n",
settings->DesktopWidth, settings->DesktopHeight, mfi->servscreen_width, mfi->servscreen_height); settings->DesktopWidth, settings->DesktopHeight, mfi->servscreen_width, mfi->servscreen_height);
} }
settings->DesktopWidth = mfi->servscreen_width;
settings->DesktopHeight = mfi->servscreen_height;
settings->ColorDepth = bitsPerPixel;
client->update->DesktopResize(client->update->context);
settings->DesktopWidth = mfi->servscreen_width;
//#ifdef WITH_SERVER_CHANNELS settings->DesktopHeight = mfi->servscreen_height;
settings->ColorDepth = bitsPerPixel;
client->update->DesktopResize(client->update->context);
//#ifdef WITH_SERVER_CHANNELS
/* Iterate all channel names requested by the client and activate those supported by the server */ /* Iterate all channel names requested by the client and activate those supported by the server */
int i; int i;
for (i = 0; i < client->settings->ChannelCount; i++) for (i = 0; i < client->settings->ChannelCount; i++)
{ {
if (client->settings->ChannelDefArray[i].joined) if (client->settings->ChannelDefArray[i].joined)
{ {
//#ifdef CHANNEL_RDPSND_SERVER //#ifdef CHANNEL_RDPSND_SERVER
if (strncmp(client->settings->ChannelDefArray[i].Name, "rdpsnd", 6) == 0) if (strncmp(client->settings->ChannelDefArray[i].Name, "rdpsnd", 6) == 0)
{ {
mf_peer_rdpsnd_init(context); /* Audio Output */ mf_peer_rdpsnd_init(context); /* Audio Output */
} }
//#endif //#endif
} }
} }
/* Dynamic Virtual Channels */ /* Dynamic Virtual Channels */
//#endif //#endif
#ifdef CHANNEL_AUDIN_SERVER #ifdef CHANNEL_AUDIN_SERVER
mf_peer_audin_init(context); /* Audio Input */ mf_peer_audin_init(context); /* Audio Input */
#endif #endif
return TRUE; return TRUE;
} }
@ -334,27 +334,27 @@ BOOL mf_peer_post_connect(freerdp_peer* client)
BOOL mf_peer_activate(freerdp_peer* client) BOOL mf_peer_activate(freerdp_peer* client)
{ {
mfPeerContext* context = (mfPeerContext*) client->context; mfPeerContext* context = (mfPeerContext*) client->context;
rfx_context_reset(context->rfx_context); rfx_context_reset(context->rfx_context);
context->activated = TRUE; context->activated = TRUE;
return TRUE; return TRUE;
} }
/*BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic) /*BOOL wf_peer_logon(freerdp_peer* client, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic)
{ {
printf("PeerLogon\n"); printf("PeerLogon\n");
if (automatic) if (automatic)
{ {
_tprintf(_T("Logon: User:%s Domain:%s Password:%s\n"), _tprintf(_T("Logon: User:%s Domain:%s Password:%s\n"),
identity->User, identity->Domain, identity->Password); identity->User, identity->Domain, identity->Password);
} }
wfreerdp_server_peer_callback_event(((rdpContext*) client->context)->peer->pId, WF_SRV_CALLBACK_EVENT_AUTH); wfreerdp_server_peer_callback_event(((rdpContext*) client->context)->peer->pId, WF_SRV_CALLBACK_EVENT_AUTH);
return TRUE; return TRUE;
}*/ }*/
void mf_peer_synchronize_event(rdpInput* input, UINT32 flags) void mf_peer_synchronize_event(rdpInput* input, UINT32 flags)
{ {
@ -364,23 +364,23 @@ void mf_peer_synchronize_event(rdpInput* input, UINT32 flags)
void mf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) void mf_peer_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{ {
printf("Client sent a keyboard event (flags:0x%04X code:0x%04X)\n", flags, code); printf("Client sent a keyboard event (flags:0x%04X code:0x%04X)\n", flags, code);
UINT16 down = 0x4000; UINT16 down = 0x4000;
//UINT16 up = 0x8000; //UINT16 up = 0x8000;
bool state_down = FALSE; bool state_down = FALSE;
if (flags == down) if (flags == down)
{ {
state_down = TRUE; state_down = TRUE;
} }
/* /*
CGEventRef event; CGEventRef event;
event = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)code, state_down); event = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)code, state_down);
CGEventPost(kCGHIDEventTap, event); CGEventPost(kCGHIDEventTap, event);
CFRelease(event); CFRelease(event);
*/ */
} }
void mf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code) void mf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
@ -399,16 +399,16 @@ void mf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1
} }
/*static void mf_peer_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas) /*static void mf_peer_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas)
{ {
BYTE i; BYTE i;
printf("Client requested to refresh:\n"); printf("Client requested to refresh:\n");
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
printf(" (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom); printf(" (%d, %d) (%d, %d)\n", areas[i].left, areas[i].top, areas[i].right, areas[i].bottom);
} }
}*/ }*/
static void mf_peer_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_16* area) static void mf_peer_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_16* area)
{ {
@ -425,74 +425,74 @@ static void mf_peer_suppress_output(rdpContext* context, BYTE allow, RECTANGLE_1
void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) void mf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
{ {
pthread_t th; pthread_t th;
pthread_create(&th, 0, mf_peer_main_loop, client); pthread_create(&th, 0, mf_peer_main_loop, client);
pthread_detach(th); pthread_detach(th);
} }
/*DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam) /*DWORD WINAPI wf_peer_socket_listener(LPVOID lpParam)
{ {
int i, fds; int i, fds;
int rcount; int rcount;
int max_fds; int max_fds;
void* rfds[32]; void* rfds[32];
fd_set rfds_set; fd_set rfds_set;
wfPeerContext* context; wfPeerContext* context;
freerdp_peer* client = (freerdp_peer*) lpParam; freerdp_peer* client = (freerdp_peer*) lpParam;
ZeroMemory(rfds, sizeof(rfds)); ZeroMemory(rfds, sizeof(rfds));
context = (wfPeerContext*) client->context; context = (wfPeerContext*) client->context;
printf("PeerSocketListener\n"); printf("PeerSocketListener\n");
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 peer file descriptor\n"); printf("Failed to get peer file descriptor\n");
break; break;
} }
max_fds = 0; max_fds = 0;
FD_ZERO(&rfds_set); FD_ZERO(&rfds_set);
for (i = 0; i < rcount; i++) for (i = 0; i < rcount; i++)
{ {
fds = (int)(long)(rfds[i]); fds = (int)(long)(rfds[i]);
if (fds > max_fds) if (fds > max_fds)
max_fds = fds; max_fds = fds;
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); WaitForSingleObject(context->socketSemaphore, INFINITE);
if (context->socketClose) if (context->socketClose)
break; break;
} }
printf("Exiting Peer Socket Listener Thread\n"); printf("Exiting Peer Socket Listener Thread\n");
return 0; return 0;
} }
void wf_peer_read_settings(freerdp_peer* client) void wf_peer_read_settings(freerdp_peer* client)
{ {
if (!wf_settings_read_string_ascii(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), _T("CertificateFile"), &(client->settings->CertificateFile))) if (!wf_settings_read_string_ascii(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), _T("CertificateFile"), &(client->settings->CertificateFile)))
client->settings->CertificateFile = _strdup("server.crt"); client->settings->CertificateFile = _strdup("server.crt");
if (!wf_settings_read_string_ascii(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), _T("PrivateKeyFile"), &(client->settings->PrivateKeyFile))) if (!wf_settings_read_string_ascii(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"), _T("PrivateKeyFile"), &(client->settings->PrivateKeyFile)))
client->settings->PrivateKeyFile = _strdup("server.key"); client->settings->PrivateKeyFile = _strdup("server.key");
}*/ }*/
void* mf_peer_main_loop(void* arg) void* mf_peer_main_loop(void* arg)
{ {
@ -504,11 +504,11 @@ void* mf_peer_main_loop(void* arg)
fd_set rfds_set; fd_set rfds_set;
mfPeerContext* context; mfPeerContext* context;
freerdp_peer* client = (freerdp_peer*) arg; freerdp_peer* client = (freerdp_peer*) arg;
memset(rfds, 0, sizeof(rfds)); memset(rfds, 0, sizeof(rfds));
mf_peer_init(client); mf_peer_init(client);
/* Initialize the real server settings here */ /* Initialize the real server settings here */
client->settings->CertificateFile = _strdup("server.crt"); client->settings->CertificateFile = _strdup("server.crt");
client->settings->PrivateKeyFile = _strdup("server.key"); client->settings->PrivateKeyFile = _strdup("server.key");
@ -517,73 +517,73 @@ void* mf_peer_main_loop(void* arg)
client->settings->ColorDepth = 32; client->settings->ColorDepth = 32;
client->settings->SuppressOutput = TRUE; client->settings->SuppressOutput = TRUE;
client->settings->RefreshRect = FALSE; client->settings->RefreshRect = FALSE;
client->PostConnect = mf_peer_post_connect; client->PostConnect = mf_peer_post_connect;
client->Activate = mf_peer_activate; client->Activate = mf_peer_activate;
client->input->SynchronizeEvent = mf_peer_synchronize_event; client->input->SynchronizeEvent = mf_peer_synchronize_event;
client->input->KeyboardEvent = mf_peer_keyboard_event; client->input->KeyboardEvent = mf_peer_keyboard_event;
client->input->UnicodeKeyboardEvent = mf_peer_unicode_keyboard_event; client->input->UnicodeKeyboardEvent = mf_peer_unicode_keyboard_event;
client->input->MouseEvent = mf_peer_mouse_event; client->input->MouseEvent = mf_peer_mouse_event;
client->input->ExtendedMouseEvent = mf_peer_extended_mouse_event; client->input->ExtendedMouseEvent = mf_peer_extended_mouse_event;
//client->update->RefreshRect = mf_peer_refresh_rect; //client->update->RefreshRect = mf_peer_refresh_rect;
client->update->SuppressOutput = mf_peer_suppress_output; client->update->SuppressOutput = mf_peer_suppress_output;
client->Initialize(client); client->Initialize(client);
context = (mfPeerContext*) client->context; context = (mfPeerContext*) client->context;
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);
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 FreeRDP file descriptor\n");
break; break;
} }
if (mf_peer_get_fds(client, rfds, &rcount) != TRUE) if (mf_peer_get_fds(client, rfds, &rcount) != TRUE)
{ {
printf("Failed to get mfreerdp file descriptor\n"); printf("Failed to get mfreerdp file descriptor\n");
break; break;
} }
//#ifdef WITH_SERVER_CHANNELS //#ifdef WITH_SERVER_CHANNELS
WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount); WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount);
//#endif //#endif
max_fds = 0; max_fds = 0;
FD_ZERO(&rfds_set); FD_ZERO(&rfds_set);
for (i = 0; i < rcount; i++) for (i = 0; i < rcount; i++)
{ {
fds = (int)(long)(rfds[i]); fds = (int)(long)(rfds[i]);
if (fds > max_fds) if (fds > max_fds)
max_fds = fds; max_fds = fds;
FD_SET(fds, &rfds_set); FD_SET(fds, &rfds_set);
} }
if (max_fds == 0) if (max_fds == 0)
break; break;
if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1)
{ {
/* these are not really errors */ /* these are not really errors */
if (!((errno == EAGAIN) || if (!((errno == EAGAIN) ||
(errno == EWOULDBLOCK) || (errno == EWOULDBLOCK) ||
(errno == EINPROGRESS) || (errno == EINPROGRESS) ||
(errno == EINTR))) /* signal occurred */ (errno == EINTR))) /* signal occurred */
{ {
printf("select failed\n"); printf("select failed\n");
break; break;
} }
} }
if (client->CheckFileDescriptor(client) != TRUE) if (client->CheckFileDescriptor(client) != TRUE)
{ {
printf("Failed to check freerdp file descriptor\n"); printf("Failed to check freerdp file descriptor\n");
break; break;
@ -593,20 +593,20 @@ void* mf_peer_main_loop(void* arg)
printf("Failed to check mfreerdp file descriptor\n"); printf("Failed to check mfreerdp file descriptor\n");
break; break;
} }
//#ifdef WITH_SERVER_CHANNELS //#ifdef WITH_SERVER_CHANNELS
if (WTSVirtualChannelManagerCheckFileDescriptor(context->vcm) != TRUE) if (WTSVirtualChannelManagerCheckFileDescriptor(context->vcm) != TRUE)
break; break;
//#endif //#endif
} }
printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname); printf("Client %s disconnected.\n", client->local ? "(local)" : client->hostname);
client->Disconnect(client); client->Disconnect(client);
freerdp_peer_context_free(client); freerdp_peer_context_free(client);
freerdp_peer_free(client); freerdp_peer_free(client);
return NULL; return NULL;
} }

View File

@ -45,106 +45,106 @@ static const rdpsndFormat audio_formats[] =
static void mf_peer_rdpsnd_activated(rdpsnd_server_context* context) static void mf_peer_rdpsnd_activated(rdpsnd_server_context* context)
{ {
printf("RDPSND Activated\n"); printf("RDPSND Activated\n");
printf("Let's create an audio queue for input!\n"); printf("Let's create an audio queue for input!\n");
OSStatus status; OSStatus status;
recorderState.dataFormat.mSampleRate = 44100.0; recorderState.dataFormat.mSampleRate = 44100.0;
recorderState.dataFormat.mFormatID = kAudioFormatLinearPCM; recorderState.dataFormat.mFormatID = kAudioFormatLinearPCM;
recorderState.dataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; recorderState.dataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
recorderState.dataFormat.mBytesPerPacket = 4; recorderState.dataFormat.mBytesPerPacket = 4;
recorderState.dataFormat.mFramesPerPacket = 1; recorderState.dataFormat.mFramesPerPacket = 1;
recorderState.dataFormat.mBytesPerFrame = 4; recorderState.dataFormat.mBytesPerFrame = 4;
recorderState.dataFormat.mChannelsPerFrame = 2; recorderState.dataFormat.mChannelsPerFrame = 2;
recorderState.dataFormat.mBitsPerChannel = 16; recorderState.dataFormat.mBitsPerChannel = 16;
recorderState.snd_context = context; recorderState.snd_context = context;
status = AudioQueueNewInput(&recorderState.dataFormat, status = AudioQueueNewInput(&recorderState.dataFormat,
mf_peer_rdpsnd_input_callback, mf_peer_rdpsnd_input_callback,
&recorderState, &recorderState,
NULL, NULL,
kCFRunLoopCommonModes, kCFRunLoopCommonModes,
0, 0,
&recorderState.queue); &recorderState.queue);
if (status != noErr) if (status != noErr)
{ {
printf("Failed to create a new Audio Queue. Status code: %d\n", status); printf("Failed to create a new Audio Queue. Status code: %d\n", status);
} }
UInt32 dataFormatSize = sizeof (recorderState.dataFormat); UInt32 dataFormatSize = sizeof (recorderState.dataFormat);
AudioQueueGetProperty(recorderState.queue, AudioQueueGetProperty(recorderState.queue,
kAudioConverterCurrentInputStreamDescription, kAudioConverterCurrentInputStreamDescription,
&recorderState.dataFormat, &recorderState.dataFormat,
&dataFormatSize); &dataFormatSize);
mf_rdpsnd_derive_buffer_size(recorderState.queue, &recorderState.dataFormat, 0.05, &recorderState.bufferByteSize); mf_rdpsnd_derive_buffer_size(recorderState.queue, &recorderState.dataFormat, 0.05, &recorderState.bufferByteSize);
printf("Preparing a set of buffers..."); printf("Preparing a set of buffers...");
for (int i = 0; i < snd_numBuffers; ++i) for (int i = 0; i < snd_numBuffers; ++i)
{ {
AudioQueueAllocateBuffer(recorderState.queue, AudioQueueAllocateBuffer(recorderState.queue,
recorderState.bufferByteSize, recorderState.bufferByteSize,
&recorderState.buffers[i]); &recorderState.buffers[i]);
AudioQueueEnqueueBuffer(recorderState.queue, AudioQueueEnqueueBuffer(recorderState.queue,
recorderState.buffers[i], recorderState.buffers[i],
0, 0,
NULL); NULL);
} }
printf("done\n"); printf("done\n");
printf("recording...\n"); printf("recording...\n");
recorderState.currentPacket = 0; recorderState.currentPacket = 0;
recorderState.isRunning = true; recorderState.isRunning = true;
context->SelectFormat(context, 4); context->SelectFormat(context, 4);
context->SetVolume(context, 0x7FFF, 0x7FFF); context->SetVolume(context, 0x7FFF, 0x7FFF);
AudioQueueStart (recorderState.queue, NULL); AudioQueueStart (recorderState.queue, NULL);
} }
BOOL mf_peer_rdpsnd_init(mfPeerContext* context) BOOL mf_peer_rdpsnd_init(mfPeerContext* context)
{ {
//printf("RDPSND INIT\n"); //printf("RDPSND INIT\n");
context->rdpsnd = rdpsnd_server_context_new(context->vcm); context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->data = context; context->rdpsnd->data = context;
context->rdpsnd->server_formats = audio_formats; context->rdpsnd->server_formats = audio_formats;
context->rdpsnd->num_server_formats = sizeof(audio_formats) / sizeof(audio_formats[0]); context->rdpsnd->num_server_formats = sizeof(audio_formats) / sizeof(audio_formats[0]);
context->rdpsnd->src_format.wFormatTag = 1; context->rdpsnd->src_format.wFormatTag = 1;
context->rdpsnd->src_format.nChannels = 2; context->rdpsnd->src_format.nChannels = 2;
context->rdpsnd->src_format.nSamplesPerSec = 44100; context->rdpsnd->src_format.nSamplesPerSec = 44100;
context->rdpsnd->src_format.wBitsPerSample = 16; context->rdpsnd->src_format.wBitsPerSample = 16;
context->rdpsnd->Activated = mf_peer_rdpsnd_activated; context->rdpsnd->Activated = mf_peer_rdpsnd_activated;
context->rdpsnd->Initialize(context->rdpsnd); context->rdpsnd->Initialize(context->rdpsnd);
return TRUE; return TRUE;
} }
BOOL mf_peer_rdpsnd_stop() BOOL mf_peer_rdpsnd_stop()
{ {
recorderState.isRunning = false; recorderState.isRunning = false;
AudioQueueStop(recorderState.queue, true); AudioQueueStop(recorderState.queue, true);
return TRUE; return TRUE;
} }
void mf_peer_rdpsnd_input_callback (void *inUserData, void mf_peer_rdpsnd_input_callback (void *inUserData,
@ -154,35 +154,35 @@ void mf_peer_rdpsnd_input_callback (void *inUserD
UInt32 inNumberPacketDescriptions, UInt32 inNumberPacketDescriptions,
const AudioStreamPacketDescription *inPacketDescs) const AudioStreamPacketDescription *inPacketDescs)
{ {
OSStatus status; OSStatus status;
AQRecorderState * rState; AQRecorderState * rState;
rState = inUserData; rState = inUserData;
if (inNumberPacketDescriptions == 0 && rState->dataFormat.mBytesPerPacket != 0) if (inNumberPacketDescriptions == 0 && rState->dataFormat.mBytesPerPacket != 0)
{ {
inNumberPacketDescriptions = inBuffer->mAudioDataByteSize / rState->dataFormat.mBytesPerPacket; inNumberPacketDescriptions = inBuffer->mAudioDataByteSize / rState->dataFormat.mBytesPerPacket;
} }
if (rState->isRunning == 0) if (rState->isRunning == 0)
{ {
return ; return ;
} }
rState->snd_context->SendSamples(rState->snd_context, inBuffer->mAudioData, inBuffer->mAudioDataByteSize/4); rState->snd_context->SendSamples(rState->snd_context, inBuffer->mAudioData, inBuffer->mAudioDataByteSize/4);
status = AudioQueueEnqueueBuffer( status = AudioQueueEnqueueBuffer(
rState->queue, rState->queue,
inBuffer, inBuffer,
0, 0,
NULL); NULL);
if (status != noErr) if (status != noErr)
{ {
printf("AudioQueueEnqueueBuffer() returned status = %d\n", status); printf("AudioQueueEnqueueBuffer() returned status = %d\n", status);
} }
} }
void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue, void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue,
@ -190,23 +190,23 @@ void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue,
Float64 seconds, Float64 seconds,
UInt32 *outBufferSize) UInt32 *outBufferSize)
{ {
static const int maxBufferSize = 0x50000; static const int maxBufferSize = 0x50000;
int maxPacketSize = ASBDescription->mBytesPerPacket; int maxPacketSize = ASBDescription->mBytesPerPacket;
if (maxPacketSize == 0) if (maxPacketSize == 0)
{ {
UInt32 maxVBRPacketSize = sizeof(maxPacketSize); UInt32 maxVBRPacketSize = sizeof(maxPacketSize);
AudioQueueGetProperty (audioQueue, AudioQueueGetProperty (audioQueue,
kAudioQueueProperty_MaximumOutputPacketSize, kAudioQueueProperty_MaximumOutputPacketSize,
// in Mac OS X v10.5, instead use // in Mac OS X v10.5, instead use
// kAudioConverterPropertyMaximumOutputPacketSize // kAudioConverterPropertyMaximumOutputPacketSize
&maxPacketSize, &maxPacketSize,
&maxVBRPacketSize &maxVBRPacketSize
); );
} }
Float64 numBytesForTime = Float64 numBytesForTime =
ASBDescription->mSampleRate * maxPacketSize * seconds; ASBDescription->mSampleRate * maxPacketSize * seconds;
*outBufferSize = (UInt32) (numBytesForTime < maxBufferSize ? numBytesForTime : maxBufferSize); *outBufferSize = (UInt32) (numBytesForTime < maxBufferSize ? numBytesForTime : maxBufferSize);
} }

View File

@ -36,25 +36,25 @@ void mf_rdpsnd_derive_buffer_size (AudioQueueRef audioQueue,
UInt32 *outBufferSize); UInt32 *outBufferSize);
void mf_peer_rdpsnd_input_callback (void *inUserData, void mf_peer_rdpsnd_input_callback (void *inUserData,
AudioQueueRef inAQ, AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer, AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime, const AudioTimeStamp *inStartTime,
UInt32 inNumberPacketDescriptions, UInt32 inNumberPacketDescriptions,
const AudioStreamPacketDescription *inPacketDescs); const AudioStreamPacketDescription *inPacketDescs);
static const int snd_numBuffers = 3; static const int snd_numBuffers = 3;
struct _AQRecorderState struct _AQRecorderState
{ {
AudioStreamBasicDescription dataFormat; AudioStreamBasicDescription dataFormat;
AudioQueueRef queue; AudioQueueRef queue;
AudioQueueBufferRef buffers[snd_numBuffers]; AudioQueueBufferRef buffers[snd_numBuffers];
AudioFileID audioFile; AudioFileID audioFile;
UInt32 bufferByteSize; UInt32 bufferByteSize;
SInt64 currentPacket; SInt64 currentPacket;
bool isRunning; bool isRunning;
rdpsnd_server_context* snd_context; rdpsnd_server_context* snd_context;
}; };
typedef struct _AQRecorderState AQRecorderState; typedef struct _AQRecorderState AQRecorderState;