]> code.delx.au - pulseaudio/blobdiff - src/pulse/introspect.c
Fixup #include directives according to Coding Style
[pulseaudio] / src / pulse / introspect.c
index ac8a11aa94a050d0ae6686bff2fd461129688e50..ec27b928ec276d9879211a2a100a7322e07026c6 100644 (file)
 #include <pulse/context.h>
 #include <pulse/gccmacro.h>
 #include <pulse/xmalloc.h>
+#include <pulse/fork-detect.h>
 
 #include <pulsecore/macro.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/pstream-util.h>
 
 #include "internal.h"
-#include "fork-detect.h"
-
 #include "introspect.h"
 
 /*** Statistics ***/
@@ -49,7 +48,7 @@ static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t t
     pa_assert(o);
     pa_assert(PA_REFCNT_VALUE(o) >= 1);
 
-    memset(&i, 0, sizeof(i));
+    pa_zero(i);
 
     if (!o->context)
         goto finish;
@@ -93,7 +92,7 @@ static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command,
     pa_assert(o);
     pa_assert(PA_REFCNT_VALUE(o) >= 1);
 
-    memset(&i, 0, sizeof(i));
+    pa_zero(i);
 
     if (!o->context)
         goto finish;
@@ -161,8 +160,10 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
             pa_bool_t mute;
             uint32_t flags;
             uint32_t state;
+            uint32_t j;
+            const char *ap = NULL;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
             i.proplist = pa_proplist_new();
             i.base_volume = PA_VOLUME_NORM;
             i.n_volume_steps = PA_VOLUME_NORM+1;
@@ -190,13 +191,55 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
                  (pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
                   pa_tagstruct_getu32(t, &state) < 0 ||
                   pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
-                  pa_tagstruct_getu32(t, &i.card) < 0))) {
+                  pa_tagstruct_getu32(t, &i.card) < 0)) ||
+                (o->context->version >= 16 &&
+                 (pa_tagstruct_getu32(t, &i.n_ports)))) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
                 pa_proplist_free(i.proplist);
                 goto finish;
             }
 
+            if (o->context->version >= 16) {
+                if (i.n_ports > 0) {
+                    i.ports = pa_xnew(pa_sink_port_info*, i.n_ports+1);
+                    i.ports[0] = pa_xnew(pa_sink_port_info, i.n_ports);
+
+                    for (j = 0; j < i.n_ports; j++) {
+                        if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
+                            pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
+                            pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
+
+                            pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                            pa_xfree(i.ports[0]);
+                            pa_xfree(i.ports);
+                            pa_proplist_free(i.proplist);
+                            goto finish;
+                        }
+
+                        i.ports[j] = &i.ports[0][j];
+                    }
+
+                    i.ports[j] = NULL;
+                }
+
+                if (pa_tagstruct_gets(t, &ap) < 0) {
+                    pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                    pa_xfree(i.ports[0]);
+                    pa_xfree(i.ports);
+                    pa_proplist_free(i.proplist);
+                    goto finish;
+                }
+
+                if (ap) {
+                    for (j = 0; j < i.n_ports; j++)
+                        if (pa_streq(i.ports[j]->name, ap)) {
+                            i.active_port = i.ports[j];
+                            break;
+                        }
+                }
+            }
+
             i.mute = (int) mute;
             i.flags = (pa_sink_flags_t) flags;
             i.state = (pa_sink_state_t) state;
@@ -206,6 +249,10 @@ static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, u
                 cb(o->context, &i, 0, o->userdata);
             }
 
+            if (i.ports) {
+                pa_xfree(i.ports[0]);
+                pa_xfree(i.ports);
+            }
             pa_proplist_free(i.proplist);
         }
     }
@@ -271,6 +318,56 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name,
     return o;
 }
 
+pa_operation* pa_context_set_sink_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag);
+    pa_tagstruct_putu32(t, idx);
+    pa_tagstruct_puts(t, NULL);
+    pa_tagstruct_puts(t, port);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_set_sink_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_SINK_PORT, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, name);
+    pa_tagstruct_puts(t, port);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
 /*** Source info ***/
 
 static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -296,8 +393,10 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
             pa_bool_t mute;
             uint32_t flags;
             uint32_t state;
+            unsigned j;
+            const char *ap;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
             i.proplist = pa_proplist_new();
             i.base_volume = PA_VOLUME_NORM;
             i.n_volume_steps = PA_VOLUME_NORM+1;
@@ -325,13 +424,55 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
                  (pa_tagstruct_get_volume(t, &i.base_volume) < 0 ||
                   pa_tagstruct_getu32(t, &state) < 0 ||
                   pa_tagstruct_getu32(t, &i.n_volume_steps) < 0 ||
-                  pa_tagstruct_getu32(t, &i.card) < 0))) {
+                  pa_tagstruct_getu32(t, &i.card) < 0)) ||
+                (o->context->version >= 16 &&
+                 (pa_tagstruct_getu32(t, &i.n_ports)))) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
                 pa_proplist_free(i.proplist);
                 goto finish;
             }
 
+            if (o->context->version >= 16) {
+                if (i.n_ports > 0) {
+                    i.ports = pa_xnew(pa_source_port_info*, i.n_ports+1);
+                    i.ports[0] = pa_xnew(pa_source_port_info, i.n_ports);
+
+                    for (j = 0; j < i.n_ports; j++) {
+                        if (pa_tagstruct_gets(t, &i.ports[0][j].name) < 0 ||
+                            pa_tagstruct_gets(t, &i.ports[0][j].description) < 0 ||
+                            pa_tagstruct_getu32(t, &i.ports[0][j].priority) < 0) {
+
+                            pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                            pa_xfree(i.ports[0]);
+                            pa_xfree(i.ports);
+                            pa_proplist_free(i.proplist);
+                            goto finish;
+                        }
+
+                        i.ports[j] = &i.ports[0][j];
+                    }
+
+                    i.ports[j] = NULL;
+                }
+
+                if (pa_tagstruct_gets(t, &ap) < 0) {
+                    pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                    pa_xfree(i.ports[0]);
+                    pa_xfree(i.ports);
+                    pa_proplist_free(i.proplist);
+                    goto finish;
+                }
+
+                if (ap) {
+                    for (j = 0; j < i.n_ports; j++)
+                        if (pa_streq(i.ports[j]->name, ap)) {
+                            i.active_port = i.ports[j];
+                            break;
+                        }
+                }
+            }
+
             i.mute = (int) mute;
             i.flags = (pa_source_flags_t) flags;
             i.state = (pa_source_state_t) state;
@@ -341,6 +482,10 @@ static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command,
                 cb(o->context, &i, 0, o->userdata);
             }
 
+            if (i.ports) {
+                pa_xfree(i.ports[0]);
+                pa_xfree(i.ports);
+            }
             pa_proplist_free(i.proplist);
         }
     }
@@ -406,6 +551,56 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name
     return o;
 }
 
+pa_operation* pa_context_set_source_port_by_index(pa_context *c, uint32_t idx, const char*port, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, idx != PA_INVALID_INDEX, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag);
+    pa_tagstruct_putu32(t, idx);
+    pa_tagstruct_puts(t, NULL);
+    pa_tagstruct_puts(t, port);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
+pa_operation* pa_context_set_source_port_by_name(pa_context *c, const char *name, const char*port, pa_context_success_cb_t cb, void *userdata) {
+    pa_operation *o;
+    pa_tagstruct *t;
+    uint32_t tag;
+
+    pa_assert(c);
+    pa_assert(PA_REFCNT_VALUE(c) >= 1);
+
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, !name || *name, PA_ERR_INVALID);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 16, PA_ERR_NOTSUPPORTED);
+
+    o = pa_operation_new(c, NULL, (pa_operation_cb_t) cb, userdata);
+
+    t = pa_tagstruct_command(c, PA_COMMAND_SET_SOURCE_PORT, &tag);
+    pa_tagstruct_putu32(t, PA_INVALID_INDEX);
+    pa_tagstruct_puts(t, name);
+    pa_tagstruct_puts(t, port);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
+
+    return o;
+}
+
 /*** Client info ***/
 
 static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -429,7 +624,7 @@ static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command,
         while (!pa_tagstruct_eof(t)) {
             pa_client_info i;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
             i.proplist = pa_proplist_new();
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
@@ -514,7 +709,7 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
             uint32_t j;
             const char*ap;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
                 pa_tagstruct_gets(t, &i.name) < 0 ||
@@ -527,7 +722,7 @@ static void context_get_card_info_callback(pa_pdispatch *pd, uint32_t command, u
             }
 
             if (i.n_profiles > 0) {
-                i.profiles = pa_xnew(pa_card_profile_info, i.n_profiles+1);
+                i.profiles = pa_xnew0(pa_card_profile_info, i.n_profiles+1);
 
                 for (j = 0; j < i.n_profiles; j++) {
 
@@ -638,6 +833,8 @@ pa_operation* pa_context_get_card_info_by_name(pa_context *c, const char*name, p
 }
 
 pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, void *userdata) {
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 15, PA_ERR_NOTSUPPORTED);
+
     return pa_context_send_simple_command(c, PA_COMMAND_GET_CARD_INFO_LIST, context_get_card_info_callback, (pa_operation_cb_t) cb, userdata);
 }
 
@@ -715,7 +912,7 @@ static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command,
             pa_module_info i;
             pa_bool_t auto_unload = FALSE;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
             i.proplist = pa_proplist_new();
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
@@ -798,9 +995,9 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm
 
         while (!pa_tagstruct_eof(t)) {
             pa_sink_input_info i;
-            pa_bool_t mute = FALSE;
+            pa_bool_t mute = FALSE, corked = FALSE, has_volume = FALSE, read_only_volume = FALSE;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
             i.proplist = pa_proplist_new();
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
@@ -816,7 +1013,10 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm
                 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
                 pa_tagstruct_gets(t, &i.driver) < 0 ||
                 (o->context->version >= 11 && pa_tagstruct_get_boolean(t, &mute) < 0) ||
-                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
+                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
+                (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0) ||
+                (o->context->version >= 20 && (pa_tagstruct_get_boolean(t, &has_volume) < 0 ||
+                                               pa_tagstruct_get_boolean(t, &read_only_volume) < 0))) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
                 pa_proplist_free(i.proplist);
@@ -824,6 +1024,9 @@ static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t comm
             }
 
             i.mute = (int) mute;
+            i.corked = (int) corked;
+            i.has_volume = (int) has_volume;
+            i.read_only_volume = (int) read_only_volume;
 
             if (o->callback) {
                 pa_sink_input_info_cb_t cb = (pa_sink_input_info_cb_t) o->callback;
@@ -893,8 +1096,9 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c
 
         while (!pa_tagstruct_eof(t)) {
             pa_source_output_info i;
+            pa_bool_t corked = FALSE;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
             i.proplist = pa_proplist_new();
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||
@@ -908,13 +1112,16 @@ static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t c
                 pa_tagstruct_get_usec(t, &i.source_usec) < 0 ||
                 pa_tagstruct_gets(t, &i.resample_method) < 0 ||
                 pa_tagstruct_gets(t, &i.driver) < 0 ||
-                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0)) {
+                (o->context->version >= 13 && pa_tagstruct_get_proplist(t, i.proplist) < 0) ||
+                (o->context->version >= 19 && pa_tagstruct_get_boolean(t, &corked) < 0)) {
 
                 pa_context_fail(o->context, PA_ERR_PROTOCOL);
                 pa_proplist_free(i.proplist);
                 goto finish;
             }
 
+            i.corked = (int) corked;
+
             if (o->callback) {
                 pa_source_output_info_cb_t cb = (pa_source_output_info_cb_t) o->callback;
                 cb(o->context, &i, 0, o->userdata);
@@ -1236,7 +1443,7 @@ static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command,
             pa_sample_info i;
             pa_bool_t lazy = FALSE;
 
-            memset(&i, 0, sizeof(i));
+            pa_zero(i);
             i.proplist = pa_proplist_new();
 
             if (pa_tagstruct_getu32(t, &i.index) < 0 ||