chiark / gitweb /
disobedience, playrtp: Have `playrtp' handle volume control.
[disorder] / disobedience / rtp.c
index 46931736b42665a205229aafd0289da15d7ef26f..bb71022a86f9566bb45f44b4da97642f13262fbc 100644 (file)
@@ -97,6 +97,27 @@ int rtp_running(void) {
   return 1;
 }
 
+int rtp_getvol(int *l, int *r) {
+  FILE *fp;
+  int rc = -1;
+
+  fp = rtp_connect(); if(!fp) goto end;
+  fprintf(fp, "getvol\n"); fflush(fp);
+  if(fscanf(fp, "%d %d\n", l, r) != 2) goto end;
+  rc = 0;
+end:
+  if(fp) fclose(fp);
+  return rc;
+}
+
+int rtp_setvol(int *l, int *r) {
+  FILE *fp = rtp_connect(); if(!fp) return -1;
+  fprintf(fp, "setvol %d %d\n", *l, *r); fflush(fp);
+  if(fscanf(fp, "%d %d\n", l, r) != 2) { /* do nothing */ }
+  fclose(fp);
+  return 0;
+}
+
 /** @brief Activate the RTP player if it is not running */
 void start_rtp(void) {
   pid_t pid;
@@ -129,7 +150,10 @@ void start_rtp(void) {
        disorder_fatal(errno, "close");
       /* execute the player */
       execlp("disorder-playrtp",
-            "disorder-playrtp", "--socket", rtp_socket, (char *)0);
+            "disorder-playrtp",
+             "--socket", rtp_socket,
+             "--api", rtp_api,
+             (char *)0);
       disorder_fatal(errno, "disorder-playrtp");
     } else {
       /* child */
@@ -152,6 +176,75 @@ void stop_rtp(void) {
   fclose(fp);
 }
 
+static char *rtp_config_file(void) {
+  static char *rtp_config;
+  const char *home = getenv("HOME");
+  if(!rtp_config)
+    byte_xasprintf(&rtp_config, "%s/.disorder/api", home);
+  return rtp_config;
+}
+
+const char *rtp_api;
+
+void load_rtp_config(void) {
+  char *rtp_config = rtp_config_file();
+  FILE *fp;
+  if((fp = fopen(rtp_config, "r"))) {
+    char *line;
+    if(inputline(rtp_config, fp, &line, '\n') == 0) {
+      for(int n = 0; uaudio_apis[n]; ++n)
+        if(!strcmp(uaudio_apis[n]->name, line))
+          rtp_api = line;
+    }
+    fclose(fp);
+  }
+  if(!rtp_api)
+    rtp_api = uaudio_default(uaudio_apis, UAUDIO_API_CLIENT)->name;
+}
+
+void save_rtp_config(void) {
+  if(rtp_api) {
+    char *rtp_config = rtp_config_file();
+    char *tmp;
+    byte_xasprintf(&tmp, "%s.tmp", rtp_config);
+    FILE *fp;
+    if(!(fp = fopen(tmp, "w"))){
+      fpopup_msg(GTK_MESSAGE_ERROR, "error opening %s: %s",
+                 tmp, strerror(errno));
+      return;
+    }
+    if(fprintf(fp, "%s\n", rtp_api) < 0) {
+      fpopup_msg(GTK_MESSAGE_ERROR, "error writing to %s: %s",
+                 tmp, strerror(errno));
+      fclose(fp);
+      return;
+    }
+    if(fclose(fp) < 0) {
+      fpopup_msg(GTK_MESSAGE_ERROR, "error closing %s: %s",
+                 tmp, strerror(errno));
+      return;
+    }
+    if(rename(tmp, rtp_config) < 0) {
+      fpopup_msg(GTK_MESSAGE_ERROR, "error renaming %s: %s",
+                 tmp, strerror(errno));
+    }
+  }
+}
+
+void change_rtp_api(const char *api) {
+  if(rtp_api && !strcmp(api, rtp_api))
+    return;                             /* no change */
+  int running = rtp_running();
+  if(running)
+    stop_rtp();
+  rtp_api = api;
+  save_rtp_config();
+  // TODO this is racy and does not work; the player doesn't shut down quickly
+  // enough.
+  if(running)
+    start_rtp();
+}
+
 /*
 Local Variables:
 c-basic-offset:2