From: Martin Mares Date: Sat, 22 Nov 2014 20:11:50 +0000 (+0100) Subject: Implemented sleep mode X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=fa9fa3aaa4f738419cf1786e15f5a8197d4e203f;p=ursary.git Implemented sleep mode --- diff --git a/mpd.c b/mpd.c index f0da2a3..12c6f50 100644 --- a/mpd.c +++ b/mpd.c @@ -4,7 +4,7 @@ * (c) 2014 Martin Mares */ -#define LOCAL_DEBUG +#undef LOCAL_DEBUG #include #include diff --git a/nocturn.c b/nocturn.c index 158f140..a313b49 100644 --- a/nocturn.c +++ b/nocturn.c @@ -328,6 +328,14 @@ void noct_set_button(int button, int val) } } +void noct_clear(void) +{ + for (int i=0; i<=8; i++) + noct_set_ring(i, RING_MODE_LEFT, 0); + for (int i=0; i<16; i++) + noct_set_button(i, 0); +} + static void noct_write_init(void) { DBG("Noct: Write init"); diff --git a/pulse.c b/pulse.c index 479a5e1..302f6a4 100644 --- a/pulse.c +++ b/pulse.c @@ -4,7 +4,7 @@ * (c) 2014 Martin Mares */ -#define LOCAL_DEBUG +#undef LOCAL_DEBUG #include #include @@ -17,6 +17,16 @@ #include "ursaryd.h" +enum pulse_state { + PS_OFFLINE, + PS_SUBSCRIBE, + PS_GET_CLIENTS, + PS_GET_SINKS, + PS_GET_SINK_INPUTS, + PS_GET_SERVER, + PS_ONLINE, +}; + enum pulse_state pulse_state; #define PULSE_STATE(s) do { pulse_state = s; DBG("Pulse: " #s); } while (0) @@ -81,8 +91,8 @@ void pulse_dump(void) msg(L_DEBUG, "## Client #%d: %s host=%s", c->idx, c->name, c->host); CLIST_FOR_EACH(struct pulse_sink *, s, pulse_sink_list) - 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); + msg(L_DEBUG, "## Sink #%d: %s channels=%u volume=%u base_vol=%u mute=%u suspended=%u", + s->idx, s->name, s->channels, s->volume, s->base_volume, s->mute, s->suspended); CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) msg(L_DEBUG, "## Sink input #%d: %s client=%d sink=%d channels=%u volume=%u mute=%u", @@ -238,6 +248,7 @@ static void pulse_sink_cb(pa_context *ctx UNUSED, const pa_sink_info *i, int eol s->volume = pa_cvolume_avg(&i->volume); s->base_volume = i->base_volume; s->mute = i->mute; + s->suspended = (i->state == PA_SINK_SUSPENDED); schedule_update(); } @@ -431,6 +442,11 @@ static void pulse_connect(struct main_timer *t) pa_context_connect(pulse_ctx, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); } +bool pulse_is_ready(void) +{ + return (pulse_state == PS_ONLINE); +} + void pulse_init(void) { pmain_init(); diff --git a/ursaryd.c b/ursaryd.c index b644a86..a0f1911 100644 --- a/ursaryd.c +++ b/ursaryd.c @@ -439,45 +439,101 @@ static void update_mpd_from_button(int button UNUSED, int on) /*** Main update routines ***/ static struct main_timer update_timer; +static timestamp_t last_touch_time; + +enum update_state { + US_OFFLINE, + US_ONLINE, + US_SLEEPING, + US_PULSE_DEAD, +}; + +static enum update_state update_state; + +static bool want_sleep_p(void) +{ + CLIST_FOR_EACH(struct pulse_sink *, s, pulse_sink_list) + if (!s->suspended) + return 0; + return 1; +} static void do_update(struct main_timer *t) { + DBG("## UPDATE in state %u", update_state); timer_del(t); + + // Nocturn dead? if (!noct_is_ready()) { DBG("## UPDATE: Nocturn is not ready"); + update_state = US_OFFLINE; return; } + else if (update_state == US_OFFLINE) + { + DBG("## UPDATE: Going online"); + update_state = US_ONLINE; + } - static bool dead; - if (pulse_state != PS_ONLINE) + // Pulse dead? + if (!pulse_is_ready()) { DBG("## UPDATE: Pulse is not online"); - for (int i=0; i<=8; i++) - noct_set_ring(i, RING_MODE_LEFT, 0); - for (int i=0; i<8; i++) + if (update_state != US_PULSE_DEAD) { - noct_set_button(i, 1); - noct_set_button(i+8, 0); + update_state = US_PULSE_DEAD; + noct_clear(); + for (int i=0; i<8; i++) + noct_set_button(i, 1); } - dead = 1; return; } - if (dead) + else if (update_state == US_PULSE_DEAD) { DBG("## UPDATE: Waking up from the dead"); - for (int i=0; i<=8; i++) - noct_set_ring(i, RING_MODE_LEFT, 0); - for (int i=0; i<16; i++) - noct_set_button(i, 0); - dead = 0; + update_state = US_ONLINE; + noct_clear(); } - DBG("## UPDATE"); #ifdef LOCAL_DEBUG pulse_dump(); #endif + // Sleeping? + bool want_sleep = want_sleep_p(); + if (!want_sleep) + last_touch_time = main_get_now(); + timestamp_t since_touch = last_touch_time ? main_get_now() - last_touch_time : 0; + timestamp_t sleep_in = 5000; + if (since_touch >= sleep_in) + { + DBG("UPDATE: Sleeping"); + if (update_state == US_ONLINE) + { + update_state = US_SLEEPING; + noct_clear(); + noct_set_ring(8, RING_MODE_LEFT, 127); + } + return; + } + else + { + if (update_state == US_SLEEPING) + { + DBG("UPDATE: Waking up"); + update_state = US_ONLINE; + noct_clear(); + } + if (want_sleep) + { + timestamp_t t = sleep_in - since_touch + 10; + DBG("UPDATE: Scheduling sleep in %d ms", (int) t); + timer_add_rel(&update_timer, t); + } + } + + // Everything normal update_ring_from_sink(0, "ursarium"); update_ring_from_sink(1, "catarium"); update_clients(); @@ -490,14 +546,29 @@ void schedule_update(void) timer_add_rel(&update_timer, 10); } -void notify_rotary(int rotary, int delta) +static bool prepare_notify(void) { - if (pulse_state != PS_ONLINE) + if (!pulse_is_ready()) { DBG("## NOTIFY: Pulse is not online"); - return; + return 0; + } + + last_touch_time = main_get_now(); + if (update_state == US_SLEEPING) + { + DBG("## NOTIFY: Scheduling wakeup"); + schedule_update(); } + return 1; +} + +void notify_rotary(int rotary, int delta) +{ + if (!prepare_notify()) + return; + switch (rotary) { case 0: @@ -517,11 +588,8 @@ void notify_rotary(int rotary, int delta) void notify_button(int button, int on) { - if (pulse_state != PS_ONLINE) - { - DBG("## NOTIFY: Pulse is not online"); - return; - } + if (!prepare_notify()) + return; switch (button) { @@ -545,11 +613,8 @@ void notify_button(int button, int on) void notify_touch(int rotary, int on UNUSED) { - if (pulse_state != PS_ONLINE) - { - DBG("## NOTIFY: Pulse is not online"); - return; - } + if (!prepare_notify()) + return; // Rotary touches switch meaning of LEDs, this is handled inside display updates if (rotary >= 4 && rotary < 8) diff --git a/ursaryd.h b/ursaryd.h index ddfc18d..0d44a7f 100644 --- a/ursaryd.h +++ b/ursaryd.h @@ -22,6 +22,7 @@ void noct_init(void); bool noct_is_ready(void); void noct_set_ring(int ring, int mode, int val); void noct_set_button(int button, int val); +void noct_clear(void); extern char noct_rotary_touched[10]; // 8=center, 9=slider extern char noct_button_pressed[16]; @@ -37,17 +38,6 @@ enum ring_mode { /* pulse.c */ -enum pulse_state { - PS_OFFLINE, - PS_SUBSCRIBE, - 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 { @@ -64,7 +54,8 @@ struct pulse_sink { uint channels; uint volume; uint base_volume; - int mute; + bool mute; + bool suspended; }; struct pulse_sink_input { @@ -75,7 +66,7 @@ struct pulse_sink_input { int sink_idx; uint channels; uint volume; - uint mute; + bool mute; int noct_client_idx; // Used by the high-level logic below }; @@ -83,6 +74,7 @@ extern clist pulse_client_list, pulse_sink_list, pulse_sink_input_list; void pulse_init(void); void pulse_dump(void); +bool pulse_is_ready(void); struct pulse_sink *pulse_sink_by_name(const char *name); struct pulse_sink *pulse_sink_by_idx(int idx); void pulse_sink_set_volume(int idx, pa_cvolume *cvol);