channels: refactoring of channel subsystems

This commit is contained in:
Marc-André Moreau 2012-11-19 22:31:15 -05:00
parent 83473d11d1
commit 2e1a7447a1
35 changed files with 533 additions and 313 deletions

View File

@ -77,7 +77,7 @@ macro(define_channel_client_subsystem _channel_name _subsystem _type)
if(_type_length GREATER 0)
set(SUBSYSTEM_TYPE ${_type})
set(MODULE_NAME "${CHANNEL_NAME}-client-${CHANNEL_SUBSYSTEM}-${SUBSYSTEM_TYPE}")
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}-${SUBSYSTEM_TYPE}" MODULE_PREFIX)
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}_${SUBSYSTEM_TYPE}" MODULE_PREFIX)
else()
set(MODULE_NAME "${CHANNEL_NAME}-client-${CHANNEL_SUBSYSTEM}")
string(TOUPPER "CHANNEL_${CHANNEL_NAME}_CLIENT_${CHANNEL_SUBSYSTEM}" MODULE_PREFIX)
@ -116,10 +116,19 @@ endmacro(add_channel_server)
macro(add_channel_client_subsystem _channel_prefix _channel_name _subsystem _type)
add_subdirectory(${_subsystem})
set(_channel_module_name "${_channel_name}-client")
string(LENGTH "${_type}" _type_length)
if(_type_length GREATER 0)
string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}_${_type}" _subsystem_prefix)
else()
string(TOUPPER "CHANNEL_${_channel_name}_CLIENT_${_subsystem}" _subsystem_prefix)
endif()
if(${${_subsystem_prefix}_STATIC})
get_target_property(CHANNEL_SUBSYSTEMS ${_channel_module_name} SUBSYSTEMS)
if(_type_length GREATER 0)
set(SUBSYSTEMS ${SUBSYSTEMS} "${_subsystem}-${_type}")
else()
set(SUBSYSTEMS ${SUBSYSTEMS} ${_subsystem})
endif()
set_target_properties(${_channel_module_name} PROPERTIES SUBSYSTEMS "${SUBSYSTEMS}")
endif()
endmacro(add_channel_client_subsystem)
@ -139,7 +148,7 @@ macro(add_channel_client_library _module_prefix _module_name _channel_name _dyna
endif()
endmacro(add_channel_client_library)
macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _dynamic _entry)
macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_name _type _dynamic _entry)
if(${_dynamic} AND MSVC AND (NOT STATIC_CHANNELS))
set(${_module_prefix}_SRCS ${${_module_prefix}_SRCS} module.def)
endif()
@ -148,6 +157,7 @@ macro(add_channel_client_subsystem_library _module_prefix _module_name _channel_
else()
set(${_module_prefix}_STATIC ON PARENT_SCOPE)
set(${_module_prefix}_NAME ${_module_name} PARENT_SCOPE)
set(${_module_prefix}_TYPE ${_type} PARENT_SCOPE)
add_library(${_module_name} STATIC ${${_module_prefix}_SRCS})
endif()
endmacro(add_channel_client_subsystem_library)

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${ALSA_INCLUDE_DIRS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -25,7 +25,12 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <alsa/asoundlib.h>
#include <freerdp/addin.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/dsp.h>
@ -36,7 +41,7 @@ typedef struct _AudinALSADevice
{
IAudinDevice iface;
char device_name[32];
char* device_name;
UINT32 frames_per_packet;
UINT32 target_rate;
UINT32 actual_rate;
@ -236,6 +241,9 @@ static void audin_alsa_free(IAudinDevice* device)
freerdp_thread_free(alsa->thread);
freerdp_dsp_context_free(alsa->dsp_context);
free(alsa->device_name);
free(alsa);
}
@ -328,40 +336,66 @@ static void audin_alsa_close(IAudinDevice* device)
alsa->user_data = NULL;
}
COMMAND_LINE_ARGUMENT_A audin_alsa_args[] =
{
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void audin_alsa_parse_addin_args(AudinALSADevice* device, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
AudinALSADevice* alsa = (AudinALSADevice*) device;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_alsa_args, flags, alsa, NULL, NULL);
arg = audin_alsa_args;
do
{
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "audio-dev")
{
alsa->device_name = _strdup(arg->Value);
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
#ifdef STATIC_CHANNELS
#define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry
#endif
int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV* args;
AudinALSADevice* alsa;
RDP_PLUGIN_DATA* data;
alsa = xnew(AudinALSADevice);
alsa = (AudinALSADevice*) malloc(sizeof(AudinALSADevice));
ZeroMemory(alsa, sizeof(AudinALSADevice));
alsa->iface.Open = audin_alsa_open;
alsa->iface.FormatSupported = audin_alsa_format_supported;
alsa->iface.SetFormat = audin_alsa_set_format;
alsa->iface.Close = audin_alsa_close;
alsa->iface.Free = audin_alsa_free;
alsa->device_name[0] = '\0';
data = pEntryPoints->plugin_data;
if (data)
{
char *data2 = (char *) (data->data[2]);
if (data->data[0] && (strcmp(data->data[0], "audin") == 0) &&
data->data[1] && (strcmp(data->data[1], "alsa") == 0) &&
data2 && (*data2 != '\0'))
{
strncpy(alsa->device_name, data2, sizeof(alsa->device_name));
}
}
args = pEntryPoints->args;
if (alsa->device_name[0] == '\0')
{
strcpy(alsa->device_name, "default");
}
audin_alsa_parse_addin_args(alsa, args);
if (!alsa->device_name)
alsa->device_name = _strdup("default");
alsa->frames_per_packet = 128;
alsa->target_rate = 22050;
@ -378,4 +412,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
return 0;
}

View File

@ -25,6 +25,9 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/addin.h>
#include <freerdp/utils/memory.h>
@ -78,6 +81,8 @@ struct _AUDIN_PLUGIN
UINT16 fixed_format;
UINT16 fixed_channel;
UINT32 fixed_rate;
char* subsystem;
char* device_name;
/* Device interface */
IAudinDevice* device;
@ -437,7 +442,7 @@ static void audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* devi
audin->device = device;
}
static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_PLUGIN_DATA* data)
static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, ADDIN_ARGV* args)
{
PFREERDP_AUDIN_DEVICE_ENTRY entry;
FREERDP_AUDIN_DEVICE_ENTRY_POINTS entryPoints;
@ -449,7 +454,7 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_
entryPoints.plugin = pPlugin;
entryPoints.pRegisterAudinDevice = audin_register_device_plugin;
entryPoints.plugin_data = data;
entryPoints.args = args;
if (entry(&entryPoints) != 0)
{
@ -460,54 +465,81 @@ static BOOL audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_
return TRUE;
}
static BOOL audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
void audin_set_subsystem(AUDIN_PLUGIN* audin, char* subsystem)
{
BOOL ret;
if (audin->subsystem)
free(audin->subsystem);
audin->subsystem = _strdup(subsystem);
}
void audin_set_device_name(AUDIN_PLUGIN* audin, char* device_name)
{
if (audin->device_name)
free(audin->device_name);
audin->device_name = _strdup(device_name);
}
COMMAND_LINE_ARGUMENT_A audin_args[] =
{
{ "sys", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "subsystem" },
{ "dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "device" },
{ "format", COMMAND_LINE_VALUE_REQUIRED, "<format>", NULL, NULL, -1, NULL, "format" },
{ "rate", COMMAND_LINE_VALUE_REQUIRED, "<rate>", NULL, NULL, -1, NULL, "rate" },
{ "channel", COMMAND_LINE_VALUE_REQUIRED, "<channel>", NULL, NULL, -1, NULL, "channel" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static BOOL audin_process_addin_args(IWTSPlugin* pPlugin, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin;
RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } };
if (data->data[0] && (strcmp((char*)data->data[0], "audin") == 0 || strstr((char*) data->data[0], "/audin.") != NULL))
{
if (data->data[1] && strcmp((char*)data->data[1], "format") == 0)
{
audin->fixed_format = atoi(data->data[2]);
return TRUE;
}
else if (data->data[1] && strcmp((char*)data->data[1], "rate") == 0)
{
audin->fixed_rate = atoi(data->data[2]);
return TRUE;
}
else if (data->data[1] && strcmp((char*)data->data[1], "channel") == 0)
{
audin->fixed_channel = atoi(data->data[2]);
return TRUE;
}
else if (data->data[1] && ((char*)data->data[1])[0])
{
return audin_load_device_plugin(pPlugin, (char*) data->data[1], data);
}
else
{
default_data[0].size = sizeof(RDP_PLUGIN_DATA);
default_data[0].data[0] = "audin";
default_data[0].data[1] = "pulse";
default_data[0].data[2] = "";
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
ret = audin_load_device_plugin(pPlugin, "pulse", default_data);
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
audin_args, flags, audin, NULL, NULL);
if (!ret)
arg = audin_args;
do
{
default_data[0].size = sizeof(RDP_PLUGIN_DATA);
default_data[0].data[0] = "audin";
default_data[0].data[1] = "alsa";
default_data[0].data[2] = "default";
ret = audin_load_device_plugin(pPlugin, "alsa", default_data);
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "sys")
{
audin_set_subsystem(audin, arg->Value);
}
CommandLineSwitchCase(arg, "dev")
{
audin_set_device_name(audin, arg->Value);
}
CommandLineSwitchCase(arg, "format")
{
audin->fixed_format = atoi(arg->Value);
}
CommandLineSwitchCase(arg, "rate")
{
audin->fixed_rate = atoi(arg->Value);
}
CommandLineSwitchCase(arg, "channel")
{
audin->fixed_channel = atoi(arg->Value);
}
CommandLineSwitchDefault(arg)
{
}
return ret;
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
return TRUE;
}
@ -519,23 +551,50 @@ static BOOL audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
int error = 0;
ADDIN_ARGV* args;
AUDIN_PLUGIN* audin;
audin = (AUDIN_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "audin");
if (audin == NULL)
{
audin = xnew(AUDIN_PLUGIN);
audin = (AUDIN_PLUGIN*) malloc(sizeof(AUDIN_PLUGIN));
ZeroMemory(audin, sizeof(AUDIN_PLUGIN));
audin->iface.Initialize = audin_plugin_initialize;
audin->iface.Connected = NULL;
audin->iface.Disconnected = NULL;
audin->iface.Terminated = audin_plugin_terminated;
error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin);
}
args = pEntryPoints->GetPluginData(pEntryPoints);
if (error == 0)
audin_process_plugin_data((IWTSPlugin*) audin, pEntryPoints->GetPluginData(pEntryPoints));
audin_process_addin_args((IWTSPlugin*) audin, args);
if (audin->subsystem)
audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args);
if (!audin->device)
{
audin_set_subsystem(audin, "pulse");
audin_set_device_name(audin, "");
audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args);
}
if (!audin->device)
{
audin_set_subsystem(audin, "alsa");
audin_set_device_name(audin, "default");
audin_load_device_plugin((IWTSPlugin*) audin, audin->subsystem, args);
}
if (audin->device == NULL)
{
DEBUG_WARN("no sound device.");
}
return error;
}

View File

@ -26,6 +26,7 @@
#include <freerdp/dvc.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/utils/debug.h>
#ifdef WITH_DEBUG_DVC
@ -66,7 +67,7 @@ struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS
{
IWTSPlugin* plugin;
PREGISTERAUDINDEVICE pRegisterAudinDevice;
RDP_PLUGIN_DATA* plugin_data;
ADDIN_ARGV* args;
};
typedef struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS FREERDP_AUDIN_DEVICE_ENTRY_POINTS;
typedef FREERDP_AUDIN_DEVICE_ENTRY_POINTS* PFREERDP_AUDIN_DEVICE_ENTRY_POINTS;

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${PULSE_INCLUDE_DIR})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -25,8 +25,13 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <pulse/pulseaudio.h>
#include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
@ -36,7 +41,7 @@ typedef struct _AudinPulseDevice
{
IAudinDevice iface;
char device_name[32];
char* device_name;
UINT32 frames_per_packet;
pa_threaded_mainloop* mainloop;
pa_context* context;
@ -430,16 +435,53 @@ static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* u
}
}
COMMAND_LINE_ARGUMENT_A audin_pulse_args[] =
{
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void audin_pulse_parse_addin_args(AudinPulseDevice* device, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
AudinPulseDevice* pulse = (AudinPulseDevice*) device;
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv, audin_pulse_args, flags, pulse, NULL, NULL);
arg = audin_pulse_args;
do
{
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "audio-dev")
{
pulse->device_name = _strdup(arg->Value);
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
#ifdef STATIC_CHANNELS
#define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry
#endif
int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
{
ADDIN_ARGV* args;
AudinPulseDevice* pulse;
RDP_PLUGIN_DATA * data;
pulse = xnew(AudinPulseDevice);
pulse = (AudinPulseDevice*) malloc(sizeof(AudinPulseDevice));
ZeroMemory(pulse, sizeof(AudinPulseDevice));
pulse->iface.Open = audin_pulse_open;
pulse->iface.FormatSupported = audin_pulse_format_supported;
@ -447,30 +489,35 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
pulse->iface.Close = audin_pulse_close;
pulse->iface.Free = audin_pulse_free;
data = pEntryPoints->plugin_data;
if (data && data->data[0] && strcmp(data->data[0], "audin") == 0 &&
data->data[1] && strcmp(data->data[1], "pulse") == 0)
{
strncpy(pulse->device_name, (char*)data->data[2], sizeof(pulse->device_name));
}
args = pEntryPoints->args;
audin_pulse_parse_addin_args(pulse, args);
if (!pulse->device_name)
pulse->device_name = _strdup("default");
pulse->dsp_context = freerdp_dsp_context_new();
pulse->mainloop = pa_threaded_mainloop_new();
if (!pulse->mainloop)
{
DEBUG_WARN("pa_threaded_mainloop_new failed");
audin_pulse_free((IAudinDevice*) pulse);
return 1;
}
pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp");
if (!pulse->context)
{
DEBUG_WARN("pa_context_new failed");
audin_pulse_free((IAudinDevice*) pulse);
return 1;
}
pa_context_set_state_callback(pulse->context, audin_pulse_context_state_callback, pulse);
if (!audin_pulse_connect((IAudinDevice*) pulse))
{
audin_pulse_free((IAudinDevice*) pulse);
@ -481,4 +528,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
return 0;
}

View File

@ -62,12 +62,24 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND")
set(CHANNEL_SUBSYSTEMS "")
endif()
message(STATUS "Channel: ${STATIC_MODULE_CHANNEL} Subsystems: ${CHANNEL_SUBSYSTEMS}")
foreach(STATIC_SUBSYSTEM ${CHANNEL_SUBSYSTEMS})
string(TOUPPER "${STATIC_MODULE}_CLIENT_${STATIC_SUBSYSTEM}" SUBSYSTEM_PREFIX)
if(${STATIC_SUBSYSTEM} MATCHES "^([^-]*)-(.*)")
string(REGEX REPLACE "^([^-]*)-(.*)" "\\1" STATIC_SUBSYSTEM_NAME ${STATIC_SUBSYSTEM})
string(REGEX REPLACE "^([^-]*)-(.*)" "\\2" STATIC_SUBSYSTEM_TYPE ${STATIC_SUBSYSTEM})
else()
set(STATIC_SUBSYSTEM_NAME "${STATIC_SUBSYSTEM}")
set(STATIC_SUBSYSTEM_TYPE "")
endif()
string(LENGTH "${STATIC_SUBSYSTEM_TYPE}" _type_length)
set(SUBSYSTEM_MODULE_NAME "${STATIC_MODULE_NAME}-${STATIC_SUBSYSTEM}")
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${SUBSYSTEM_MODULE_NAME})
set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry")
set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM}\", \"\", ${STATIC_SUBSYSTEM_ENTRY} },")
if(_type_length GREATER 0)
set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM_NAME}_freerdp_${STATIC_MODULE_CHANNEL}_client_${STATIC_SUBSYSTEM_TYPE}_subsystem_entry")
else()
set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM_NAME}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry")
endif()
set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM_NAME}\", \"${STATIC_SUBSYSTEM_TYPE}\", ${STATIC_SUBSYSTEM_ENTRY} },")
set(SUBSYSTEM_IMPORT "extern void ${STATIC_SUBSYSTEM_ENTRY}();")
set(CLIENT_STATIC_SUBSYSTEM_IMPORTS "${CLIENT_STATIC_SUBSYSTEM_IMPORTS}\n${SUBSYSTEM_IMPORT}")
endforeach()

View File

@ -360,10 +360,13 @@ void* freerdp_channels_load_static_addin_entry(LPCSTR pszName, LPSTR pszSubsyste
}
}
else
{
if (strcmp(CLIENT_STATIC_ADDIN_TABLE[i].name, pszName) == 0)
{
return (void*) CLIENT_STATIC_ADDIN_TABLE[i].entry;
}
}
}
return NULL;
}
@ -990,7 +993,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v
if (channels->num_libs_data + 1 >= CHANNEL_MAX_COUNT)
{
DEBUG_CHANNELS("too many channels");
printf("error: too many channels\n");
return 1;
}
@ -1024,7 +1027,7 @@ int freerdp_channels_client_load(rdpChannels* channels, rdpSettings* settings, v
if (!status)
{
DEBUG_CHANNELS("export function call failed");
printf("error: channel export function call failed\n");
return 1;
}

View File

@ -76,6 +76,7 @@ static int drdynvc_write_variable_uint(STREAM* stream, UINT32 val)
cb = 2;
stream_write_UINT32(stream, val);
}
return cb;
}
@ -148,12 +149,14 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
}
}
if (error != CHANNEL_RC_OK)
{
drdynvc->channel_error = error;
DEBUG_WARN("VirtualChannelWrite failed %d", error);
return 1;
}
return 0;
}
@ -162,11 +165,13 @@ int drdynvc_push_event(drdynvcPlugin* drdynvc, RDP_EVENT* event)
int error;
error = svc_plugin_send_event((rdpSvcPlugin*) drdynvc, event);
if (error != CHANNEL_RC_OK)
{
DEBUG_WARN("pVirtualChannelEventPush failed %d", error);
return 1;
}
return 0;
}
@ -178,6 +183,7 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in
DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId);
stream_seek(s, 1); /* pad */
stream_read_UINT16(s, drdynvc->version);
if (drdynvc->version == 2)
{
stream_read_UINT16(s, drdynvc->PriorityCharge0);
@ -185,15 +191,18 @@ static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, in
stream_read_UINT16(s, drdynvc->PriorityCharge2);
stream_read_UINT16(s, drdynvc->PriorityCharge3);
}
data_out = stream_new(4);
stream_write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */
stream_write_UINT16(data_out, drdynvc->version);
error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
if (error != CHANNEL_RC_OK)
{
DEBUG_WARN("VirtualChannelWrite failed %d", error);
return 1;
}
drdynvc->channel_error = error;
return 0;
@ -208,22 +217,25 @@ static UINT32 drdynvc_read_variable_uint(STREAM* stream, int cbLen)
case 0:
stream_read_BYTE(stream, val);
break;
case 1:
stream_read_UINT16(stream, val);
break;
default:
stream_read_UINT32(stream, val);
break;
}
return val;
}
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
{
STREAM* data_out;
int pos;
int error;
UINT32 ChannelId;
STREAM* data_out;
ChannelId = drdynvc_read_variable_uint(s, cbChId);
pos = stream_get_pos(s);
@ -248,25 +260,28 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb
}
error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
if (error != CHANNEL_RC_OK)
{
DEBUG_WARN("VirtualChannelWrite failed %d", error);
return 1;
}
return 0;
}
static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
{
UINT32 ChannelId;
UINT32 Length;
int error;
UINT32 Length;
UINT32 ChannelId;
ChannelId = drdynvc_read_variable_uint(s, cbChId);
Length = drdynvc_read_variable_uint(s, Sp);
DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length);
error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length);
if (error)
return error;
@ -298,11 +313,11 @@ static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbC
static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s)
{
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
int value;
int Cmd;
int Sp;
int cbChId;
drdynvcPlugin* drdynvc = (drdynvcPlugin*) plugin;
stream_read_BYTE(s, value);
Cmd = (value & 0xf0) >> 4;
@ -338,13 +353,24 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s)
static void drdynvc_process_connect(rdpSvcPlugin* plugin)
{
int index;
ADDIN_ARGV* args;
rdpSettings* settings;
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
DEBUG_DVC("connecting");
drdynvc->channel_mgr = dvcman_new(drdynvc);
drdynvc->channel_error = 0;
dvcman_load_plugin(drdynvc->channel_mgr, svc_plugin_get_data(plugin));
settings = (rdpSettings*) ((rdpSvcPlugin*) plugin)->channel_entry_points.pExtendedData;
for (index = 0; index < settings->DynamicChannelCount; index++)
{
args = settings->DynamicChannelArray[index];
dvcman_load_addin(drdynvc->channel_mgr, args);
}
dvcman_init(drdynvc->channel_mgr);
}
@ -391,4 +417,3 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
return 1;
}

View File

@ -74,7 +74,7 @@ struct _DVCMAN_ENTRY_POINTS
IDRDYNVC_ENTRY_POINTS iface;
DVCMAN* dvcman;
RDP_PLUGIN_DATA* plugin_data;
ADDIN_ARGV* args;
};
typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL;
@ -183,9 +183,9 @@ IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* n
return NULL;
}
RDP_PLUGIN_DATA* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
ADDIN_ARGV* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->plugin_data;
return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->args;
}
UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel)
@ -224,16 +224,14 @@ IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin)
return (IWTSVirtualChannelManager*) dvcman;
}
int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data)
int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args)
{
DVCMAN_ENTRY_POINTS entryPoints;
PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL;
while (data && data->size > 0)
{
printf("Loading Dynamic Virtual Channel %s\n", data->data[0]);
printf("Loading Dynamic Virtual Channel %s\n", args->argv[0]);
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry((char*) data->data[0],
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0],
NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC);
if (pDVCPluginEntry != NULL)
@ -242,13 +240,10 @@ int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA*
entryPoints.iface.GetPlugin = dvcman_get_plugin;
entryPoints.iface.GetPluginData = dvcman_get_plugin_data;
entryPoints.dvcman = (DVCMAN*) pChannelMgr;
entryPoints.plugin_data = data;
entryPoints.args = args;
pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints);
}
data = (RDP_PLUGIN_DATA*)(((BYTE*) data) + data->size);
}
return 0;
}
@ -382,7 +377,6 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
return 1;
}
int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId)
{
DVCMAN_CHANNEL* channel;

View File

@ -21,10 +21,12 @@
#define __DVCMAN_H
#include <freerdp/dvc.h>
#include <freerdp/addin.h>
#include "drdynvc_main.h"
IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin);
int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data);
int dvcman_load_addin(IWTSVirtualChannelManager* pChannelMgr, ADDIN_ARGV* args);
void dvcman_free(IWTSVirtualChannelManager* pChannelMgr);
int dvcman_init(IWTSVirtualChannelManager* pChannelMgr);
int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, const char* ChannelName);

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${ALSA_INCLUDE_DIRS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -462,7 +462,8 @@ int freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pE
ADDIN_ARGV* args;
rdpsndAlsaPlugin* alsa;
alsa = xnew(rdpsndAlsaPlugin);
alsa = (rdpsndAlsaPlugin*) malloc(sizeof(rdpsndAlsaPlugin));
ZeroMemory(alsa, sizeof(rdpsndAlsaPlugin));
alsa->device.Open = rdpsnd_alsa_open;
alsa->device.FormatSupported = rdpsnd_alsa_format_supported;

View File

@ -24,7 +24,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${MACAUDIO_INCLUDE_DIRS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${PULSE_INCLUDE_DIR})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} TRUE "")
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -20,5 +20,3 @@ define_channel("tsmf")
if(WITH_CLIENT_CHANNELS)
add_channel_client(${MODULE_PREFIX} ${CHANNEL_NAME})
endif()

View File

@ -43,7 +43,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-utils)
MODULES freerdp-utils freerdp-common)
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
@ -54,19 +54,19 @@ endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Channels/${CHANNEL_NAME}/Client")
if(WITH_FFMPEG)
add_subdirectory(ffmpeg)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "ffmpeg" "decoder")
endif()
if(WITH_XRANDR)
if(GSTREAMER_FOUND)
add_subdirectory(gstreamer)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "gstreamer" "decoder")
endif()
endif()
if(WITH_ALSA)
add_subdirectory(alsa)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "alsa" "audio")
endif()
if(WITH_PULSE)
add_subdirectory(pulse)
add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "pulse" "audio")
endif()

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${ALSA_INCLUDE_DIRS})
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
@ -36,6 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${ALSA_LIBRARIES})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
endif()

View File

@ -26,7 +26,11 @@
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <winpr/crt.h>
#include <alsa/asoundlib.h>
#include <freerdp/types.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h>
@ -248,11 +252,16 @@ static void tsmf_alsa_free(ITSMFAudioDevice* audio)
free(alsa);
}
ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry alsa_freerdp_tsmf_client_audio_subsystem_entry
#endif
ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void)
{
TSMFALSAAudioDevice* alsa;
alsa = xnew(TSMFALSAAudioDevice);
alsa = (TSMFALSAAudioDevice*) malloc(sizeof(TSMFALSAAudioDevice));
ZeroMemory(alsa, sizeof(TSMFALSAAudioDevice));
alsa->iface.Open = tsmf_alsa_open;
alsa->iface.SetFormat = tsmf_alsa_set_format;
@ -265,4 +274,3 @@ ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
return (ITSMFAudioDevice*) alsa;
}

View File

@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
define_channel_client_subsystem("tsmf" "ffmpeg" "video")
define_channel_client_subsystem("tsmf" "ffmpeg" "decoder")
set(${MODULE_PREFIX}_SRCS
tsmf_ffmpeg.c)
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${FFMPEG_INCLUDE_DIRS})
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
@ -36,4 +36,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${FFMPEG_LIBRARIES})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
endif()

View File

@ -25,6 +25,8 @@
#include <stdlib.h>
#include <string.h>
#include <winpr/crt.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/event.h>
#include <freerdp/client/tsmf.h>
@ -60,6 +62,7 @@ static BOOL tsmf_ffmpeg_init_context(ITSMFDecoder* decoder)
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
mdecoder->codec_context = avcodec_alloc_context3(NULL);
if (!mdecoder->codec_context)
{
DEBUG_WARN("avcodec_alloc_context failed.");
@ -108,12 +111,13 @@ static BOOL tsmf_ffmpeg_init_audio_stream(ITSMFDecoder* decoder, const TS_AM_MED
static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type)
{
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
BYTE* p;
UINT32 size;
const BYTE* s;
BYTE* p;
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id);
if (!mdecoder->codec)
{
DEBUG_WARN("avcodec_find_decoder failed.");
@ -396,6 +400,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI
DEBUG_WARN("error decoding");
break;
}
src += len;
src_size -= len;
mdecoder->decoded_size += frame_size;
@ -444,13 +449,14 @@ static BOOL tsmf_ffmpeg_decode(ITSMFDecoder* decoder, const BYTE* data, UINT32 d
static BYTE* tsmf_ffmpeg_get_decoded_data(ITSMFDecoder* decoder, UINT32* size)
{
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
BYTE* buf;
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
*size = mdecoder->decoded_size;
buf = mdecoder->decoded_data;
mdecoder->decoded_data = NULL;
mdecoder->decoded_size = 0;
return buf;
}
@ -492,8 +498,10 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
if (mdecoder->frame)
av_free(mdecoder->frame);
if (mdecoder->decoded_data)
free(mdecoder->decoded_data);
if (mdecoder->codec_context)
{
if (mdecoder->prepared)
@ -502,12 +510,17 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
free(mdecoder->codec_context->extradata);
av_free(mdecoder->codec_context);
}
free(decoder);
}
static BOOL initialized = FALSE;
ITSMFDecoder* TSMFDecoderEntry(void)
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_decoder_subsystem_entry ffmpeg_freerdp_tsmf_client_decoder_subsystem_entry
#endif
ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
{
TSMFFFmpegDecoder* decoder;
@ -517,7 +530,10 @@ ITSMFDecoder* TSMFDecoderEntry(void)
initialized = TRUE;
}
decoder = xnew(TSMFFFmpegDecoder);
printf("TSMFDecoderEntry FFMPEG\n");
decoder = (TSMFFFmpegDecoder*) malloc(sizeof(TSMFFFmpegDecoder));
ZeroMemory(decoder, sizeof(TSMFFFmpegDecoder));
decoder->iface.SetFormat = tsmf_ffmpeg_set_format;
decoder->iface.Decode = tsmf_ffmpeg_decode;
@ -528,4 +544,3 @@ ITSMFDecoder* TSMFDecoderEntry(void)
return (ITSMFDecoder*) decoder;
}

View File

@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
define_channel_client_subsystem("tsmf" "gstreamer" "video")
define_channel_client_subsystem("tsmf" "gstreamer" "decoder")
set(${MODULE_PREFIX}_SRCS
tsmf_gstreamer.c)
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${GSTREAMER_INCLUDE_DIRS})
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
@ -40,4 +40,6 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
endif()

View File

@ -1565,8 +1565,11 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
static int initialized = 0;
ITSMFDecoder *
TSMFDecoderEntry(void)
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_decoder_subsystem_entry gstreamer_freerdp_tsmf_client_decoder_subsystem_entry
#endif
ITSMFDecoder* freerdp_tsmf_client_decoder_subsystem_entry(void)
{
TSMFGstreamerDecoder* decoder;

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..)
include_directories(${PULSE_INCLUDE_DIR})
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
add_channel_client_subsystem_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} "" TRUE "")
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
@ -36,4 +36,7 @@ set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${PULSE_LIBRARY})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
if(NOT STATIC_CHANNELS)
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_ADDIN_PATH})
endif()

View File

@ -26,7 +26,10 @@
#include <string.h>
#include <unistd.h>
#include <winpr/crt.h>
#include <pulse/pulseaudio.h>
#include <freerdp/utils/memory.h>
#include "tsmf_audio.h"
@ -389,11 +392,16 @@ static void tsmf_pulse_free(ITSMFAudioDevice* audio)
free(pulse);
}
ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
#ifdef STATIC_CHANNELS
#define freerdp_tsmf_client_audio_subsystem_entry pulse_freerdp_tsmf_client_audio_subsystem_entry
#endif
ITSMFAudioDevice* freerdp_tsmf_client_audio_subsystem_entry(void)
{
TSMFPulseAudioDevice* pulse;
pulse = xnew(TSMFPulseAudioDevice);
pulse = (TSMFPulseAudioDevice*) malloc(sizeof(TSMFPulseAudioDevice));
ZeroMemory(pulse, sizeof(TSMFPulseAudioDevice));
pulse->iface.Open = tsmf_pulse_open;
pulse->iface.SetFormat = tsmf_pulse_set_format;

View File

@ -34,34 +34,26 @@ static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const
{
ITSMFAudioDevice* audio;
TSMF_AUDIO_DEVICE_ENTRY entry;
char* fullname;
if (strrchr(name, '.') != NULL)
entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(name, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME);
else
{
fullname = xzalloc(strlen(name) + 6);
strcpy(fullname, "tsmf_");
strcat(fullname, name);
entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(fullname, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME);
free(fullname);
}
entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_channel_addin_entry("tsmf", (LPSTR) name, "audio", 0);
if (entry == NULL)
{
return NULL;
}
audio = entry();
if (audio == NULL)
{
DEBUG_WARN("failed to call export function in %s", name);
return NULL;
}
if (!audio->Open(audio, device))
{
audio->Free(audio);
audio = NULL;
}
return audio;
}
@ -76,6 +68,7 @@ ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device)
else
{
audio = tsmf_load_audio_device_by_name("pulse", device);
if (!audio)
audio = tsmf_load_audio_device_by_name("alsa", device);
}

View File

@ -25,31 +25,22 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/addin.h>
#include <freerdp/client/channels.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/client/channels.h>
#include "tsmf_types.h"
#include "tsmf_constants.h"
#include "tsmf_decoder.h"
static ITSMFDecoder* tsmf_load_decoder_by_name(const char* name, TS_AM_MEDIA_TYPE* media_type)
{
char* fullname;
ITSMFDecoder* decoder;
TSMF_DECODER_ENTRY entry;
if (strrchr(name, '.') != NULL)
entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(name, TSMF_DECODER_EXPORT_FUNC_NAME);
else
{
fullname = xzalloc(strlen(name) + 6);
strcpy(fullname, "tsmf_");
strcat(fullname, name);
entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(fullname, TSMF_DECODER_EXPORT_FUNC_NAME);
free(fullname);
}
entry = (TSMF_DECODER_ENTRY) freerdp_load_channel_addin_entry("tsmf", (LPSTR) name, "decoder", 0);
if (entry == NULL)
return NULL;
@ -86,4 +77,3 @@ ITSMFDecoder* tsmf_load_decoder(const char* name, TS_AM_MEDIA_TYPE* media_type)
return decoder;
}

View File

@ -25,7 +25,9 @@
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <freerdp/utils/stream.h>
#include "tsmf_types.h"
@ -76,7 +78,7 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback,
UINT32 message_id, UINT64 duration, UINT32 data_size)
{
STREAM* s;
int error;
int status;
TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback;
s = stream_new(32);
@ -88,26 +90,29 @@ void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback,
stream_write_UINT64(s, data_size); /* cbData */
DEBUG_DVC("response size %d", (int) stream_get_length(s));
error = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL);
if (error)
status = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL);
if (status)
{
DEBUG_WARN("response error %d", error);
DEBUG_WARN("response error %d", status);
}
stream_free(s);
}
BOOL tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback,
RDP_EVENT* event)
BOOL tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback, RDP_EVENT* event)
{
int error;
int status;
TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback;
error = callback->channel_mgr->PushEvent(callback->channel_mgr, event);
if (error)
status = callback->channel_mgr->PushEvent(callback->channel_mgr, event);
if (status)
{
DEBUG_WARN("response error %d", error);
DEBUG_WARN("response error %d", status);
return FALSE;
}
return TRUE;
}
@ -118,7 +123,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
int length;
STREAM* input;
STREAM* output;
int error = -1;
int status = -1;
TSMF_IFMAN ifman;
UINT32 MessageId;
UINT32 FunctionId;
@ -163,7 +168,7 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
switch (FunctionId)
{
case RIM_EXCHANGE_CAPABILITY_REQUEST:
error = tsmf_ifman_rim_exchange_capability_request(&ifman);
status = tsmf_ifman_rim_exchange_capability_request(&ifman);
break;
default:
@ -181,91 +186,91 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
stream_read_UINT32(input, callback->stream_id);
DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id);
ifman.output_pending = TRUE;
error = 0;
status = 0;
break;
case EXCHANGE_CAPABILITIES_REQ:
error = tsmf_ifman_exchange_capability_request(&ifman);
status = tsmf_ifman_exchange_capability_request(&ifman);
break;
case CHECK_FORMAT_SUPPORT_REQ:
error = tsmf_ifman_check_format_support_request(&ifman);
status = tsmf_ifman_check_format_support_request(&ifman);
break;
case ON_NEW_PRESENTATION:
error = tsmf_ifman_on_new_presentation(&ifman);
status = tsmf_ifman_on_new_presentation(&ifman);
break;
case ADD_STREAM:
error = tsmf_ifman_add_stream(&ifman);
status = tsmf_ifman_add_stream(&ifman);
break;
case SET_TOPOLOGY_REQ:
error = tsmf_ifman_set_topology_request(&ifman);
status = tsmf_ifman_set_topology_request(&ifman);
break;
case REMOVE_STREAM:
error = tsmf_ifman_remove_stream(&ifman);
status = tsmf_ifman_remove_stream(&ifman);
break;
case SHUTDOWN_PRESENTATION_REQ:
error = tsmf_ifman_shutdown_presentation(&ifman);
status = tsmf_ifman_shutdown_presentation(&ifman);
break;
case ON_STREAM_VOLUME:
error = tsmf_ifman_on_stream_volume(&ifman);
status = tsmf_ifman_on_stream_volume(&ifman);
break;
case ON_CHANNEL_VOLUME:
error = tsmf_ifman_on_channel_volume(&ifman);
status = tsmf_ifman_on_channel_volume(&ifman);
break;
case SET_VIDEO_WINDOW:
error = tsmf_ifman_set_video_window(&ifman);
status = tsmf_ifman_set_video_window(&ifman);
break;
case UPDATE_GEOMETRY_INFO:
error = tsmf_ifman_update_geometry_info(&ifman);
status = tsmf_ifman_update_geometry_info(&ifman);
break;
case SET_ALLOCATOR:
error = tsmf_ifman_set_allocator(&ifman);
status = tsmf_ifman_set_allocator(&ifman);
break;
case NOTIFY_PREROLL:
error = tsmf_ifman_notify_preroll(&ifman);
status = tsmf_ifman_notify_preroll(&ifman);
break;
case ON_SAMPLE:
error = tsmf_ifman_on_sample(&ifman);
status = tsmf_ifman_on_sample(&ifman);
break;
case ON_FLUSH:
error = tsmf_ifman_on_flush(&ifman);
status = tsmf_ifman_on_flush(&ifman);
break;
case ON_END_OF_STREAM:
error = tsmf_ifman_on_end_of_stream(&ifman);
status = tsmf_ifman_on_end_of_stream(&ifman);
break;
case ON_PLAYBACK_STARTED:
error = tsmf_ifman_on_playback_started(&ifman);
status = tsmf_ifman_on_playback_started(&ifman);
break;
case ON_PLAYBACK_PAUSED:
error = tsmf_ifman_on_playback_paused(&ifman);
status = tsmf_ifman_on_playback_paused(&ifman);
break;
case ON_PLAYBACK_RESTARTED:
error = tsmf_ifman_on_playback_restarted(&ifman);
status = tsmf_ifman_on_playback_restarted(&ifman);
break;
case ON_PLAYBACK_STOPPED:
error = tsmf_ifman_on_playback_stopped(&ifman);
status = tsmf_ifman_on_playback_stopped(&ifman);
break;
case ON_PLAYBACK_RATE_CHANGED:
error = tsmf_ifman_on_playback_rate_changed(&ifman);
status = tsmf_ifman_on_playback_rate_changed(&ifman);
break;
default:
@ -282,34 +287,34 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
input = NULL;
ifman.input = NULL;
if (error == -1)
if (status == -1)
{
switch (FunctionId)
{
case RIMCALL_RELEASE:
/* [MS-RDPEXPS] 2.2.2.2 Interface Release (IFACE_RELEASE)
This message does not require a reply. */
error = 0;
status = 0;
ifman.output_pending = 1;
break;
case RIMCALL_QUERYINTERFACE:
/* [MS-RDPEXPS] 2.2.2.1.2 Query Interface Response (QI_RSP)
This message is not supported in this channel. */
error = 0;
status = 0;
break;
}
if (error == -1)
if (status == -1)
{
DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.",
InterfaceId, FunctionId);
/* When a request is not implemented we return empty response indicating error */
}
error = 0;
status = 0;
}
if (error == 0 && !ifman.output_pending)
if (status == 0 && !ifman.output_pending)
{
/* Response packet does not have FunctionId */
length = stream_get_length(output);
@ -318,16 +323,16 @@ static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
stream_write_UINT32(output, MessageId);
DEBUG_DVC("response size %d", length);
error = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL);
if (error)
status = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL);
if (status)
{
DEBUG_WARN("response error %d", error);
DEBUG_WARN("response error %d", status);
}
}
stream_free(output);
return error;
return status;
}
static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback)
@ -341,13 +346,16 @@ static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback)
if (callback->stream_id)
{
presentation = tsmf_presentation_find_by_id(callback->presentation_id);
if (presentation)
{
stream = tsmf_stream_find_by_id(presentation, callback->stream_id);
if (stream)
tsmf_stream_free(stream);
}
}
free(pChannelCallback);
return 0;
@ -364,7 +372,9 @@ static int tsmf_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac
DEBUG_DVC("");
callback = xnew(TSMF_CHANNEL_CALLBACK);
callback = (TSMF_CHANNEL_CALLBACK*) malloc(sizeof(TSMF_CHANNEL_CALLBACK));
ZeroMemory(callback, sizeof(TSMF_CHANNEL_CALLBACK));
callback->iface.OnDataReceived = tsmf_on_data_received;
callback->iface.OnClose = tsmf_on_close;
callback->plugin = listener_callback->plugin;
@ -381,10 +391,13 @@ static int tsmf_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager
DEBUG_DVC("");
tsmf->listener_callback = xnew(TSMF_LISTENER_CALLBACK);
tsmf->listener_callback = (TSMF_LISTENER_CALLBACK*) malloc(sizeof(TSMF_LISTENER_CALLBACK));
ZeroMemory(tsmf->listener_callback, sizeof(TSMF_LISTENER_CALLBACK));
tsmf->listener_callback->iface.OnNewChannelConnection = tsmf_on_new_channel_connection;
tsmf->listener_callback->plugin = pPlugin;
tsmf->listener_callback->channel_mgr = pChannelMgr;
return pChannelMgr->CreateListener(pChannelMgr, "TSMF", 0,
(IWTSListenerCallback*) tsmf->listener_callback, NULL);
}
@ -402,27 +415,55 @@ static int tsmf_plugin_terminated(IWTSPlugin* pPlugin)
return 0;
}
static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
COMMAND_LINE_ARGUMENT_A tsmf_args[] =
{
{ "audio", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "audio subsystem" },
{ "audio-dev", COMMAND_LINE_VALUE_REQUIRED, "<device>", NULL, NULL, -1, NULL, "audio device name" },
{ "decoder", COMMAND_LINE_VALUE_REQUIRED, "<subsystem>", NULL, NULL, -1, NULL, "decoder subsystem" },
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
static void tsmf_process_addin_args(IWTSPlugin* pPlugin, ADDIN_ARGV* args)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
TSMF_PLUGIN* tsmf = (TSMF_PLUGIN*) pPlugin;
while (data && data->size > 0)
flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON;
status = CommandLineParseArgumentsA(args->argc, (const char**) args->argv,
tsmf_args, flags, tsmf, NULL, NULL);
arg = tsmf_args;
do
{
if (data->data[0] && ( strcmp((char*)data->data[0], "tsmf") == 0 || strstr((char*)data->data[0], "/tsmf.") != NULL) )
if (!(arg->Flags & COMMAND_LINE_VALUE_PRESENT))
continue;
CommandLineSwitchStart(arg)
CommandLineSwitchCase(arg, "audio")
{
if (data->data[1] && strcmp((char*)data->data[1], "decoder") == 0)
{
tsmf->decoder_name = data->data[2];
tsmf->audio_name = _strdup(arg->Value);
}
else if (data->data[1] && strcmp((char*)data->data[1], "audio") == 0)
CommandLineSwitchCase(arg, "audio-dev")
{
tsmf->audio_name = data->data[2];
tsmf->audio_device = data->data[3];
tsmf->audio_device = _strdup(arg->Value);
}
CommandLineSwitchCase(arg, "decoder")
{
tsmf->decoder_name = _strdup(arg->Value);
}
CommandLineSwitchDefault(arg)
{
}
data = (RDP_PLUGIN_DATA*)(((BYTE*)data) + data->size);
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
}
#ifdef STATIC_CHANNELS
@ -431,29 +472,29 @@ static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data)
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
{
int error = 0;
int status = 0;
TSMF_PLUGIN* tsmf;
tsmf = (TSMF_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "tsmf");
if (tsmf == NULL)
{
tsmf = xnew(TSMF_PLUGIN);
tsmf = (TSMF_PLUGIN*) malloc(sizeof(TSMF_PLUGIN));
ZeroMemory(tsmf, sizeof(TSMF_PLUGIN));
tsmf->iface.Initialize = tsmf_plugin_initialize;
tsmf->iface.Connected = NULL;
tsmf->iface.Disconnected = NULL;
tsmf->iface.Terminated = tsmf_plugin_terminated;
error = pEntryPoints->RegisterPlugin(pEntryPoints, "tsmf", (IWTSPlugin*) tsmf);
status = pEntryPoints->RegisterPlugin(pEntryPoints, "tsmf", (IWTSPlugin*) tsmf);
tsmf_media_init();
}
if (error == 0)
if (status == 0)
{
tsmf_process_plugin_data((IWTSPlugin*) tsmf,
pEntryPoints->GetPluginData(pEntryPoints));
tsmf_process_addin_args((IWTSPlugin*) tsmf, pEntryPoints->GetPluginData(pEntryPoints));
}
return error;
return status;
}

View File

@ -837,7 +837,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
args = settings->StaticChannelArray[index];
entry = freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
entry = freerdp_load_channel_addin_entry(args->argv[0], NULL, NULL, 0);
if (entry)
{
@ -848,7 +848,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
if (settings->DeviceRedirection)
{
entry = freerdp_load_channel_addin_entry("rdpdr", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
entry = freerdp_load_channel_addin_entry("rdpdr", NULL, NULL, 0);
if (entry)
{
@ -859,7 +859,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
if (settings->RemoteApplicationMode)
{
entry = freerdp_load_channel_addin_entry("rail", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
entry = freerdp_load_channel_addin_entry("rail", NULL, NULL, 0);
if (entry)
{
@ -870,7 +870,7 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings)
if (settings->DynamicChannelCount)
{
entry = freerdp_load_channel_addin_entry("drdynvc", NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
entry = freerdp_load_channel_addin_entry("drdynvc", NULL, NULL, 0);
if (entry)
{

View File

@ -52,6 +52,7 @@
#define __FREERDP_DVC_H
#include <freerdp/types.h>
#include <freerdp/addin.h>
typedef struct _IWTSVirtualChannelManager IWTSVirtualChannelManager;
typedef struct _IWTSListener IWTSListener;
@ -145,7 +146,7 @@ struct _IDRDYNVC_ENTRY_POINTS
const char* name, IWTSPlugin* pPlugin);
IWTSPlugin* (*GetPlugin) (IDRDYNVC_ENTRY_POINTS* pEntryPoints,
const char* name);
RDP_PLUGIN_DATA* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints);
ADDIN_ARGV* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints);
};
typedef int (*PDVC_PLUGIN_ENTRY) (IDRDYNVC_ENTRY_POINTS*);

View File

@ -25,6 +25,7 @@
#include <freerdp/api.h>
#include <freerdp/svc.h>
#include <freerdp/addin.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/event.h>
#include <freerdp/utils/debug.h>
@ -52,8 +53,6 @@ FREERDP_API void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEn
FREERDP_API int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out);
FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event);
#define svc_plugin_get_data(_p) (RDP_PLUGIN_DATA*)(((rdpSvcPlugin*)_p)->channel_entry_points.pExtendedData)
#ifdef WITH_DEBUG_SVC
#define DEBUG_SVC(fmt, ...) DEBUG_CLASS(SVC, fmt, ## __VA_ARGS__)
#else

View File

@ -30,7 +30,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION_FULL}
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-crt winpr-path winpr-file winpr-utils)
MODULES winpr-crt winpr-path winpr-file winpr-library winpr-utils)
if(MONOLITHIC_BUILD)
set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)

View File

@ -111,37 +111,6 @@ void* freerdp_load_library_symbol(const char* file, const char* name)
*/
void* freerdp_load_plugin(const char* name, const char* entry_name)
{
#if 0
char* path;
void* entry;
char* suffixed_name;
suffixed_name = freerdp_append_shared_library_suffix((char*) name);
if (!freerdp_path_contains_separator(suffixed_name))
{
/* no explicit path given, use default path */
path = freerdp_construct_path(FREERDP_PLUGIN_PATH, suffixed_name);
}
else
{
/* explicit path given, use it instead of default path */
path = _strdup(suffixed_name);
}
entry = freerdp_load_library_symbol(path, entry_name);
free(suffixed_name);
free(path);
if (entry == NULL)
{
printf("freerdp_load_plugin: failed to load %s/%s\n", name, entry_name);
return NULL;
}
return entry;
#endif
return freerdp_load_dynamic_addin(name, NULL, entry_name);
}

View File

@ -166,10 +166,12 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3
if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
{
/* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
This flag is only valid in server-to-client virtual channel traffic. It MUST be
ignored in client-to-server data." Thus it would be best practice to cease data
transmission. However, simply returning here avoids a crash. */
/*
* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
* This flag is only valid in server-to-client virtual channel traffic. It MUST be
* ignored in client-to-server data." Thus it would be best practice to cease data
* transmission. However, simply returning here avoids a crash.
*/
return;
}