Henri Verbeet : winealsa.drv: Only report endpoints for "default" if they can be opened.

Alexandre Julliard julliard at winehq.org
Thu Sep 22 13:39:47 CDT 2011


Module: wine
Branch: master
Commit: 0625d439de7106c3fb32d31ccb453eaaf89d5773
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0625d439de7106c3fb32d31ccb453eaaf89d5773

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Wed Sep 21 21:01:44 2011 +0200

winealsa.drv: Only report endpoints for "default" if they can be opened.

The default device may for example be a set of USB speakers or an USB
microphone, in which case you'd have just an output or just an input
respectively.

---

 dlls/winealsa.drv/mmdevdrv.c |   54 +++++++++++++++++++++++++++--------------
 1 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index e754738..c609903 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -237,15 +237,28 @@ int WINAPI AUDDRV_GetPriority(void)
     return Priority_Neutral;
 }
 
-static HRESULT alsa_get_card_devices(EDataFlow flow, WCHAR **ids, char **keys,
+static BOOL alsa_try_open(const char *devnode, snd_pcm_stream_t stream)
+{
+    snd_pcm_t *handle;
+    int err;
+
+    if((err = snd_pcm_open(&handle, devnode, stream, SND_PCM_NONBLOCK)) < 0){
+        WARN("The device \"%s\" failed to open: %d (%s).\n",
+                devnode, err, snd_strerror(err));
+        return FALSE;
+    }
+
+    snd_pcm_close(handle);
+    return TRUE;
+}
+
+static HRESULT alsa_get_card_devices(snd_pcm_stream_t stream, WCHAR **ids, char **keys,
         UINT *num, snd_ctl_t *ctl, int card, const WCHAR *cardnameW,
         BOOL count_failed)
 {
     static const WCHAR dashW[] = {' ','-',' ',0};
     int err, device;
     snd_pcm_info_t *info;
-    snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK :
-        SND_PCM_STREAM_CAPTURE);
 
     info = HeapAlloc(GetProcessHeap(), 0, snd_pcm_info_sizeof());
     if(!info)
@@ -259,7 +272,6 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, WCHAR **ids, char **keys,
             err = snd_ctl_pcm_next_device(ctl, &device)){
         const char *devname;
         char devnode[32];
-        snd_pcm_t *handle;
 
         snd_pcm_info_set_device(info, device);
 
@@ -274,16 +286,12 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, WCHAR **ids, char **keys,
         }
 
         sprintf(devnode, "hw:%d,%d", card, device);
-        if((err = snd_pcm_open(&handle, devnode, stream, SND_PCM_NONBLOCK)) < 0){
-            WARN("The device \"%s\" failed to open, pretending it doesn't exist: %d (%s)\n",
-                    devnode, err, snd_strerror(err));
+        if(!alsa_try_open(devnode, stream)){
             if(count_failed)
                 ++(*num);
             continue;
         }
 
-        snd_pcm_close(handle);
-
         if(ids && keys){
             DWORD len, cardlen;
 
@@ -333,10 +341,24 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, WCHAR **ids, char **keys,
 static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR **ids, char **keys,
         UINT *num, BOOL count_failed)
 {
+    snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK :
+        SND_PCM_STREAM_CAPTURE);
     int err, card;
 
     card = -1;
     *num = 0;
+
+    if(alsa_try_open(defname, stream)){
+        if(ids && keys){
+            *ids = HeapAlloc(GetProcessHeap(), 0, sizeof(defaultW));
+            memcpy(*ids, defaultW, sizeof(defaultW));
+            *keys = HeapAlloc(GetProcessHeap(), 0, sizeof(defname));
+            memcpy(*keys, defname, sizeof(defname));
+        }
+        ++*num;
+    }else if(count_failed)
+        ++*num;
+
     for(err = snd_card_next(&card); card != -1 && err >= 0;
             err = snd_card_next(&card)){
         char cardpath[64];
@@ -368,7 +390,7 @@ static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR **ids, char **keys,
         }
         MultiByteToWideChar(CP_UNIXCP, 0, cardname, -1, cardnameW, len);
 
-        alsa_get_card_devices(flow, ids, keys, num, ctl, card, cardnameW,
+        alsa_get_card_devices(stream, ids, keys, num, ctl, card, cardnameW,
                 count_failed);
 
         HeapFree(GetProcessHeap(), 0, cardnameW);
@@ -401,21 +423,17 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, char ***keys,
         return S_OK;
     }
 
-    *ids = HeapAlloc(GetProcessHeap(), 0, (*num + 1) * sizeof(WCHAR *));
-    *keys = HeapAlloc(GetProcessHeap(), 0, (*num + 1) * sizeof(char *));
+    *ids = HeapAlloc(GetProcessHeap(), 0, *num * sizeof(WCHAR *));
+    *keys = HeapAlloc(GetProcessHeap(), 0, *num * sizeof(char *));
     if(!*ids || !*keys){
         HeapFree(GetProcessHeap(), 0, *ids);
         HeapFree(GetProcessHeap(), 0, *keys);
         return E_OUTOFMEMORY;
     }
 
-    (*ids)[0] = HeapAlloc(GetProcessHeap(), 0, sizeof(defaultW));
-    memcpy((*ids)[0], defaultW, sizeof(defaultW));
-    (*keys)[0] = HeapAlloc(GetProcessHeap(), 0, sizeof(defname));
-    memcpy((*keys)[0], defname, sizeof(defname));
     *def_index = 0;
 
-    hr = alsa_enum_devices(flow, (*ids) + 1, (*keys) + 1, num, FALSE);
+    hr = alsa_enum_devices(flow, *ids, *keys, num, FALSE);
     if(FAILED(hr)){
         int i;
         for(i = 0; i < *num; ++i){
@@ -427,8 +445,6 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, char ***keys,
         return E_OUTOFMEMORY;
     }
 
-    ++(*num); /* for default device */
-
     return S_OK;
 }
 




More information about the wine-cvs mailing list