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

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..) include_directories(..)
include_directories(${ALSA_INCLUDE_DIRS}) 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 "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -25,7 +25,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <freerdp/addin.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/thread.h> #include <freerdp/utils/thread.h>
#include <freerdp/utils/dsp.h> #include <freerdp/utils/dsp.h>
@ -36,7 +41,7 @@ typedef struct _AudinALSADevice
{ {
IAudinDevice iface; IAudinDevice iface;
char device_name[32]; char* device_name;
UINT32 frames_per_packet; UINT32 frames_per_packet;
UINT32 target_rate; UINT32 target_rate;
UINT32 actual_rate; UINT32 actual_rate;
@ -236,6 +241,9 @@ static void audin_alsa_free(IAudinDevice* device)
freerdp_thread_free(alsa->thread); freerdp_thread_free(alsa->thread);
freerdp_dsp_context_free(alsa->dsp_context); freerdp_dsp_context_free(alsa->dsp_context);
free(alsa->device_name);
free(alsa); free(alsa);
} }
@ -328,40 +336,66 @@ static void audin_alsa_close(IAudinDevice* device)
alsa->user_data = NULL; 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 #ifdef STATIC_CHANNELS
#define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry #define freerdp_audin_client_subsystem_entry alsa_freerdp_audin_client_subsystem_entry
#endif #endif
int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
{ {
ADDIN_ARGV* args;
AudinALSADevice* alsa; 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.Open = audin_alsa_open;
alsa->iface.FormatSupported = audin_alsa_format_supported; alsa->iface.FormatSupported = audin_alsa_format_supported;
alsa->iface.SetFormat = audin_alsa_set_format; alsa->iface.SetFormat = audin_alsa_set_format;
alsa->iface.Close = audin_alsa_close; alsa->iface.Close = audin_alsa_close;
alsa->iface.Free = audin_alsa_free; alsa->iface.Free = audin_alsa_free;
alsa->device_name[0] = '\0';
data = pEntryPoints->plugin_data; args = pEntryPoints->args;
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));
}
}
if (alsa->device_name[0] == '\0') audin_alsa_parse_addin_args(alsa, args);
{
strcpy(alsa->device_name, "default"); if (!alsa->device_name)
} alsa->device_name = _strdup("default");
alsa->frames_per_packet = 128; alsa->frames_per_packet = 128;
alsa->target_rate = 22050; alsa->target_rate = 22050;
@ -378,4 +412,3 @@ int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEnt
return 0; return 0;
} }

View File

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

View File

@ -26,6 +26,7 @@
#include <freerdp/dvc.h> #include <freerdp/dvc.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/utils/debug.h> #include <freerdp/utils/debug.h>
#ifdef WITH_DEBUG_DVC #ifdef WITH_DEBUG_DVC
@ -66,7 +67,7 @@ struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS
{ {
IWTSPlugin* plugin; IWTSPlugin* plugin;
PREGISTERAUDINDEVICE pRegisterAudinDevice; PREGISTERAUDINDEVICE pRegisterAudinDevice;
RDP_PLUGIN_DATA* plugin_data; ADDIN_ARGV* args;
}; };
typedef struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS FREERDP_AUDIN_DEVICE_ENTRY_POINTS; typedef struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS FREERDP_AUDIN_DEVICE_ENTRY_POINTS;
typedef FREERDP_AUDIN_DEVICE_ENTRY_POINTS* PFREERDP_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(..)
include_directories(${PULSE_INCLUDE_DIR}) 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 "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -25,8 +25,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <winpr/crt.h>
#include <winpr/cmdline.h>
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/addin.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h> #include <freerdp/utils/dsp.h>
@ -36,7 +41,7 @@ typedef struct _AudinPulseDevice
{ {
IAudinDevice iface; IAudinDevice iface;
char device_name[32]; char* device_name;
UINT32 frames_per_packet; UINT32 frames_per_packet;
pa_threaded_mainloop* mainloop; pa_threaded_mainloop* mainloop;
pa_context* context; 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 #ifdef STATIC_CHANNELS
#define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry #define freerdp_audin_client_subsystem_entry pulse_freerdp_audin_client_subsystem_entry
#endif #endif
int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) int freerdp_audin_client_subsystem_entry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints)
{ {
ADDIN_ARGV* args;
AudinPulseDevice* pulse; 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.Open = audin_pulse_open;
pulse->iface.FormatSupported = audin_pulse_format_supported; 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.Close = audin_pulse_close;
pulse->iface.Free = audin_pulse_free; pulse->iface.Free = audin_pulse_free;
data = pEntryPoints->plugin_data; args = pEntryPoints->args;
if (data && data->data[0] && strcmp(data->data[0], "audin") == 0 &&
data->data[1] && strcmp(data->data[1], "pulse") == 0) audin_pulse_parse_addin_args(pulse, args);
{
strncpy(pulse->device_name, (char*)data->data[2], sizeof(pulse->device_name)); if (!pulse->device_name)
} pulse->device_name = _strdup("default");
pulse->dsp_context = freerdp_dsp_context_new(); pulse->dsp_context = freerdp_dsp_context_new();
pulse->mainloop = pa_threaded_mainloop_new(); pulse->mainloop = pa_threaded_mainloop_new();
if (!pulse->mainloop) if (!pulse->mainloop)
{ {
DEBUG_WARN("pa_threaded_mainloop_new failed"); DEBUG_WARN("pa_threaded_mainloop_new failed");
audin_pulse_free((IAudinDevice*) pulse); audin_pulse_free((IAudinDevice*) pulse);
return 1; return 1;
} }
pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp");
if (!pulse->context) if (!pulse->context)
{ {
DEBUG_WARN("pa_context_new failed"); DEBUG_WARN("pa_context_new failed");
audin_pulse_free((IAudinDevice*) pulse); audin_pulse_free((IAudinDevice*) pulse);
return 1; return 1;
} }
pa_context_set_state_callback(pulse->context, audin_pulse_context_state_callback, pulse); pa_context_set_state_callback(pulse->context, audin_pulse_context_state_callback, pulse);
if (!audin_pulse_connect((IAudinDevice*) pulse)) if (!audin_pulse_connect((IAudinDevice*) pulse))
{ {
audin_pulse_free((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; return 0;
} }

View File

@ -62,12 +62,24 @@ foreach(STATIC_MODULE ${CHANNEL_STATIC_CLIENT_MODULES})
if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND") if(CHANNEL_SUBSYSTEMS MATCHES "NOTFOUND")
set(CHANNEL_SUBSYSTEMS "") set(CHANNEL_SUBSYSTEMS "")
endif() endif()
message(STATUS "Channel: ${STATIC_MODULE_CHANNEL} Subsystems: ${CHANNEL_SUBSYSTEMS}")
foreach(STATIC_SUBSYSTEM ${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(SUBSYSTEM_MODULE_NAME "${STATIC_MODULE_NAME}-${STATIC_SUBSYSTEM}")
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${SUBSYSTEM_MODULE_NAME}) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${SUBSYSTEM_MODULE_NAME})
set(STATIC_SUBSYSTEM_ENTRY "${STATIC_SUBSYSTEM}_freerdp_${STATIC_MODULE_CHANNEL}_client_subsystem_entry") if(_type_length GREATER 0)
set(SUBSYSTEM_TABLE "${SUBSYSTEM_TABLE}\n\t{ \"${STATIC_SUBSYSTEM}\", \"\", ${STATIC_SUBSYSTEM_ENTRY} },") 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(SUBSYSTEM_IMPORT "extern void ${STATIC_SUBSYSTEM_ENTRY}();")
set(CLIENT_STATIC_SUBSYSTEM_IMPORTS "${CLIENT_STATIC_SUBSYSTEM_IMPORTS}\n${SUBSYSTEM_IMPORT}") set(CLIENT_STATIC_SUBSYSTEM_IMPORTS "${CLIENT_STATIC_SUBSYSTEM_IMPORTS}\n${SUBSYSTEM_IMPORT}")
endforeach() endforeach()

View File

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

View File

@ -37,11 +37,11 @@
#include "drdynvc_types.h" #include "drdynvc_types.h"
#include "drdynvc_main.h" #include "drdynvc_main.h"
#define CREATE_REQUEST_PDU 0x01 #define CREATE_REQUEST_PDU 0x01
#define DATA_FIRST_PDU 0x02 #define DATA_FIRST_PDU 0x02
#define DATA_PDU 0x03 #define DATA_PDU 0x03
#define CLOSE_REQUEST_PDU 0x04 #define CLOSE_REQUEST_PDU 0x04
#define CAPABILITY_REQUEST_PDU 0x05 #define CAPABILITY_REQUEST_PDU 0x05
struct drdynvc_plugin struct drdynvc_plugin
{ {
@ -76,6 +76,7 @@ static int drdynvc_write_variable_uint(STREAM* stream, UINT32 val)
cb = 2; cb = 2;
stream_write_UINT32(stream, val); stream_write_UINT32(stream, val);
} }
return cb; return cb;
} }
@ -97,13 +98,13 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN
stream_set_pos(data_out, 1); stream_set_pos(data_out, 1);
cbChId = drdynvc_write_variable_uint(data_out, ChannelId); cbChId = drdynvc_write_variable_uint(data_out, ChannelId);
if(data_size == 0) if (data_size == 0)
{ {
pos = stream_get_pos(data_out); pos = stream_get_pos(data_out);
stream_set_pos(data_out, 0); stream_set_pos(data_out, 0);
stream_write_BYTE(data_out, 0x40 | cbChId); stream_write_BYTE(data_out, 0x40 | cbChId);
stream_set_pos(data_out, pos); stream_set_pos(data_out, pos);
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
} }
else if (data_size <= CHANNEL_CHUNK_LENGTH - pos) else if (data_size <= CHANNEL_CHUNK_LENGTH - pos)
{ {
@ -112,7 +113,7 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN
stream_write_BYTE(data_out, 0x30 | cbChId); stream_write_BYTE(data_out, 0x30 | cbChId);
stream_set_pos(data_out, pos); stream_set_pos(data_out, pos);
stream_write(data_out, data, data_size); stream_write(data_out, data, data_size);
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
} }
else else
{ {
@ -126,7 +127,7 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN
stream_write(data_out, data, chunk_len); stream_write(data_out, data, chunk_len);
data += chunk_len; data += chunk_len;
data_size -= chunk_len; data_size -= chunk_len;
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
while (error == CHANNEL_RC_OK && data_size > 0) while (error == CHANNEL_RC_OK && data_size > 0)
{ {
@ -148,12 +149,14 @@ int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UIN
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out);
} }
} }
if (error != CHANNEL_RC_OK) if (error != CHANNEL_RC_OK)
{ {
drdynvc->channel_error = error; drdynvc->channel_error = error;
DEBUG_WARN("VirtualChannelWrite failed %d", error); DEBUG_WARN("VirtualChannelWrite failed %d", error);
return 1; return 1;
} }
return 0; return 0;
} }
@ -161,12 +164,14 @@ int drdynvc_push_event(drdynvcPlugin* drdynvc, RDP_EVENT* event)
{ {
int error; int error;
error = svc_plugin_send_event((rdpSvcPlugin*)drdynvc, event); error = svc_plugin_send_event((rdpSvcPlugin*) drdynvc, event);
if (error != CHANNEL_RC_OK) if (error != CHANNEL_RC_OK)
{ {
DEBUG_WARN("pVirtualChannelEventPush failed %d", error); DEBUG_WARN("pVirtualChannelEventPush failed %d", error);
return 1; return 1;
} }
return 0; 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); DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId);
stream_seek(s, 1); /* pad */ stream_seek(s, 1); /* pad */
stream_read_UINT16(s, drdynvc->version); stream_read_UINT16(s, drdynvc->version);
if (drdynvc->version == 2) if (drdynvc->version == 2)
{ {
stream_read_UINT16(s, drdynvc->PriorityCharge0); 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->PriorityCharge2);
stream_read_UINT16(s, drdynvc->PriorityCharge3); stream_read_UINT16(s, drdynvc->PriorityCharge3);
} }
data_out = stream_new(4); data_out = stream_new(4);
stream_write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ stream_write_UINT16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */
stream_write_UINT16(data_out, drdynvc->version); stream_write_UINT16(data_out, drdynvc->version);
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
if (error != CHANNEL_RC_OK) if (error != CHANNEL_RC_OK)
{ {
DEBUG_WARN("VirtualChannelWrite failed %d", error); DEBUG_WARN("VirtualChannelWrite failed %d", error);
return 1; return 1;
} }
drdynvc->channel_error = error; drdynvc->channel_error = error;
return 0; return 0;
@ -208,28 +217,31 @@ static UINT32 drdynvc_read_variable_uint(STREAM* stream, int cbLen)
case 0: case 0:
stream_read_BYTE(stream, val); stream_read_BYTE(stream, val);
break; break;
case 1: case 1:
stream_read_UINT16(stream, val); stream_read_UINT16(stream, val);
break; break;
default: default:
stream_read_UINT32(stream, val); stream_read_UINT32(stream, val);
break; break;
} }
return val; return val;
} }
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
{ {
STREAM* data_out;
int pos; int pos;
int error; int error;
UINT32 ChannelId; UINT32 ChannelId;
STREAM* data_out;
ChannelId = drdynvc_read_variable_uint(s, cbChId); ChannelId = drdynvc_read_variable_uint(s, cbChId);
pos = stream_get_pos(s); pos = stream_get_pos(s);
DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s)); DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s));
error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*)stream_get_tail(s)); error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) stream_get_tail(s));
data_out = stream_new(pos + 4); data_out = stream_new(pos + 4);
stream_write_BYTE(data_out, 0x10 | cbChId); stream_write_BYTE(data_out, 0x10 | cbChId);
@ -247,26 +259,29 @@ static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cb
stream_write_UINT32(data_out, (UINT32)(-1)); stream_write_UINT32(data_out, (UINT32)(-1));
} }
error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out);
if (error != CHANNEL_RC_OK) if (error != CHANNEL_RC_OK)
{ {
DEBUG_WARN("VirtualChannelWrite failed %d", error); DEBUG_WARN("VirtualChannelWrite failed %d", error);
return 1; return 1;
} }
return 0; return 0;
} }
static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s)
{ {
UINT32 ChannelId;
UINT32 Length;
int error; int error;
UINT32 Length;
UINT32 ChannelId;
ChannelId = drdynvc_read_variable_uint(s, cbChId); ChannelId = drdynvc_read_variable_uint(s, cbChId);
Length = drdynvc_read_variable_uint(s, Sp); Length = drdynvc_read_variable_uint(s, Sp);
DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length); DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length);
error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length);
if (error) if (error)
return 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) static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s)
{ {
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
int value; int value;
int Cmd; int Cmd;
int Sp; int Sp;
int cbChId; int cbChId;
drdynvcPlugin* drdynvc = (drdynvcPlugin*) plugin;
stream_read_BYTE(s, value); stream_read_BYTE(s, value);
Cmd = (value & 0xf0) >> 4; Cmd = (value & 0xf0) >> 4;
@ -338,13 +353,24 @@ static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s)
static void drdynvc_process_connect(rdpSvcPlugin* plugin) static void drdynvc_process_connect(rdpSvcPlugin* plugin)
{ {
int index;
ADDIN_ARGV* args;
rdpSettings* settings;
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin;
DEBUG_DVC("connecting"); DEBUG_DVC("connecting");
drdynvc->channel_mgr = dvcman_new(drdynvc); drdynvc->channel_mgr = dvcman_new(drdynvc);
drdynvc->channel_error = 0; 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); dvcman_init(drdynvc->channel_mgr);
} }
@ -355,7 +381,7 @@ static void drdynvc_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event)
static void drdynvc_process_terminate(rdpSvcPlugin* plugin) static void drdynvc_process_terminate(rdpSvcPlugin* plugin)
{ {
drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; drdynvcPlugin* drdynvc = (drdynvcPlugin*) plugin;
DEBUG_DVC("terminating"); DEBUG_DVC("terminating");
@ -391,4 +417,3 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
return 1; return 1;
} }

View File

@ -74,7 +74,7 @@ struct _DVCMAN_ENTRY_POINTS
IDRDYNVC_ENTRY_POINTS iface; IDRDYNVC_ENTRY_POINTS iface;
DVCMAN* dvcman; DVCMAN* dvcman;
RDP_PLUGIN_DATA* plugin_data; ADDIN_ARGV* args;
}; };
typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL; typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL;
@ -183,14 +183,14 @@ IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* n
return NULL; 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) UINT32 dvcman_get_channel_id(IWTSVirtualChannel * channel)
{ {
return ((DVCMAN_CHANNEL*)channel)->channel_id; return ((DVCMAN_CHANNEL*) channel)->channel_id;
} }
IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId)
@ -202,7 +202,7 @@ IWTSVirtualChannel* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChanne
{ {
if (((DVCMAN_CHANNEL*) curr->data)->channel_id == ChannelId) if (((DVCMAN_CHANNEL*) curr->data)->channel_id == ChannelId)
{ {
return (IWTSVirtualChannel*)curr->data; return (IWTSVirtualChannel*) curr->data;
} }
} }
@ -224,29 +224,24 @@ IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin)
return (IWTSVirtualChannelManager*) dvcman; 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; DVCMAN_ENTRY_POINTS entryPoints;
PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL; PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL;
while (data && data->size > 0) printf("Loading Dynamic Virtual Channel %s\n", args->argv[0]);
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry(args->argv[0],
NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC);
if (pDVCPluginEntry != NULL)
{ {
printf("Loading Dynamic Virtual Channel %s\n", data->data[0]); entryPoints.iface.RegisterPlugin = dvcman_register_plugin;
entryPoints.iface.GetPlugin = dvcman_get_plugin;
pDVCPluginEntry = (PDVC_PLUGIN_ENTRY) freerdp_load_channel_addin_entry((char*) data->data[0], entryPoints.iface.GetPluginData = dvcman_get_plugin_data;
NULL, NULL, FREERDP_ADDIN_CHANNEL_DYNAMIC); entryPoints.dvcman = (DVCMAN*) pChannelMgr;
entryPoints.args = args;
if (pDVCPluginEntry != NULL) pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints);
{
entryPoints.iface.RegisterPlugin = dvcman_register_plugin;
entryPoints.iface.GetPlugin = dvcman_get_plugin;
entryPoints.iface.GetPluginData = dvcman_get_plugin_data;
entryPoints.dvcman = (DVCMAN*) pChannelMgr;
entryPoints.plugin_data = data;
pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints);
}
data = (RDP_PLUGIN_DATA*)(((BYTE*) data) + data->size);
} }
return 0; return 0;
@ -346,7 +341,7 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
for (i = 0; i < dvcman->num_listeners; i++) for (i = 0; i < dvcman->num_listeners; i++)
{ {
listener = (DVCMAN_LISTENER*)dvcman->listeners[i]; listener = (DVCMAN_LISTENER*) dvcman->listeners[i];
if (strcmp(listener->channel_name, ChannelName) == 0) if (strcmp(listener->channel_name, ChannelName) == 0)
{ {
@ -382,7 +377,6 @@ int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 Channel
return 1; return 1;
} }
int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId) int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId)
{ {
DVCMAN_CHANNEL* channel; DVCMAN_CHANNEL* channel;

View File

@ -21,10 +21,12 @@
#define __DVCMAN_H #define __DVCMAN_H
#include <freerdp/dvc.h> #include <freerdp/dvc.h>
#include <freerdp/addin.h>
#include "drdynvc_main.h" #include "drdynvc_main.h"
IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin); 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); void dvcman_free(IWTSVirtualChannelManager* pChannelMgr);
int dvcman_init(IWTSVirtualChannelManager* pChannelMgr); int dvcman_init(IWTSVirtualChannelManager* pChannelMgr);
int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, const char* ChannelName); 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(..)
include_directories(${ALSA_INCLUDE_DIRS}) 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 "") 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; ADDIN_ARGV* args;
rdpsndAlsaPlugin* alsa; rdpsndAlsaPlugin* alsa;
alsa = xnew(rdpsndAlsaPlugin); alsa = (rdpsndAlsaPlugin*) malloc(sizeof(rdpsndAlsaPlugin));
ZeroMemory(alsa, sizeof(rdpsndAlsaPlugin));
alsa->device.Open = rdpsnd_alsa_open; alsa->device.Open = rdpsnd_alsa_open;
alsa->device.FormatSupported = rdpsnd_alsa_format_supported; alsa->device.FormatSupported = rdpsnd_alsa_format_supported;

View File

@ -24,7 +24,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..) include_directories(..)
include_directories(${MACAUDIO_INCLUDE_DIRS}) 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 "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..) include_directories(..)
include_directories(${PULSE_INCLUDE_DIR}) 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 "") set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")

View File

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

View File

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

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..) include_directories(..)
include_directories(${ALSA_INCLUDE_DIRS}) 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 "") 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}) 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 <string.h>
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <winpr/crt.h>
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/dsp.h> #include <freerdp/utils/dsp.h>
@ -248,11 +252,16 @@ static void tsmf_alsa_free(ITSMFAudioDevice* audio)
free(alsa); 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; TSMFALSAAudioDevice* alsa;
alsa = xnew(TSMFALSAAudioDevice); alsa = (TSMFALSAAudioDevice*) malloc(sizeof(TSMFALSAAudioDevice));
ZeroMemory(alsa, sizeof(TSMFALSAAudioDevice));
alsa->iface.Open = tsmf_alsa_open; alsa->iface.Open = tsmf_alsa_open;
alsa->iface.SetFormat = tsmf_alsa_set_format; alsa->iface.SetFormat = tsmf_alsa_set_format;
@ -265,4 +274,3 @@ ITSMFAudioDevice* TSMFAudioDeviceEntry(void)
return (ITSMFAudioDevice*) alsa; return (ITSMFAudioDevice*) alsa;
} }

View File

@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
define_channel_client_subsystem("tsmf" "ffmpeg" "video") define_channel_client_subsystem("tsmf" "ffmpeg" "decoder")
set(${MODULE_PREFIX}_SRCS set(${MODULE_PREFIX}_SRCS
tsmf_ffmpeg.c) tsmf_ffmpeg.c)
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..) include_directories(..)
include_directories(${FFMPEG_INCLUDE_DIRS}) 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 "") 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}) 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 <stdlib.h>
#include <string.h> #include <string.h>
#include <winpr/crt.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include <freerdp/utils/event.h> #include <freerdp/utils/event.h>
#include <freerdp/client/tsmf.h> #include <freerdp/client/tsmf.h>
@ -60,6 +62,7 @@ static BOOL tsmf_ffmpeg_init_context(ITSMFDecoder* decoder)
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
mdecoder->codec_context = avcodec_alloc_context3(NULL); mdecoder->codec_context = avcodec_alloc_context3(NULL);
if (!mdecoder->codec_context) if (!mdecoder->codec_context)
{ {
DEBUG_WARN("avcodec_alloc_context failed."); 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) static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type)
{ {
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; BYTE* p;
UINT32 size; UINT32 size;
const BYTE* s; const BYTE* s;
BYTE* p; TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id); mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id);
if (!mdecoder->codec) if (!mdecoder->codec)
{ {
DEBUG_WARN("avcodec_find_decoder failed."); DEBUG_WARN("avcodec_find_decoder failed.");
@ -345,7 +349,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI
mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16; mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16;
mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max); mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max);
/* align the memory for SSE2 needs */ /* align the memory for SSE2 needs */
dst = (BYTE*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F); dst = (BYTE*) (((uintptr_t) mdecoder->decoded_data + 15) & ~ 0x0F);
dst_offset = dst - mdecoder->decoded_data; dst_offset = dst - mdecoder->decoded_data;
src = data; src = data;
src_size = data_size; src_size = data_size;
@ -373,7 +377,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI
(int16_t*) dst, &frame_size, src, src_size); (int16_t*) dst, &frame_size, src, src_size);
#else #else
{ {
AVFrame* decoded_frame = avcodec_alloc_frame(); AVFrame* decoded_frame = avcodec_alloc_frame();
int got_frame = 0; int got_frame = 0;
AVPacket pkt; AVPacket pkt;
av_init_packet(&pkt); av_init_packet(&pkt);
@ -383,7 +387,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI
if (len >= 0 && got_frame) if (len >= 0 && got_frame)
{ {
frame_size = av_samples_get_buffer_size(NULL, mdecoder->codec_context->channels, frame_size = av_samples_get_buffer_size(NULL, mdecoder->codec_context->channels,
decoded_frame->nb_samples, mdecoder->codec_context->sample_fmt, 1); decoded_frame->nb_samples, mdecoder->codec_context->sample_fmt, 1);
memcpy(dst, decoded_frame->data[0], frame_size); memcpy(dst, decoded_frame->data[0], frame_size);
} }
@ -396,6 +400,7 @@ static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE* data, UI
DEBUG_WARN("error decoding"); DEBUG_WARN("error decoding");
break; break;
} }
src += len; src += len;
src_size -= len; src_size -= len;
mdecoder->decoded_size += frame_size; 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) static BYTE* tsmf_ffmpeg_get_decoded_data(ITSMFDecoder* decoder, UINT32* size)
{ {
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
BYTE* buf; BYTE* buf;
TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
*size = mdecoder->decoded_size; *size = mdecoder->decoded_size;
buf = mdecoder->decoded_data; buf = mdecoder->decoded_data;
mdecoder->decoded_data = NULL; mdecoder->decoded_data = NULL;
mdecoder->decoded_size = 0; mdecoder->decoded_size = 0;
return buf; return buf;
} }
@ -492,8 +498,10 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
if (mdecoder->frame) if (mdecoder->frame)
av_free(mdecoder->frame); av_free(mdecoder->frame);
if (mdecoder->decoded_data) if (mdecoder->decoded_data)
free(mdecoder->decoded_data); free(mdecoder->decoded_data);
if (mdecoder->codec_context) if (mdecoder->codec_context)
{ {
if (mdecoder->prepared) if (mdecoder->prepared)
@ -502,12 +510,17 @@ static void tsmf_ffmpeg_free(ITSMFDecoder* decoder)
free(mdecoder->codec_context->extradata); free(mdecoder->codec_context->extradata);
av_free(mdecoder->codec_context); av_free(mdecoder->codec_context);
} }
free(decoder); free(decoder);
} }
static BOOL initialized = FALSE; 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; TSMFFFmpegDecoder* decoder;
@ -517,7 +530,10 @@ ITSMFDecoder* TSMFDecoderEntry(void)
initialized = TRUE; 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.SetFormat = tsmf_ffmpeg_set_format;
decoder->iface.Decode = tsmf_ffmpeg_decode; decoder->iface.Decode = tsmf_ffmpeg_decode;
@ -528,4 +544,3 @@ ITSMFDecoder* TSMFDecoderEntry(void)
return (ITSMFDecoder*) decoder; return (ITSMFDecoder*) decoder;
} }

View File

@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
define_channel_client_subsystem("tsmf" "gstreamer" "video") define_channel_client_subsystem("tsmf" "gstreamer" "decoder")
set(${MODULE_PREFIX}_SRCS set(${MODULE_PREFIX}_SRCS
tsmf_gstreamer.c) tsmf_gstreamer.c)
@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..) include_directories(..)
include_directories(${GSTREAMER_INCLUDE_DIRS}) 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 "") 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}) 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,10 +1565,13 @@ static void tsmf_gstreamer_update_rendering_area(ITSMFDecoder * decoder, int new
static int initialized = 0; static int initialized = 0;
ITSMFDecoder * #ifdef STATIC_CHANNELS
TSMFDecoderEntry(void) #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; TSMFGstreamerDecoder* decoder;
if (!initialized) if (!initialized)
{ {

View File

@ -23,7 +23,7 @@ set(${MODULE_PREFIX}_SRCS
include_directories(..) include_directories(..)
include_directories(${PULSE_INCLUDE_DIR}) 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 "") 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}) 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 <string.h>
#include <unistd.h> #include <unistd.h>
#include <winpr/crt.h>
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
#include "tsmf_audio.h" #include "tsmf_audio.h"
@ -389,11 +392,16 @@ static void tsmf_pulse_free(ITSMFAudioDevice* audio)
free(pulse); 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; TSMFPulseAudioDevice* pulse;
pulse = xnew(TSMFPulseAudioDevice); pulse = (TSMFPulseAudioDevice*) malloc(sizeof(TSMFPulseAudioDevice));
ZeroMemory(pulse, sizeof(TSMFPulseAudioDevice));
pulse->iface.Open = tsmf_pulse_open; pulse->iface.Open = tsmf_pulse_open;
pulse->iface.SetFormat = tsmf_pulse_set_format; 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; ITSMFAudioDevice* audio;
TSMF_AUDIO_DEVICE_ENTRY entry; TSMF_AUDIO_DEVICE_ENTRY entry;
char* fullname;
if (strrchr(name, '.') != NULL) entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_channel_addin_entry("tsmf", (LPSTR) name, "audio", 0);
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);
}
if (entry == NULL) if (entry == NULL)
{
return NULL; return NULL;
}
audio = entry(); audio = entry();
if (audio == NULL) if (audio == NULL)
{ {
DEBUG_WARN("failed to call export function in %s", name); DEBUG_WARN("failed to call export function in %s", name);
return NULL; return NULL;
} }
if (!audio->Open(audio, device)) if (!audio->Open(audio, device))
{ {
audio->Free(audio); audio->Free(audio);
audio = NULL; audio = NULL;
} }
return audio; return audio;
} }
@ -76,6 +68,7 @@ ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device)
else else
{ {
audio = tsmf_load_audio_device_by_name("pulse", device); audio = tsmf_load_audio_device_by_name("pulse", device);
if (!audio) if (!audio)
audio = tsmf_load_audio_device_by_name("alsa", device); audio = tsmf_load_audio_device_by_name("alsa", device);
} }

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@
#include <freerdp/api.h> #include <freerdp/api.h>
#include <freerdp/svc.h> #include <freerdp/svc.h>
#include <freerdp/addin.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#include <freerdp/utils/event.h> #include <freerdp/utils/event.h>
#include <freerdp/utils/debug.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(rdpSvcPlugin* plugin, STREAM* data_out);
FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event); 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 #ifdef WITH_DEBUG_SVC
#define DEBUG_SVC(fmt, ...) DEBUG_CLASS(SVC, fmt, ## __VA_ARGS__) #define DEBUG_SVC(fmt, ...) DEBUG_CLASS(SVC, fmt, ## __VA_ARGS__)
#else #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} set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr 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) if(MONOLITHIC_BUILD)
set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) 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) 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); return freerdp_load_dynamic_addin(name, NULL, entry_name);
} }

View File

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