[pulseaudio-commits] r1069 - in /trunk/src: Makefile.am pulse/browser.c pulse/browser.h pulsecore/avahi-wrap.h

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Thu Jul 13 10:33:45 PDT 2006


Author: lennart
Date: Thu Jul 13 19:33:44 2006
New Revision: 1069

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=1069&root=pulseaudio&view=rev
Log:
* port libpulse-browse to use the native avahi API instead of the HOWL cruft
* add new function pa_browser_set_error_callback()
* add doxygen docs to browser.h

Modified:
    trunk/src/Makefile.am
    trunk/src/pulse/browser.c
    trunk/src/pulse/browser.h
    trunk/src/pulsecore/avahi-wrap.h

Modified: trunk/src/Makefile.am
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/Makefile.am?rev=1069&root=pulseaudio&r1=1068&r2=1069&view=diff
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Thu Jul 13 19:33:44 2006
@@ -140,7 +140,7 @@
 bin_PROGRAMS += pax11publish
 endif
 
-if HAVE_HOWL
+if HAVE_AVAHI
 bin_PROGRAMS += pabrowse
 endif
 
@@ -319,7 +319,7 @@
 		pulse/volume.h \
 		pulse/xmalloc.h
 
-if HAVE_HOWL
+if HAVE_AVAHI
 pulseinclude_HEADERS += \
 		pulse/browser.h
 endif
@@ -338,7 +338,7 @@
 		libpulse.la \
 		libpulse-simple.la
 
-if HAVE_HOWL
+if HAVE_AVAHI
 lib_LTLIBRARIES += \
 		libpulse-browse.la
 endif
@@ -444,9 +444,9 @@
 libpulse_simple_la_LIBADD = $(AM_LIBADD) libpulse.la
 libpulse_simple_la_LDFLAGS = -version-info $(LIBPULSE_SIMPLE_VERSION_INFO)
 
-libpulse_browse_la_SOURCES = pulse/browser.c pulse/browser.h 
-libpulse_browse_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS)
-libpulse_browse_la_LIBADD = $(AM_LIBADD) libpulse.la $(HOWL_LIBS)
+libpulse_browse_la_SOURCES = pulse/browser.c pulse/browser.h pulsecore/avahi-wrap.c pulsecore/avahi-wrap.h
+libpulse_browse_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
+libpulse_browse_la_LIBADD = $(AM_LIBADD) libpulse.la $(AVAHI_LIBS)
 libpulse_browse_la_LDFLAGS = -version-info $(LIBPULSE_BROWSE_VERSION_INFO)
 
 libpulse_mainloop_glib_la_SOURCES = pulse/glib-mainloop.h pulse/glib-mainloop.c
@@ -864,9 +864,8 @@
 		module-solaris.la
 endif
 
-if HAVE_HOWL
-modlibexec_LTLIBRARIES += \
-		libhowl-wrap.la \
+if HAVE_AVAHI
+modlibexec_LTLIBRARIES += \
 		module-zeroconf-publish.la
 endif
 
@@ -1111,12 +1110,7 @@
 module_solaris_la_LDFLAGS = -module -avoid-version
 module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la
 
-# HOWL
-
-libhowl_wrap_la_SOURCES = modules/howl-wrap.c modules/howl-wrap.h
-libhowl_wrap_la_LDFLAGS = -avoid-version
-libhowl_wrap_la_LIBADD = $(AM_LIBADD) $(HOWL_LIBS) libpulsecore.la
-libhowl_wrap_la_CFLAGS = $(AM_CFLAGS) $(HOWL_CFLAGS)
+# Avahi
 
 module_zeroconf_publish_la_SOURCES = modules/module-zeroconf-publish.c
 module_zeroconf_publish_la_LDFLAGS = -module -avoid-version

Modified: trunk/src/pulse/browser.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulse/browser.c?rev=1069&root=pulseaudio&r1=1068&r2=1069&view=diff
==============================================================================
--- trunk/src/pulse/browser.c (original)
+++ trunk/src/pulse/browser.c Thu Jul 13 19:33:44 2006
@@ -24,85 +24,68 @@
 #endif 
 
 #include <assert.h>
-#include <howl.h>
+#include <string.h>
+
+#include <avahi-client/lookup.h>
+#include <avahi-common/domain.h>
+#include <avahi-common/error.h>
 
 #include <pulse/xmalloc.h>
 
 #include <pulsecore/log.h>
 #include <pulsecore/core-util.h>
 
+#include <pulsecore/avahi-wrap.h>
+
 #include "browser.h"
 
-#define SERVICE_NAME_SINK "_pulse-sink._tcp."
-#define SERVICE_NAME_SOURCE "_pulse-source._tcp."
-#define SERVICE_NAME_SERVER "_pulse-server._tcp."
+#define SERVICE_TYPE_SINK "_pulse-sink._tcp."
+#define SERVICE_TYPE_SOURCE "_pulse-source._tcp."
+#define SERVICE_TYPE_SERVER "_pulse-server._tcp."
 
 struct pa_browser {
     int ref;
     pa_mainloop_api *mainloop;
+    AvahiPoll* avahi_poll;
 
     pa_browse_cb_t callback;
     void *userdata;
-    
-    sw_discovery discovery;
-    pa_io_event *io_event;
+
+    pa_browser_error_cb_t error_callback;
+    void *error_userdata;
+    
+    AvahiClient *client;
+    AvahiServiceBrowser *server_browser, *sink_browser, *source_browser;
+    
 };
 
-static void io_callback(pa_mainloop_api*a, PA_GCC_UNUSED pa_io_event*e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void *userdata) {
+static int map_to_opcode(const char *type, int new) {
+    if (avahi_domain_equal(type, SERVICE_TYPE_SINK))
+        return new ? PA_BROWSE_NEW_SINK : PA_BROWSE_REMOVE_SINK;
+    else if (avahi_domain_equal(type, SERVICE_TYPE_SOURCE))
+        return new ? PA_BROWSE_NEW_SOURCE : PA_BROWSE_REMOVE_SOURCE;
+    else if (avahi_domain_equal(type, SERVICE_TYPE_SERVER))
+        return new ? PA_BROWSE_NEW_SERVER : PA_BROWSE_REMOVE_SERVER;
+
+    return -1;
+}
+
+static void resolve_callback(
+        AvahiServiceResolver *r,
+        AvahiIfIndex interface,
+        AvahiProtocol protocol,
+        AvahiResolverEvent event,
+        const char *name,
+        const char *type,
+        const char *domain,
+        const char *host_name,
+        const AvahiAddress *aa,
+        uint16_t port,
+        AvahiStringList *txt,
+        AvahiLookupResultFlags flags,
+        void *userdata) {
+    
     pa_browser *b = userdata;
-    assert(a && b && b->mainloop == a);
-
-    if (events != PA_IO_EVENT_INPUT || sw_discovery_read_socket(b->discovery) != SW_OKAY) {
-        pa_log(__FILE__": connection to HOWL daemon failed.");
-        b->mainloop->io_free(b->io_event);
-        b->io_event = NULL;
-        return;
-    }
-}
-
-static int type_equal(const char *a, const char *b) {
-    size_t la, lb;
-    
-    if (strcasecmp(a, b) == 0)
-        return 1;
-
-    la = strlen(a);
-    lb = strlen(b);
-
-    if (la > 0 && a[la-1] == '.' && la == lb+1 && strncasecmp(a, b, la-1) == 0)
-        return 1;
-                                            
-    if (lb > 0 && b[lb-1] == '.' && lb == la+1 && strncasecmp(a, b, lb-1) == 0)
-        return 1;
-
-    return 0;
-}
-
-static int map_to_opcode(const char *type, int new) {
-    if (type_equal(type, SERVICE_NAME_SINK))
-        return new ? PA_BROWSE_NEW_SINK : PA_BROWSE_REMOVE_SINK;
-    else if (type_equal(type, SERVICE_NAME_SOURCE))
-        return new ? PA_BROWSE_NEW_SOURCE : PA_BROWSE_REMOVE_SOURCE;
-    else if (type_equal(type, SERVICE_NAME_SERVER))
-        return new ? PA_BROWSE_NEW_SERVER : PA_BROWSE_REMOVE_SERVER;
-
-    return -1;
-}
-
-static sw_result resolve_reply(
-        sw_discovery discovery,
-        sw_discovery_oid oid,
-        sw_uint32 interface_index,
-        sw_const_string name,
-        sw_const_string type,
-        sw_const_string domain,
-        sw_ipv4_address address,
-        sw_port port,
-        sw_octets text_record,
-        sw_ulong text_record_len,
-        sw_opaque extra) {
-    
-    pa_browser *b = extra;
     pa_browse_info i;
     char ip[256], a[256];
     int opcode;
@@ -110,100 +93,96 @@
     uint32_t cookie;
     pa_sample_spec ss;
     int ss_valid = 0;
-    sw_text_record_iterator iterator;
-    int free_iterator = 0;
-    char *c = NULL;
-    
-    assert(b);
-
-    sw_discovery_cancel(discovery, oid);
+    char *key = NULL, *value = NULL;
+    
+    assert(b);
 
     memset(&i, 0, sizeof(i));
     i.name = name;
-        
+
+    if (event != AVAHI_RESOLVER_FOUND)
+        goto fail;
+    
     if (!b->callback)
         goto fail;
 
     opcode = map_to_opcode(type, 1);
     assert(opcode >= 0);
-    
-    snprintf(a, sizeof(a), "tcp:%s:%u", sw_ipv4_address_name(address, ip, sizeof(ip)), port);
+
+    if (aa->proto == AVAHI_PROTO_INET)
+        snprintf(a, sizeof(a), "tcp:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port);
+    else {
+        assert(aa->proto == AVAHI_PROTO_INET6);
+        snprintf(a, sizeof(a), "tcp6:%s:%u", avahi_address_snprint(ip, sizeof(ip), aa), port);
+    }
     i.server = a;
-    
-    if (text_record && text_record_len) {
-        char key[SW_TEXT_RECORD_MAX_LEN];
-        uint8_t val[SW_TEXT_RECORD_MAX_LEN];
-        uint32_t val_len;
+
+
+    while (txt) {
+        
+        if (avahi_string_list_get_pair(txt, &key, &value, NULL) < 0)
+            break;
   
-        if (sw_text_record_iterator_init(&iterator, text_record, text_record_len) != SW_OKAY) {
-            pa_log_error(__FILE__": sw_text_record_string_iterator_init() failed.");
-            goto fail;
+        if (!strcmp(key, "device")) {
+            device_found = 1;
+            pa_xfree((char*) i.device);
+            i.device = value;
+            value = NULL;
+        } else if (!strcmp(key, "server-version")) {
+            pa_xfree((char*) i.server_version);
+            i.server_version = value;
+            value = NULL;
+        } else if (!strcmp(key, "user-name")) {
+            pa_xfree((char*) i.user_name);
+            i.user_name = value;
+            value = NULL;
+        } else if (!strcmp(key, "fqdn")) {
+            size_t l;
+            
+            pa_xfree((char*) i.fqdn);
+            i.fqdn = value;
+            value = NULL;
+                
+            l = strlen(a);
+            assert(l+1 <= sizeof(a));
+            strncat(a, " ", sizeof(a)-l-1);
+            strncat(a, i.fqdn, sizeof(a)-l-2);
+        } else if (!strcmp(key, "cookie")) {
+
+            if (pa_atou(value, &cookie) < 0)
+                goto fail;
+            
+            i.cookie = &cookie;
+        } else if (!strcmp(key, "description")) {
+            pa_xfree((char*) i.description);
+            i.description = value;
+            value = NULL;
+        } else if (!strcmp(key, "channels")) {
+            uint32_t ch;
+            
+            if (pa_atou(value, &ch) < 0 || ch <= 0 || ch > 255)
+                goto fail;
+            
+            ss.channels = (uint8_t) ch;
+            ss_valid |= 1;
+            
+        } else if (!strcmp(key, "rate")) {
+            if (pa_atou(value, &ss.rate) < 0)
+                goto fail;
+            ss_valid |= 2;
+        } else if (!strcmp(key, "format")) {
+
+            if ((ss.format = pa_parse_sample_format(value)) == PA_SAMPLE_INVALID)
+                goto fail;
+            
+            ss_valid |= 4;
         }
 
-        free_iterator = 1;
-        
-        while (sw_text_record_iterator_next(iterator, key, val, &val_len) == SW_OKAY) {
-            c = pa_xstrndup((char*) val, val_len);
-            
-            if (!strcmp(key, "device")) {
-                device_found = 1;
-                pa_xfree((char*) i.device);
-                i.device = c;
-                c = NULL;
-            } else if (!strcmp(key, "server-version")) {
-                pa_xfree((char*) i.server_version);
-                i.server_version = c;
-                c = NULL;
-            } else if (!strcmp(key, "user-name")) {
-                pa_xfree((char*) i.user_name);
-                i.user_name = c;
-                c = NULL;
-            } else if (!strcmp(key, "fqdn")) {
-                size_t l;
-                
-                pa_xfree((char*) i.fqdn);
-                i.fqdn = c;
-                c = NULL;
-                
-                l = strlen(a);
-                assert(l+1 <= sizeof(a));
-                strncat(a, " ", sizeof(a)-l-1);
-                strncat(a, i.fqdn, sizeof(a)-l-2);
-            } else if (!strcmp(key, "cookie")) {
-
-                if (pa_atou(c, &cookie) < 0)
-                    goto fail;
-                
-                i.cookie = &cookie;
-            } else if (!strcmp(key, "description")) {
-                pa_xfree((char*) i.description);
-                i.description = c;
-                c = NULL;
-            } else if (!strcmp(key, "channels")) {
-                uint32_t ch;
-                
-                if (pa_atou(c, &ch) < 0 || ch <= 0 || ch > 255)
-                    goto fail;
-
-                ss.channels = (uint8_t) ch;
-                ss_valid |= 1;
-
-            } else if (!strcmp(key, "rate")) {
-                if (pa_atou(c, &ss.rate) < 0)
-                    goto fail;
-                ss_valid |= 2;
-            } else if (!strcmp(key, "format")) {
-
-                if ((ss.format = pa_parse_sample_format(c)) == PA_SAMPLE_INVALID)
-                    goto fail;
-                
-                ss_valid |= 4;
-            }
-
-            pa_xfree(c);
-            c = NULL;
-        }
-        
+        pa_xfree(key);
+        pa_xfree(value);
+        key = value = NULL;
+
+        txt = avahi_string_list_get_next(txt);
     }
 
     /* No device txt record was sent for a sink or source service */
@@ -212,7 +191,6 @@
 
     if (ss_valid == 7)
         i.sample_spec = &ss;
-    
 
     b->callback(b, opcode, &i, b->userdata);
 
@@ -222,39 +200,72 @@
     pa_xfree((void*) i.server_version);
     pa_xfree((void*) i.user_name);
     pa_xfree((void*) i.description);
-    pa_xfree(c);
-
-    if (free_iterator)
-        sw_text_record_iterator_fina(iterator);
-
-    
-    return SW_OKAY;
-}
-
-static sw_result browse_reply(
-        sw_discovery discovery,
-        sw_discovery_oid id,
-        sw_discovery_browse_status status,
-        sw_uint32 interface_index,
-        sw_const_string name,
-        sw_const_string type,
-        sw_const_string domain,
-        sw_opaque extra) {
-    
-    pa_browser *b = extra;
-    assert(b);
-
-    switch (status) {
-        case SW_DISCOVERY_BROWSE_ADD_SERVICE: {
-            sw_discovery_oid oid;
-
-            if (sw_discovery_resolve(b->discovery, 0, name, type, domain, resolve_reply, b, &oid) != SW_OKAY)
-                pa_log_error(__FILE__": sw_discovery_resolve() failed");
+
+    pa_xfree(key);
+    pa_xfree(value);
+    
+    avahi_service_resolver_free(r);
+}
+
+static void handle_failure(pa_browser *b) {
+    const char *e = NULL;
+    assert(b);
+
+    if (b->sink_browser)
+        avahi_service_browser_free(b->sink_browser);
+    if (b->source_browser)
+        avahi_service_browser_free(b->source_browser);
+    if (b->server_browser)
+        avahi_service_browser_free(b->server_browser);
+
+    b->sink_browser = b->source_browser = b->server_browser = NULL;
+
+    if (b->client) {
+        e = avahi_strerror(avahi_client_errno(b->client));
+        avahi_client_free(b->client);
+    }
+
+    b->client = NULL;
+
+    if (b->error_callback)
+        b->error_callback(b, e, b->error_userdata);
+}
+
+static void browse_callback(
+        AvahiServiceBrowser *sb,
+        AvahiIfIndex interface,
+        AvahiProtocol protocol,
+        AvahiBrowserEvent event,
+        const char *name,
+        const char *type,
+        const char *domain,
+        AvahiLookupResultFlags flags,
+        void *userdata) {
+
+    pa_browser *b = userdata;
+    assert(b);
+
+    switch (event) {
+        case AVAHI_BROWSER_NEW: {
+
+            if (!avahi_service_resolver_new(
+                          b->client,
+                          interface,
+                          protocol,
+                          name,
+                          type,
+                          domain,
+                          AVAHI_PROTO_UNSPEC,
+                          0,
+                          resolve_callback,
+                          b))
+                handle_failure(b);
 
             break;
         }
             
-        case SW_DISCOVERY_BROWSE_REMOVE_SERVICE:
+        case AVAHI_BROWSER_REMOVE: {
+
             if (b->callback) {
                 pa_browse_info i;
                 int opcode;
@@ -268,63 +279,144 @@
                 b->callback(b, opcode, &i, b->userdata);
             }
             break;
-
+        }
+
+        case AVAHI_BROWSER_FAILURE: {
+            handle_failure(b);
+            break;
+        }
+            
         default:
             ;
     }
-
-    return SW_OKAY;
-}
+}
+
+static void client_callback(AvahiClient *s, AvahiClientState state, void *userdata) {
+    pa_browser *b = userdata;
+    assert(s);
+
+    if (state == AVAHI_CLIENT_FAILURE)
+        handle_failure(b);
+}
+
+static void browser_free(pa_browser *b);
 
 pa_browser *pa_browser_new(pa_mainloop_api *mainloop) {
+    return pa_browser_new_full(mainloop, PA_BROWSE_FOR_SERVERS|PA_BROWSE_FOR_SINKS|PA_BROWSE_FOR_SOURCES, NULL);
+}
+
+pa_browser *pa_browser_new_full(pa_mainloop_api *mainloop, pa_browse_flags_t flags, const char **error_string) {
     pa_browser *b;
-    sw_discovery_oid oid;
-
+    int error;
+
+    assert(mainloop);
+
+    if (flags & ~(PA_BROWSE_FOR_SERVERS|PA_BROWSE_FOR_SINKS|PA_BROWSE_FOR_SOURCES) || flags == 0)
+        return NULL;
+    
     b = pa_xnew(pa_browser, 1);
     b->mainloop = mainloop;
     b->ref = 1;
     b->callback = NULL;
     b->userdata = NULL;
-
-    if (sw_discovery_init(&b->discovery) != SW_OKAY) {
-        pa_log_error(__FILE__": sw_discovery_init() failed.");
-        pa_xfree(b);
-        return NULL;
-    }
-    
-    if (sw_discovery_browse(b->discovery, 0, SERVICE_NAME_SERVER, NULL, browse_reply, b, &oid) != SW_OKAY ||
-        sw_discovery_browse(b->discovery, 0, SERVICE_NAME_SINK, NULL, browse_reply, b, &oid) != SW_OKAY ||
-        sw_discovery_browse(b->discovery, 0, SERVICE_NAME_SOURCE, NULL, browse_reply, b, &oid) != SW_OKAY) {
-
-        pa_log_error(__FILE__": sw_discovery_browse() failed.");
-        
-        sw_discovery_fina(b->discovery);
-        pa_xfree(b);
-        return NULL;
-    }
-    
-    b->io_event = mainloop->io_new(mainloop, sw_discovery_socket(b->discovery), PA_IO_EVENT_INPUT, io_callback, b);
+    b->error_callback = NULL;
+    b->error_userdata = NULL;
+    b->sink_browser = b->source_browser = b->server_browser = NULL;
+
+    b->avahi_poll = pa_avahi_poll_new(mainloop);
+
+    if (!(b->client = avahi_client_new(b->avahi_poll, 0, client_callback, b, &error))) {
+        if (error_string)
+            *error_string = avahi_strerror(error);
+        goto fail;
+    }
+
+    if ((flags & PA_BROWSE_FOR_SERVERS) &&
+        !(b->server_browser = avahi_service_browser_new(
+                  b->client,
+                  AVAHI_IF_UNSPEC,
+                  AVAHI_PROTO_UNSPEC,
+                  SERVICE_TYPE_SERVER,
+                  NULL,
+                  0,
+                  browse_callback,
+                  b))) {
+
+        if (error_string)
+            *error_string = avahi_strerror(avahi_client_errno(b->client));
+        goto fail;
+    }
+    
+    if ((flags & PA_BROWSE_FOR_SINKS) &&
+        !(b->sink_browser = avahi_service_browser_new(
+                  b->client,
+                  AVAHI_IF_UNSPEC,
+                  AVAHI_PROTO_UNSPEC,
+                  SERVICE_TYPE_SINK,
+                  NULL,
+                  0,
+                  browse_callback,
+                  b))) {
+
+        if (error_string)
+            *error_string = avahi_strerror(avahi_client_errno(b->client));
+        goto fail;
+    }
+
+    if ((flags & PA_BROWSE_FOR_SOURCES) &&
+        !(b->source_browser = avahi_service_browser_new(
+                  b->client,
+                  AVAHI_IF_UNSPEC,
+                  AVAHI_PROTO_UNSPEC,
+                  SERVICE_TYPE_SOURCE,
+                  NULL,
+                  0,
+                  browse_callback,
+                  b))) {
+
+        if (error_string)
+            *error_string = avahi_strerror(avahi_client_errno(b->client));
+        goto fail;
+    }
+    
     return b;
+
+fail:
+    if (b)
+        browser_free(b);
+    
+    return NULL;
 }
 
 static void browser_free(pa_browser *b) {
     assert(b && b->mainloop);
 
-    if (b->io_event)
-        b->mainloop->io_free(b->io_event);
-    
-    sw_discovery_fina(b->discovery);
+    if (b->sink_browser)
+        avahi_service_browser_free(b->sink_browser);
+    if (b->source_browser)
+        avahi_service_browser_free(b->source_browser);
+    if (b->server_browser)
+        avahi_service_browser_free(b->server_browser);
+
+    if (b->client)
+        avahi_client_free(b->client);
+
+    if (b->avahi_poll)
+        pa_avahi_poll_free(b->avahi_poll);
+    
     pa_xfree(b);
 }
 
 pa_browser *pa_browser_ref(pa_browser *b) {
-    assert(b && b->ref >= 1);
+    assert(b);
+    assert(b->ref >= 1);
     b->ref++;
     return b;
 }
 
 void pa_browser_unref(pa_browser *b) {
-    assert(b && b->ref >= 1);
+    assert(b);
+    assert(b->ref >= 1);
 
     if ((-- (b->ref)) <= 0)
         browser_free(b);
@@ -336,3 +428,10 @@
     b->callback = cb;
     b->userdata = userdata;
 }
+
+void pa_browser_set_error_callback(pa_browser *b, pa_browser_error_cb_t cb, void *userdata) {
+    assert(b);
+
+    b->error_callback = cb;
+    b->error_userdata = userdata;
+}

Modified: trunk/src/pulse/browser.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulse/browser.h?rev=1069&root=pulseaudio&r1=1068&r2=1069&view=diff
==============================================================================
--- trunk/src/pulse/browser.h (original)
+++ trunk/src/pulse/browser.h Thu Jul 13 19:33:44 2006
@@ -27,41 +27,71 @@
 #include <pulse/channelmap.h>
 #include <pulse/cdecl.h>
 
+/** \file
+ * An abstract interface for Zeroconf browsing of PulseAudio servers */
+
 PA_C_DECL_BEGIN
 
+/** An opaque Zeroconf service browser object */
 typedef struct pa_browser pa_browser;
 
+/** Opcodes for pa_browser_cb_t callbacks */
 typedef enum pa_browse_opcode {
-    PA_BROWSE_NEW_SERVER = 0,
-    PA_BROWSE_NEW_SINK,
-    PA_BROWSE_NEW_SOURCE,
-    PA_BROWSE_REMOVE_SERVER,
-    PA_BROWSE_REMOVE_SINK,
-    PA_BROWSE_REMOVE_SOURCE
+    PA_BROWSE_NEW_SERVER = 0, /**< New server found */
+    PA_BROWSE_NEW_SINK,       /**< New sink found */
+    PA_BROWSE_NEW_SOURCE,     /**< New source found */
+    PA_BROWSE_REMOVE_SERVER,  /**< Server disappeared */
+    PA_BROWSE_REMOVE_SINK,    /**< Sink disappeared */ 
+    PA_BROWSE_REMOVE_SOURCE   /**< Source disappeared */
 } pa_browse_opcode_t;
 
+typedef enum pa_browse_flags {
+    PA_BROWSE_FOR_SERVERS = 1, /**< Browse for servers */
+    PA_BROWSE_FOR_SINKS = 2, /**< Browse for sinks */
+    PA_BROWSE_FOR_SOURCES = 4 /** Browse for sources */
+} pa_browse_flags_t;
+
+/** Create a new browser object on the specified main loop */
 pa_browser *pa_browser_new(pa_mainloop_api *mainloop);
+
+/** Same pa_browser_new, but pass additional flags parameter. */
+pa_browser *pa_browser_new_full(pa_mainloop_api *mainloop, pa_browse_flags_t flags, const char **error_string);
+
+/** Increase reference counter of the specified browser object */
 pa_browser *pa_browser_ref(pa_browser *z);
+
+/** Decrease reference counter of the specified browser object */
 void pa_browser_unref(pa_browser *z);
 
+/** Information about a sink/source/server found with Zeroconf */
 typedef struct pa_browse_info {
-    /* Unique service name */
-    const char *name;  /* always available */
+    const char *name;  /**< Unique service name; always available */
 
-    /* Server info */
-    const char *server; /* always available */
-    const char *server_version, *user_name, *fqdn; /* optional */
-    const uint32_t *cookie;  /* optional */
+    const char *server; /**< Server name; always available */
+    const char *server_version; /**< Server version string; optional */
+    const char *user_name; /**< User name of the server process; optional */
+    const char *fqdn; /* Server version; optional */
+    const uint32_t *cookie;  /* Server cookie; optional */
 
-    /* Device info */
-    const char *device; /* always available when this information is of a sink/source */
-    const char *description;  /* optional */
-    const pa_sample_spec *sample_spec;  /* optional */
+    const char *device; /* Device name; always available when this information is of a sink/source */
+    const char *description;  /* Device description; optional */
+    const pa_sample_spec *sample_spec;  /* Sample specification of the device; optional */
 } pa_browse_info;
 
+/** Callback prototype */
 typedef void (*pa_browse_cb_t)(pa_browser *z, pa_browse_opcode_t c, const pa_browse_info *i, void *userdata);
 
+/** Set the callback pointer for the browser object */
 void pa_browser_set_callback(pa_browser *z, pa_browse_cb_t cb, void *userdata);
+
+/** Callback prototype for errors */
+typedef void (*pa_browser_error_cb_t)(pa_browser *z, const char *error_string, void *userdata);
+
+/** Set a callback function that is called whenever the browser object
+ * becomes invalid due to an error. After this function has been
+ * called the browser object has become invalid and should be
+ * freed. */
+void pa_browser_set_error_callback(pa_browser *z, pa_browser_error_cb_t, void *userdata);
 
 PA_C_DECL_END
 

Modified: trunk/src/pulsecore/avahi-wrap.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/pulsecore/avahi-wrap.h?rev=1069&root=pulseaudio&r1=1068&r2=1069&view=diff
==============================================================================
--- trunk/src/pulsecore/avahi-wrap.h (original)
+++ trunk/src/pulsecore/avahi-wrap.h Thu Jul 13 19:33:44 2006
@@ -29,5 +29,4 @@
 AvahiPoll* pa_avahi_poll_new(pa_mainloop_api *api);
 void pa_avahi_poll_free(AvahiPoll *p);
 
-
 #endif




More information about the pulseaudio-commits mailing list