From: Martin Mares Date: Sun, 9 Nov 2014 20:22:47 +0000 (+0100) Subject: Moving clients to different sinks X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=40685eefc0e00f67a2f9c3f4de1caf958eb93c20;p=ursary.git Moving clients to different sinks --- diff --git a/nocturn.c b/nocturn.c index f8665ed..510fb33 100644 --- a/nocturn.c +++ b/nocturn.c @@ -88,6 +88,8 @@ static const char noct_magic[4][9] = { static struct libusb_transfer *noct_read_xfer; static bool noct_read_pending; +char noct_rotary_touched[10]; +char noct_button_pressed[16]; static void noct_read_done(struct libusb_transfer *xfer) { @@ -140,6 +142,7 @@ static void noct_read_done(struct libusb_transfer *xfer) if (arg < 0x80) { DBG("Noct: Slider value = %d", arg); + notify_rotary(9, arg); continue; } break; @@ -160,6 +163,8 @@ static void noct_read_done(struct libusb_transfer *xfer) { int state = !!arg; DBG("Noct: Center touch = %d", state); + noct_rotary_touched[8] = state; + notify_touch(8, state); continue; } break; @@ -168,6 +173,8 @@ static void noct_read_done(struct libusb_transfer *xfer) { int state = !!arg; DBG("Noct: Slider touch = %d", state); + noct_rotary_touched[9] = state; + notify_touch(9, state); continue; } break; @@ -177,6 +184,8 @@ static void noct_read_done(struct libusb_transfer *xfer) int r = cmd - 0x60; int state = !!arg; DBG("Noct: Rotary %d touch = %d", r, state); + noct_rotary_touched[r] = state; + notify_touch(r, state); continue; } break; @@ -186,6 +195,7 @@ static void noct_read_done(struct libusb_transfer *xfer) int b = cmd - 0x70; int state = !!arg; DBG("Noct: Button %d = %d", b, state); + noct_button_pressed[b] = state; notify_button(b, state); continue; } @@ -215,7 +225,7 @@ static void noct_read_init(void) noct_read_pending = 1; } -static byte noct_button_state[16]; +static byte noct_button_light[16]; static byte noct_ring_mode[8]; // RING_MODE_xxx static byte noct_ring_val[9]; @@ -267,7 +277,7 @@ static void noct_sched_write(void) { int i = bit_ffs(noct_dirty_button); noct_dirty_button ^= 1U << i; - noct_do_write(0x70 + i, noct_button_state[i]); + noct_do_write(0x70 + i, noct_button_light[i]); } else if (noct_dirty_ring_mode) { @@ -310,9 +320,9 @@ void noct_set_button(int button, int val) { ASSERT(button >= 0 && button < 16); ASSERT(val == 0 || val == 1); - if (noct_button_state[button] != val) + if (noct_button_light[button] != val) { - noct_button_state[button] = val; + noct_button_light[button] = val; noct_dirty_button |= 1U << button; noct_sched_write(); } @@ -325,6 +335,8 @@ static void noct_write_init(void) noct_write_xfer = libusb_alloc_transfer(0); libusb_fill_interrupt_transfer(noct_write_xfer, usb_dev, 0x02, xmalloc(8), 0, noct_write_done, NULL, 1000); + bzero(noct_button_pressed, sizeof(noct_button_pressed)); + bzero(noct_rotary_touched, sizeof(noct_rotary_touched)); noct_dirty_button = 0xffff; noct_dirty_ring_mode = 0xff; noct_dirty_ring_val = 0x1ff; diff --git a/pulse.c b/pulse.c index a2dd720..72b40d8 100644 --- a/pulse.c +++ b/pulse.c @@ -191,6 +191,11 @@ void pulse_sink_input_set_mute(int idx, bool mute) PULSE_ASYNC_RUN(pa_context_set_sink_input_mute, idx, mute, pulse_success_cb); } +void pulse_sink_input_move(int input_idx, int sink_idx) +{ + PULSE_ASYNC_RUN(pa_context_move_sink_input_by_index, input_idx, sink_idx, pulse_success_cb); +} + /*** Sinks ***/ #define HASH_NODE struct pulse_sink @@ -249,6 +254,11 @@ struct pulse_sink *pulse_sink_by_name(const char *name) return NULL; } +struct pulse_sink *pulse_sink_by_idx(int idx) +{ + return pulse_sink_lookup(idx); +} + void pulse_sink_set_volume(int idx, pa_cvolume *cvol) { PULSE_ASYNC_RUN(pa_context_set_sink_volume_by_index, idx, cvol, pulse_success_cb); diff --git a/ursaryd.c b/ursaryd.c index 469f7ae..b2cd009 100644 --- a/ursaryd.c +++ b/ursaryd.c @@ -225,17 +225,54 @@ static void update_client_from_button(int button, int on) } } +static int find_touched_client(void) +{ + int touched = -1; + + for (uns i=0; i < NUM_CLIENTS; i++) + if (noct_rotary_touched[client_map[i].rotary]) + { + if (touched >= 0) + return -1; + touched = i; + } + return touched; +} + /*** Default sink controls ***/ +static const char *get_client_sink(int i) +{ + const char *sink = NULL; + + CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) + if (s->noct_client_idx == i) + { + struct pulse_sink *sk = (s->sink_idx >= 0) ? pulse_sink_by_idx(s->sink_idx) : NULL; + const char *ss = sk ? sk->name : NULL; + if (!sink) + sink = ss; + else if (strcmp(sink, ss)) + sink = "?"; + } + return sink ? : "?"; +} + static void update_default_sink(void) { - const char *def = pulse_default_sink_name ? : "?"; - if (!strcmp(def, "ursarium")) + int i = find_touched_client(); + const char *sink; + if (i >= 0) + sink = get_client_sink(i); + else + sink = pulse_default_sink_name ? : "?"; + + if (!strcmp(sink, "ursarium")) { noct_set_button(8, 1); noct_set_button(9, 0); } - else if (!strcmp(def, "catarium")) + else if (!strcmp(sink, "catarium")) { noct_set_button(8, 0); noct_set_button(9, 1); @@ -252,18 +289,24 @@ static void update_default_sink_from_button(int button, int on) if (!on) return; - const char *def = pulse_default_sink_name ? : "?"; + int i = find_touched_client(); + const char *sink; + if (i >= 0) + sink = get_client_sink(i); + else + sink = pulse_default_sink_name ? : "?"; + const char *switch_to = NULL; if (button == 8) { - if (!strcmp(def, "ursarium")) + if (!strcmp(sink, "ursarium")) switch_to = "burrow"; else switch_to = "ursarium"; } else if (button == 9) { - if (!strcmp(def, "catarium")) + if (!strcmp(sink, "catarium")) switch_to = "burrow"; else switch_to = "catarium"; @@ -272,8 +315,24 @@ static void update_default_sink_from_button(int button, int on) if (!switch_to) return; - DBG("Switching default sink to %s", switch_to); - pulse_server_set_default_sink(switch_to); + if (i >= 0) + { + struct pulse_sink *sk = pulse_sink_by_name(switch_to); + if (!sk) + return; + + CLIST_FOR_EACH(struct pulse_sink_input *, s, pulse_sink_input_list) + if (s->noct_client_idx == i) + { + DBG("Moving input #%d to sink #%d", s->idx, sk->idx); + pulse_sink_input_move(s->idx, sk->idx); + } + } + else + { + DBG("Switching default sink to %s", switch_to); + pulse_server_set_default_sink(switch_to); + } } /*** Main update routines ***/ @@ -379,6 +438,19 @@ 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; + } + + // Rotary touches switch meaning of LEDs, this is handled inside display updates + if (rotary >= 4 && rotary < 8) + schedule_update(); +} + /*** Main entry point ***/ int main(int argc UNUSED, char **argv) diff --git a/ursaryd.h b/ursaryd.h index 4781f39..87f4854 100644 --- a/ursaryd.h +++ b/ursaryd.h @@ -11,6 +11,7 @@ void schedule_update(void); void notify_rotary(int rotary, int delta); +void notify_touch(int rotary, int on); void notify_button(int button, int on); /* nocturn.c */ @@ -20,6 +21,9 @@ bool noct_is_ready(void); void noct_set_ring(int ring, int mode, int val); void noct_set_button(int button, int val); +extern char noct_rotary_touched[10]; // 8=center, 9=slider +extern char noct_button_pressed[16]; + enum ring_mode { RING_MODE_LEFT, RING_MODE_RIGHT, @@ -78,10 +82,12 @@ extern clist pulse_client_list, pulse_sink_list, pulse_sink_input_list; void pulse_init(void); void pulse_dump(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); 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); +void pulse_sink_input_move(int input_idx, int sink_idx); struct pulse_client *pulse_client_by_idx(int idx); void pulse_server_set_default_sink(const char *name);