Commit acc457d1 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

config: improve/fix the callback prototype for config item choices

parent 04e363a9
......@@ -50,6 +50,9 @@ typedef union
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 */
......@@ -66,7 +69,7 @@ struct module_config_t
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 */
......
......@@ -36,6 +36,7 @@
#include <inttypes.h>
#include <list>
#include <string>
#include <assert.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
......@@ -71,8 +72,7 @@ static size_t EnumDeviceCaps( vlc_object_t *, IBaseFilter *,
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 * );
......@@ -222,11 +222,11 @@ vlc_module_begin ()
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)
......@@ -2010,32 +2010,10 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
/*****************************************************************************
* 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;
......@@ -2048,25 +2026,28 @@ static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
/* 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,
......
......@@ -54,9 +54,8 @@ struct aout_sys_t
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).")
......@@ -81,7 +80,7 @@ vlc_module_begin ()
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)
......@@ -540,7 +539,7 @@ static int Open (vlc_object_t *obj)
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);
......@@ -733,55 +732,68 @@ static void Reorder71 (void *p, size_t n, unsigned size)
}
/*****************************************************************************
* 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;
p_item = config_FindConfig( p_this, psz_name );
if( !p_item ) return VLC_SUCCESS;
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();
/* Clear-up the current list */
if( p_item->i_list )
void **hints;
if (snd_device_name_hint(-1, "pcm", &hints) < 0)
return n;
for (size_t i = 0; hints[i] != NULL; i++)
{
int i;
void *hint = hints[i];
/* Keep the first entrie */
for( i = 1; i < p_item->i_list; i++ )
char *name = snd_device_name_get_hint(hint, "NAME");
if (unlikely(name == NULL))
continue;
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] );
}
/* TODO: Remove when no more needed */
p_item->ppsz_list[i] = NULL;
p_item->ppsz_list_text[i] = NULL;
free (name);
continue;
}
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];
......@@ -801,41 +813,15 @@ static void GetDevices (vlc_object_t *obj, module_config_t *item,
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);
}
}
snd_device_name_free_hint(hints);
if (item != NULL)
{
item->ppsz_list[item->i_list] = NULL;
item->ppsz_list_text[item->i_list] = NULL;
}
else
{
vlc_value_t val, text;
if (!hinted_default)
{
val.psz_string = (char *)"default";
......@@ -850,5 +836,4 @@ static void GetDevices (vlc_object_t *obj, module_config_t *item,
var_Change(obj, "audio-device", VLC_VAR_ADDCHOICE, &val, &text);
}
var_Change(obj, "audio-device", VLC_VAR_SETVALUE, &val, NULL);
}
}
......@@ -113,8 +113,8 @@ static void DestroyDSBuffer ( audio_output_t * );
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",
......@@ -1165,12 +1165,12 @@ static void* DirectSoundThread( void *data )
* 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;
}
......@@ -1178,15 +1178,15 @@ static int CALLBACK CallBackConfigNBEnum( LPGUID p_guid, LPCWSTR psz_desc,
* 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;
}
......@@ -1194,54 +1194,34 @@ static int CALLBACK CallBackConfigEnum( LPGUID p_guid, LPCWSTR psz_desc,
* 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;
}
......@@ -73,8 +73,8 @@ static int MuteSet( audio_output_t *, bool );
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)";
......@@ -172,11 +172,6 @@ static int Open( vlc_object_t *p_this )
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!
*/
......@@ -1041,39 +1036,20 @@ static int MuteSet( audio_output_t * p_aout, bool mute )
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];
......@@ -1084,15 +1060,12 @@ static int ReloadWaveoutDevices( vlc_object_t *p_this, char const *psz_name,
_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++;
(*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;
}
/*
......
......@@ -43,6 +43,7 @@
#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>
......@@ -87,8 +88,8 @@
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"))
......@@ -1404,70 +1405,66 @@ static int WallpaperCallback(vlc_object_t *object, char const *cmd,
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);
enum_context_t ctx;
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;
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;
if (hddraw_dll != NULL)
{
/* Enumerate displays */
HRESULT (WINAPI *OurDirectDrawEnumerateEx)(LPDDENUMCALLBACKEXA,
LPVOID, DWORD) =
(void *)GetProcAddress(hddraw_dll, _T("DirectDrawEnumerateExA"));
if (OurDirectDrawEnumerateEx)
OurDirectDrawEnumerateEx(DirectXEnumCallback2, item,
if (OurDirectDrawEnumerateEx != NULL)
OurDirectDrawEnumerateEx(DirectXEnumCallback2, &ctx,
DDENUM_ATTACHEDSECONDARYDEVICES);
FreeLibrary(hddraw_dll);
}
return VLC_SUCCESS;
VLC_UNUSED(object);
VLC_UNUSED(name);
*values = ctx.values;
*descs = ctx.descs;
return ctx.count;
}
......@@ -398,11 +398,7 @@ ssize_t config_GetPszChoices (vlc_object_t *obj, const char *name,
}
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)
......
......@@ -422,7 +422,7 @@ static int vlc_plugin_setter (void *plugin, void *tgt, int propid, ...)
}
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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment