Introduce "available" concept for ports, and communicate that to clients. Bump protoc...
authorDavid Henningsson <david.henningsson@canonical.com>
Fri, 25 Nov 2011 14:17:11 +0000 (15:17 +0100)
committerTanu Kaskinen <tanuk@iki.fi>
Sat, 26 Nov 2011 11:47:33 +0000 (13:47 +0200)
Note: There is still no notification when status availability changes.

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
PROTOCOL
configure.ac
src/modules/module-tunnel.c
src/pulse/def.h
src/pulse/introspect.c
src/pulse/introspect.h
src/pulsecore/protocol-native.c
src/pulsecore/sink.h

index 8c69190..8b2f81f 100644 (file)
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -278,6 +278,16 @@ New field in PA_COMMAND_UNDERFLOW:
 
     int64_t index
 
+## v24, implemented by >= 2.0
+
+New field in all commands that send/receive port introspection data
+(PA_COMMAND_GET_(SOURCE|SINK)_OUTPUT_INFO,
+PA_COMMAND_GET_(SOURCE|SINK)_OUTPUT_INFO_LIST):
+
+    uint32_t available
+
+The field is added once for every port.
+
 #### If you just changed the protocol, read this
 ## module-tunnel depends on the sink/source/sink-input/source-input protocol
 ## internals, so if you changed these, you might have broken module-tunnel.
index 1f65dd5..fa126f8 100644 (file)
@@ -36,7 +36,7 @@ AC_SUBST(PA_MINOR, pa_minor)
 AC_SUBST(PA_MAJORMINOR, pa_major.pa_minor)
 
 AC_SUBST(PA_API_VERSION, 12)
-AC_SUBST(PA_PROTOCOL_VERSION, 23)
+AC_SUBST(PA_PROTOCOL_VERSION, 24)
 
 # The stable ABI for client applications, for the version info x:y:z
 # always will hold y=z
index faee995..61ec35d 100644 (file)
@@ -996,6 +996,41 @@ fail:
     pa_module_unload_request(u->module, TRUE);
 }
 
+static int read_ports(struct userdata *u, pa_tagstruct *t)
+{
+    if (u->version >= 16) {
+        uint32_t n_ports;
+        const char *s;
+
+        if (pa_tagstruct_getu32(t, &n_ports)) {
+            pa_log("Parse failure");
+            return -PA_ERR_PROTOCOL;
+        }
+
+        for (uint32_t j = 0; j < n_ports; j++) {
+            uint32_t priority;
+
+            if (pa_tagstruct_gets(t, &s) < 0 || /* name */
+                pa_tagstruct_gets(t, &s) < 0 || /* description */
+                pa_tagstruct_getu32(t, &priority) < 0) {
+
+                pa_log("Parse failure");
+                return -PA_ERR_PROTOCOL;
+            }
+            if (u->version >= 24 && pa_tagstruct_getu32(t, &priority) < 0) { /* available */
+                pa_log("Parse failure");
+                return -PA_ERR_PROTOCOL;
+            }
+        }
+
+        if (pa_tagstruct_gets(t, &s) < 0) { /* active port */
+            pa_log("Parse failure");
+            return -PA_ERR_PROTOCOL;
+        }
+    }
+    return 0;
+}
+
 #ifdef TUNNEL_SINK
 
 /* Called from main context */
@@ -1066,32 +1101,8 @@ static void sink_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa_t
         }
     }
 
-    if (u->version >= 16) {
-        uint32_t n_ports;
-        const char *s;
-
-        if (pa_tagstruct_getu32(t, &n_ports)) {
-            pa_log("Parse failure");
-            goto fail;
-        }
-
-        for (uint32_t j = 0; j < n_ports; j++) {
-            uint32_t priority;
-
-            if (pa_tagstruct_gets(t, &s) < 0 || /* name */
-                pa_tagstruct_gets(t, &s) < 0 || /* description */
-                pa_tagstruct_getu32(t, &priority) < 0) {
-
-                pa_log("Parse failure");
-                goto fail;
-            }
-        }
-
-        if (pa_tagstruct_gets(t, &s) < 0) { /* active port */
-            pa_log("Parse failure");
-            goto fail;
-        }
-    }
+    if (read_ports(u, t) < 0)
+        goto fail;
 
     if (u->version >= 21) {
         uint8_t n_formats;
@@ -1318,32 +1329,8 @@ static void source_info_cb(pa_pdispatch *pd, uint32_t command,  uint32_t tag, pa
         }
     }
 
-    if (u->version >= 16) {
-        uint32_t n_ports;
-        const char *s;
-
-        if (pa_tagstruct_getu32(t, &n_ports)) {
-            pa_log("Parse failure");
-            goto fail;
-        }
-
-        for (uint32_t j = 0; j < n_ports; j++) {
-            uint32_t priority;
-
-            if (pa_tagstruct_gets(t, &s) < 0 || /* name */
-                pa_tagstruct_gets(t, &s) < 0 || /* description */
-                pa_tagstruct_getu32(t, &priority) < 0) {
-
-                pa_log("Parse failure");
-                goto fail;
-            }
-        }
-
-        if (pa_tagstruct_gets(t, &s) < 0) { /* active port */
-            pa_log("Parse failure");
-            goto fail;
-        }
-    }
+    if (read_ports(u, t) < 0)
+        goto fail;
 
     if (!pa_tagstruct_eof(t)) {
         pa_log("Packet too long");
index 49e4fdc..ca74dfc 100644 (file)
@@ -977,6 +977,21 @@ typedef void (*pa_free_cb_t)(void *p);
  * playback, \since 1.0 */
 #define PA_STREAM_EVENT_FORMAT_LOST "format-lost"
 
+/** Port availability / jack detection status
+ * \since 2.0 */
+typedef enum pa_port_available {
+    PA_PORT_AVAILABLE_UNKNOWN = 0, /**< This port does not support jack detection \since 2.0 */
+    PA_PORT_AVAILABLE_NO = 1,      /**< This port is not available, likely because the jack is not plugged in. \since 2.0 */
+    PA_PORT_AVAILABLE_YES = 2,     /**< This port is available, likely because the jack is plugged in. \since 2.0 */
+} pa_port_available_t;
+
+/** \cond fulldocs */
+#define PA_PORT_AVAILABLE_UNKNOWN PA_PORT_AVAILABLE_UNKNOWN
+#define PA_PORT_AVAILABLE_NO PA_PORT_AVAILABLE_NO
+#define PA_PORT_AVAILABLE_YES PA_PORT_AVAILABLE_YES
+
+/** \endcond */
+
 PA_C_DECL_END
 
 #endif
index 0d1d03f..c8bf7ca 100644 (file)
@@ -211,6 +211,14 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
                             goto fail;
                         }
 
+                        i.ports[0][j].available = PA_PORT_AVAILABLE_UNKNOWN;
+                        if (o->context->version >= 24) {
+                            uint32_t av;
+                            if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
+                                goto fail;
+                            i.ports[0][j].available = av;
+                        }
+
                         i.ports[j] = &i.ports[0][j];
                     }
 
@@ -476,6 +484,14 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
                             goto fail;
                         }
 
+                        i.ports[0][j].available = PA_PORT_AVAILABLE_UNKNOWN;
+                        if (o->context->version >= 24) {
+                            uint32_t av;
+                            if (pa_tagstruct_getu32(t, &av) < 0 || av > PA_PORT_AVAILABLE_YES)
+                                goto fail;
+                            i.ports[0][j].available = av;
+                        }
+
                         i.ports[j] = &i.ports[0][j];
                     }
 
index 1d77d45..afa4e8e 100644 (file)
@@ -202,6 +202,7 @@ typedef struct pa_sink_port_info {
     const char *name;                   /**< Name of this port */
     const char *description;            /**< Description of this port */
     uint32_t priority;                  /**< The higher this value is the more useful this port is as a default */
+    int available;                      /**< A \link pa_port_available_t, indicating availability status of this port. \since 2.0 */
 } pa_sink_port_info;
 
 /** Stores information about sinks. Please note that this structure
@@ -281,6 +282,7 @@ typedef struct pa_source_port_info {
     const char *name;                   /**< Name of this port */
     const char *description;            /**< Description of this port */
     uint32_t priority;                  /**< The higher this value is the more useful this port is as a default */
+    int available;                      /**< A \link pa_port_available_t, indicating availability status of this port. \since 2.0 */
 } pa_source_port_info;
 
 /** Stores information about sources. Please note that this structure
index 951aff7..5d1d485 100644 (file)
@@ -3124,6 +3124,8 @@ static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sin
                 pa_tagstruct_puts(t, p->name);
                 pa_tagstruct_puts(t, p->description);
                 pa_tagstruct_putu32(t, p->priority);
+                if (c->version >= 24)
+                    pa_tagstruct_putu32(t, p->available);
             }
         }
 
@@ -3195,6 +3197,8 @@ static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s
                 pa_tagstruct_puts(t, p->name);
                 pa_tagstruct_puts(t, p->description);
                 pa_tagstruct_putu32(t, p->priority);
+                if (c->version >= 24)
+                    pa_tagstruct_putu32(t, p->available);
             }
         }
 
index a88ac58..04fab19 100644 (file)
@@ -60,6 +60,7 @@ struct pa_device_port {
     char *description;
 
     unsigned priority;
+    pa_port_available_t available;         /* PA_PORT_AVAILABLE_UNKNOWN, PA_PORT_AVAILABLE_NO or PA_PORT_AVAILABLE_YES */
 
     /* .. followed by some implementation specific data */
 };