]> code.delx.au - pulseaudio/commitdiff
add more subscription events
authorLennart Poettering <lennart@poettering.net>
Thu, 12 Aug 2004 23:25:28 +0000 (23:25 +0000)
committerLennart Poettering <lennart@poettering.net>
Thu, 12 Aug 2004 23:25:28 +0000 (23:25 +0000)
add support for clients/modules in native protocol

git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@115 fefdeb5f-60dc-0310-8127-8f9354f1896f

polyp/cli-command.c
polyp/module.c
polyp/native-common.h
polyp/polypaudio.pa
polyp/polyplib.c
polyp/polyplib.h
polyp/protocol-native.c
polyp/sink.c
polyp/sink.h

index 6386d4e45ce96d1dfaf82b64ea49e9c1683cb48d..1d454f2a5bc2b23bf7067fa3927878f588b02daf 100644 (file)
@@ -300,7 +300,7 @@ static int pa_cli_command_sink_volume(struct pa_core *c, struct pa_tokenizer *t,
         return -1;
     }
 
-    sink->volume = (uint32_t) volume;
+    pa_sink_set_volume(sink, (uint32_t) volume);
     return 0;
 }
 
index 849afca4ddf64781686f07904b9fe0aa413d3d58..1deb7cde8265af61006b06527bd19b18aa306d25 100644 (file)
@@ -218,6 +218,9 @@ void pa_module_unload_request(struct pa_core *c, struct pa_module *m) {
 void pa_module_set_used(struct pa_module*m, int used) {
     assert(m);
 
+    if (m->n_used != used)
+        pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_CHANGE, m->index);
+    
     if (m->n_used != used && used == 0)
         time(&m->last_used_time);
 
index 5e69c805ce834e3d176b8f42fc3d1d840fa60502..4d5ab53d75938a6e92af0a0603a1b70037575192 100644 (file)
@@ -55,7 +55,9 @@ enum {
     PA_COMMAND_GET_SOURCE_INFO,
     PA_COMMAND_GET_SOURCE_INFO_LIST,
     PA_COMMAND_GET_MODULE_INFO,
+    PA_COMMAND_GET_MODULE_INFO_LIST,
     PA_COMMAND_GET_CLIENT_INFO,
+    PA_COMMAND_GET_CLIENT_INFO_LIST,
     PA_COMMAND_GET_SINK_INPUT_INFO,
     PA_COMMAND_GET_SOURCE_OUTPUT_INFO,
     PA_COMMAND_GET_SAMPLE_INFO,
index d57f81275108c58ba1151089aca8c634d74bfa2a..9f8cf8602e7b9712322cf5ec4cea2d4385b7a263 100755 (executable)
@@ -24,7 +24,7 @@
 #load module-alsa-source device=plughw:1,0
 #load module-oss device="/dev/dsp" sink_name=output source_name=input
 #load module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
-#load module-pipe-sink
+load module-pipe-sink
 
 # Load audio drivers automatically on access
 
@@ -32,8 +32,8 @@
 #autoload_source_add input module-oss device="/dev/dsp" sink_name=output source_name=input
 #autoload_sink_add output module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
 #autoload_source_add input module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
-autoload_sink_add output module-alsa-sink sink_name=output
-autoload_source_add input module-alsa-source source_name=input
+#autoload_sink_add output module-alsa-sink sink_name=output
+#autoload_source_add input module-alsa-source source_name=input
 
 # Load several protocols
 load module-esound-protocol-tcp
index b77d24ea5e977ae5e2dd975185fde8bca033771a..35001d3d31d29d8445af21a8ffedcd32d8c5d3a0 100644 (file)
@@ -102,6 +102,12 @@ struct pa_context {
     void *subscribe_userdata;
     enum pa_subscription_mask subscribe_mask;
 
+    void (*get_client_info_callback)(struct pa_context*c, const struct pa_client_info* i, int is_last, void *userdata);
+    void *get_client_info_userdata;
+
+    void (*get_module_info_callback)(struct pa_context*c, const struct pa_module_info* i, int is_last, void *userdata);
+    void *get_module_info_userdata;
+
     uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH];
 };
 
@@ -209,6 +215,12 @@ struct pa_context *pa_context_new(struct pa_mainloop_api *mainloop, const char *
     c->subscribe_callback = NULL;
     c->subscribe_userdata = NULL;
 
+    c->get_client_info_callback = NULL;
+    c->get_client_info_userdata = NULL;
+    
+    c->get_module_info_callback = NULL;
+    c->get_module_info_userdata = NULL;
+    
     pa_check_for_sigpipe();
     return c;
 }
@@ -1386,3 +1398,153 @@ void pa_context_get_source_info_by_index(struct pa_context *c, uint32_t index, v
     pa_pstream_send_tagstruct(c->pstream, t);
     pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, c);
 }
+
+static void context_get_client_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+    struct pa_context *c = userdata;
+    assert(pd && c);
+
+    if (command != PA_COMMAND_REPLY) {
+        if (handle_error(c, command, t) < 0) {
+            context_dead(c);
+            return;
+        }
+
+        if (c->get_client_info_callback)
+            c->get_client_info_callback(c, NULL, 0, c->get_client_info_userdata);
+        return;
+    }
+
+    while (!pa_tagstruct_eof(t)) {
+        struct pa_client_info i;
+
+        if (pa_tagstruct_getu32(t, &i.index) < 0 ||
+            pa_tagstruct_gets(t, &i.name) < 0 ||
+            pa_tagstruct_gets(t, &i.protocol_name) < 0 ||
+            pa_tagstruct_getu32(t, &i.owner_module) < 0) {
+            c->error = PA_ERROR_PROTOCOL;
+            context_dead(c);
+            return;
+        }
+        
+        if (c->get_client_info_callback)
+            c->get_client_info_callback(c, &i, 0, c->get_client_info_userdata);
+    }
+
+    if (c->get_client_info_callback)
+        c->get_client_info_callback(c, NULL, 1, c->get_client_info_userdata);
+}
+
+
+void pa_context_get_client_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata) {
+    struct pa_tagstruct *t;
+    uint32_t tag;
+    assert(c);
+
+    c->get_client_info_callback = cb;
+    c->get_client_info_userdata = userdata;
+
+    if (!cb)
+        return;
+    
+    t = pa_tagstruct_new(NULL, 0);
+    assert(t);
+    pa_tagstruct_putu32(t, PA_COMMAND_GET_CLIENT_INFO);
+    pa_tagstruct_putu32(t, tag = c->ctag++);
+    pa_tagstruct_putu32(t, index);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, c);
+}
+
+void pa_context_get_client_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata) {
+    struct pa_tagstruct *t;
+    uint32_t tag;
+    assert(c);
+
+    c->get_client_info_callback = cb;
+    c->get_client_info_userdata = userdata;
+
+    if (!cb)
+        return;
+    
+    t = pa_tagstruct_new(NULL, 0);
+    assert(t);
+    pa_tagstruct_putu32(t, PA_COMMAND_GET_CLIENT_INFO_LIST);
+    pa_tagstruct_putu32(t, tag = c->ctag++);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_client_info_callback, c);
+}
+
+static void context_get_module_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
+    struct pa_context *c = userdata;
+    assert(pd && c);
+
+    if (command != PA_COMMAND_REPLY) {
+        if (handle_error(c, command, t) < 0) {
+            context_dead(c);
+            return;
+        }
+
+        if (c->get_module_info_callback)
+            c->get_module_info_callback(c, NULL, 0, c->get_module_info_userdata);
+        return;
+    }
+
+    while (!pa_tagstruct_eof(t)) {
+        struct pa_module_info i;
+
+        if (pa_tagstruct_getu32(t, &i.index) < 0 ||
+            pa_tagstruct_gets(t, &i.name) < 0 ||
+            pa_tagstruct_gets(t, &i.argument) < 0 ||
+            pa_tagstruct_getu32(t, &i.n_used) < 0 ||
+            pa_tagstruct_getu32(t, &i.auto_unload) < 0) {
+            c->error = PA_ERROR_PROTOCOL;
+            context_dead(c);
+            return;
+        }
+        
+        if (c->get_module_info_callback)
+            c->get_module_info_callback(c, &i, 0, c->get_module_info_userdata);
+    }
+
+    if (c->get_module_info_callback)
+        c->get_module_info_callback(c, NULL, 1, c->get_module_info_userdata);
+}
+
+void pa_context_get_module_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata) {
+    struct pa_tagstruct *t;
+    uint32_t tag;
+    assert(c);
+
+    c->get_module_info_callback = cb;
+    c->get_module_info_userdata = userdata;
+
+    if (!cb)
+        return;
+    
+    t = pa_tagstruct_new(NULL, 0);
+    assert(t);
+    pa_tagstruct_putu32(t, PA_COMMAND_GET_MODULE_INFO);
+    pa_tagstruct_putu32(t, tag = c->ctag++);
+    pa_tagstruct_putu32(t, index);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, c);
+}
+
+void pa_context_get_module_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata) {
+    struct pa_tagstruct *t;
+    uint32_t tag;
+    assert(c);
+
+    c->get_module_info_callback = cb;
+    c->get_module_info_userdata = userdata;
+
+    if (!cb)
+        return;
+    
+    t = pa_tagstruct_new(NULL, 0);
+    assert(t);
+    pa_tagstruct_putu32(t, PA_COMMAND_GET_MODULE_INFO_LIST);
+    pa_tagstruct_putu32(t, tag = c->ctag++);
+    pa_pstream_send_tagstruct(c->pstream, t);
+    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_module_info_callback, c);
+}
index 8708cd72345f4fe78d9ad979a52d57be14fb17ed..590b978f883d67b00a3f2f717d38d495e143007c 100644 (file)
@@ -141,6 +141,25 @@ struct pa_server_info {
 
 void pa_context_get_server_info(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_server_info*i, void *userdata), void *userdata);
 
+struct pa_module_info {
+    uint32_t index;
+    const char*name, *argument;
+    uint32_t n_used, auto_unload;
+};
+
+void pa_context_get_module_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata);
+void pa_context_get_module_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_module_info*i, int is_last, void *userdata), void *userdata);
+
+struct pa_client_info {
+    uint32_t index;
+    const char *name;
+    uint32_t owner_module;
+    const char *protocol_name;
+};
+
+void pa_context_get_client_info(struct pa_context *c, uint32_t index, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata);
+void pa_context_get_client_info_list(struct pa_context *c, void (*cb)(struct pa_context *c, const struct pa_client_info*i, int is_last, void *userdata), void *userdata);
+
 void pa_context_subscribe(struct pa_context *c, enum pa_subscription_mask m, void (*cb)(struct pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata), void *userdata);
 
 #ifdef __cplusplus
index caaa13962530be0a3b18e5d7b6ac700597ac8f96..247851fc13569e9386a0d38e516cde7065e0ecda 100644 (file)
@@ -159,8 +159,12 @@ static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_REMOVE_SAMPLE] = { command_remove_sample },
     [PA_COMMAND_GET_SINK_INFO] = { command_get_info },
     [PA_COMMAND_GET_SOURCE_INFO] = { command_get_info },
+    [PA_COMMAND_GET_CLIENT_INFO] = { command_get_info },
+    [PA_COMMAND_GET_MODULE_INFO] = { command_get_info },
     [PA_COMMAND_GET_SINK_INFO_LIST] = { command_get_info_list },
     [PA_COMMAND_GET_SOURCE_INFO_LIST] = { command_get_info_list },
+    [PA_COMMAND_GET_MODULE_INFO_LIST] = { command_get_info_list },
+    [PA_COMMAND_GET_CLIENT_INFO_LIST] = { command_get_info_list },
     [PA_COMMAND_GET_SERVER_INFO] = { command_get_server_info },
     [PA_COMMAND_SUBSCRIBE] = { command_subscribe },
 };
@@ -964,11 +968,30 @@ static void source_fill_tagstruct(struct pa_tagstruct *t, struct pa_source *sour
     pa_tagstruct_puts(t, source->monitor_of ? source->monitor_of->name : "");
 }
 
+static void client_fill_tagstruct(struct pa_tagstruct *t, struct pa_client *client) {
+    assert(t && client);
+    pa_tagstruct_putu32(t, client->index);
+    pa_tagstruct_puts(t, client->name);
+    pa_tagstruct_puts(t, client->protocol_name);
+    pa_tagstruct_putu32(t, client->owner ? client->owner->index : (uint32_t) -1);
+}
+
+static void module_fill_tagstruct(struct pa_tagstruct *t, struct pa_module *module) {
+    assert(t && module);
+    pa_tagstruct_putu32(t, module->index);
+    pa_tagstruct_puts(t, module->name);
+    pa_tagstruct_puts(t, module->argument ? module->argument : "");
+    pa_tagstruct_putu32(t, module->n_used);
+    pa_tagstruct_putu32(t, module->auto_unload);
+}
+
 static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) {
     struct connection *c = userdata;
     uint32_t index;
     struct pa_sink *sink = NULL;
     struct pa_source *source = NULL;
+    struct pa_client *client = NULL;
+    struct pa_module *module = NULL;
     const char *name;
     struct pa_tagstruct *reply;
     assert(c && t);
@@ -990,15 +1013,19 @@ static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t
             sink = pa_idxset_get_by_index(c->protocol->core->sinks, index);
         else
             sink = pa_namereg_get(c->protocol->core, *name ? name : NULL, PA_NAMEREG_SINK, 1);
-    } else {
-        assert(command == PA_COMMAND_GET_SOURCE_INFO);
+    } else if (command == PA_COMMAND_GET_SOURCE_INFO) {
         if (index != (uint32_t) -1)
             source = pa_idxset_get_by_index(c->protocol->core->sources, index);
         else
             source = pa_namereg_get(c->protocol->core, *name ? name : NULL, PA_NAMEREG_SOURCE, 1);
+    } else if (command == PA_COMMAND_GET_CLIENT_INFO)
+        client = pa_idxset_get_by_index(c->protocol->core->clients, index);
+    else {
+        assert(command == PA_COMMAND_GET_MODULE_INFO);
+        module = pa_idxset_get_by_index(c->protocol->core->modules, index);
     }
-
-    if (!sink && !source) {
+    
+    if (!sink && !source && !client && !module) {
         pa_pstream_send_error(c->pstream, tag, PA_ERROR_NOENTITY);
         return;
     }
@@ -1009,8 +1036,12 @@ static void command_get_info(struct pa_pdispatch *pd, uint32_t command, uint32_t
     pa_tagstruct_putu32(reply, tag); 
     if (sink)
         sink_fill_tagstruct(reply, sink);
-    else
+    else if (source)
         source_fill_tagstruct(reply, source);
+    else if (client)
+        client_fill_tagstruct(reply, client);
+    else
+        module_fill_tagstruct(reply, module);
     pa_pstream_send_tagstruct(c->pstream, reply);
 }
 
@@ -1039,17 +1070,25 @@ static void command_get_info_list(struct pa_pdispatch *pd, uint32_t command, uin
 
     if (command == PA_COMMAND_GET_SINK_INFO_LIST)
         i = c->protocol->core->sinks;
-    else {
-        assert(command == PA_COMMAND_GET_SOURCE_INFO_LIST);
+    else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
         i = c->protocol->core->sources;
+    else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
+        i = c->protocol->core->clients;
+    else {
+        assert(command == PA_COMMAND_GET_MODULE_INFO_LIST);
+        i = c->protocol->core->modules;
     }
 
     for (p = pa_idxset_first(i, &index); p; p = pa_idxset_next(i, &index)) {
         if (command == PA_COMMAND_GET_SINK_INFO_LIST)
             sink_fill_tagstruct(reply, p);
-        else {
-            assert(command == PA_COMMAND_GET_SOURCE_INFO_LIST);
+        else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST)
             source_fill_tagstruct(reply, p);
+        else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST)
+            client_fill_tagstruct(reply, p);
+        else {
+            assert(command == PA_COMMAND_GET_MODULE_INFO_LIST);
+            module_fill_tagstruct(reply, p);
         }
     } 
     
index 7e0e15cdd17d4f1ca9f34ce1376b1c0503aaa9f8..d9a3ae86177d1c70fa809adba11aee76cd2fe9a8 100644 (file)
@@ -276,10 +276,17 @@ uint32_t pa_sink_get_latency(struct pa_sink *s) {
     return s->get_latency(s);
 }
 
-
 void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m) {
     sink->owner = m;
 
     if (sink->monitor_source)
         pa_source_set_owner(sink->monitor_source, m);
 }
+
+void pa_sink_set_volume(struct pa_sink *sink, uint32_t volume) {
+    assert(sink);
+    if (sink->volume != volume) {
+        pa_subscription_post(sink->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, sink->index);
+        sink->volume = volume;
+    }
+}
index 400d5d04f05857bb3f7162ed9f086878f6cb41b8..2aa5d6112110f3213a20d7be716602b038084d7a 100644 (file)
@@ -62,4 +62,6 @@ void pa_sink_notify(struct pa_sink*s);
 
 void pa_sink_set_owner(struct pa_sink *sink, struct pa_module *m);
 
+void pa_sink_set_volume(struct pa_sink *sink, uint32_t volume);
+
 #endif