Merge pull request #4889 from akallabeth/shadow_server_audin_refactor

Shadow server audin refactor
This commit is contained in:
Martin Fleisz
2018-10-08 12:56:09 +02:00
committed by GitHub
28 changed files with 782 additions and 633 deletions

View File

@@ -85,9 +85,7 @@ struct _AUDIN_PLUGIN
AUDIN_LISTENER_CALLBACK* listener_callback;
/* Parsed plugin data */
UINT16 fixed_format;
UINT16 fixed_channel;
UINT32 fixed_rate;
AUDIO_FORMAT* fixed_format;
char* subsystem;
char* device_name;
@@ -210,7 +208,7 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
}
Stream_Seek_UINT32(s); /* cbSizeFormatsPacket */
callback->formats = (AUDIO_FORMAT*) calloc(NumFormats, sizeof(AUDIO_FORMAT));
callback->formats = audio_formats_new(NumFormats);
if (!callback->formats)
{
@@ -234,51 +232,17 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
{
AUDIO_FORMAT format = { 0 };
if (Stream_GetRemainingLength(s) < 18)
if (!audio_format_read(s, &format))
{
error = ERROR_INVALID_DATA;
goto out;
}
Stream_Read_UINT16(s, format.wFormatTag);
Stream_Read_UINT16(s, format.nChannels);
Stream_Read_UINT32(s, format.nSamplesPerSec);
Stream_Read_UINT32(s, format.nAvgBytesPerSec);
Stream_Read_UINT16(s, format.nBlockAlign);
Stream_Read_UINT16(s, format.wBitsPerSample);
Stream_Read_UINT16(s, format.cbSize);
audio_format_print(audin->log, WLOG_DEBUG, &format);
if (Stream_GetRemainingLength(s) < format.cbSize)
if (!audio_format_compatible(audin->fixed_format, &format))
{
error = ERROR_INVALID_DATA;
goto out;
}
if (format.cbSize > 0)
{
format.data = malloc(format.cbSize);
if (!format.data)
{
error = ERROR_OUTOFMEMORY;
goto out;
}
memcpy(format.data, Stream_Pointer(s), format.cbSize);
Stream_Seek(s, format.cbSize);
}
WLog_Print(audin->log, WLOG_DEBUG,
"wFormatTag=%s nChannels=%"PRIu16" nSamplesPerSec=%"PRIu32" "
"nBlockAlign=%"PRIu16" wBitsPerSample=%"PRIu16" cbSize=%"PRIu16"",
rdpsnd_get_audio_tag_string(format.wFormatTag), format.nChannels, format.nSamplesPerSec,
format.nBlockAlign, format.wBitsPerSample, format.cbSize);
if ((audin->fixed_format > 0 && audin->fixed_format != format.wFormatTag) ||
(audin->fixed_channel > 0 && audin->fixed_channel != format.nChannels) ||
(audin->fixed_rate > 0 && audin->fixed_rate != format.nSamplesPerSec))
{
free(format.data);
audio_format_free(&format);
continue;
}
@@ -288,20 +252,16 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c
/* Store the agreed format in the corresponding index */
callback->formats[callback->formats_count++] = format;
/* Put the format to output buffer */
if (!Stream_EnsureRemainingCapacity(out, 18 + format.cbSize))
if (!audio_format_write(out, &format))
{
error = CHANNEL_RC_NO_MEMORY;
WLog_Print(audin->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
goto out;
}
Stream_Write(out, &format, 18);
Stream_Write(out, format.data, format.cbSize);
}
else
{
free(format.data);
audio_format_free(&format);
}
}
@@ -322,16 +282,8 @@ out:
if (error != CHANNEL_RC_OK)
{
size_t x;
if (callback->formats)
{
for (x = 0; x < NumFormats; x++)
free(callback->formats[x].data);
free(callback->formats);
callback->formats = NULL;
}
audio_formats_free(callback->formats, NumFormats);
callback->formats = NULL;
}
Stream_Free(out, TRUE);
@@ -427,12 +379,8 @@ static UINT audin_receive_wave_data(const AUDIO_FORMAT* format,
if (Stream_GetPosition(audin->data) <= 1)
return CHANNEL_RC_OK;
WLog_Print(audin->log, WLOG_TRACE,
"%s: nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" "
"nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16" [%"PRIdz"/%"PRIdz"]",
rdpsnd_get_audio_tag_string(audin->format->wFormatTag),
audin->format->nChannels, audin->format->nSamplesPerSec, audin->format->nAvgBytesPerSec,
audin->format->nBlockAlign, audin->format->wBitsPerSample, audin->format->cbSize, size,
audio_format_print(audin->log, WLOG_TRACE, audin->format);
WLog_Print(audin->log, WLOG_TRACE, "[%"PRIdz"/%"PRIdz"]", size,
Stream_GetPosition(audin->data) - 1);
if ((error = audin_send_incoming_data_pdu(callback)))
@@ -456,7 +404,7 @@ static BOOL audin_open_device(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* callb
format = *audin->format;
supported = IFCALLRESULT(FALSE, audin->device->FormatSupported, audin->device, &format);
WLog_Print(audin->log, WLOG_DEBUG, "microphone uses %s codec",
rdpsnd_get_audio_tag_string(format.wFormatTag));
audio_format_get_tag_string(format.wFormatTag));
if (!supported)
{
@@ -641,7 +589,6 @@ static UINT audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
*/
static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
size_t x;
AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback;
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin;
UINT error = CHANNEL_RC_OK;
@@ -656,18 +603,7 @@ static UINT audin_on_close(IWTSVirtualChannelCallback* pChannelCallback)
}
audin->format = NULL;
if (callback->formats)
{
for (x = 0; x < callback->formats_count; x++)
{
AUDIO_FORMAT* format = &callback->formats[x];
free(format->data);
}
free(callback->formats);
}
audio_formats_free(callback->formats, callback->formats_count);
free(callback);
return error;
}
@@ -752,6 +688,7 @@ static UINT audin_plugin_terminated(IWTSPlugin* pPlugin)
return CHANNEL_RC_BAD_CHANNEL_HANDLE;
WLog_Print(audin->log, WLOG_TRACE, "...");
audio_format_free(audin->fixed_format);
if (audin->device)
{
@@ -952,7 +889,7 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
if ((errno != 0) || (val > UINT16_MAX))
return FALSE;
audin->fixed_format = val;
audin->fixed_format->wFormatTag = val;
}
CommandLineSwitchCase(arg, "rate")
{
@@ -961,14 +898,14 @@ BOOL audin_process_addin_args(AUDIN_PLUGIN* audin, ADDIN_ARGV* args)
if ((errno != 0) || (val < INT32_MIN) || (val > INT32_MAX))
return FALSE;
audin->fixed_rate = val;
audin->fixed_format->nSamplesPerSec = val;
}
CommandLineSwitchCase(arg, "channel")
{
unsigned long val = strtoul(arg->Value, NULL, 0);
if ((errno != 0) || (val > UINT16_MAX))
audin->fixed_channel = val;
audin->fixed_format->nChannels = val;
}
CommandLineSwitchDefault(arg)
{
@@ -1041,6 +978,10 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
audin->log = WLog_Get(TAG);
audin->data = Stream_New(NULL, 4096);
audin->fixed_format = audio_format_new();
if (!audin->fixed_format)
goto out;
if (!audin->data)
goto out;

View File

@@ -133,7 +133,7 @@ static UINT audin_mac_set_format(IAudinDevice* device, const AUDIO_FORMAT* forma
mac->FramesPerPacket = FramesPerPacket;
mac->format = *format;
WLog_INFO(TAG, "Audio Format %s [channels=%d, samples=%d, bits=%d]",
rdpsnd_get_audio_tag_string(format->wFormatTag),
audio_format_get_tag_string(format->wFormatTag),
format->nChannels, format->nSamplesPerSec, format->wBitsPerSample);
mac->audioFormat.mBitsPerChannel = format->wBitsPerSample;
@@ -169,6 +169,7 @@ static void mac_audio_queue_input_cb(void* aqData,
if (buffer_size > 0)
error = mac->receive(&mac->format, buffer, buffer_size, mac->user_data);
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
if (error)

View File

@@ -129,7 +129,7 @@ static BOOL audin_opensles_format_supported(IAudinDevice* device,
default:
WLog_Print(opensles->log, WLOG_DEBUG, "Encoding '%s' [0x%04X"PRIX16"] not supported",
rdpsnd_get_audio_tag_string(format->wFormatTag),
audio_format_get_tag_string(format->wFormatTag),
format->wFormatTag);
break;
}

View File

@@ -70,7 +70,7 @@ typedef struct _audin_server
* @return 0 on success, otherwise a Win32 error code
*/
static UINT audin_server_select_format(audin_server_context* context,
int client_format_index)
size_t client_format_index)
{
audin_server* audin = (audin_server*) context;
@@ -81,7 +81,7 @@ static UINT audin_server_select_format(audin_server_context* context,
return ERROR_INVALID_DATA;
}
context->selected_client_format = client_format_index;
context->selected_client_format = (SSIZE_T)client_format_index;
if (!freerdp_dsp_context_reset(audin->dsp_context,
&audin->context.client_formats[client_format_index]))
@@ -154,8 +154,7 @@ static UINT audin_server_recv_version(audin_server* audin, wStream* s,
*/
static UINT audin_server_send_formats(audin_server* audin, wStream* s)
{
int i;
UINT32 nAvgBytesPerSec;
size_t i;
ULONG written;
Stream_SetPosition(s, 0);
Stream_Write_UINT8(s, MSG_SNDIN_FORMATS);
@@ -166,35 +165,15 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s)
for (i = 0; i < audin->context.num_server_formats; i++)
{
nAvgBytesPerSec = audin->context.server_formats[i].nSamplesPerSec *
audin->context.server_formats[i].nChannels *
audin->context.server_formats[i].wBitsPerSample / 8;
AUDIO_FORMAT format = audin->context.server_formats[i];
// TODO: Eliminate this
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nChannels * format.wBitsPerSample / 8;
if (!Stream_EnsureRemainingCapacity(s, 18))
if (!audio_format_write(s, &format))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write_UINT16(s, audin->context.server_formats[i].wFormatTag);
Stream_Write_UINT16(s, audin->context.server_formats[i].nChannels);
Stream_Write_UINT32(s, audin->context.server_formats[i].nSamplesPerSec);
Stream_Write_UINT32(s, nAvgBytesPerSec);
Stream_Write_UINT16(s, audin->context.server_formats[i].nBlockAlign);
Stream_Write_UINT16(s, audin->context.server_formats[i].wBitsPerSample);
Stream_Write_UINT16(s, audin->context.server_formats[i].cbSize);
if (audin->context.server_formats[i].cbSize)
{
if (!Stream_EnsureRemainingCapacity(s, audin->context.server_formats[i].cbSize))
{
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
return CHANNEL_RC_NO_MEMORY;
}
Stream_Write(s, audin->context.server_formats[i].data,
audin->context.server_formats[i].cbSize);
}
}
return WTSVirtualChannelWrite(audin->audin_channel, (PCHAR) Stream_Buffer(s),
@@ -209,7 +188,7 @@ static UINT audin_server_send_formats(audin_server* audin, wStream* s)
static UINT audin_server_recv_formats(audin_server* audin, wStream* s,
UINT32 length)
{
int i;
size_t i;
UINT success = CHANNEL_RC_OK;
if (length < 8)
@@ -231,34 +210,24 @@ static UINT audin_server_recv_formats(audin_server* audin, wStream* s,
return ERROR_INVALID_DATA;
}
audin->context.client_formats = calloc(audin->context.num_client_formats,
sizeof(AUDIO_FORMAT));
audin->context.client_formats = audio_formats_new(audin->context.num_client_formats);
if (!audin->context.client_formats)
return ERROR_NOT_ENOUGH_MEMORY;
for (i = 0; i < audin->context.num_client_formats; i++)
{
if (length < 18)
AUDIO_FORMAT* format = &audin->context.client_formats[i];
if (!audio_format_read(s, format))
{
free(audin->context.client_formats);
audio_formats_free(audin->context.client_formats, i);
audin->context.client_formats = NULL;
WLog_ERR(TAG, "expected length at least 18, but got %"PRIu32"", length);
return ERROR_INVALID_DATA;
}
Stream_Read_UINT16(s, audin->context.client_formats[i].wFormatTag);
Stream_Read_UINT16(s, audin->context.client_formats[i].nChannels);
Stream_Read_UINT32(s, audin->context.client_formats[i].nSamplesPerSec);
Stream_Seek_UINT32(s); /* nAvgBytesPerSec */
Stream_Read_UINT16(s, audin->context.client_formats[i].nBlockAlign);
Stream_Read_UINT16(s, audin->context.client_formats[i].wBitsPerSample);
Stream_Read_UINT16(s, audin->context.client_formats[i].cbSize);
if (audin->context.client_formats[i].cbSize > 0)
{
Stream_Seek(s, audin->context.client_formats[i].cbSize);
}
audio_format_print(WLog_Get(TAG), WLOG_DEBUG, format);
}
IFCALLRET(audin->context.Opening, success, &audin->context);
@@ -366,11 +335,15 @@ static UINT audin_server_recv_data(audin_server* audin, wStream* s,
if (freerdp_dsp_decode(audin->dsp_context, format, Stream_Pointer(s), length, out))
{
AUDIO_FORMAT dformat = *format;
dformat.wFormatTag = WAVE_FORMAT_PCM;
dformat.wBitsPerSample = 16;
Stream_SealLength(out);
Stream_SetPosition(out, 0);
sbytes_per_sample = format->wBitsPerSample / 8;
sbytes_per_frame = format->nChannels * sbytes_per_sample;
frames = Stream_Length(out) / sbytes_per_frame;
IFCALLRET(audin->context.ReceiveSamples, success, &audin->context, Stream_Buffer(out), frames);
IFCALLRET(audin->context.ReceiveSamples, success, &audin->context, &dformat, out, frames);
if (success)
WLog_ERR(TAG, "context.ReceiveSamples failed with error %"PRIu32"", success);
@@ -701,11 +674,13 @@ audin_server_context* audin_server_context_new(HANDLE vcm)
void audin_server_context_free(audin_server_context* context)
{
audin_server* audin = (audin_server*) context;
if (!audin)
return;
audin_server_close(context);
if (audin->dsp_context)
freerdp_dsp_context_free(audin->dsp_context);
free(audin->context.client_formats);
freerdp_dsp_context_free(audin->dsp_context);
audio_formats_free(audin->context.client_formats, audin->context.num_client_formats);
audio_formats_free(audin->context.server_formats, audin->context.num_server_formats);
free(audin);
}

View File

@@ -109,7 +109,7 @@ static BOOL rdpsnd_mac_set_format(rdpsndDevicePlugin* device, const AUDIO_FORMAT
return FALSE;
}
rdpsnd_print_audio_format(format);
audio_format_print(WLog_Get(TAG), WLOG_DEBUG, format);
return TRUE;
}

View File

@@ -86,9 +86,7 @@ struct rdpsnd_plugin
UINT32 latency;
BOOL isOpen;
UINT16 fixedFormat;
UINT16 fixedChannel;
UINT32 fixedRate;
AUDIO_FORMAT* fixed_format;
char* subsystem;
char* device_name;
@@ -139,16 +137,14 @@ static UINT rdpsnd_send_quality_mode_pdu(rdpsndPlugin* rdpsnd)
static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
{
UINT16 index;
rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats);
audio_formats_free(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats);
rdpsnd->NumberOfClientFormats = 0;
rdpsnd->ClientFormats = NULL;
if (!rdpsnd->NumberOfServerFormats)
return;
rdpsnd->ClientFormats = (AUDIO_FORMAT*) calloc(
rdpsnd->NumberOfServerFormats,
sizeof(AUDIO_FORMAT));
rdpsnd->ClientFormats = audio_formats_new(rdpsnd->NumberOfServerFormats);
if (!rdpsnd->ClientFormats)
return;
@@ -157,29 +153,14 @@ static void rdpsnd_select_supported_audio_formats(rdpsndPlugin* rdpsnd)
{
const AUDIO_FORMAT* serverFormat = &rdpsnd->ServerFormats[index];
if ((rdpsnd->fixedFormat > 0) &&
(rdpsnd->fixedFormat != serverFormat->wFormatTag))
continue;
if ((rdpsnd->fixedChannel > 0) &&
(rdpsnd->fixedChannel != serverFormat->nChannels))
continue;
if ((rdpsnd->fixedRate > 0) &&
(rdpsnd->fixedRate != serverFormat->nSamplesPerSec))
if (!audio_format_compatible(rdpsnd->fixed_format, serverFormat))
continue;
if (freerdp_dsp_supports_format(serverFormat, FALSE) ||
rdpsnd->device->FormatSupported(rdpsnd->device, serverFormat))
{
AUDIO_FORMAT* clientFormat = &rdpsnd->ClientFormats[rdpsnd->NumberOfClientFormats++];
*clientFormat = *serverFormat;
if (serverFormat->cbSize > 0)
{
clientFormat->data = (BYTE*) malloc(serverFormat->cbSize);
CopyMemory(clientFormat->data, serverFormat->data, serverFormat->cbSize);
}
audio_format_copy(serverFormat, clientFormat);
}
}
}
@@ -226,16 +207,12 @@ static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd)
for (index = 0; index < wNumberOfFormats; index++)
{
const AUDIO_FORMAT* clientFormat = &rdpsnd->ClientFormats[index];
Stream_Write_UINT16(pdu, clientFormat->wFormatTag);
Stream_Write_UINT16(pdu, clientFormat->nChannels);
Stream_Write_UINT32(pdu, clientFormat->nSamplesPerSec);
Stream_Write_UINT32(pdu, clientFormat->nAvgBytesPerSec);
Stream_Write_UINT16(pdu, clientFormat->nBlockAlign);
Stream_Write_UINT16(pdu, clientFormat->wBitsPerSample);
Stream_Write_UINT16(pdu, clientFormat->cbSize);
if (clientFormat->cbSize > 0)
Stream_Write(pdu, clientFormat->data, clientFormat->cbSize);
if (!audio_format_write(pdu, clientFormat))
{
Stream_Free(pdu, TRUE);
return ERROR_INTERNAL_ERROR;
}
}
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Client Audio Formats");
@@ -254,7 +231,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd,
UINT16 wVersion;
UINT16 wNumberOfFormats;
UINT ret = ERROR_BAD_LENGTH;
rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
rdpsnd->NumberOfServerFormats = 0;
rdpsnd->ServerFormats = NULL;
@@ -275,8 +252,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd,
if (Stream_GetRemainingLength(s) / 14 < wNumberOfFormats)
return ERROR_BAD_LENGTH;
rdpsnd->ServerFormats = (AUDIO_FORMAT*) calloc(wNumberOfFormats,
sizeof(AUDIO_FORMAT));
rdpsnd->ServerFormats = audio_formats_new(wNumberOfFormats);
if (!rdpsnd->ServerFormats)
return CHANNEL_RC_NO_MEMORY;
@@ -285,32 +261,8 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd,
{
AUDIO_FORMAT* format = &rdpsnd->ServerFormats[index];
if (Stream_GetRemainingLength(s) < 14)
if (!audio_format_read(s, format))
goto out_fail;
Stream_Read_UINT16(s, format->wFormatTag); /* wFormatTag */
Stream_Read_UINT16(s, format->nChannels); /* nChannels */
Stream_Read_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */
Stream_Read_UINT32(s, format->nAvgBytesPerSec); /* nAvgBytesPerSec */
Stream_Read_UINT16(s, format->nBlockAlign); /* nBlockAlign */
Stream_Read_UINT16(s, format->wBitsPerSample); /* wBitsPerSample */
Stream_Read_UINT16(s, format->cbSize); /* cbSize */
if (format->cbSize > 0)
{
if (Stream_GetRemainingLength(s) < format->cbSize)
goto out_fail;
format->data = (BYTE*) malloc(format->cbSize);
if (!format->data)
{
ret = CHANNEL_RC_NO_MEMORY;
goto out_fail;
}
Stream_Read(s, format->data, format->cbSize);
}
}
rdpsnd_select_supported_audio_formats(rdpsnd);
@@ -325,7 +277,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd,
return ret;
out_fail:
rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
rdpsnd->ServerFormats = NULL;
rdpsnd->NumberOfServerFormats = 0;
return ret;
@@ -407,7 +359,7 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s,
rdpsnd->waveDataSize = BodySize - 8;
format = &rdpsnd->ClientFormats[wFormatNo];
WLog_Print(rdpsnd->log, WLOG_DEBUG, "WaveInfo: cBlockNo: %"PRIu8" wFormatNo: %"PRIu16" [%s]",
rdpsnd->cBlockNo, wFormatNo, rdpsnd_get_audio_tag_string(format->wFormatTag));
rdpsnd->cBlockNo, wFormatNo, audio_format_get_tag_string(format->wFormatTag));
if (!rdpsnd->isOpen || (wFormatNo != rdpsnd->wCurrentFormatNo))
{
@@ -799,7 +751,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
if ((errno != 0) || (val > UINT16_MAX))
return CHANNEL_RC_INITIALIZATION_ERROR;
rdpsnd->fixedFormat = val;
rdpsnd->fixed_format->wFormatTag = val;
}
CommandLineSwitchCase(arg, "rate")
{
@@ -808,7 +760,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
if ((errno != 0) || (val > UINT32_MAX))
return CHANNEL_RC_INITIALIZATION_ERROR;
rdpsnd->fixedRate = val;
rdpsnd->fixed_format->nSamplesPerSec = val;
}
CommandLineSwitchCase(arg, "channel")
{
@@ -817,7 +769,7 @@ static UINT rdpsnd_process_addin_args(rdpsndPlugin* rdpsnd, ADDIN_ARGV* args)
if ((errno != 0) || (val > UINT16_MAX))
return CHANNEL_RC_INITIALIZATION_ERROR;
rdpsnd->fixedChannel = val;
rdpsnd->fixed_format->nChannels = val;
}
CommandLineSwitchCase(arg, "latency")
{
@@ -1225,10 +1177,10 @@ static UINT rdpsnd_virtual_channel_event_disconnected(rdpsndPlugin* rdpsnd)
StreamPool_Return(rdpsnd->pool, rdpsnd->data_in);
StreamPool_Free(rdpsnd->pool);
Queue_Free(rdpsnd->queue);
rdpsnd_free_audio_formats(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats);
audio_formats_free(rdpsnd->ClientFormats, rdpsnd->NumberOfClientFormats);
rdpsnd->NumberOfClientFormats = 0;
rdpsnd->ClientFormats = NULL;
rdpsnd_free_audio_formats(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats);
rdpsnd->NumberOfServerFormats = 0;
rdpsnd->ServerFormats = NULL;
@@ -1245,6 +1197,7 @@ static void rdpsnd_virtual_channel_event_terminated(rdpsndPlugin* rdpsnd)
{
if (rdpsnd)
{
audio_format_free(rdpsnd->fixed_format);
free(rdpsnd->subsystem);
free(rdpsnd->device_name);
CloseHandle(rdpsnd->stopEvent);
@@ -1340,6 +1293,14 @@ BOOL VCAPITYPE VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS pEntryPoints, PVOID p
rdpsnd->rdpcontext = pEntryPointsEx->context;
}
rdpsnd->fixed_format = audio_format_new();
if (!rdpsnd->fixed_format)
{
free(rdpsnd);
return FALSE;
}
rdpsnd->log = WLog_Get("com.freerdp.channels.rdpsnd.client");
CopyMemory(&(rdpsnd->channelEntryPoints), pEntryPoints,
sizeof(CHANNEL_ENTRY_POINTS_FREERDP_EX));

View File

@@ -45,7 +45,7 @@ static UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
{
size_t pos;
UINT16 i;
BOOL status;
BOOL status = FALSE;
ULONG written;
Stream_Write_UINT8(s, SNDC_FORMATS);
Stream_Write_UINT8(s, 0);
@@ -61,25 +61,12 @@ static UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
for (i = 0; i < context->num_server_formats; i++)
{
Stream_Write_UINT16(s,
context->server_formats[i].wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */
Stream_Write_UINT16(s, context->server_formats[i].nChannels); /* nChannels */
Stream_Write_UINT32(s,
context->server_formats[i].nSamplesPerSec); /* nSamplesPerSec */
Stream_Write_UINT32(s, context->server_formats[i].nSamplesPerSec*
context->server_formats[i].nChannels*
context->server_formats[i].wBitsPerSample / 8); /* nAvgBytesPerSec */
Stream_Write_UINT16(s,
context->server_formats[i].nBlockAlign); /* nBlockAlign */
Stream_Write_UINT16(s,
context->server_formats[i].wBitsPerSample); /* wBitsPerSample */
Stream_Write_UINT16(s, context->server_formats[i].cbSize); /* cbSize */
AUDIO_FORMAT format = context->server_formats[i];
// TODO: Eliminate this!!!
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nChannels * format.wBitsPerSample / 8;
if (context->server_formats[i].cbSize > 0)
{
Stream_Write(s, context->server_formats[i].data,
context->server_formats[i].cbSize);
}
if (!audio_format_write(s, &format))
goto fail;
}
pos = Stream_GetPosition(s);
@@ -89,6 +76,7 @@ static UINT rdpsnd_server_send_formats(RdpsndServerContext* context, wStream* s)
status = WTSVirtualChannelWrite(context->priv->ChannelHandle,
(PCHAR) Stream_Buffer(s), Stream_GetPosition(s), &written);
Stream_SetPosition(s, 0);
fail:
return status ? CHANNEL_RC_OK : ERROR_INTERNAL_ERROR;
}
@@ -184,8 +172,7 @@ static UINT rdpsnd_server_recv_formats(RdpsndServerContext* context, wStream* s)
return ERROR_INTERNAL_ERROR;
}
context->client_formats = (AUDIO_FORMAT*)calloc(context->num_client_formats,
sizeof(AUDIO_FORMAT));
context->client_formats = audio_formats_new(context->num_client_formats);
if (!context->client_formats)
{
@@ -322,17 +309,18 @@ static UINT rdpsnd_server_select_format(RdpsndServerContext* context,
AUDIO_FORMAT* format;
UINT error = CHANNEL_RC_OK;
if (client_format_index < 0
|| client_format_index >= context->num_client_formats)
if ((client_format_index < 0)
|| (client_format_index >= context->num_client_formats)
|| (!context->src_format))
{
WLog_ERR(TAG, "index %d is not correct.", client_format_index);
return ERROR_INVALID_DATA;
}
EnterCriticalSection(&context->priv->lock);
context->priv->src_bytes_per_sample = context->src_format.wBitsPerSample / 8;
context->priv->src_bytes_per_sample = context->src_format->wBitsPerSample / 8;
context->priv->src_bytes_per_frame = context->priv->src_bytes_per_sample *
context->src_format.nChannels;
context->src_format->nChannels;
context->selected_client_format = client_format_index;
format = &context->client_formats[client_format_index];
@@ -346,7 +334,7 @@ static UINT rdpsnd_server_select_format(RdpsndServerContext* context,
if (context->latency <= 0)
context->latency = 50;
context->priv->out_frames = context->src_format.nSamplesPerSec *
context->priv->out_frames = context->src_format->nSamplesPerSec *
context->latency / 1000;
if (context->priv->out_frames < 1)

View File

@@ -20,6 +20,8 @@
#ifndef FREERDP_CODEC_AUDIO_H
#define FREERDP_CODEC_AUDIO_H
#include <winpr/wlog.h>
#include <freerdp/api.h>
#include <freerdp/types.h>
@@ -191,14 +193,24 @@ typedef struct AUDIO_FORMAT AUDIO_FORMAT;
extern "C" {
#endif
FREERDP_API UINT32 rdpsnd_compute_audio_time_length(const AUDIO_FORMAT* format, size_t size);
FREERDP_API UINT32 audio_format_compute_time_length(const AUDIO_FORMAT* format, size_t size);
FREERDP_API char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag);
FREERDP_API char* audio_format_get_tag_string(UINT16 wFormatTag);
FREERDP_API void rdpsnd_print_audio_format(const AUDIO_FORMAT* format);
FREERDP_API void rdpsnd_print_audio_formats(const AUDIO_FORMAT* formats, UINT16 count);
FREERDP_API void audio_format_print(wLog* log, DWORD level, const AUDIO_FORMAT* format);
FREERDP_API void audio_formats_print(wLog* log, DWORD level, const AUDIO_FORMAT* formats,
UINT16 count);
FREERDP_API void rdpsnd_free_audio_formats(AUDIO_FORMAT* formats, UINT16 count);
FREERDP_API BOOL audio_format_read(wStream* s, AUDIO_FORMAT* format);
FREERDP_API BOOL audio_format_write(wStream* s, const AUDIO_FORMAT* format);
FREERDP_API BOOL audio_format_copy(const AUDIO_FORMAT* srcFormat, AUDIO_FORMAT* dstFormat);
FREERDP_API BOOL audio_format_compatible(const AUDIO_FORMAT* with, const AUDIO_FORMAT* what);
FREERDP_API AUDIO_FORMAT* audio_format_new(void);
FREERDP_API AUDIO_FORMAT* audio_formats_new(size_t count);
FREERDP_API void audio_format_free(AUDIO_FORMAT* format);
FREERDP_API void audio_formats_free(AUDIO_FORMAT* formats, size_t count);
#ifdef __cplusplus
}

View File

@@ -28,15 +28,16 @@
typedef struct _audin_server_context audin_server_context;
typedef UINT(*psAudinServerSelectFormat)(audin_server_context* context, int client_format_index);
typedef UINT(*psAudinServerSelectFormat)(audin_server_context* context, size_t client_format_index);
typedef BOOL (*psAudinServerOpen)(audin_server_context* context);
typedef BOOL (*psAudinServerIsOpen)(audin_server_context* context);
typedef BOOL (*psAudinServerClose)(audin_server_context* context);
typedef UINT(*psAudinServerOpening)(audin_server_context* context);
typedef UINT(*psAudinServerOpenResult)(audin_server_context* context, UINT32 result);
typedef UINT(*psAudinServerReceiveSamples)(audin_server_context* context, const void* buf,
int nframes);
typedef UINT(*psAudinServerReceiveSamples)(audin_server_context* context,
const AUDIO_FORMAT* format, wStream* buf,
size_t nframes);
struct _audin_server_context
{
@@ -46,19 +47,19 @@ struct _audin_server_context
void* data;
/* Server supported formats. Set by server. */
const AUDIO_FORMAT* server_formats;
int num_server_formats;
AUDIO_FORMAT* server_formats;
size_t num_server_formats;
/* Server destination PCM audio format. Set by server. */
AUDIO_FORMAT dst_format;
AUDIO_FORMAT* dst_format;
/* Server preferred frames per packet. */
int frames_per_packet;
/* Client supported formats. */
AUDIO_FORMAT* client_formats;
int num_client_formats;
int selected_client_format;
size_t num_client_formats;
SSIZE_T selected_client_format;
/*** APIs called by the server. ***/
/**

View File

@@ -57,11 +57,11 @@ struct _rdpsnd_server_context
void* data;
/* Server supported formats. Set by server. */
const AUDIO_FORMAT* server_formats;
int num_server_formats;
AUDIO_FORMAT* server_formats;
size_t num_server_formats;
/* Server source PCM audio format. Set by server. */
AUDIO_FORMAT src_format;
AUDIO_FORMAT* src_format;
/* Server audio latency, or buffer size, in milli-seconds. Set by server. */
int latency;

View File

@@ -0,0 +1,31 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* FreeRDP Server Common
*
* Copyright 2018 Armin Novak <armin.novak@thincast.com>
* Copyright 2018 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_SERVER_COMMON_SERVER_H
#define FREERDP_SERVER_COMMON_SERVER_H
#include <winpr/wtypes.h>
#include <freerdp/api.h>
#include <freerdp/codec/audio.h>
FREERDP_API size_t server_audin_get_formats(AUDIO_FORMAT** dst_formats);
FREERDP_API size_t server_rdpsnd_get_formats(AUDIO_FORMAT** dst_formats);
#endif /* FREERDP_SERVER_COMMON_SERVER_H */

View File

@@ -63,7 +63,7 @@ typedef int (*pfnShadowSubsystemUninit)(rdpShadowSubsystem* subsystem);
typedef int (*pfnShadowSubsystemStart)(rdpShadowSubsystem* subsystem);
typedef int (*pfnShadowSubsystemStop)(rdpShadowSubsystem* subsystem);
typedef UINT32 (*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, UINT32 maxMonitors);
typedef UINT32(*pfnShadowEnumMonitors)(MONITOR_DEF* monitors, UINT32 maxMonitors);
typedef int (*pfnShadowAuthenticate)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client,
@@ -75,20 +75,20 @@ typedef void (*pfnShadowClientDisconnect)(rdpShadowSubsystem* subsystem,
typedef BOOL (*pfnShadowClientCapabilities)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client);
typedef int (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem,
typedef BOOL (*pfnShadowSynchronizeEvent)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT32 flags);
typedef int (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 code);
typedef int (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem,
typedef BOOL (*pfnShadowKeyboardEvent)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 code);
typedef BOOL (*pfnShadowUnicodeKeyboardEvent)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 code);
typedef int (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y);
typedef int (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem,
typedef BOOL (*pfnShadowMouseEvent)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y);
typedef BOOL (*pfnShadowExtendedMouseEvent)(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y);
typedef void (*pfnShadowChannelAudinServerReceiveSamples)(
rdpShadowSubsystem* subsystem, rdpShadowClient* client, const void* buf,
int nframes);
typedef BOOL (*pfnShadowChannelAudinServerReceiveSamples)(
rdpShadowSubsystem* subsystem, rdpShadowClient* client,
const AUDIO_FORMAT* format, wStream* buf, size_t nframes);
struct rdp_shadow_client
{
@@ -184,46 +184,43 @@ struct _RDP_SHADOW_ENTRY_POINTS
pfnShadowEnumMonitors EnumMonitors;
};
#define RDP_SHADOW_SUBSYSTEM_COMMON() \
RDP_SHADOW_ENTRY_POINTS ep; \
HANDLE event; \
int numMonitors; \
int captureFrameRate; \
int selectedMonitor; \
MONITOR_DEF monitors[16]; \
MONITOR_DEF virtualScreen; \
\
/* This event indicates that we have graphic change */ \
/* such as screen update and resize. It should not be */ \
/* used by subsystem implementation directly */ \
rdpShadowMultiClientEvent* updateEvent; \
\
wMessagePipe* MsgPipe; \
UINT32 pointerX; \
UINT32 pointerY; \
\
const AUDIO_FORMAT* rdpsndFormats; \
int nRdpsndFormats; \
const AUDIO_FORMAT* audinFormats; \
int nAudinFormats; \
\
pfnShadowSynchronizeEvent SynchronizeEvent; \
pfnShadowKeyboardEvent KeyboardEvent; \
pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent; \
pfnShadowMouseEvent MouseEvent; \
pfnShadowExtendedMouseEvent ExtendedMouseEvent; \
pfnShadowChannelAudinServerReceiveSamples AudinServerReceiveSamples; \
\
pfnShadowAuthenticate Authenticate; \
pfnShadowClientConnect ClientConnect; \
pfnShadowClientDisconnect ClientDisconnect; \
pfnShadowClientCapabilities ClientCapabilities; \
\
rdpShadowServer* server
struct rdp_shadow_subsystem
{
RDP_SHADOW_SUBSYSTEM_COMMON();
RDP_SHADOW_ENTRY_POINTS ep;
HANDLE event;
int numMonitors;
int captureFrameRate;
int selectedMonitor;
MONITOR_DEF monitors[16];
MONITOR_DEF virtualScreen;
/* This event indicates that we have graphic change */
/* such as screen update and resize. It should not be */
/* used by subsystem implementation directly */
rdpShadowMultiClientEvent* updateEvent;
wMessagePipe* MsgPipe;
UINT32 pointerX;
UINT32 pointerY;
AUDIO_FORMAT* rdpsndFormats;
size_t nRdpsndFormats;
AUDIO_FORMAT* audinFormats;
size_t nAudinFormats;
pfnShadowSynchronizeEvent SynchronizeEvent;
pfnShadowKeyboardEvent KeyboardEvent;
pfnShadowUnicodeKeyboardEvent UnicodeKeyboardEvent;
pfnShadowMouseEvent MouseEvent;
pfnShadowExtendedMouseEvent ExtendedMouseEvent;
pfnShadowChannelAudinServerReceiveSamples AudinServerReceiveSamples;
pfnShadowAuthenticate Authenticate;
pfnShadowClientConnect ClientConnect;
pfnShadowClientDisconnect ClientDisconnect;
pfnShadowClientCapabilities ClientCapabilities;
rdpShadowServer* server;
};
/* Definition of message between subsystem and clients */
@@ -232,13 +229,11 @@ struct rdp_shadow_subsystem
typedef struct _SHADOW_MSG_OUT SHADOW_MSG_OUT;
typedef void (*MSG_OUT_FREE_FN)(UINT32 id,
SHADOW_MSG_OUT* msg); /* function to free SHADOW_MSG_OUT */
#define RDP_SHADOW_MSG_OUT_COMMON() \
int refCount; \
MSG_OUT_FREE_FN Free
struct _SHADOW_MSG_OUT
{
RDP_SHADOW_MSG_OUT_COMMON();
int refCount;
MSG_OUT_FREE_FN Free;
};
#define SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID 2001
@@ -248,16 +243,16 @@ struct _SHADOW_MSG_OUT
struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
{
RDP_SHADOW_MSG_OUT_COMMON();
SHADOW_MSG_OUT common;
UINT32 xPos;
UINT32 yPos;
};
typedef struct _SHADOW_MSG_OUT_POINTER_POSITION_UPDATE
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
SHADOW_MSG_OUT_POINTER_POSITION_UPDATE;
struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
{
RDP_SHADOW_MSG_OUT_COMMON();
SHADOW_MSG_OUT common;
UINT32 xHot;
UINT32 yHot;
UINT32 width;
@@ -268,22 +263,22 @@ struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
BYTE* andMaskData;
};
typedef struct _SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE
SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE;
struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
{
RDP_SHADOW_MSG_OUT_COMMON();
AUDIO_FORMAT audio_format;
SHADOW_MSG_OUT common;
AUDIO_FORMAT* audio_format;
void* buf;
int nFrames;
UINT16 wTimestamp;
};
typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES
SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
SHADOW_MSG_OUT_AUDIO_OUT_SAMPLES;
struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME
{
RDP_SHADOW_MSG_OUT_COMMON();
SHADOW_MSG_OUT common;
int left;
int right;
};

View File

@@ -28,7 +28,7 @@
#define TAG FREERDP_TAG("codec")
UINT32 rdpsnd_compute_audio_time_length(const AUDIO_FORMAT* format, size_t size)
UINT32 audio_format_compute_time_length(const AUDIO_FORMAT* format, size_t size)
{
UINT32 mstime;
UINT32 wSamples;
@@ -59,19 +59,19 @@ UINT32 rdpsnd_compute_audio_time_length(const AUDIO_FORMAT* format, size_t size)
}
else
{
WLog_ERR(TAG, "rdpsnd_compute_audio_time_length: invalid WAVE_FORMAT_GSM610 format");
WLog_ERR(TAG, "audio_format_compute_time_length: invalid WAVE_FORMAT_GSM610 format");
}
}
else
{
WLog_ERR(TAG, "rdpsnd_compute_audio_time_length: unknown format %"PRIu16"", format->wFormatTag);
WLog_ERR(TAG, "audio_format_compute_time_length: unknown format %"PRIu16"", format->wFormatTag);
}
}
return mstime;
}
char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag)
char* audio_format_get_tag_string(UINT16 wFormatTag)
{
switch (wFormatTag)
{
@@ -112,45 +112,184 @@ char* rdpsnd_get_audio_tag_string(UINT16 wFormatTag)
return "WAVE_FORMAT_UNKNOWN";
}
void rdpsnd_print_audio_format(const AUDIO_FORMAT* format)
void audio_format_print(wLog* log, DWORD level, const AUDIO_FORMAT* format)
{
WLog_INFO(TAG, "%s:\t wFormatTag: 0x%04"PRIX16" nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" "
"nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16"",
rdpsnd_get_audio_tag_string(format->wFormatTag), format->wFormatTag,
format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec,
format->nBlockAlign, format->wBitsPerSample, format->cbSize);
WLog_Print(log, level,
"%s:\t wFormatTag: 0x%04"PRIX16" nChannels: %"PRIu16" nSamplesPerSec: %"PRIu32" "
"nAvgBytesPerSec: %"PRIu32" nBlockAlign: %"PRIu16" wBitsPerSample: %"PRIu16" cbSize: %"PRIu16"",
audio_format_get_tag_string(format->wFormatTag), format->wFormatTag,
format->nChannels, format->nSamplesPerSec, format->nAvgBytesPerSec,
format->nBlockAlign, format->wBitsPerSample, format->cbSize);
}
void rdpsnd_print_audio_formats(const AUDIO_FORMAT* formats, UINT16 count)
void audio_formats_print(wLog* log, DWORD level, const AUDIO_FORMAT* formats, UINT16 count)
{
UINT16 index;
const AUDIO_FORMAT* format;
if (formats)
{
WLog_INFO(TAG, "AUDIO_FORMATS (%"PRIu16") ={", count);
WLog_Print(log, level, "AUDIO_FORMATS (%"PRIu16") ={", count);
for (index = 0; index < count; index++)
{
format = &formats[index];
WLog_ERR(TAG, "\t");
rdpsnd_print_audio_format(format);
WLog_Print(log, level, "\t");
audio_format_print(log, level, format);
}
WLog_ERR(TAG, "}");
WLog_Print(log, level, "}");
}
}
void rdpsnd_free_audio_formats(AUDIO_FORMAT* formats, UINT16 count)
BOOL audio_format_read(wStream* s, AUDIO_FORMAT* format)
{
UINT16 index;
if (!s || !format)
return FALSE;
if (Stream_GetRemainingLength(s) < 18)
return FALSE;
Stream_Read_UINT16(s, format->wFormatTag);
Stream_Read_UINT16(s, format->nChannels);
Stream_Read_UINT32(s, format->nSamplesPerSec);
Stream_Read_UINT32(s, format->nAvgBytesPerSec);
Stream_Read_UINT16(s, format->nBlockAlign);
Stream_Read_UINT16(s, format->wBitsPerSample);
Stream_Read_UINT16(s, format->cbSize);
if (Stream_GetRemainingLength(s) < format->cbSize)
return FALSE;
format->data = NULL;
if (format->cbSize > 0)
{
format->data = malloc(format->cbSize);
if (!format->data)
return FALSE;
Stream_Read(s, format->data, format->cbSize);
}
return TRUE;
}
BOOL audio_format_write(wStream* s, const AUDIO_FORMAT* format)
{
if (!s || !format)
return FALSE;
if (!Stream_EnsureRemainingCapacity(s, 18 + format->cbSize))
return FALSE;
Stream_Write_UINT16(s, format->wFormatTag); /* wFormatTag (WAVE_FORMAT_PCM) */
Stream_Write_UINT16(s, format->nChannels); /* nChannels */
Stream_Write_UINT32(s, format->nSamplesPerSec); /* nSamplesPerSec */
Stream_Write_UINT32(s, format->nAvgBytesPerSec); /* nAvgBytesPerSec */
Stream_Write_UINT16(s, format->nBlockAlign); /* nBlockAlign */
Stream_Write_UINT16(s, format->wBitsPerSample); /* wBitsPerSample */
Stream_Write_UINT16(s, format->cbSize); /* cbSize */
if (format->cbSize > 0)
Stream_Write(s, format->data, format->cbSize);
return TRUE;
}
BOOL audio_format_copy(const AUDIO_FORMAT* srcFormat, AUDIO_FORMAT* dstFormat)
{
if (!srcFormat || !dstFormat)
return FALSE;
*dstFormat = *srcFormat;
if (srcFormat->cbSize > 0)
{
dstFormat->data = malloc(srcFormat->cbSize);
if (!dstFormat->data)
return FALSE;
memcpy(dstFormat->data, srcFormat->data, dstFormat->cbSize);
}
return TRUE;
}
BOOL audio_format_compatible(const AUDIO_FORMAT* with, const AUDIO_FORMAT* what)
{
if (!with || !what)
return FALSE;
if (with->wFormatTag != WAVE_FORMAT_UNKNOWN)
{
if (with->wFormatTag != what->wFormatTag)
return FALSE;
}
if (with->nChannels != 0)
{
if (with->nChannels != what->nChannels)
return FALSE;
}
if (with->nSamplesPerSec != 0)
{
if (with->nSamplesPerSec != what->nSamplesPerSec)
return FALSE;
}
if (with->wBitsPerSample != 0)
{
if (with->wBitsPerSample != what->wBitsPerSample)
return FALSE;
}
return TRUE;
}
BOOL audio_format_valid(const AUDIO_FORMAT* format)
{
if (!format)
return FALSE;
if (format->nChannels == 0)
return FALSE;
if (format->nSamplesPerSec == 0)
return FALSE;
return TRUE;
}
AUDIO_FORMAT* audio_format_new(void)
{
return audio_formats_new(1);
}
AUDIO_FORMAT* audio_formats_new(size_t count)
{
return calloc(count, sizeof(AUDIO_FORMAT));
}
void audio_format_free(AUDIO_FORMAT* format)
{
if (format)
free(format->data);
}
void audio_formats_free(AUDIO_FORMAT* formats, size_t count)
{
size_t index;
if (formats)
{
for (index = 0; index < count; index++)
{
AUDIO_FORMAT* format = &formats[index];
free(format->data);
audio_format_free(format);
}
free(formats);

View File

@@ -91,7 +91,7 @@ static enum AVCodecID ffmpeg_get_avcodec(const AUDIO_FORMAT* format)
if (!format)
return AV_CODEC_ID_NONE;
id = rdpsnd_get_audio_tag_string(format->wFormatTag);
id = audio_format_get_tag_string(format->wFormatTag);
switch (format->wFormatTag)
{

View File

@@ -27,15 +27,10 @@
#include "mf_audin.h"
#include <freerdp/server/server-common.h>
#include <freerdp/log.h>
#define TAG SERVER_TAG("mac")
static const AUDIO_FORMAT supported_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
/**
* Function description
*
@@ -73,13 +68,9 @@ void mf_peer_audin_init(mfPeerContext* context)
context->audin = audin_server_context_new(context->vcm);
context->audin->rdpcontext = &context->_p;
context->audin->data = context;
context->audin->server_formats = supported_audio_formats;
context->audin->num_server_formats = sizeof(supported_audio_formats) / sizeof(
supported_audio_formats[0]);
context->audin->dst_format.wFormatTag = 1;
context->audin->dst_format.nChannels = 2;
context->audin->dst_format.nSamplesPerSec = 44100;
context->audin->dst_format.wBitsPerSample = 16;
context->audin->num_server_formats = server_audin_get_formats(&context->audin->server_formats);
if (context->audin->num_server_formats > 0)
context->audin->dst_format = &context->audin->server_formats[0];
context->audin->Opening = mf_peer_audin_opening;
context->audin->OpenResult = mf_peer_audin_open_result;
context->audin->ReceiveSamples = mf_peer_audin_receive_samples;

View File

@@ -29,17 +29,12 @@
#include "mf_rdpsnd.h"
#include <winpr/sysinfo.h>
#include <freerdp/server/server-common.h>
#include <freerdp/log.h>
#define TAG SERVER_TAG("mac")
AQRecorderState recorderState;
static const AUDIO_FORMAT supported_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
static void mf_peer_rdpsnd_activated(RdpsndServerContext* context)
{
OSStatus status;
@@ -145,13 +140,11 @@ BOOL mf_peer_rdpsnd_init(mfPeerContext* context)
context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->rdpcontext = &context->_p;
context->rdpsnd->data = context;
context->rdpsnd->server_formats = supported_audio_formats;
context->rdpsnd->num_server_formats = sizeof(supported_audio_formats) / sizeof(
supported_audio_formats[0]);
context->rdpsnd->src_format.wFormatTag = 1;
context->rdpsnd->src_format.nChannels = 2;
context->rdpsnd->src_format.nSamplesPerSec = 44100;
context->rdpsnd->src_format.wBitsPerSample = 16;
context->rdpsnd->num_server_formats = server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
if (context->rdpsnd->num_server_formats > 0)
context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
context->rdpsnd->Activated = mf_peer_rdpsnd_activated;
context->rdpsnd->Initialize(context->rdpsnd, TRUE);
return TRUE;

View File

@@ -32,12 +32,6 @@
#include <freerdp/log.h>
#define TAG SERVER_TAG("sample")
static const AUDIO_FORMAT test_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
/**
* Function description
*
@@ -67,7 +61,8 @@ static UINT sf_peer_audin_open_result(audin_server_context* context, UINT32 resu
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT sf_peer_audin_receive_samples(audin_server_context* context, const void* buf, int nframes)
static UINT sf_peer_audin_receive_samples(audin_server_context* context, const void* buf,
int nframes)
{
WLog_DBG(TAG, "AUDIN receive %d frames.", nframes);
return CHANNEL_RC_OK;
@@ -78,15 +73,10 @@ void sf_peer_audin_init(testPeerContext* context)
context->audin = audin_server_context_new(context->vcm);
context->audin->rdpcontext = &context->_p;
context->audin->data = context;
context->audin->num_server_formats = server_audin_get_formats(&context->audin->server_formats);
context->audin->server_formats = test_audio_formats;
context->audin->num_server_formats =
sizeof(test_audio_formats) / sizeof(test_audio_formats[0]);
context->audin->dst_format.wFormatTag = 1;
context->audin->dst_format.nChannels = 2;
context->audin->dst_format.nSamplesPerSec = 44100;
context->audin->dst_format.wBitsPerSample = 16;
if (context->audin->num_server_formats > 0)
context->audin->dst_format = &context->audin->server_formats[0];
context->audin->Opening = sf_peer_audin_opening;
context->audin->OpenResult = sf_peer_audin_open_result;

View File

@@ -28,15 +28,10 @@
#include "sf_rdpsnd.h"
#include <freerdp/server/server-common.h>
#include <freerdp/log.h>
#define TAG SERVER_TAG("sample")
static const AUDIO_FORMAT test_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
static void sf_peer_rdpsnd_activated(RdpsndServerContext* context)
{
WLog_DBG(TAG, "RDPSND Activated");
@@ -47,15 +42,10 @@ BOOL sf_peer_rdpsnd_init(testPeerContext* context)
context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->rdpcontext = &context->_p;
context->rdpsnd->data = context;
context->rdpsnd->num_server_formats = server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
context->rdpsnd->server_formats = test_audio_formats;
context->rdpsnd->num_server_formats =
sizeof(test_audio_formats) / sizeof(test_audio_formats[0]);
context->rdpsnd->src_format.wFormatTag = 1;
context->rdpsnd->src_format.nChannels = 2;
context->rdpsnd->src_format.nSamplesPerSec = 44100;
context->rdpsnd->src_format.wBitsPerSample = 16;
if (context->rdpsnd->num_server_formats > 0)
context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
context->rdpsnd->Activated = sf_peer_rdpsnd_activated;

View File

@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <winpr/windows.h>
#include <freerdp/server/server-common.h>
#include "wf_rdpsnd.h"
#include "wf_info.h"
@@ -42,19 +43,11 @@
#define TAG SERVER_TAG("windows")
static const AUDIO_FORMAT supported_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
static void wf_peer_rdpsnd_activated(RdpsndServerContext* context)
{
wfInfo* wfi;
int i, j;
wfi = wf_info_get_instance();
wfi->agreed_format = NULL;
WLog_DBG(TAG, "Client supports the following %d formats:", context->num_client_formats);
@@ -72,56 +65,48 @@ static void wf_peer_rdpsnd_activated(RdpsndServerContext* context)
break;
}
}
if (wfi->agreed_format != NULL)
break;
}
if (wfi->agreed_format == NULL)
{
WLog_ERR(TAG, "Could not agree on a audio format with the server");
return;
}
context->SelectFormat(context, i);
context->SetVolume(context, 0x7FFF, 0x7FFF);
#ifdef WITH_RDPSND_DSOUND
wf_directsound_activate(context);
#else
wf_wasapi_activate(context);
#endif
}
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_ABANDONED:
case WAIT_OBJECT_0:
return TRUE;
break;
case WAIT_TIMEOUT:
return FALSE;
break;
case WAIT_TIMEOUT:
return FALSE;
break;
case WAIT_FAILED:
WLog_ERR(TAG, "wf_rdpsnd_lock failed with 0x%08lX", GetLastError());
return -1;
break;
case WAIT_FAILED:
WLog_ERR(TAG, "wf_rdpsnd_lock failed with 0x%08lX", GetLastError());
return -1;
break;
}
return -1;
@@ -130,7 +115,6 @@ int wf_rdpsnd_lock()
int wf_rdpsnd_unlock()
{
wfInfo* wfi;
wfi = wf_info_get_instance();
if (ReleaseMutex(wfi->snd_mutex) == 0)
@@ -145,7 +129,7 @@ int wf_rdpsnd_unlock()
BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
{
wfInfo* wfi = wf_info_get_instance();
if (!wfi)
return FALSE;
@@ -155,22 +139,14 @@ BOOL wf_peer_rdpsnd_init(wfPeerContext* context)
context->rdpsnd = rdpsnd_server_context_new(context->vcm);
context->rdpsnd->rdpcontext = &context->_p;
context->rdpsnd->data = context;
context->rdpsnd->num_server_formats = server_rdpsnd_get_formats(&context->rdpsnd->server_formats);
context->rdpsnd->server_formats = supported_audio_formats;
context->rdpsnd->num_server_formats =
sizeof(supported_audio_formats) / sizeof(supported_audio_formats[0]);
context->rdpsnd->src_format.wFormatTag = 1;
context->rdpsnd->src_format.nChannels = 2;
context->rdpsnd->src_format.nSamplesPerSec = 44100;
context->rdpsnd->src_format.wBitsPerSample = 16;
if (context->rdpsnd->num_server_formats > 0)
context->rdpsnd->src_format = &context->rdpsnd->server_formats[0];
context->rdpsnd->Activated = wf_peer_rdpsnd_activated;
context->rdpsnd->Initialize(context->rdpsnd, TRUE);
wf_rdpsnd_set_latest_peer(context);
wfi->snd_stop = FALSE;
return TRUE;
}

View File

@@ -21,3 +21,154 @@
#include "config.h"
#endif
#include <winpr/wtypes.h>
#include <freerdp/codec/audio.h>
#include <freerdp/codec/dsp.h>
#include <freerdp/server/server-common.h>
size_t server_audin_get_formats(AUDIO_FORMAT** dst_formats)
{
/* Default supported audio formats */
BYTE adpcm_data_7[] =
{
0xf4, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00,
0x00, 0x00, 0xcc, 0x01, 0x30, 0xff, 0x88, 0x01, 0x18, 0xff
};
BYTE adpcm_data_3[] =
{
0xf4, 0x03, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00,
0x00, 0x00, 0xcc, 0x01, 0x30, 0xff, 0x88, 0x01, 0x18, 0xff
};
BYTE adpcm_data_1[] =
{
0xf4, 0x01, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
0xff, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00,
0x00, 0x00, 0xcc, 0x01, 0x30, 0xff, 0x88, 0x01, 0x18, 0xff
};
BYTE adpcm_dvi_data_7[] = { 0xf9, 0x07 };
BYTE adpcm_dvi_data_3[] = { 0xf9, 0x03 };
BYTE adpcm_dvi_data_1[] = { 0xf9, 0x01 };
BYTE gsm610_data[] = { 0x40, 0x01 };
const AUDIO_FORMAT default_supported_audio_formats[] =
{
/* Formats sent by windows 10 server */
{ WAVE_FORMAT_AAC_MS, 2, 44100, 24000, 4, 16, 0, NULL },
{ WAVE_FORMAT_AAC_MS, 2, 44100, 20000, 4, 16, 0, NULL },
{ WAVE_FORMAT_AAC_MS, 2, 44100, 16000, 4, 16, 0, NULL },
{ WAVE_FORMAT_AAC_MS, 2, 44100, 12000, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ADPCM, 2, 44100, 44359, 2048, 4, 32, adpcm_data_7 },
{ WAVE_FORMAT_DVI_ADPCM, 2, 44100, 44251, 2048, 4, 2, adpcm_dvi_data_7 },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
{ WAVE_FORMAT_ADPCM, 2, 22050, 22311, 1024, 4, 32, adpcm_data_3 },
{ WAVE_FORMAT_DVI_ADPCM, 2, 22050, 22201, 1024, 4, 2, adpcm_dvi_data_3 },
{ WAVE_FORMAT_ADPCM, 1, 44100, 22179, 1024, 4, 32, adpcm_data_7 },
{ WAVE_FORMAT_DVI_ADPCM, 1, 44100, 22125, 1024, 4, 2, adpcm_dvi_data_7 },
{ WAVE_FORMAT_ADPCM, 2, 11025, 11289, 512, 4, 32, adpcm_data_1 },
{ WAVE_FORMAT_DVI_ADPCM, 2, 11025, 11177, 512, 4, 2, adpcm_dvi_data_1 },
{ WAVE_FORMAT_ADPCM, 1, 22050, 11155, 512, 4, 32, adpcm_data_3 },
{ WAVE_FORMAT_DVI_ADPCM, 1, 22050, 11100, 512, 4, 2, adpcm_dvi_data_3 },
{ WAVE_FORMAT_GSM610, 1, 44100, 8957, 65, 0, 2, gsm610_data },
{ WAVE_FORMAT_ADPCM, 2, 8000, 8192, 512, 4, 32, adpcm_data_1 },
{ WAVE_FORMAT_DVI_ADPCM, 2, 8000, 8110, 512, 4, 2, adpcm_dvi_data_1 },
{ WAVE_FORMAT_ADPCM, 1, 11025, 5644, 256, 4, 32, adpcm_data_1 },
{ WAVE_FORMAT_DVI_ADPCM, 1, 11025, 5588, 256, 4, 2, adpcm_dvi_data_1 },
{ WAVE_FORMAT_GSM610, 1, 22050, 4478, 65, 0, 2, gsm610_data },
{ WAVE_FORMAT_ADPCM, 1, 8000, 4096, 256, 4, 32, adpcm_data_1 },
{ WAVE_FORMAT_DVI_ADPCM, 1, 8000, 4055, 256, 4, 2, adpcm_dvi_data_1 },
{ WAVE_FORMAT_GSM610, 1, 11025, 2239, 65, 0, 2, gsm610_data },
{ WAVE_FORMAT_GSM610, 1, 8000, 1625, 65, 0, 2, gsm610_data },
/* Formats added for others */
{ WAVE_FORMAT_MSG723, 2, 44100, 0, 4, 16, 0, NULL },
{ WAVE_FORMAT_MSG723, 2, 22050, 0, 4, 16, 0, NULL },
{ WAVE_FORMAT_MSG723, 1, 44100, 0, 4, 16, 0, NULL },
{ WAVE_FORMAT_MSG723, 1, 22050, 0, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 2, 22050, 88200, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 1, 44100, 88200, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 1, 22050, 44100, 4, 16, 0, NULL },
{ WAVE_FORMAT_MULAW, 2, 44100, 88200, 4, 16, 0, NULL },
{ WAVE_FORMAT_MULAW, 2, 22050, 44100, 4, 16, 0, NULL },
{ WAVE_FORMAT_MULAW, 1, 44100, 44100, 4, 16, 0, NULL },
{ WAVE_FORMAT_MULAW, 1, 22050, 22050, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 44100, 88200, 2, 8, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
{ WAVE_FORMAT_ALAW, 1, 44100, 44100, 2, 8, 0, NULL },
{ WAVE_FORMAT_ALAW, 1, 22050, 22050, 2, 8, 0, NULL }
};
const size_t nrDefaultFormatsMax = ARRAYSIZE(default_supported_audio_formats);
size_t x, nr_formats = 0;
AUDIO_FORMAT* formats = audio_formats_new(nrDefaultFormatsMax);
if (!dst_formats)
goto fail;
*dst_formats = NULL;
if (!formats)
goto fail;
for (x = 0; x < nrDefaultFormatsMax; x++)
{
const AUDIO_FORMAT* format = &default_supported_audio_formats[x];
if (freerdp_dsp_supports_format(format, FALSE))
{
AUDIO_FORMAT* dst = &formats[nr_formats++];
if (!audio_format_copy(format, dst))
goto fail;
}
}
*dst_formats = formats;
return nr_formats;
fail:
audio_formats_free(formats, nrDefaultFormatsMax);
return 0;
}
size_t server_rdpsnd_get_formats(AUDIO_FORMAT** dst_formats)
{
size_t x, y = 0;
/* Default supported audio formats */
static const AUDIO_FORMAT default_supported_audio_formats[] =
{
{ WAVE_FORMAT_AAC_MS, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_MPEGLAYER3, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_MSG723, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_GSM610, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ADPCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
{ WAVE_FORMAT_MULAW, 2, 22050, 44100, 2, 8, 0, NULL },
};
AUDIO_FORMAT* supported_audio_formats = audio_formats_new(ARRAYSIZE(
default_supported_audio_formats));
if (!supported_audio_formats)
goto fail;
for (x = 0; x < ARRAYSIZE(default_supported_audio_formats); x++)
{
const AUDIO_FORMAT* format = &default_supported_audio_formats[x];
if (freerdp_dsp_supports_format(format, TRUE))
supported_audio_formats[y++] = *format;
}
/* Set default audio formats. */
*dst_formats = supported_audio_formats;
fail:
audio_formats_free(supported_audio_formats, ARRAYSIZE(default_supported_audio_formats));
if (dst_formats)
*dst_formats = NULL;
return 0;
}

View File

@@ -32,12 +32,16 @@
static macShadowSubsystem* g_Subsystem = NULL;
static void mac_shadow_input_synchronize_event(macShadowSubsystem* subsystem,
static BOOL mac_shadow_input_synchronize_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT32 flags)
{
if (!subsystem || !client)
return FALSE;
return TRUE;
}
static void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem,
static BOOL mac_shadow_input_keyboard_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 code)
{
DWORD vkcode;
@@ -47,6 +51,9 @@ static void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem,
CGEventSourceRef source;
extended = (flags & KBD_FLAGS_EXTENDED) ? TRUE : FALSE;
if (!subsystem || !client)
return FALSE;
if (extended)
code |= KBDEXT;
@@ -58,7 +65,7 @@ static void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem,
keycode = GetKeycodeFromVirtualKeyCode(vkcode, KEYCODE_TYPE_APPLE);
if (keycode < 8)
return;
return TRUE;
keycode -= 8;
source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
@@ -77,20 +84,29 @@ static void mac_shadow_input_keyboard_event(macShadowSubsystem* subsystem,
}
CFRelease(source);
return TRUE;
}
static void mac_shadow_input_unicode_keyboard_event(macShadowSubsystem*
static BOOL mac_shadow_input_unicode_keyboard_event(rdpShadowSubsystem*
subsystem, rdpShadowClient* client, UINT16 flags, UINT16 code)
{
if (!subsystem || !client)
return FALSE;
return TRUE;
}
static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
static BOOL mac_shadow_input_mouse_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
{
macShadowSubsystem* mac = (macShadowSubsystem*)subsystem;
UINT32 scrollX = 0;
UINT32 scrollY = 0;
CGWheelCount wheelCount = 2;
if (!subsystem || !client)
return FALSE;
if (flags & PTR_FLAGS_WHEEL)
{
scrollY = flags & WheelRotationMask;
@@ -122,11 +138,11 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
if (flags & PTR_FLAGS_MOVE)
{
if (subsystem->mouseDownLeft)
if (mac->mouseDownLeft)
mouseType = kCGEventLeftMouseDragged;
else if (subsystem->mouseDownRight)
else if (mac->mouseDownRight)
mouseType = kCGEventRightMouseDragged;
else if (subsystem->mouseDownOther)
else if (mac->mouseDownOther)
mouseType = kCGEventOtherMouseDragged;
else
mouseType = kCGEventMouseMoved;
@@ -144,12 +160,12 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
if (flags & PTR_FLAGS_DOWN)
{
mouseType = kCGEventLeftMouseDown;
subsystem->mouseDownLeft = TRUE;
mac->mouseDownLeft = TRUE;
}
else
{
mouseType = kCGEventLeftMouseUp;
subsystem->mouseDownLeft = FALSE;
mac->mouseDownLeft = FALSE;
}
}
else if (flags & PTR_FLAGS_BUTTON2)
@@ -159,12 +175,12 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
if (flags & PTR_FLAGS_DOWN)
{
mouseType = kCGEventRightMouseDown;
subsystem->mouseDownRight = TRUE;
mac->mouseDownRight = TRUE;
}
else
{
mouseType = kCGEventRightMouseUp;
subsystem->mouseDownRight = FALSE;
mac->mouseDownRight = FALSE;
}
}
else if (flags & PTR_FLAGS_BUTTON3)
@@ -174,12 +190,12 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
if (flags & PTR_FLAGS_DOWN)
{
mouseType = kCGEventOtherMouseDown;
subsystem->mouseDownOther = TRUE;
mac->mouseDownOther = TRUE;
}
else
{
mouseType = kCGEventOtherMouseUp;
subsystem->mouseDownOther = FALSE;
mac->mouseDownOther = FALSE;
}
}
@@ -189,11 +205,17 @@ static void mac_shadow_input_mouse_event(macShadowSubsystem* subsystem,
CFRelease(mouseEvent);
CFRelease(source);
}
return TRUE;
}
static void mac_shadow_input_extended_mouse_event(macShadowSubsystem* subsystem,
static BOOL mac_shadow_input_extended_mouse_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
{
if (!subsystem || !client)
return FALSE;
return TRUE;
}
static int mac_shadow_detect_monitors(macShadowSubsystem* subsystem)
@@ -221,8 +243,8 @@ static int mac_shadow_detect_monitors(macShadowSubsystem* subsystem)
subsystem->height = subsystem->pixelHeight;
}
subsystem->numMonitors = 1;
monitor = &(subsystem->monitors[0]);
subsystem->common.numMonitors = 1;
monitor = &(subsystem->common.monitors[0]);
monitor->left = 0;
monitor->top = 0;
monitor->right = subsystem->width;
@@ -259,7 +281,7 @@ static int mac_shadow_capture_get_dirty_region(macShadowSubsystem* subsystem)
size_t numRects;
const CGRect* rects;
RECTANGLE_16 invalidRect;
rdpShadowSurface* surface = subsystem->server->surface;
rdpShadowSurface* surface = subsystem->common.server->surface;
rects = CGDisplayStreamUpdateGetRects(subsystem->lastUpdate,
kCGDisplayStreamUpdateDirtyRects, &numRects);
@@ -359,7 +381,7 @@ static void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t,
RECTANGLE_16 surfaceRect;
const RECTANGLE_16* extents;
macShadowSubsystem* subsystem = g_Subsystem;
rdpShadowServer* server = subsystem->server;
rdpShadowServer* server = subsystem->common.server;
rdpShadowSurface* surface = server->surface;
count = ArrayList_Count(server->clients);
@@ -401,7 +423,7 @@ static void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t,
ArrayList_Lock(server->clients);
count = ArrayList_Count(server->clients);
EnterCriticalSection(&(surface->lock));
shadow_subsystem_frame_update((rdpShadowSubsystem*)subsystem);
shadow_subsystem_frame_update(&subsystem->common);
LeaveCriticalSection(&(surface->lock));
if (count == 1)
@@ -411,7 +433,7 @@ static void (^mac_capture_stream_handler)(CGDisplayStreamFrameStatus, uint64_t,
if (client)
{
subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
subsystem->common.captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
}
}
@@ -477,7 +499,7 @@ static int mac_shadow_screen_grab(macShadowSubsystem* subsystem)
static int mac_shadow_subsystem_process_message(macShadowSubsystem* subsystem,
wMessage* message)
{
rdpShadowServer* server = subsystem->server;
rdpShadowServer* server = subsystem->common.server;
rdpShadowSurface* surface = server->surface;
switch (message->id)
@@ -511,11 +533,11 @@ static DWORD WINAPI mac_shadow_subsystem_thread(LPVOID arg)
HANDLE events[32];
wMessage message;
wMessagePipe* MsgPipe;
MsgPipe = subsystem->MsgPipe;
MsgPipe = subsystem->common.MsgPipe;
nCount = 0;
events[nCount++] = MessageQueue_Event(MsgPipe->In);
subsystem->captureFrameRate = 16;
dwInterval = 1000 / subsystem->captureFrameRate;
subsystem->common.captureFrameRate = 16;
dwInterval = 1000 / subsystem->common.captureFrameRate;
frameTime = GetTickCount64() + dwInterval;
while (1)
@@ -538,7 +560,7 @@ static DWORD WINAPI mac_shadow_subsystem_thread(LPVOID arg)
if ((status == WAIT_TIMEOUT) || (GetTickCount64() > frameTime))
{
mac_shadow_screen_grab(subsystem);
dwInterval = 1000 / subsystem->captureFrameRate;
dwInterval = 1000 / subsystem->common.captureFrameRate;
frameTime += dwInterval;
}
}
@@ -636,15 +658,11 @@ static macShadowSubsystem* mac_shadow_subsystem_new(void)
if (!subsystem)
return NULL;
subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent)
mac_shadow_input_synchronize_event;
subsystem->KeyboardEvent = (pfnShadowKeyboardEvent)
mac_shadow_input_keyboard_event;
subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent)
mac_shadow_input_unicode_keyboard_event;
subsystem->MouseEvent = (pfnShadowMouseEvent) mac_shadow_input_mouse_event;
subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent)
mac_shadow_input_extended_mouse_event;
subsystem->common.SynchronizeEvent = mac_shadow_input_synchronize_event;
subsystem->common.KeyboardEvent = mac_shadow_input_keyboard_event;
subsystem->common.UnicodeKeyboardEvent = mac_shadow_input_unicode_keyboard_event;
subsystem->common.MouseEvent = mac_shadow_input_mouse_event;
subsystem->common.ExtendedMouseEvent = mac_shadow_input_extended_mouse_event;
return subsystem;
}

View File

@@ -37,7 +37,7 @@ typedef struct mac_shadow_subsystem macShadowSubsystem;
struct mac_shadow_subsystem
{
RDP_SHADOW_SUBSYSTEM_COMMON();
rdpShadowSubsystem common;
int width;
int height;

View File

@@ -162,7 +162,7 @@ static int x11_shadow_pam_get_service_name(SHADOW_PAM_AUTH_INFO* info)
return 1;
}
static int x11_shadow_pam_authenticate(x11ShadowSubsystem* subsystem,
static int x11_shadow_pam_authenticate(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, const char* user, const char* domain,
const char* password)
{
@@ -219,19 +219,24 @@ static int x11_shadow_pam_authenticate(x11ShadowSubsystem* subsystem,
#endif
static void x11_shadow_input_synchronize_event(x11ShadowSubsystem* subsystem,
static BOOL x11_shadow_input_synchronize_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT32 flags)
{
return TRUE;
}
static void x11_shadow_input_keyboard_event(x11ShadowSubsystem* subsystem,
static BOOL x11_shadow_input_keyboard_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 code)
{
#ifdef WITH_XTEST
x11ShadowSubsystem* x11 = (x11ShadowSubsystem*)subsystem;
DWORD vkcode;
DWORD keycode;
BOOL extended = FALSE;
if (!client || !subsystem)
return FALSE;
if (flags & KBD_FLAGS_EXTENDED)
extended = TRUE;
@@ -247,43 +252,58 @@ static void x11_shadow_input_keyboard_event(x11ShadowSubsystem* subsystem,
if (keycode != 0)
{
XLockDisplay(subsystem->display);
XTestGrabControl(subsystem->display, True);
XLockDisplay(x11->display);
XTestGrabControl(x11->display, True);
if (flags & KBD_FLAGS_DOWN)
XTestFakeKeyEvent(subsystem->display, keycode, True, CurrentTime);
XTestFakeKeyEvent(x11->display, keycode, True, CurrentTime);
else if (flags & KBD_FLAGS_RELEASE)
XTestFakeKeyEvent(subsystem->display, keycode, False, CurrentTime);
XTestFakeKeyEvent(x11->display, keycode, False, CurrentTime);
XTestGrabControl(subsystem->display, False);
XFlush(subsystem->display);
XUnlockDisplay(subsystem->display);
XTestGrabControl(x11->display, False);
XFlush(x11->display);
XUnlockDisplay(x11->display);
}
#endif
return TRUE;
}
static void x11_shadow_input_unicode_keyboard_event(x11ShadowSubsystem*
static BOOL x11_shadow_input_unicode_keyboard_event(rdpShadowSubsystem*
subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 code)
{
return TRUE;
}
static void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem,
static BOOL x11_shadow_input_mouse_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
{
#ifdef WITH_XTEST
x11ShadowSubsystem* x11 = (x11ShadowSubsystem*)subsystem;
int button = 0;
BOOL down = FALSE;
rdpShadowServer* server;
rdpShadowSurface* surface;
if (!subsystem || !client)
return FALSE;
server = subsystem->server;
if (!server)
return FALSE;
surface = server->surface;
subsystem->lastMouseClient = client;
if (!surface)
return FALSE;
x11->lastMouseClient = client;
x += surface->x;
y += surface->y;
XLockDisplay(subsystem->display);
XTestGrabControl(subsystem->display, True);
XLockDisplay(x11->display);
XTestGrabControl(x11->display, True);
if (flags & PTR_FLAGS_WHEEL)
{
@@ -293,13 +313,13 @@ static void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem,
negative = TRUE;
button = (negative) ? 5 : 4;
XTestFakeButtonEvent(subsystem->display, button, True, CurrentTime);
XTestFakeButtonEvent(subsystem->display, button, False, CurrentTime);
XTestFakeButtonEvent(x11->display, button, True, CurrentTime);
XTestFakeButtonEvent(x11->display, button, False, CurrentTime);
}
else
{
if (flags & PTR_FLAGS_MOVE)
XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime);
XTestFakeMotionEvent(x11->display, 0, x, y, CurrentTime);
if (flags & PTR_FLAGS_BUTTON1)
button = 1;
@@ -312,31 +332,45 @@ static void x11_shadow_input_mouse_event(x11ShadowSubsystem* subsystem,
down = TRUE;
if (button)
XTestFakeButtonEvent(subsystem->display, button, down, CurrentTime);
XTestFakeButtonEvent(x11->display, button, down, CurrentTime);
}
XTestGrabControl(subsystem->display, False);
XFlush(subsystem->display);
XUnlockDisplay(subsystem->display);
XTestGrabControl(x11->display, False);
XFlush(x11->display);
XUnlockDisplay(x11->display);
#endif
return TRUE;
}
static void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem,
static BOOL x11_shadow_input_extended_mouse_event(rdpShadowSubsystem* subsystem,
rdpShadowClient* client, UINT16 flags, UINT16 x, UINT16 y)
{
#ifdef WITH_XTEST
x11ShadowSubsystem* x11 = (x11ShadowSubsystem*)subsystem;
int button = 0;
BOOL down = FALSE;
rdpShadowServer* server;
rdpShadowSurface* surface;
if (!subsystem || !client)
return FALSE;
server = subsystem->server;
if (!server)
return FALSE;
surface = server->surface;
subsystem->lastMouseClient = client;
if (!surface)
return FALSE;
x11->lastMouseClient = client;
x += surface->x;
y += surface->y;
XLockDisplay(subsystem->display);
XTestGrabControl(subsystem->display, True);
XTestFakeMotionEvent(subsystem->display, 0, x, y, CurrentTime);
XLockDisplay(x11->display);
XTestGrabControl(x11->display, True);
XTestFakeMotionEvent(x11->display, 0, x, y, CurrentTime);
if (flags & PTR_XFLAGS_BUTTON1)
button = 8;
@@ -347,12 +381,13 @@ static void x11_shadow_input_extended_mouse_event(x11ShadowSubsystem* subsystem,
down = TRUE;
if (button)
XTestFakeButtonEvent(subsystem->display, button, down, CurrentTime);
XTestFakeButtonEvent(x11->display, button, down, CurrentTime);
XTestGrabControl(subsystem->display, False);
XFlush(subsystem->display);
XUnlockDisplay(subsystem->display);
XTestGrabControl(x11->display, False);
XFlush(x11->display);
XUnlockDisplay(x11->display);
#endif
return TRUE;
}
static void x11_shadow_message_free(UINT32 id, SHADOW_MSG_OUT* msg)
@@ -384,13 +419,13 @@ static int x11_shadow_pointer_position_update(x11ShadowSubsystem* subsystem)
int count = 0;
int index = 0;
if (!subsystem || !subsystem->server || !subsystem->server->clients)
if (!subsystem || !subsystem->common.server || !subsystem->common.server->clients)
return -1;
templateMsg.xPos = subsystem->pointerX;
templateMsg.yPos = subsystem->pointerY;
templateMsg.Free = x11_shadow_message_free;
server = subsystem->server;
templateMsg.xPos = subsystem->common.pointerX;
templateMsg.yPos = subsystem->common.pointerY;
templateMsg.common.Free = x11_shadow_message_free;
server = subsystem->common.server;
ArrayList_Lock(server->clients);
for (index = 0; index < ArrayList_Count(server->clients); index++)
@@ -443,8 +478,8 @@ static int x11_shadow_pointer_alpha_update(x11ShadowSubsystem* subsystem)
return -1;
}
msg->Free = x11_shadow_message_free;
return shadow_client_boardcast_msg(subsystem->server, NULL, msgId,
msg->common.Free = x11_shadow_message_free;
return shadow_client_boardcast_msg(subsystem->common.server, NULL, msgId,
(SHADOW_MSG_OUT*) msg, NULL) ? 1 : -1;
}
@@ -453,7 +488,7 @@ static int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage)
int x = 0, y = 0, n, k;
rdpShadowServer* server;
rdpShadowSurface* surface;
server = subsystem->server;
server = subsystem->common.server;
surface = server->surface;
if (getImage)
@@ -522,10 +557,10 @@ static int x11_shadow_query_cursor(x11ShadowSubsystem* subsystem, BOOL getImage)
y -= surface->y;
}
if ((x != subsystem->pointerX) || (y != subsystem->pointerY))
if ((x != subsystem->common.pointerX) || (y != subsystem->common.pointerY))
{
subsystem->pointerX = x;
subsystem->pointerY = y;
subsystem->common.pointerX = x;
subsystem->common.pointerY = y;
x11_shadow_pointer_position_update(subsystem);
}
@@ -594,13 +629,13 @@ static int x11_shadow_blend_cursor(x11ShadowSubsystem* subsystem)
if (!subsystem)
return -1;
surface = subsystem->server->surface;
surface = subsystem->common.server->surface;
nXSrc = 0;
nYSrc = 0;
nWidth = subsystem->cursorWidth;
nHeight = subsystem->cursorHeight;
nXDst = subsystem->pointerX - subsystem->cursorHotX;
nYDst = subsystem->pointerY - subsystem->cursorHotY;
nXDst = subsystem->common.pointerX - subsystem->cursorHotX;
nYDst = subsystem->common.pointerY - subsystem->cursorHotY;
if (nXDst >= surface->width)
return 1;
@@ -687,11 +722,11 @@ static BOOL x11_shadow_check_resize(x11ShadowSubsystem* subsystem)
if (attr.width != subsystem->width || attr.height != subsystem->height)
{
/* Screen size changed. Refresh monitor definitions and trigger screen resize */
subsystem->numMonitors = x11_shadow_enum_monitors(subsystem->monitors, 16);
shadow_screen_resize(subsystem->server->screen);
subsystem->common.numMonitors = x11_shadow_enum_monitors(subsystem->common.monitors, 16);
shadow_screen_resize(subsystem->common.server->screen);
subsystem->width = attr.width;
subsystem->height = attr.height;
virtualScreen = &(subsystem->virtualScreen);
virtualScreen = &(subsystem->common.virtualScreen);
virtualScreen->left = 0;
virtualScreen->top = 0;
virtualScreen->right = subsystem->width;
@@ -732,7 +767,7 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
RECTANGLE_16 invalidRect;
RECTANGLE_16 surfaceRect;
const RECTANGLE_16* extents;
server = subsystem->server;
server = subsystem->common.server;
surface = server->surface;
count = ArrayList_Count(server->clients);
@@ -815,7 +850,7 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
client = (rdpShadowClient*) ArrayList_GetItem(server->clients, 0);
if (client)
subsystem->captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
subsystem->common.captureFrameRate = shadow_encoder_preferred_fps(client->encoder);
}
region16_clear(&(surface->invalidRegion));
@@ -870,12 +905,12 @@ static DWORD WINAPI x11_shadow_subsystem_thread(LPVOID arg)
HANDLE events[32];
wMessage message;
wMessagePipe* MsgPipe;
MsgPipe = subsystem->MsgPipe;
MsgPipe = subsystem->common.MsgPipe;
nCount = 0;
events[nCount++] = subsystem->event;
events[nCount++] = subsystem->common.event;
events[nCount++] = MessageQueue_Event(MsgPipe->In);
subsystem->captureFrameRate = 16;
dwInterval = 1000 / subsystem->captureFrameRate;
subsystem->common.captureFrameRate = 16;
dwInterval = 1000 / subsystem->common.captureFrameRate;
frameTime = GetTickCount64() + dwInterval;
while (1)
@@ -895,7 +930,7 @@ static DWORD WINAPI x11_shadow_subsystem_thread(LPVOID arg)
}
}
if (WaitForSingleObject(subsystem->event, 0) == WAIT_OBJECT_0)
if (WaitForSingleObject(subsystem->common.event, 0) == WAIT_OBJECT_0)
{
XLockDisplay(subsystem->display);
@@ -913,7 +948,7 @@ static DWORD WINAPI x11_shadow_subsystem_thread(LPVOID arg)
x11_shadow_check_resize(subsystem);
x11_shadow_screen_grab(subsystem);
x11_shadow_query_cursor(subsystem, FALSE);
dwInterval = 1000 / subsystem->captureFrameRate;
dwInterval = 1000 / subsystem->common.captureFrameRate;
frameTime += dwInterval;
}
}
@@ -1198,7 +1233,7 @@ static int x11_shadow_subsystem_init(rdpShadowSubsystem* sub)
if (!subsystem)
return -1;
subsystem->numMonitors = x11_shadow_enum_monitors(subsystem->monitors, 16);
subsystem->common.numMonitors = x11_shadow_enum_monitors(subsystem->common.monitors, 16);
x11_shadow_subsystem_base_init(subsystem);
if ((subsystem->depth != 24) && (subsystem->depth != 32))
@@ -1304,11 +1339,11 @@ static int x11_shadow_subsystem_init(rdpShadowSubsystem* sub)
subsystem->use_xdamage = FALSE;
}
if (!(subsystem->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE,
subsystem->xfds, WINPR_FD_READ)))
if (!(subsystem->common.event = CreateFileDescriptorEvent(NULL, FALSE, FALSE,
subsystem->xfds, WINPR_FD_READ)))
return -1;
virtualScreen = &(subsystem->virtualScreen);
virtualScreen = &(subsystem->common.virtualScreen);
virtualScreen->left = 0;
virtualScreen->top = 0;
virtualScreen->right = subsystem->width;
@@ -1334,10 +1369,10 @@ static int x11_shadow_subsystem_uninit(rdpShadowSubsystem* sub)
subsystem->display = NULL;
}
if (subsystem->event)
if (subsystem->common.event)
{
CloseHandle(subsystem->event);
subsystem->event = NULL;
CloseHandle(subsystem->common.event);
subsystem->common.event = NULL;
}
if (subsystem->cursorPixels)
@@ -1375,7 +1410,7 @@ static int x11_shadow_subsystem_stop(rdpShadowSubsystem* sub)
if (subsystem->thread)
{
if (MessageQueue_PostQuit(subsystem->MsgPipe->In, 0))
if (MessageQueue_PostQuit(subsystem->common.MsgPipe->In, 0))
WaitForSingleObject(subsystem->thread, INFINITE);
CloseHandle(subsystem->thread);
@@ -1394,17 +1429,13 @@ static rdpShadowSubsystem* x11_shadow_subsystem_new(void)
return NULL;
#ifdef WITH_PAM
subsystem->Authenticate = (pfnShadowAuthenticate) x11_shadow_pam_authenticate;
subsystem->common.Authenticate = x11_shadow_pam_authenticate;
#endif
subsystem->SynchronizeEvent = (pfnShadowSynchronizeEvent)
x11_shadow_input_synchronize_event;
subsystem->KeyboardEvent = (pfnShadowKeyboardEvent)
x11_shadow_input_keyboard_event;
subsystem->UnicodeKeyboardEvent = (pfnShadowUnicodeKeyboardEvent)
x11_shadow_input_unicode_keyboard_event;
subsystem->MouseEvent = (pfnShadowMouseEvent) x11_shadow_input_mouse_event;
subsystem->ExtendedMouseEvent = (pfnShadowExtendedMouseEvent)
x11_shadow_input_extended_mouse_event;
subsystem->common.SynchronizeEvent = x11_shadow_input_synchronize_event;
subsystem->common.KeyboardEvent = x11_shadow_input_keyboard_event;
subsystem->common.UnicodeKeyboardEvent = x11_shadow_input_unicode_keyboard_event;
subsystem->common.MouseEvent = x11_shadow_input_mouse_event;
subsystem->common.ExtendedMouseEvent = x11_shadow_input_extended_mouse_event;
subsystem->composite = FALSE;
subsystem->use_xshm = FALSE; /* temporarily disabled */
subsystem->use_xfixes = TRUE;

View File

@@ -53,7 +53,7 @@ typedef struct x11_shadow_subsystem x11ShadowSubsystem;
struct x11_shadow_subsystem
{
RDP_SHADOW_SUBSYSTEM_COMMON();
rdpShadowSubsystem common;
HANDLE thread;

View File

@@ -21,19 +21,14 @@
#endif
#include <freerdp/log.h>
#include <freerdp/codec/dsp.h>
#include "shadow.h"
#include "shadow_audin.h"
#include <freerdp/server/server-common.h>
#define TAG SERVER_TAG("shadow")
/* Default supported audio formats */
static const AUDIO_FORMAT default_supported_audio_formats[] =
{
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL }
};
/**
* Function description
*
@@ -42,17 +37,15 @@ static const AUDIO_FORMAT default_supported_audio_formats[] =
static UINT AudinServerOpening(audin_server_context* context)
{
AUDIO_FORMAT* agreed_format = NULL;
int i = 0, j = 0;
size_t i = 0, j = 0;
for (i = 0; i < context->num_client_formats; i++)
{
for (j = 0; j < context->num_server_formats; j++)
{
if ((context->client_formats[i].wFormatTag == context->server_formats[j].wFormatTag) &&
(context->client_formats[i].nChannels == context->server_formats[j].nChannels) &&
(context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec))
if (audio_format_compatible(&context->server_formats[j], &context->client_formats[i]))
{
agreed_format = (AUDIO_FORMAT*) &context->server_formats[j];
agreed_format = &context->server_formats[j];
break;
}
}
@@ -67,8 +60,7 @@ static UINT AudinServerOpening(audin_server_context* context)
return CHANNEL_RC_OK;
}
context->SelectFormat(context, i);
return CHANNEL_RC_OK;
return IFCALLRESULT(ERROR_CALL_NOT_IMPLEMENTED, context->SelectFormat, context, i);
}
/**
* Function description
@@ -85,7 +77,8 @@ static UINT AudinServerOpenResult(audin_server_context* context, UINT32 result)
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT AudinServerReceiveSamples(audin_server_context* context, const void* buf, int nframes)
static UINT AudinServerReceiveSamples(audin_server_context* context, const AUDIO_FORMAT* format,
wStream* buf, size_t nframes)
{
rdpShadowClient* client = (rdpShadowClient*)context->data;
rdpShadowSubsystem* subsystem = client->server->subsystem;
@@ -93,42 +86,56 @@ static UINT AudinServerReceiveSamples(audin_server_context* context, const void*
if (!client->mayInteract)
return CHANNEL_RC_OK;
if (subsystem->AudinServerReceiveSamples)
subsystem->AudinServerReceiveSamples(subsystem, client, buf, nframes);
if (!IFCALLRESULT(TRUE, subsystem->AudinServerReceiveSamples, subsystem, client, format, buf,
nframes))
return ERROR_INTERNAL_ERROR;
return CHANNEL_RC_OK;
}
int shadow_client_audin_init(rdpShadowClient* client)
BOOL shadow_client_audin_init(rdpShadowClient* client)
{
audin_server_context* audin;
audin = client->audin = audin_server_context_new(client->vcm);
if (!audin)
{
return 0;
}
return FALSE;
audin->data = client;
if (client->subsystem->audinFormats)
{
audin->server_formats = client->subsystem->audinFormats;
size_t x;
audin->server_formats = audio_formats_new(client->subsystem->nAudinFormats);
if (!audin->server_formats)
goto fail;
for (x = 0; x < client->subsystem->nAudinFormats; x++)
{
if (!audio_format_copy(&client->subsystem->audinFormats[x], &audin->server_formats[x]))
goto fail;
}
audin->num_server_formats = client->subsystem->nAudinFormats;
}
else
{
/* Set default audio formats. */
audin->server_formats = default_supported_audio_formats;
audin->num_server_formats = sizeof(default_supported_audio_formats) / sizeof(
default_supported_audio_formats[0]);
audin->num_server_formats = server_audin_get_formats(&audin->server_formats);
}
audin->dst_format = audin->server_formats[0];
if (audin->num_server_formats < 1)
goto fail;
audin->dst_format = &audin->server_formats[0];
audin->Opening = AudinServerOpening;
audin->OpenResult = AudinServerOpenResult;
audin->ReceiveSamples = AudinServerReceiveSamples;
return 1;
return TRUE;
fail:
audin_server_context_free(audin);
client->audin = NULL;
return FALSE;
}
void shadow_client_audin_uninit(rdpShadowClient* client)

View File

@@ -28,7 +28,7 @@
extern "C" {
#endif
int shadow_client_audin_init(rdpShadowClient* client);
BOOL shadow_client_audin_init(rdpShadowClient* client);
void shadow_client_audin_uninit(rdpShadowClient* client);
#ifdef __cplusplus

View File

@@ -22,7 +22,7 @@
#include "shadow.h"
BOOL shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
static BOOL shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
{
rdpShadowClient* client = (rdpShadowClient*) input->context;
rdpShadowSubsystem* subsystem = client->server->subsystem;
@@ -30,29 +30,10 @@ BOOL shadow_input_synchronize_event(rdpInput* input, UINT32 flags)
if (!client->mayInteract)
return TRUE;
if (subsystem->SynchronizeEvent)
{
subsystem->SynchronizeEvent(subsystem, client, flags);
}
return TRUE;
return IFCALLRESULT(TRUE, subsystem->SynchronizeEvent, subsystem, client, flags);
}
BOOL shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{
rdpShadowClient* client = (rdpShadowClient*) input->context;
rdpShadowSubsystem* subsystem = client->server->subsystem;
if (!client->mayInteract)
return TRUE;
if (subsystem->KeyboardEvent)
{
subsystem->KeyboardEvent(subsystem, client, flags, code);
}
return TRUE;
}
BOOL shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
static BOOL shadow_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{
rdpShadowClient* client = (rdpShadowClient*) input->context;
rdpShadowSubsystem* subsystem = client->server->subsystem;
@@ -60,14 +41,21 @@ BOOL shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 c
if (!client->mayInteract)
return TRUE;
if (subsystem->UnicodeKeyboardEvent)
{
subsystem->UnicodeKeyboardEvent(subsystem, client, flags, code);
}
return TRUE;
return IFCALLRESULT(TRUE, subsystem->KeyboardEvent, subsystem, client, flags, code);
}
BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
static BOOL shadow_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{
rdpShadowClient* client = (rdpShadowClient*) input->context;
rdpShadowSubsystem* subsystem = client->server->subsystem;
if (!client->mayInteract)
return TRUE;
return IFCALLRESULT(TRUE, subsystem->UnicodeKeyboardEvent, subsystem, client, flags, code);
}
static BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
rdpShadowClient* client = (rdpShadowClient*) input->context;
rdpShadowSubsystem* subsystem = client->server->subsystem;
@@ -84,7 +72,7 @@ BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
client->pointerY = y;
if ((client->pointerX == subsystem->pointerX) &&
(client->pointerY == subsystem->pointerY))
(client->pointerY == subsystem->pointerY))
{
flags &= ~PTR_FLAGS_MOVE;
@@ -96,14 +84,10 @@ BOOL shadow_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
if (!client->mayInteract)
return TRUE;
if (subsystem->MouseEvent)
{
subsystem->MouseEvent(subsystem, client, flags, x, y);
}
return TRUE;
return IFCALLRESULT(TRUE, subsystem->MouseEvent, subsystem, client, flags, x, y);
}
BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
static BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
rdpShadowClient* client = (rdpShadowClient*) input->context;
rdpShadowSubsystem* subsystem = client->server->subsystem;
@@ -120,11 +104,7 @@ BOOL shadow_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x,
if (!client->mayInteract)
return TRUE;
if (subsystem->ExtendedMouseEvent)
{
subsystem->ExtendedMouseEvent(subsystem, client, flags, x, y);
}
return TRUE;
return IFCALLRESULT(TRUE, subsystem->ExtendedMouseEvent, subsystem, client, flags, x, y);
}
void shadow_input_register_callbacks(rdpInput* input)

View File

@@ -23,6 +23,7 @@
#include <winpr/crt.h>
#include <freerdp/log.h>
#include <freerdp/codec/dsp.h>
#include <freerdp/server/server-common.h>
#include "shadow.h"
@@ -30,31 +31,18 @@
#define TAG SERVER_TAG("shadow")
/* Default supported audio formats */
static const AUDIO_FORMAT default_supported_audio_formats[] =
{
{ WAVE_FORMAT_AAC_MS, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_MPEGLAYER3, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_GSM610, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_PCM, 2, 44100, 176400, 4, 16, 0, NULL },
{ WAVE_FORMAT_ALAW, 2, 22050, 44100, 2, 8, 0, NULL },
};
static AUDIO_FORMAT supported_audio_formats[ARRAYSIZE(default_supported_audio_formats)] = { 0 };
static void rdpsnd_activated(RdpsndServerContext* context)
{
AUDIO_FORMAT* agreed_format = NULL;
const AUDIO_FORMAT* agreed_format = NULL;
UINT16 i = 0, j = 0;
for (i = 0; i < context->num_client_formats; i++)
{
for (j = 0; j < context->num_server_formats; j++)
{
if ((context->client_formats[i].wFormatTag == context->server_formats[j].wFormatTag) &&
(context->client_formats[i].nChannels == context->server_formats[j].nChannels) &&
(context->client_formats[i].nSamplesPerSec == context->server_formats[j].nSamplesPerSec))
if (audio_format_compatible(&context->server_formats[j], &context->client_formats[i]))
{
agreed_format = (AUDIO_FORMAT*) &context->server_formats[j];
agreed_format = &context->server_formats[j];
break;
}
}
@@ -91,22 +79,12 @@ int shadow_client_rdpsnd_init(rdpShadowClient* client)
}
else
{
size_t x, y = 0;
for (x = 0; x < ARRAYSIZE(default_supported_audio_formats); x++)
{
const AUDIO_FORMAT* format = &default_supported_audio_formats[x];
if (freerdp_dsp_supports_format(format, TRUE))
supported_audio_formats[y++] = *format;
}
/* Set default audio formats. */
rdpsnd->server_formats = supported_audio_formats;
rdpsnd->num_server_formats = y;
rdpsnd->num_server_formats = server_rdpsnd_get_formats(&rdpsnd->server_formats);
}
rdpsnd->src_format = rdpsnd->server_formats[0];
if (rdpsnd->num_server_formats > 0)
rdpsnd->src_format = &rdpsnd->server_formats[0];
rdpsnd->Activated = rdpsnd_activated;
rdpsnd->Initialize(rdpsnd, TRUE);
return 1;