float f;
} module_value_t;
+typedef int (*vlc_string_list_cb)(vlc_object_t *, const char *,
+ char ***, char ***);
+
struct module_config_t
{
char *psz_type; /* Configuration subtype */
int *pi_list; /* Idem for integers */
char **ppsz_list_text; /* Friendly names for list values */
int i_list; /* Options list size */
- vlc_callback_t pf_update_list; /* Callback to initialize dropdown lists */
+ vlc_string_list_cb pf_update_list;
uint8_t i_type; /* Configuration type */
char i_short; /* Optional short option name */
#include <inttypes.h>
#include <list>
#include <string>
+#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
AM_MEDIA_TYPE *mt, size_t );
static bool ConnectFilters( vlc_object_t *, access_sys_t *,
IBaseFilter *, CaptureFilter * );
-static int FindDevicesCallback( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
+static int FindDevices( vlc_object_t *, const char *, char ***, char *** );
static int ConfigDevicesCallback( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
set_subcategory( SUBCAT_INPUT_ACCESS )
add_string( CFG_PREFIX "vdev", NULL, VDEV_TEXT, VDEV_LONGTEXT, false)
- change_string_cb( FindDevicesCallback )
+ change_string_cb( FindDevices )
change_action_add( ConfigDevicesCallback, N_("Configure") )
add_string( CFG_PREFIX "adev", NULL, ADEV_TEXT, ADEV_LONGTEXT, false)
- change_string_cb( FindDevicesCallback )
+ change_string_cb( FindDevices )
change_action_add( ConfigDevicesCallback, N_("Configure") )
add_string( CFG_PREFIX "size", NULL, SIZE_TEXT, SIZE_LONGTEXT, false)
/*****************************************************************************
* config variable callback
*****************************************************************************/
-static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
- vlc_value_t, vlc_value_t, void * )
+static int FindDevices( vlc_object_t *p_this, const char *psz_name,
+ char ***vp, char ***tp )
{
- module_config_t *p_item;
- bool b_audio = false;
- int i;
-
- p_item = config_FindConfig( p_this, psz_name );
- if( !p_item ) return VLC_SUCCESS;
-
- if( !strcmp( psz_name, CFG_PREFIX "adev" ) ) b_audio = true;
-
- /* Clear-up the current list */
- if( p_item->i_list )
- {
- /* Keep the 2 first entries */
- for( i = 2; i < p_item->i_list; i++ )
- {
- free( p_item->ppsz_list[i] );
- free( p_item->ppsz_list_text[i] );
- }
- /* TODO: Remove when no more needed */
- p_item->ppsz_list[i] = NULL;
- p_item->ppsz_list_text[i] = NULL;
- }
- p_item->i_list = 2;
+ bool b_audio = !strcmp( psz_name, CFG_PREFIX "adev" );
/* Find list of devices */
list<string> list_devices;
/* Uninitialize OLE/COM */
CoUninitialize();
- if( list_devices.empty() ) return VLC_SUCCESS;
+ unsigned count = 2 + list_devices.size(), i = 2;
+ char **values = (char **)xmalloc( count * sizeof(*values) );
+ char **texts = (char **)xmalloc( count * sizeof(*texts) );
- p_item->ppsz_list = (char**)xrealloc( p_item->ppsz_list,
- (list_devices.size()+3) * sizeof(char *) );
- p_item->ppsz_list_text = (char**)xrealloc( p_item->ppsz_list_text,
- (list_devices.size()+3) * sizeof(char *) );
+ values[0] = strdup( "" );
+ texts[0] = strdup( N_("Default") );
+ values[1] = strdup( "none" );
+ texts[1] = strdup( N_("None") );
- list<string>::iterator iter;
- for( iter = list_devices.begin(), i = 2; iter != list_devices.end();
- ++iter, i++ )
+ for( list<string>::iterator iter = list_devices.begin();
+ iter != list_devices.end();
+ ++iter )
{
- p_item->ppsz_list[i] = strdup( iter->c_str() );
- p_item->ppsz_list_text[i] = NULL;
- p_item->i_list++;
+ assert( i < count );
+ values[i] = strdup( iter->c_str() );
+ texts[i] = strdup( iter->c_str() );
+ i++;
}
- p_item->ppsz_list[i] = NULL;
- p_item->ppsz_list_text[i] = NULL;
- return VLC_SUCCESS;
+ *vp = values;
+ *tp = texts;
+ return count;
}
static int ConfigDevicesCallback( vlc_object_t *p_this, char const *psz_name,
static int Open (vlc_object_t *);
static void Close (vlc_object_t *);
-static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
- vlc_value_t newval, vlc_value_t oldval, void *p_unused );
-static void GetDevices (vlc_object_t *, module_config_t *, const char *);
+static int EnumDevices (vlc_object_t *, char const *, char ***, char ***);
+static void GetDevices (vlc_object_t *, const char *);
#define AUDIO_DEV_TEXT N_("Audio output device")
#define AUDIO_DEV_LONGTEXT N_("Audio output device (using ALSA syntax).")
set_subcategory( SUBCAT_AUDIO_AOUT )
add_string ("alsa-audio-device", "default",
AUDIO_DEV_TEXT, AUDIO_DEV_LONGTEXT, false)
- change_string_cb( FindDevicesCallback )
+ change_string_cb (EnumDevices)
add_integer ("alsa-audio-channels", AOUT_CHANS_FRONT,
AUDIO_CHAN_TEXT, AUDIO_CHAN_LONGTEXT, false)
change_integer_list (channels, channels_text)
text.psz_string = _("Audio Device");
var_Change (obj, "audio-device", VLC_VAR_SETTEXT, &text, NULL);
- GetDevices (obj, NULL, device);
+ GetDevices (obj, device);
}
var_AddCallback (obj, "audio-device", DeviceChanged, NULL);
}
-/*****************************************************************************
- * config variable callback
- *****************************************************************************/
-static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
- vlc_value_t newval, vlc_value_t oldval, void *p_unused )
+/**
+ * Enumerates ALSA output devices.
+ */
+static int EnumDevices(vlc_object_t *obj, char const *varname,
+ char ***restrict vp, char ***restrict tp)
{
- module_config_t *p_item;
- (void)newval;
- (void)oldval;
- (void)p_unused;
+ unsigned n = 0;
+
+ char **names = xmalloc(sizeof (*names));
+ char **descs = xmalloc(sizeof (*names));
+ names[0] = strdup ("default");
+ descs[0] = strdup (N_("Default"));
+ n++;
+ if (unlikely(names[0] == NULL || descs[0] == NULL))
+ abort();
- p_item = config_FindConfig( p_this, psz_name );
- if( !p_item ) return VLC_SUCCESS;
+ void **hints;
+ if (snd_device_name_hint(-1, "pcm", &hints) < 0)
+ return n;
- /* Clear-up the current list */
- if( p_item->i_list )
+ for (size_t i = 0; hints[i] != NULL; i++)
{
- int i;
+ void *hint = hints[i];
+
+ char *name = snd_device_name_get_hint(hint, "NAME");
+ if (unlikely(name == NULL))
+ continue;
- /* Keep the first entrie */
- for( i = 1; i < p_item->i_list; i++ )
+ char *desc = snd_device_name_get_hint(hint, "DESC");
+ if (desc == NULL)
{
- free( (char *)p_item->ppsz_list[i] );
- free( (char *)p_item->ppsz_list_text[i] );
+ free (name);
+ continue;
}
- /* TODO: Remove when no more needed */
- p_item->ppsz_list[i] = NULL;
- p_item->ppsz_list_text[i] = NULL;
- }
- p_item->i_list = 1;
- GetDevices (p_this, p_item, "default");
+ names = xrealloc (names, (n + 1) * sizeof (*names));
+ descs = xrealloc (descs, (n + 1) * sizeof (*descs));
+ names[n] = name;
+ descs[n] = desc;
+ n++;
+ }
+ snd_device_name_free_hint(hints);
- return VLC_SUCCESS;
+ (void) obj; (void) varname;
+ *vp = names;
+ *tp = descs;
+ return n;
}
-static void GetDevices (vlc_object_t *obj, module_config_t *item,
- const char *prefs_dev)
+static void GetDevices(vlc_object_t *obj, const char *prefs_dev)
{
void **hints;
- bool hinted_default = false;
- bool hinted_prefs = !strcmp (prefs_dev, "default");
msg_Dbg(obj, "Available ALSA PCM devices:");
-
if (snd_device_name_hint(-1, "pcm", &hints) < 0)
return;
+ vlc_value_t val, text;
+ bool hinted_default = false;
+ bool hinted_prefs = !strcmp (prefs_dev, "default");
+
for (size_t i = 0; hints[i] != NULL; i++)
{
void *hint = hints[i];
if (!strcmp (name, prefs_dev))
hinted_prefs = true;
- if (item != NULL)
- {
- item->ppsz_list = xrealloc(item->ppsz_list,
- (item->i_list + 2) * sizeof(char *));
- item->ppsz_list_text = xrealloc(item->ppsz_list_text,
- (item->i_list + 2) * sizeof(char *));
- item->ppsz_list[item->i_list] = name;
- if (desc == NULL)
- desc = strdup(name);
- item->ppsz_list_text[item->i_list] = desc;
- item->i_list++;
- }
- else
- {
- vlc_value_t val, text;
-
- val.psz_string = name;
- text.psz_string = desc;
- var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
- free(desc);
- free(name);
- }
+ val.psz_string = name;
+ text.psz_string = desc;
+ var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
+ free(desc);
+ free(name);
}
snd_device_name_free_hint(hints);
- if (item != NULL)
+ if (!hinted_default)
{
- item->ppsz_list[item->i_list] = NULL;
- item->ppsz_list_text[item->i_list] = NULL;
+ val.psz_string = (char *)"default";
+ text.psz_string = (char *)N_("Default");
+ var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
}
- else
- {
- vlc_value_t val, text;
- if (!hinted_default)
- {
- val.psz_string = (char *)"default";
- text.psz_string = (char *)N_("Default");
- var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
- }
-
- val.psz_string = (char *)prefs_dev;
- if (!hinted_prefs)
- {
- text.psz_string = (char *)N_("VLC preferences");
- var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
- }
- var_Change(obj, "audio-device", VLC_VAR_SETVALUE, &val, NULL);
+ val.psz_string = (char *)prefs_dev;
+ if (!hinted_prefs)
+ {
+ text.psz_string = (char *)N_("VLC preferences");
+ var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
}
+ var_Change(obj, "audio-device", VLC_VAR_SETVALUE, &val, NULL);
}
static void* DirectSoundThread( void * );
static int FillBuffer ( audio_output_t *, int, block_t * );
-static int ReloadDirectXDevices( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
+static int ReloadDirectXDevices( vlc_object_t *, const char *,
+ char ***, char *** );
/* Speaker setup override options list */
static const char *const speaker_list[] = { "Windows default", "Mono", "Stereo",
* CallBackConfigNBEnum: callback to get the number of available devices
*****************************************************************************/
static int CALLBACK CallBackConfigNBEnum( LPGUID p_guid, LPCWSTR psz_desc,
- LPCWSTR psz_mod, LPVOID p_nb )
+ LPCWSTR psz_mod, LPVOID data )
{
- VLC_UNUSED( psz_mod ); VLC_UNUSED( psz_desc ); VLC_UNUSED( p_guid );
+ int *p_nb = data;
- int * a = (int *)p_nb;
- (*a)++;
+ (*p_nb)++;
+ VLC_UNUSED( psz_mod ); VLC_UNUSED( psz_desc ); VLC_UNUSED( p_guid );
return true;
}
* CallBackConfigEnum: callback to add available devices to the preferences list
*****************************************************************************/
static int CALLBACK CallBackConfigEnum( LPGUID p_guid, LPCWSTR psz_desc,
- LPCWSTR psz_mod, LPVOID _p_item )
+ LPCWSTR psz_mod, LPVOID data )
{
- VLC_UNUSED( psz_mod ); VLC_UNUSED( p_guid );
+ char **values = data;
- module_config_t *p_item = (module_config_t *) _p_item;
+ while( *values != NULL )
+ values++;
+ *values = FromWide( psz_desc );
- p_item->ppsz_list[p_item->i_list] = FromWide( psz_desc );
- p_item->ppsz_list_text[p_item->i_list] = FromWide( psz_desc );
- p_item->i_list++;
+ VLC_UNUSED( psz_mod ); VLC_UNUSED( p_guid );
return true;
}
* ReloadDirectXDevices: store the list of devices in preferences
*****************************************************************************/
static int ReloadDirectXDevices( vlc_object_t *p_this, char const *psz_name,
- vlc_value_t newval, vlc_value_t oldval, void *data )
+ char ***values, char ***descs )
{
- VLC_UNUSED( newval ); VLC_UNUSED( oldval ); VLC_UNUSED( data );
+ int nb_devices = 0;
- module_config_t *p_item = config_FindConfig( p_this, psz_name );
- if( !p_item ) return VLC_SUCCESS;
+ (void) psz_name;
- /* Clear-up the current list */
- if( p_item->i_list )
- {
- for( int i = 0; i < p_item->i_list; i++ )
- {
- free((char *)(p_item->ppsz_list[i]) );
- free((char *)(p_item->ppsz_list_text[i]) );
- }
- }
-
- HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACKW, LPVOID);
-
- HANDLE hdsound_dll = LoadLibrary("DSOUND.DLL");
+ HANDLE hdsound_dll = LoadLibrary(_T("DSOUND.DLL"));
if( hdsound_dll == NULL )
{
msg_Warn( p_this, "cannot open DSOUND.DLL" );
- return VLC_SUCCESS;
+ goto error;
}
/* Get DirectSoundEnumerate */
- OurDirectSoundEnumerate = (void *)
- GetProcAddress( hdsound_dll, "DirectSoundEnumerateW" );
-
+ HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACKW, LPVOID) =
+ (void *)GetProcAddress( hdsound_dll, _T("DirectSoundEnumerateW") );
if( OurDirectSoundEnumerate == NULL )
goto error;
- int nb_devices = 0;
OurDirectSoundEnumerate(CallBackConfigNBEnum, &nb_devices);
- msg_Dbg(p_this,"found %d devices", nb_devices);
-
- p_item->ppsz_list = xrealloc( p_item->ppsz_list,
- nb_devices * sizeof(char *) );
- p_item->ppsz_list_text = xrealloc( p_item->ppsz_list_text,
- nb_devices * sizeof(char *) );
-
- p_item->i_list = 0;
- OurDirectSoundEnumerate(CallBackConfigEnum, p_item);
+ msg_Dbg(p_this, "found %d devices", nb_devices);
+ *values = xcalloc( nb_devices, sizeof(char *) );
+ OurDirectSoundEnumerate(CallBackConfigEnum, *values);
+ *descs = xcalloc( nb_devices, sizeof(char *) );
+ OurDirectSoundEnumerate(CallBackConfigEnum, *descs);
error:
FreeLibrary(hdsound_dll);
-
- return VLC_SUCCESS;
+ return nb_devices;
}
static int WaveOutClearDoneBuffers(aout_sys_t *p_sys);
-static int ReloadWaveoutDevices( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
+static int ReloadWaveoutDevices( vlc_object_t *, const char *,
+ char ***, char *** );
static uint32_t findDeviceID(char *);
static const wchar_t device_name_fmt[] = L"%ls ($%x,$%x)";
p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = aout_PacketFlush;
- /*
- initialize/update Device selection List
- */
- ReloadWaveoutDevices( p_this, "waveout-audio-device", val, val, NULL);
-
/*
check for configured audio device!
*/
reload the configuration drop down list, of the Audio Devices
*/
static int ReloadWaveoutDevices( vlc_object_t *p_this, char const *psz_name,
- vlc_value_t newval, vlc_value_t oldval, void *data )
+ char ***values, char ***descs )
{
- VLC_UNUSED( newval ); VLC_UNUSED( oldval ); VLC_UNUSED( data );
-
- module_config_t *p_item = config_FindConfig( p_this, psz_name );
- if( !p_item ) return VLC_SUCCESS;
-
- /* Clear-up the current list */
- if( p_item->i_list )
- {
- int i;
+ int n = 0, nb_devices = waveOutGetNumDevs();
- /* Keep the first entry */
- for( i = 1; i < p_item->i_list; i++ )
- {
- free((char *)(p_item->ppsz_list[i]) );
- free((char *)(p_item->ppsz_list_text[i]) );
- }
- /* TODO: Remove when no more needed */
- p_item->ppsz_list[i] = NULL;
- p_item->ppsz_list_text[i] = NULL;
- }
- p_item->i_list = 1;
+ VLC_UNUSED( psz_name );
- int wave_devices = waveOutGetNumDevs();
+ *values = xmalloc( (nb_devices + 1) * sizeof(char *) );
+ *descs = xmalloc( (nb_devices + 1) * sizeof(char *) );
- p_item->ppsz_list = xrealloc( p_item->ppsz_list,
- (wave_devices+2) * sizeof(char *) );
- p_item->ppsz_list_text = xrealloc( p_item->ppsz_list_text,
- (wave_devices+2) * sizeof(char *) );
+ (*values)[n] = strdup( "wavemapper" );
+ (*descs)[n] = strdup( _("Microsoft Soundmapper") );
+ n++;
- int j=1;
- for(int i=0; i<wave_devices; i++)
+ for(int i = 0; i < nb_devices; i++)
{
WAVEOUTCAPS caps;
wchar_t dev_name[MAXPNAMELEN+32];
continue;
_snwprintf(dev_name, MAXPNAMELEN + 32, device_name_fmt,
- caps.szPname, caps.wMid, caps.wPid);
- p_item->ppsz_list[j] = FromWide( dev_name );
- p_item->ppsz_list_text[j] = FromWide( dev_name );
- p_item->i_list++;
- j++;
+ caps.szPname, caps.wMid, caps.wPid);
+ (*values)[n] = FromWide( dev_name );
+ (*descs)[n] = strdup( (*values)[n] );
+ n++;
}
- p_item->ppsz_list[j] = NULL;
- p_item->ppsz_list_text[j] = NULL;
- return VLC_SUCCESS;
+ return n;
}
/*
#include <vlc_plugin.h>
#include <vlc_vout_display.h>
#include <vlc_playlist.h> /* needed for wallpaper */
+#include <vlc_charset.h>
#include <windows.h>
#include <winuser.h>
static int Open (vlc_object_t *);
static void Close(vlc_object_t *);
-static int FindDevicesCallback(vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void *);
+static int FindDevicesCallback(vlc_object_t *, const char *,
+ char ***, char ***);
vlc_module_begin()
set_shortname("DirectX")
set_description(N_("DirectX (DirectDraw) video output"))
return VLC_SUCCESS;
}
+typedef struct
+{
+ char **values;
+ char **descs;
+ size_t count;
+} enum_context_t;
+
/*****************************************************************************
* config variable callback
*****************************************************************************/
static BOOL WINAPI DirectXEnumCallback2(GUID *guid, LPTSTR desc,
- LPTSTR drivername, VOID *context,
+ LPTSTR drivername, VOID *data,
HMONITOR hmon)
{
- VLC_UNUSED(guid); VLC_UNUSED(desc); VLC_UNUSED(hmon);
+ enum_context_t *ctx = data;
- module_config_t *item = context;
+ VLC_UNUSED(guid); VLC_UNUSED(desc); VLC_UNUSED(hmon);
- item->ppsz_list = xrealloc(item->ppsz_list,
- (item->i_list+2) * sizeof(char *));
- item->ppsz_list_text = xrealloc(item->ppsz_list_text,
- (item->i_list+2) * sizeof(char *));
+ ctx->values = xrealloc(ctx->values, (ctx->count + 1) * sizeof(char *));
+ ctx->descs = xrealloc(ctx->descs, (ctx->count + 1) * sizeof(char *));
- item->ppsz_list[item->i_list] = strdup(drivername);
- item->ppsz_list_text[item->i_list] = NULL;
- item->i_list++;
- item->ppsz_list[item->i_list] = NULL;
- item->ppsz_list_text[item->i_list] = NULL;
+ /* TODO? Unicode APIs */
+ ctx->values[ctx->count] = FromANSI(drivername);
+ ctx->descs[ctx->count] = FromANSI(drivername);
+ ctx->count++;
return TRUE; /* Keep enumerating */
}
-static int FindDevicesCallback(vlc_object_t *object, char const *name,
- vlc_value_t newval, vlc_value_t oldval, void *data)
+static int FindDevicesCallback(vlc_object_t *object, const char *name,
+ char ***values, char ***descs)
{
- VLC_UNUSED(newval); VLC_UNUSED(oldval); VLC_UNUSED(data);
-
- module_config_t *item = config_FindConfig(object, name);
- if (!item)
- return VLC_SUCCESS;
-
- /* Clear-up the current list */
- if (item->i_list > 0) {
- int i;
- /* Keep the first entry */
- for (i = 1; i < item->i_list; i++) {
- free(item->ppsz_list[i]);
- free(item->ppsz_list_text[i]);
- }
- /* TODO: Remove when no more needed */
- item->ppsz_list[i] = NULL;
- item->ppsz_list_text[i] = NULL;
- }
- item->i_list = 1;
+ enum_context_t ctx;
+
+ ctx.values = xmalloc(sizeof(char *));
+ ctx.descs = xmalloc(sizeof(char *));
+ ctx.values[0] = strdup("");
+ ctx.descs[0] = strdup(_("Default"));
+ ctx.count = 1;
/* Load direct draw DLL */
HINSTANCE hddraw_dll = LoadLibrary(_T("DDRAW.DLL"));
- if (!hddraw_dll)
- return VLC_SUCCESS;
-
- /* Enumerate displays */
- HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA,
- LPVOID, DWORD) =
- (void *)GetProcAddress(hddraw_dll, _T("DirectDrawEnumerateExA"));
- if (OurDirectDrawEnumerateEx)
- OurDirectDrawEnumerateEx(DirectXEnumCallback2, item,
- DDENUM_ATTACHEDSECONDARYDEVICES);
+ if (hddraw_dll != NULL)
+ {
+ /* Enumerate displays */
+ HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA,
+ LPVOID, DWORD) =
+ (void *)GetProcAddress(hddraw_dll, _T("DirectDrawEnumerateExA"));
+ if (OurDirectDrawEnumerateEx != NULL)
+ OurDirectDrawEnumerateEx(DirectXEnumCallback2, &ctx,
+ DDENUM_ATTACHEDSECONDARYDEVICES);
+ FreeLibrary(hddraw_dll);
+ }
- FreeLibrary(hddraw_dll);
+ VLC_UNUSED(object);
+ VLC_UNUSED(name);
- return VLC_SUCCESS;
+ *values = ctx.values;
+ *descs = ctx.descs;
+ return ctx.count;
}
}
if (cfg->pf_update_list != NULL)
- {
- /* FIXME: not thread-safe */
- vlc_value_t dummy = { .psz_string = (char *)"" };
- cfg->pf_update_list (obj, name, dummy, dummy, NULL);
- }
+ return cfg->pf_update_list (obj, name, values, texts);
size_t count = cfg->i_list;
if (count == 0)
}
case VLC_CONFIG_LIST_CB:
- item->pf_update_list = va_arg (ap, vlc_callback_t);
+ item->pf_update_list = va_arg (ap, vlc_string_list_cb);
break;
default: