diff options
| -rw-r--r-- | doc/todo | 4 | ||||
| -rw-r--r-- | polyp/namereg.c | 8 | ||||
| -rw-r--r-- | polyp/native-common.h | 6 | ||||
| -rw-r--r-- | polyp/pdispatch.c | 24 | ||||
| -rwxr-xr-x | polyp/polypaudio.pa | 10 | ||||
| -rw-r--r-- | polyp/polyplib-context.c | 40 | ||||
| -rw-r--r-- | polyp/polyplib-context.h | 6 | ||||
| -rw-r--r-- | polyp/polyplib-def.h | 4 | ||||
| -rw-r--r-- | polyp/polyplib-introspect.c | 45 | ||||
| -rw-r--r-- | polyp/polyplib-introspect.h | 2 | ||||
| -rw-r--r-- | polyp/protocol-native.c | 27 | 
11 files changed, 161 insertions, 15 deletions
| @@ -12,9 +12,9 @@  - add sample directory  - add timing parameter to write callback of stream in client API  - config file for command line arguments -- vumeter  - add FAQ -- pa_context_connect_spawn() change function to fork+exec+waitpid-like function +- pa_context_connect_spawn(): change function to fork+exec+waitpid-like function +- on delete event in paman  ** later ***  - xmlrpc/http diff --git a/polyp/namereg.c b/polyp/namereg.c index 72a4c648..44a9cdc6 100644 --- a/polyp/namereg.c +++ b/polyp/namereg.c @@ -35,6 +35,7 @@  #include "source.h"  #include "sink.h"  #include "xmalloc.h" +#include "subscribe.h"  struct namereg_entry {      enum pa_namereg_type type; @@ -186,6 +187,13 @@ void pa_namereg_set_default(struct pa_core*c, const char *name, enum pa_namereg_      s = type == PA_NAMEREG_SINK ? &c->default_sink_name : &c->default_source_name;      assert(s); +    if (!name && !*s) +        return; +     +    if (name && *s && !strcmp(name, *s)) +        return; +          pa_xfree(*s);      *s = pa_xstrdup(name); +    pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);  } diff --git a/polyp/native-common.h b/polyp/native-common.h index 5250532e..c5192cec 100644 --- a/polyp/native-common.h +++ b/polyp/native-common.h @@ -66,17 +66,15 @@ enum {      PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST,      PA_COMMAND_GET_SAMPLE_INFO,      PA_COMMAND_GET_SAMPLE_INFO_LIST, -      PA_COMMAND_SUBSCRIBE,      PA_COMMAND_SUBSCRIBE_EVENT, -      PA_COMMAND_SET_SINK_VOLUME,      PA_COMMAND_SET_SINK_INPUT_VOLUME, -      PA_COMMAND_CORK_PLAYBACK_STREAM,      PA_COMMAND_FLUSH_PLAYBACK_STREAM,      PA_COMMAND_TRIGGER_PLAYBACK_STREAM, -     +    PA_COMMAND_SET_DEFAULT_SINK, +    PA_COMMAND_SET_DEFAULT_SOURCE,      PA_COMMAND_MAX  }; diff --git a/polyp/pdispatch.c b/polyp/pdispatch.c index 23bdf68b..88f85e02 100644 --- a/polyp/pdispatch.c +++ b/polyp/pdispatch.c @@ -62,8 +62,20 @@ static const char *command_names[PA_COMMAND_MAX] = {      [PA_COMMAND_PLAY_SAMPLE] = "PLAY_SAMPLE",      [PA_COMMAND_REMOVE_SAMPLE] = "REMOVE_SAMPLE",      [PA_COMMAND_GET_SERVER_INFO] = "GET_SERVER_INFO", -    [PA_COMMAND_GET_SINK_INFO] = "GET_SET_INFO", +    [PA_COMMAND_GET_SINK_INFO] = "GET_SINK_INFO", +    [PA_COMMAND_GET_SINK_INFO_LIST] = "GET_SINK_INFO_LIST", +    [PA_COMMAND_GET_SOURCE_INFO] = "GET_SOURCE_INFO", +    [PA_COMMAND_GET_SOURCE_INFO_LIST] = "GET_SOURCE_INFO_LIST", +    [PA_COMMAND_GET_MODULE_INFO] = "GET_MODULE_INFO", +    [PA_COMMAND_GET_MODULE_INFO_LIST] = "GET_MODULE_INFO_LIST", +    [PA_COMMAND_GET_CLIENT_INFO] = "GET_CLIENT_INFO", +    [PA_COMMAND_GET_CLIENT_INFO_LIST] = "GET_CLIENT_INFO_LIST", +    [PA_COMMAND_GET_SAMPLE_INFO] = "GET_SAMPLE_INFO", +    [PA_COMMAND_GET_SAMPLE_INFO_LIST] = "GET_SAMPLE_INFO_LIST",      [PA_COMMAND_GET_SINK_INPUT_INFO] = "GET_SINK_INPUT_INFO", +    [PA_COMMAND_GET_SINK_INPUT_INFO_LIST] = "GET_SINK_INPUT_INFO_LIST", +    [PA_COMMAND_GET_SOURCE_OUTPUT_INFO] = "GET_SOURCE_OUTPUT_INFO", +    [PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST] = "GET_SOURCE_OUTPUT_INFO_LIST",      [PA_COMMAND_SUBSCRIBE] = "SUBSCRIBE",      [PA_COMMAND_SUBSCRIBE_EVENT] = "SUBSCRIBE_EVENT",      [PA_COMMAND_SET_SINK_VOLUME] = "SET_SINK_VOLUME", @@ -71,7 +83,6 @@ static const char *command_names[PA_COMMAND_MAX] = {      [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = "TRIGGER_PLAYBACK_STREAM",      [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = "FLUSH_PLAYBACK_STREAM",      [PA_COMMAND_CORK_PLAYBACK_STREAM] = "CORK_PLAYBACK_STREAM", -      };  #endif @@ -174,7 +185,14 @@ int pa_pdispatch_run(struct pa_pdispatch *pd, struct pa_packet*packet, void *use          goto finish;  #ifdef DEBUG_OPCODES -    pa_log(__FILE__": Recieved opcode <%s>\n", command_names[command]); +{ +    char t[256]; +    char const *p; +    if (!(p = command_names[command])) +        snprintf((char*) (p = t), sizeof(t), "%u", command); +         +    pa_log(__FILE__": Recieved opcode <%s>\n", p); +}  #endif      if (command == PA_COMMAND_ERROR || command == PA_COMMAND_REPLY) { diff --git a/polyp/polypaudio.pa b/polyp/polypaudio.pa index 87b4114a..9e18abfd 100755 --- a/polyp/polypaudio.pa +++ b/polyp/polypaudio.pa @@ -22,7 +22,7 @@  #load module-alsa-sink  #load module-alsa-source device=plughw:1,0 -#load module-oss device="/dev/dsp" sink_name=output source_name=input +load module-oss device="/dev/dsp" sink_name=output source_name=input record=0  #load module-oss-mmap device="/dev/dsp" sink_name=output source_name=input  #load module-pipe-sink @@ -46,8 +46,8 @@ load module-native-protocol-unix  load module-cli  # Make some devices default -sink_default output -source_default input +#isink_default output +#source_default input  .nofail @@ -57,6 +57,6 @@ scache_load /usr/share/sounds/KDE_Notify.wav x11-bell  # Load X11 bell module  #load module-x11-bell sample=x11-bell sink=output -load module-pipe-source -load module-pipe-sink +#load module-pipe-source +#load module-pipe-sink diff --git a/polyp/polyplib-context.c b/polyp/polyplib-context.c index 94df7ec0..a810bd98 100644 --- a/polyp/polyplib-context.c +++ b/polyp/polyplib-context.c @@ -633,3 +633,43 @@ fail:      return -1;  } + +struct pa_operation* pa_context_set_default_sink(struct pa_context *c, const char *name, void(*cb)(struct pa_context*c, int success, void *userdata), void *userdata) { +    struct pa_tagstruct *t; +    struct pa_operation *o; +    uint32_t tag; +    assert(c && cb); + +    o = pa_operation_new(c, NULL); +    o->callback = cb; +    o->userdata = userdata; + +    t = pa_tagstruct_new(NULL, 0); +    pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SINK); +    pa_tagstruct_putu32(t, tag = c->ctag++); +    pa_tagstruct_puts(t, name); +    pa_pstream_send_tagstruct(c->pstream, t); +    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT,  pa_context_simple_ack_callback, o); + +    return pa_operation_ref(o); +} + +struct pa_operation* pa_context_set_default_source(struct pa_context *c, const char *name, void(*cb)(struct pa_context*c, int success,  void *userdata), void *userdata) { +    struct pa_tagstruct *t; +    struct pa_operation *o; +    uint32_t tag; +    assert(c && cb); + +    o = pa_operation_new(c, NULL); +    o->callback = cb; +    o->userdata = userdata; + +    t = pa_tagstruct_new(NULL, 0); +    pa_tagstruct_putu32(t, PA_COMMAND_SET_DEFAULT_SOURCE); +    pa_tagstruct_putu32(t, tag = c->ctag++); +    pa_tagstruct_puts(t, name); +    pa_pstream_send_tagstruct(c->pstream, t); +    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT,  pa_context_simple_ack_callback, o); + +    return pa_operation_ref(o); +} diff --git a/polyp/polyplib-context.h b/polyp/polyplib-context.h index c7d20703..65befbb3 100644 --- a/polyp/polyplib-context.h +++ b/polyp/polyplib-context.h @@ -98,6 +98,12 @@ struct pa_operation* pa_context_drain(struct pa_context *c, void (*cb) (struct p   * would never complete. */  void pa_context_exit_daemon(struct pa_context *c); +/** Set the name of the default sink. \since 0.4 */ +struct pa_operation* pa_context_set_default_sink(struct pa_context *c, const char *name, void(*cb)(struct pa_context*c, int success, void *userdata), void *userdata); + +/** Set the name of the default source. \since 0.4 */ +struct pa_operation* pa_context_set_default_source(struct pa_context *c, const char *name, void(*cb)(struct pa_context*c, int success,  void *userdata), void *userdata); +  PA_C_DECL_END  #endif diff --git a/polyp/polyplib-def.h b/polyp/polyplib-def.h index f0ecc5c4..067ebf89 100644 --- a/polyp/polyplib-def.h +++ b/polyp/polyplib-def.h @@ -106,7 +106,8 @@ enum pa_subscription_mask {      PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 8,      /**< Source output events */      PA_SUBSCRIPTION_MASK_MODULE = 16,            /**< Module events */      PA_SUBSCRIPTION_MASK_CLIENT = 32,            /**< Client events */ -    PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 64       /**< Sample cache events */ +    PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 64,      /**< Sample cache events */ +    PA_SUBSCRIPTION_MASK_SERVER = 128            /**< Other global server changes. \since 0.4 */  };  /** Subscription event types, as used by pa_context_subscribe() */ @@ -118,6 +119,7 @@ enum pa_subscription_event_type {      PA_SUBSCRIPTION_EVENT_MODULE = 4,         /**< Event type: Module */      PA_SUBSCRIPTION_EVENT_CLIENT = 5,         /**< Event type: Client */      PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 6,   /**< Event type: Sample cache item */ +    PA_SUBSCRIPTION_EVENT_SERVER = 7,         /**< Event type: Global server change, only occuring with PA_SUBSCRIPTION_EVENT_CHANGE. \since 0.4  */      PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 7,  /**< A mask to extract the event type from an event value */      PA_SUBSCRIPTION_EVENT_NEW = 0,            /**< A new object was created */ diff --git a/polyp/polyplib-introspect.c b/polyp/polyplib-introspect.c index b31a40c7..2baeb540 100644 --- a/polyp/polyplib-introspect.c +++ b/polyp/polyplib-introspect.c @@ -83,7 +83,10 @@ static void context_get_server_info_callback(struct pa_pdispatch *pd, uint32_t c                 pa_tagstruct_gets(t, &i.user_name) < 0 ||                 pa_tagstruct_gets(t, &i.host_name) < 0 ||                 pa_tagstruct_get_sample_spec(t, &i.sample_spec) < 0 || +               pa_tagstruct_gets(t, &i.default_sink_name) < 0 || +               pa_tagstruct_gets(t, &i.default_source_name) < 0 ||                 !pa_tagstruct_eof(t)) { +          pa_context_fail(o->context, PA_ERROR_PROTOCOL);          goto finish;      } @@ -174,6 +177,27 @@ struct pa_operation* pa_context_get_sink_info_by_index(struct pa_context *c, uin      return pa_operation_ref(o);  } +struct pa_operation* pa_context_get_sink_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_sink_info *i, int is_last, void *userdata), void *userdata) { +    struct pa_tagstruct *t; +    struct pa_operation *o; +    uint32_t tag; +    assert(c && cb); + +    o = pa_operation_new(c, NULL); +    o->callback = cb; +    o->userdata = userdata; + +    t = pa_tagstruct_new(NULL, 0); +    pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO); +    pa_tagstruct_putu32(t, tag = c->ctag++); +    pa_tagstruct_putu32(t, PA_INVALID_INDEX); +    pa_tagstruct_puts(t, name); +    pa_pstream_send_tagstruct(c->pstream, t); +    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_sink_info_callback, o); + +    return pa_operation_ref(o); +} +  /*** Source info ***/  static void context_get_source_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { @@ -244,6 +268,27 @@ struct pa_operation* pa_context_get_source_info_by_index(struct pa_context *c, u      return pa_operation_ref(o);  } +struct pa_operation* pa_context_get_source_info_by_name(struct pa_context *c, const char *name, void (*cb)(struct pa_context *c, const struct pa_source_info *i, int is_last, void *userdata), void *userdata) { +    struct pa_tagstruct *t; +    struct pa_operation *o; +    uint32_t tag; +    assert(c && cb); + +    o = pa_operation_new(c, NULL); +    o->callback = cb; +    o->userdata = userdata; + +    t = pa_tagstruct_new(NULL, 0); +    pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO); +    pa_tagstruct_putu32(t, tag = c->ctag++); +    pa_tagstruct_putu32(t, PA_INVALID_INDEX); +    pa_tagstruct_puts(t, name); +    pa_pstream_send_tagstruct(c->pstream, t); +    pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, context_get_source_info_callback, o); + +    return pa_operation_ref(o); +} +  /*** Client info ***/  static void context_get_client_info_callback(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { diff --git a/polyp/polyplib-introspect.h b/polyp/polyplib-introspect.h index 0a14fad0..3da71b80 100644 --- a/polyp/polyplib-introspect.h +++ b/polyp/polyplib-introspect.h @@ -96,6 +96,8 @@ struct pa_server_info {      const char *server_version;         /**< Version string of the daemon */      const char *server_name;            /**< Server package name (usually "polypaudio") */      struct pa_sample_spec sample_spec;  /**< Default sample specification */ +    const char *default_sink_name;      /**< Name of default sink. \since 0.4 */ +    const char *default_source_name;      /**< Name of default sink. \since 0.4*/  };  /** Get some information about the server */ diff --git a/polyp/protocol-native.c b/polyp/protocol-native.c index 1ec1b608..3d6114cf 100644 --- a/polyp/protocol-native.c +++ b/polyp/protocol-native.c @@ -138,6 +138,7 @@ static void command_subscribe(struct pa_pdispatch *pd, uint32_t command, uint32_  static void command_set_volume(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);  static void command_cork_playback_stream(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);  static void command_flush_or_trigger_playback_stream(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata); +static void command_set_default_sink_or_source(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata);  static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = {      [PA_COMMAND_ERROR] = { NULL }, @@ -182,6 +183,8 @@ static const struct pa_pdispatch_command command_table[PA_COMMAND_MAX] = {      [PA_COMMAND_CORK_PLAYBACK_STREAM] = { command_cork_playback_stream },      [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = { command_flush_or_trigger_playback_stream },      [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = { command_flush_or_trigger_playback_stream }, +    [PA_COMMAND_SET_DEFAULT_SINK] = { command_set_default_sink_or_source }, +    [PA_COMMAND_SET_DEFAULT_SOURCE] = { command_set_default_sink_or_source },  };  /* structure management */ @@ -1221,6 +1224,8 @@ static void command_get_server_info(struct pa_pdispatch *pd, uint32_t command, u      pa_tagstruct_puts(reply, pa_get_user_name(txt, sizeof(txt)));      pa_tagstruct_puts(reply, pa_get_host_name(txt, sizeof(txt)));      pa_tagstruct_put_sample_spec(reply, &c->protocol->core->default_sample_spec); +    pa_tagstruct_puts(reply, c->protocol->core->default_sink_name ?  c->protocol->core->default_sink_name : ""); +    pa_tagstruct_puts(reply, c->protocol->core->default_source_name ?  c->protocol->core->default_source_name : "");      pa_pstream_send_tagstruct(c->pstream, reply);  } @@ -1373,6 +1378,28 @@ static void command_flush_or_trigger_playback_stream(struct pa_pdispatch *pd, ui      request_bytes(s);  } +static void command_set_default_sink_or_source(struct pa_pdispatch *pd, uint32_t command, uint32_t tag, struct pa_tagstruct *t, void *userdata) { +    struct connection *c = userdata; +    uint32_t index; +    const char *s; +    assert(c && t); + +    if (pa_tagstruct_getu32(t, &index) < 0 || +        pa_tagstruct_gets(t, &s) < 0 || +        !pa_tagstruct_eof(t)) { +        protocol_error(c); +        return; +    } + +    if (!c->authorized) { +        pa_pstream_send_error(c->pstream, tag, PA_ERROR_ACCESS); +        return; +    } + +    pa_namereg_set_default(c->protocol->core, s, command == PA_COMMAND_SET_DEFAULT_SOURCE ? PA_NAMEREG_SOURCE : PA_NAMEREG_SINK); +    pa_pstream_send_simple_ack(c->pstream, tag); +} +  /*** pstream callbacks ***/  static void pstream_packet_callback(struct pa_pstream *p, struct pa_packet *packet, void *userdata) { | 
