]> mj.ucw.cz Git - misc.git/commitdiff
Ursary: Moving clients to different sinks
authorMartin Mares <mj@ucw.cz>
Sun, 9 Nov 2014 20:22:47 +0000 (21:22 +0100)
committerMartin Mares <mj@ucw.cz>
Sun, 9 Nov 2014 20:22:47 +0000 (21:22 +0100)
ursaryd/nocturn.c
ursaryd/pulse.c
ursaryd/ursaryd.c
ursaryd/ursaryd.h

index f8665ed8a04d9d4d094cd521a328a4a67d4ec24b..510fb33590178118743bbef1252c382e7f7d4df0 100644 (file)
@@ -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;
index a2dd720b5c84bd61266f011d6df0348f1bd71478..72b40d82107838b87957c54a3f4b954d26a4cad7 100644 (file)
@@ -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);
index 469f7aed5fc95dacdae0c12afe92837a2569e1d9..b2cd009a3988223944cbbaebae744041d8c8f3b8 100644 (file)
@@ -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)
index 4781f3940212b6234e70fb8c6a342cd61bb8b58a..87f4854d844cf291f59333f1d008501a9f8233c5 100644 (file)
@@ -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);