channels: refactoring of channel subsystems
This commit is contained in:
parent
83473d11d1
commit
2e1a7447a1
@ -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)
|
||||||
|
@ -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 "")
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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 "")
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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 "")
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 "")
|
||||||
|
|
||||||
|
@ -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 "")
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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*);
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user