Commit f461e849 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

winealsa.drv: Enumerate ALSA devices in a single pass.

parent 78fc648d
...@@ -329,6 +329,8 @@ static BOOL alsa_try_open(const char *devnode, snd_pcm_stream_t stream) ...@@ -329,6 +329,8 @@ static BOOL alsa_try_open(const char *devnode, snd_pcm_stream_t stream)
snd_pcm_t *handle; snd_pcm_t *handle;
int err; int err;
TRACE("devnode: %s, stream: %d\n", devnode, stream);
if((err = snd_pcm_open(&handle, devnode, stream, SND_PCM_NONBLOCK)) < 0){ if((err = snd_pcm_open(&handle, devnode, stream, SND_PCM_NONBLOCK)) < 0){
WARN("The device \"%s\" failed to open: %d (%s).\n", WARN("The device \"%s\" failed to open: %d (%s).\n",
devnode, err, snd_strerror(err)); devnode, err, snd_strerror(err));
...@@ -386,11 +388,13 @@ static WCHAR *construct_device_id(EDataFlow flow, const WCHAR *chunk1, const cha ...@@ -386,11 +388,13 @@ static WCHAR *construct_device_id(EDataFlow flow, const WCHAR *chunk1, const cha
}else }else
ret[copied] = 0; ret[copied] = 0;
TRACE("Enumerated device: %s\n", wine_dbgstr_w(ret));
return ret; return ret;
} }
static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream, static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream,
WCHAR **ids, GUID *guids, UINT *num, snd_ctl_t *ctl, int card, WCHAR ***ids, GUID **guids, UINT *num, snd_ctl_t *ctl, int card,
const WCHAR *cardnameW) const WCHAR *cardnameW)
{ {
int err, device; int err, device;
...@@ -425,18 +429,24 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream, ...@@ -425,18 +429,24 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream,
if(!alsa_try_open(devnode, stream)) if(!alsa_try_open(devnode, stream))
continue; continue;
if(ids && guids){ if(*num){
devname = snd_pcm_info_get_name(info); *ids = HeapReAlloc(GetProcessHeap(), 0, *ids, sizeof(WCHAR *) * (*num + 1));
if(!devname){ *guids = HeapReAlloc(GetProcessHeap(), 0, *guids, sizeof(GUID) * (*num + 1));
WARN("Unable to get device name for card %d, device %d\n", card, }else{
device); *ids = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *));
continue; *guids = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID));
} }
ids[*num] = construct_device_id(flow, cardnameW, devname); devname = snd_pcm_info_get_name(info);
get_device_guid(flow, devnode, &guids[*num]); if(!devname){
WARN("Unable to get device name for card %d, device %d\n", card,
device);
continue;
} }
(*ids)[*num] = construct_device_id(flow, cardnameW, devname);
get_device_guid(flow, devnode, &(*guids)[*num]);
++(*num); ++(*num);
} }
...@@ -449,8 +459,8 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream, ...@@ -449,8 +459,8 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream,
return S_OK; return S_OK;
} }
static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids, static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR ***ids,
GUID *guids, UINT *num) GUID **guids, UINT *num)
{ {
static const WCHAR ALSAOutputDevices[] = {'A','L','S','A','O','u','t','p','u','t','D','e','v','i','c','e','s',0}; static const WCHAR ALSAOutputDevices[] = {'A','L','S','A','O','u','t','p','u','t','D','e','v','i','c','e','s',0};
static const WCHAR ALSAInputDevices[] = {'A','L','S','A','I','n','p','u','t','D','e','v','i','c','e','s',0}; static const WCHAR ALSAInputDevices[] = {'A','L','S','A','I','n','p','u','t','D','e','v','i','c','e','s',0};
...@@ -477,10 +487,15 @@ static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids ...@@ -477,10 +487,15 @@ static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids
WideCharToMultiByte(CP_UNIXCP, 0, p, -1, devname, sizeof(devname), NULL, NULL); WideCharToMultiByte(CP_UNIXCP, 0, p, -1, devname, sizeof(devname), NULL, NULL);
if(alsa_try_open(devname, stream)){ if(alsa_try_open(devname, stream)){
if(ids && guids){ if(*num){
ids[*num] = construct_device_id(flow, p, NULL); *ids = HeapReAlloc(GetProcessHeap(), 0, *ids, sizeof(WCHAR *) * (*num + 1));
get_device_guid(flow, devname, &guids[*num]); *guids = HeapReAlloc(GetProcessHeap(), 0, *guids, sizeof(GUID) * (*num + 1));
}else{
*ids = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *));
*guids = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID));
} }
(*ids)[*num] = construct_device_id(flow, p, NULL);
get_device_guid(flow, devname, &(*guids)[*num]);
++*num; ++*num;
} }
...@@ -492,7 +507,7 @@ static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids ...@@ -492,7 +507,7 @@ static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids
} }
} }
static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR **ids, GUID *guids, static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR ***ids, GUID **guids,
UINT *num) UINT *num)
{ {
snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK : snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK :
...@@ -503,10 +518,10 @@ static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR **ids, GUID *guids, ...@@ -503,10 +518,10 @@ static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR **ids, GUID *guids,
*num = 0; *num = 0;
if(alsa_try_open(defname, stream)){ if(alsa_try_open(defname, stream)){
if(ids && guids){ *ids = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *));
*ids = construct_device_id(flow, defaultW, NULL); (*ids)[0] = construct_device_id(flow, defaultW, NULL);
get_device_guid(flow, defname, guids); *guids = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID));
} get_device_guid(flow, defname, &(*guids)[0]);
++*num; ++*num;
} }
...@@ -568,37 +583,30 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, GUID **guids, ...@@ -568,37 +583,30 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, GUID **guids,
TRACE("%d %p %p %p %p\n", flow, ids, guids, num, def_index); TRACE("%d %p %p %p %p\n", flow, ids, guids, num, def_index);
hr = alsa_enum_devices(flow, NULL, NULL, num); *ids = NULL;
if(FAILED(hr)) *guids = NULL;
return hr;
if(*num == 0)
{
*ids = NULL;
*guids = NULL;
return S_OK;
}
*ids = HeapAlloc(GetProcessHeap(), 0, *num * sizeof(WCHAR *)); hr = alsa_enum_devices(flow, ids, guids, num);
*guids = HeapAlloc(GetProcessHeap(), 0, *num * sizeof(GUID)); if(FAILED(hr)){
if(!*ids || !*guids){ UINT i;
for(i = 0; i < *num; ++i)
HeapFree(GetProcessHeap(), 0, (*ids)[i]);
HeapFree(GetProcessHeap(), 0, *ids); HeapFree(GetProcessHeap(), 0, *ids);
HeapFree(GetProcessHeap(), 0, *guids); HeapFree(GetProcessHeap(), 0, *guids);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
*def_index = 0; TRACE("Enumerated %u devices\n", *num);
hr = alsa_enum_devices(flow, *ids, *guids, num); if(*num == 0){
if(FAILED(hr)){
int i;
for(i = 0; i < *num; ++i)
HeapFree(GetProcessHeap(), 0, (*ids)[i]);
HeapFree(GetProcessHeap(), 0, *ids); HeapFree(GetProcessHeap(), 0, *ids);
*ids = NULL;
HeapFree(GetProcessHeap(), 0, *guids); HeapFree(GetProcessHeap(), 0, *guids);
return E_OUTOFMEMORY; *guids = NULL;
} }
*def_index = 0;
return S_OK; return S_OK;
} }
......
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