From: Martin Mares Date: Sun, 9 Nov 2014 19:45:37 +0000 (+0100) Subject: Ursary: Default sink X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=6dafe2d6d03021de9886f74c25c4c9538c5ec322;p=misc.git Ursary: Default sink --- diff --git a/ursaryd/Makefile b/ursaryd/Makefile index f6d8d8a..52e4dd2 100644 --- a/ursaryd/Makefile +++ b/ursaryd/Makefile @@ -15,6 +15,11 @@ all: ursaryd ursaryd: ursaryd.o nocturn.o pulse.o pulse-ucw.o +ursaryd.o: ursaryd.c ursaryd.h +nocturn.o: nocturn.c ursaryd.h +pulse.o: pulse.c ursaryd.h +pulse-ucw.o: pulse-ucw.c ursaryd.h + clean: rm -f `find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core -or -name .depend -or -name .#*` rm -f ursaryd diff --git a/ursaryd/pulse.c b/ursaryd/pulse.c index 08f51be..a2dd720 100644 --- a/ursaryd/pulse.c +++ b/ursaryd/pulse.c @@ -4,7 +4,7 @@ * (c) 2014 Martin Mares */ -#undef LOCAL_DEBUG +#define LOCAL_DEBUG #include #include @@ -63,8 +63,8 @@ static void pulse_op_cancel_all(void) } } -#define PULSE_ASYNC_RUN(name, ...) do { struct pulse_op *_op = pulse_op_new(); _op->o = name(__VA_ARGS__, _op); } while (0) -#define PULSE_ASYNC_INIT_RUN(name, ...) do { struct pulse_op *_op = pulse_op_new(); _op->is_init = 1; _op->o = name(__VA_ARGS__, _op); } while (0) +#define PULSE_ASYNC_RUN(name, ...) do { struct pulse_op *_op = pulse_op_new(); _op->o = name(pulse_ctx, __VA_ARGS__, _op); } while (0) +#define PULSE_ASYNC_INIT_RUN(name, ...) do { struct pulse_op *_op = pulse_op_new(); _op->is_init = 1; _op->o = name(pulse_ctx, __VA_ARGS__, _op); } while (0) static void pulse_success_cb(pa_context *ctx UNUSED, int success, void *userdata) { @@ -77,16 +77,18 @@ static void pulse_success_cb(pa_context *ctx UNUSED, int success, void *userdata void pulse_dump(void) { + msg(L_DEBUG, "## Server: default_sink=%s", pulse_default_sink_name); + CLIST_FOR_EACH(struct pulse_client *, c, pulse_client_list) - DBG("## Client #%d: %s host=%s", c->idx, c->name, c->host); + msg(L_DEBUG, "## Client #%d: %s host=%s", c->idx, c->name, c->host); CLIST_FOR_EACH(struct pulse_sink *, s, pulse_sink_list) - DBG("## Sink #%d: %s channels=%u volume=%u base_vol=%u mute=%u", - s->idx, s->name, s->channels, s->volume, s->base_volume, s->mute); + msg(L_DEBUG, "## Sink #%d: %s channels=%u volume=%u base_vol=%u mute=%u", + s->idx, s->name, s->channels, s->volume, s->base_volume, s->mute); CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) - DBG("## Sink input #%d: %s client=%d sink=%d channels=%u volume=%u mute=%u", - s->idx, s->name, s->client_idx, s->sink_idx, s->channels, s->volume, s->mute); + msg(L_DEBUG, "## Sink input #%d: %s client=%d sink=%d channels=%u volume=%u mute=%u", + s->idx, s->name, s->client_idx, s->sink_idx, s->channels, s->volume, s->mute); } static void pulse_dump_proplist(pa_proplist *pl UNUSED) @@ -103,6 +105,31 @@ static void pulse_dump_proplist(pa_proplist *pl UNUSED) #endif } +/*** Server state ***/ + +char *pulse_default_sink_name; + +static void pulse_server_cb(pa_context *ctx UNUSED, const pa_server_info *i, void *userdata) +{ + struct pulse_op *op = userdata; + + DBG("Pulse: SERVER default_sink=%s", i->default_sink_name); + SET_STRING(pulse_default_sink_name, i->default_sink_name); + + if (op->is_init) + { + PULSE_STATE(PS_ONLINE); + msg(L_INFO, "PulseAudio is ready"); + } + pulse_op_done(op); + schedule_update(); +} + +void pulse_server_set_default_sink(const char *name) +{ + PULSE_ASYNC_RUN(pa_context_set_default_sink, name, pulse_success_cb); +} + /*** Sink inputs ***/ #define HASH_NODE struct pulse_sink_input @@ -122,9 +149,8 @@ static void pulse_sink_input_cb(pa_context *ctx UNUSED, const pa_sink_input_info { if (op->is_init) { - PULSE_STATE(PS_ONLINE); - msg(L_INFO, "PulseAudio is ready"); - schedule_update(); + PULSE_STATE(PS_GET_SERVER); + PULSE_ASYNC_INIT_RUN(pa_context_get_server_info, pulse_server_cb); } pulse_op_done(op); return; @@ -157,12 +183,12 @@ static void pulse_sink_input_gone(int idx) void pulse_sink_input_set_volume(int idx, pa_cvolume *cvol) { - PULSE_ASYNC_RUN(pa_context_set_sink_input_volume, pulse_ctx, idx, cvol, pulse_success_cb); + PULSE_ASYNC_RUN(pa_context_set_sink_input_volume, idx, cvol, pulse_success_cb); } void pulse_sink_input_set_mute(int idx, bool mute) { - PULSE_ASYNC_RUN(pa_context_set_sink_input_mute, pulse_ctx, idx, mute, pulse_success_cb); + PULSE_ASYNC_RUN(pa_context_set_sink_input_mute, idx, mute, pulse_success_cb); } /*** Sinks ***/ @@ -176,7 +202,7 @@ void pulse_sink_input_set_mute(int idx, bool mute) #define HASH_ZERO_FILL #include -static void pulse_sink_cb(pa_context *ctx, const pa_sink_info *i, int eol, void *userdata) +static void pulse_sink_cb(pa_context *ctx UNUSED, const pa_sink_info *i, int eol, void *userdata) { struct pulse_op *op = userdata; @@ -185,7 +211,7 @@ static void pulse_sink_cb(pa_context *ctx, const pa_sink_info *i, int eol, void if (op->is_init) { PULSE_STATE(PS_GET_SINK_INPUTS); - PULSE_ASYNC_INIT_RUN(pa_context_get_sink_input_info_list, ctx, pulse_sink_input_cb); + PULSE_ASYNC_INIT_RUN(pa_context_get_sink_input_info_list, pulse_sink_input_cb); } pulse_op_done(op); return; @@ -225,12 +251,12 @@ struct pulse_sink *pulse_sink_by_name(const char *name) void pulse_sink_set_volume(int idx, pa_cvolume *cvol) { - PULSE_ASYNC_RUN(pa_context_set_sink_volume_by_index, pulse_ctx, idx, cvol, pulse_success_cb); + PULSE_ASYNC_RUN(pa_context_set_sink_volume_by_index, idx, cvol, pulse_success_cb); } void pulse_sink_set_mute(int idx, bool mute) { - PULSE_ASYNC_RUN(pa_context_set_sink_mute_by_index, pulse_ctx, idx, mute, pulse_success_cb); + PULSE_ASYNC_RUN(pa_context_set_sink_mute_by_index, idx, mute, pulse_success_cb); } /*** Clients ***/ @@ -244,7 +270,7 @@ void pulse_sink_set_mute(int idx, bool mute) #define HASH_ZERO_FILL #include -static void pulse_client_cb(pa_context *ctx, const pa_client_info *i, int eol, void *userdata) +static void pulse_client_cb(pa_context *ctx UNUSED, const pa_client_info *i, int eol, void *userdata) { struct pulse_op *op = userdata; @@ -253,7 +279,7 @@ static void pulse_client_cb(pa_context *ctx, const pa_client_info *i, int eol, v if (op->is_init) { PULSE_STATE(PS_GET_SINKS); - PULSE_ASYNC_INIT_RUN(pa_context_get_sink_info_list, ctx, pulse_sink_cb); + PULSE_ASYNC_INIT_RUN(pa_context_get_sink_info_list, pulse_sink_cb); } pulse_op_done(op); return; @@ -288,7 +314,7 @@ struct pulse_client *pulse_client_by_idx(int idx) /*** Events ***/ -static void pulse_subscribe_done_cb(pa_context *ctx, int success, void *userdata) +static void pulse_subscribe_done_cb(pa_context *ctx UNUSED, int success, void *userdata) { pulse_op_done(userdata); @@ -296,10 +322,10 @@ static void pulse_subscribe_done_cb(pa_context *ctx, int success, void *userdata msg(L_ERROR, "pa_context_subscribe failed: success=%d", success); PULSE_STATE(PS_GET_CLIENTS); - PULSE_ASYNC_INIT_RUN(pa_context_get_client_info_list, ctx, pulse_client_cb); + PULSE_ASYNC_INIT_RUN(pa_context_get_client_info_list, pulse_client_cb); } -static void pulse_event_cb(pa_context *ctx, pa_subscription_event_type_t type, uint32_t idx, void *userdata UNUSED) +static void pulse_event_cb(pa_context *ctx UNUSED, pa_subscription_event_type_t type, uint32_t idx, void *userdata UNUSED) { DBG("Pulse: SUBSCRIBE EVENT type=%08x idx=%u", type, idx); @@ -309,22 +335,26 @@ static void pulse_event_cb(pa_context *ctx, pa_subscription_event_type_t type, u { case PA_SUBSCRIPTION_EVENT_CLIENT: if (action == PA_SUBSCRIPTION_EVENT_NEW || action == PA_SUBSCRIPTION_EVENT_CHANGE) - PULSE_ASYNC_RUN(pa_context_get_client_info, ctx, idx, pulse_client_cb); + PULSE_ASYNC_RUN(pa_context_get_client_info, idx, pulse_client_cb); else if (action == PA_SUBSCRIPTION_EVENT_REMOVE) pulse_client_gone(idx); break; case PA_SUBSCRIPTION_EVENT_SINK: if (action == PA_SUBSCRIPTION_EVENT_NEW || action == PA_SUBSCRIPTION_EVENT_CHANGE) - PULSE_ASYNC_RUN(pa_context_get_sink_info_by_index, ctx, idx, pulse_sink_cb); + PULSE_ASYNC_RUN(pa_context_get_sink_info_by_index, idx, pulse_sink_cb); else if (action == PA_SUBSCRIPTION_EVENT_REMOVE) pulse_sink_gone(idx); break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: if (action == PA_SUBSCRIPTION_EVENT_NEW || action == PA_SUBSCRIPTION_EVENT_CHANGE) - PULSE_ASYNC_RUN(pa_context_get_sink_input_info, ctx, idx, pulse_sink_input_cb); + PULSE_ASYNC_RUN(pa_context_get_sink_input_info, idx, pulse_sink_input_cb); else if (action == PA_SUBSCRIPTION_EVENT_REMOVE) pulse_sink_input_gone(idx); break; + case PA_SUBSCRIPTION_EVENT_SERVER: + if (action == PA_SUBSCRIPTION_EVENT_CHANGE) + PULSE_ASYNC_RUN(pa_context_get_server_info, pulse_server_cb); + break; } } @@ -348,7 +378,7 @@ static void pulse_state_cb(pa_context *ctx, void *userdata UNUSED) { PULSE_STATE(PS_SUBSCRIBE); pa_context_set_subscribe_callback(ctx, pulse_event_cb, NULL); - PULSE_ASYNC_INIT_RUN(pa_context_subscribe, ctx, PA_SUBSCRIPTION_MASK_ALL, pulse_subscribe_done_cb); + PULSE_ASYNC_INIT_RUN(pa_context_subscribe, PA_SUBSCRIPTION_MASK_ALL, pulse_subscribe_done_cb); } } else diff --git a/ursaryd/ursaryd.c b/ursaryd/ursaryd.c index c8a87a2..469f7ae 100644 --- a/ursaryd/ursaryd.c +++ b/ursaryd/ursaryd.c @@ -225,6 +225,57 @@ static void update_client_from_button(int button, int on) } } +/*** Default sink controls ***/ + +static void update_default_sink(void) +{ + const char *def = pulse_default_sink_name ? : "?"; + if (!strcmp(def, "ursarium")) + { + noct_set_button(8, 1); + noct_set_button(9, 0); + } + else if (!strcmp(def, "catarium")) + { + noct_set_button(8, 0); + noct_set_button(9, 1); + } + else + { + noct_set_button(8, 0); + noct_set_button(9, 0); + } +} + +static void update_default_sink_from_button(int button, int on) +{ + if (!on) + return; + + const char *def = pulse_default_sink_name ? : "?"; + const char *switch_to = NULL; + if (button == 8) + { + if (!strcmp(def, "ursarium")) + switch_to = "burrow"; + else + switch_to = "ursarium"; + } + else if (button == 9) + { + if (!strcmp(def, "catarium")) + switch_to = "burrow"; + else + switch_to = "catarium"; + } + + if (!switch_to) + return; + + DBG("Switching default sink to %s", switch_to); + pulse_server_set_default_sink(switch_to); +} + /*** Main update routines ***/ static struct main_timer update_timer; @@ -263,11 +314,14 @@ static void do_update(struct main_timer *t) } DBG("## UPDATE"); +#ifdef LOCAL_DEBUG pulse_dump(); +#endif update_ring_from_sink(0, "ursarium"); update_ring_from_sink(1, "catarium"); update_clients(); + update_default_sink(); } void schedule_update(void) @@ -316,6 +370,10 @@ void notify_button(int button, int on) case 1: update_sink_mute_from_button(on, "catarium"); break; + case 8: + case 9: + update_default_sink_from_button(button, on); + break; default: update_client_from_button(button, on); } diff --git a/ursaryd/ursaryd.h b/ursaryd/ursaryd.h index 8fa213a..4781f39 100644 --- a/ursaryd/ursaryd.h +++ b/ursaryd/ursaryd.h @@ -37,10 +37,12 @@ enum pulse_state { PS_GET_CLIENTS, PS_GET_SINKS, PS_GET_SINK_INPUTS, + PS_GET_SERVER, PS_ONLINE, }; extern enum pulse_state pulse_state; +extern char *pulse_default_sink_name; struct pulse_client { cnode n; @@ -81,6 +83,7 @@ void pulse_sink_set_mute(int idx, bool mute); void pulse_sink_input_set_volume(int idx, pa_cvolume *cvol); void pulse_sink_input_set_mute(int idx, bool mute); struct pulse_client *pulse_client_by_idx(int idx); +void pulse_server_set_default_sink(const char *name); /* pulse-ucw.c */