chiark / gitweb /
Support global prefs through eclient interface.
[disorder] / lib / eclient.c
index 8e89a3122ce038ee72aa458af27c58cdff353e7c..d03306e852347b8d726f3ef9bf116ccb1922109d 100644 (file)
@@ -2,20 +2,18 @@
  * This file is part of DisOrder.
  * Copyright (C) 2006-2008 Richard Kettlewell
  *
- * This program is free software; you can redistribute it and/or modify
+ * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 /** @file lib/eclient.c
  * @brief Client code for event-driven programs
@@ -191,9 +189,11 @@ static void logentry_user_confirm(disorder_eclient *c, int nvec, char **vec);
 static void logentry_user_delete(disorder_eclient *c, int nvec, char **vec);
 static void logentry_user_edit(disorder_eclient *c, int nvec, char **vec);
 static void logentry_rights_changed(disorder_eclient *c, int nvec, char **vec);
+static void logentry_adopted(disorder_eclient *c, int nvec, char **vec);
 static void logentry_playlist_created(disorder_eclient *c, int nvec, char **vec);
 static void logentry_playlist_deleted(disorder_eclient *c, int nvec, char **vec);
 static void logentry_playlist_modified(disorder_eclient *c, int nvec, char **vec);
+static void logentry_global_pref(disorder_eclient *c, int nvec, char **vec);
 
 /* Tables ********************************************************************/
 
@@ -210,8 +210,10 @@ struct logentry_handler {
 /** @brief Table for parsing log entries */
 static const struct logentry_handler logentry_handlers[] = {
 #define LE(X, MIN, MAX) { #X, MIN, MAX, logentry_##X }
+  LE(adopted, 2, 2),
   LE(completed, 1, 1),
   LE(failed, 2, 2),
+  LE(global_pref, 1, 2),
   LE(moved, 1, 1),
   LE(playing, 1, 2),
   LE(playlist_created, 2, 2),
@@ -440,7 +442,7 @@ void disorder_eclient_polled(disorder_eclient *c, unsigned mode) {
   /* Queue up a byte to send */
   if(c->state == state_log
      && c->output.nvec == 0
-     && time(&now) - c->last_prod > LOG_PROD_INTERVAL) {
+     && xtime(&now) - c->last_prod > LOG_PROD_INTERVAL) {
     put(c, "x", 1);
     c->last_prod = now;
   }
@@ -741,7 +743,7 @@ static void process_line(disorder_eclient *c, char *line) {
          && line[1] >= '0' && line[1] <= '9'
          && line[2] >= '0' && line[2] <= '9'
          && line[3] == ' '))
-      fatal(0, "invalid response from server: %s", line);
+      disorder_fatal(0, "invalid response from server: %s", line);
     c->rc = (line[0] * 10 + line[1]) * 10 + line[2] - 111 * '0';
     c->line = line;
     switch(c->rc % 10) {
@@ -916,8 +918,8 @@ static void string_response_opcallback(disorder_eclient *c,
     = (disorder_eclient_string_response *)op->completed;
     
   D(("string_response_callback"));
-  if(c->rc / 100 == 2 || c->rc == 555) {
-    if(op->completed) {
+  if(completed) {
+    if(c->rc / 100 == 2 || c->rc == 555) {
       if(c->rc == 555)
         completed(op->v, NULL, NULL);
       else if(c->protocol >= 2) {
@@ -931,9 +933,9 @@ static void string_response_opcallback(disorder_eclient *c,
           completed(op->v, "error parsing response", NULL);
       } else
         completed(op->v, NULL, c->line + 4);
-    }
-  } else
-    completed(op->v, errorstring(c), NULL);
+    } else
+      completed(op->v, errorstring(c), NULL);
+  }
 }
 
 /* for commands with a simple integer response */ 
@@ -963,10 +965,12 @@ static void no_response_opcallback(disorder_eclient *c,
     = (disorder_eclient_no_response *)op->completed;
 
   D(("no_response_callback"));
-  if(c->rc / 100 == 2)
-    completed(op->v, NULL);
-  else
-    completed(op->v, errorstring(c));
+  if(completed) {
+    if(c->rc / 100 == 2)
+      completed(op->v, NULL);
+    else
+      completed(op->v, errorstring(c));
+  }
 }
 
 /* error callback for queue_unmarshall */
@@ -1132,6 +1136,28 @@ int disorder_eclient_play(disorder_eclient *c,
                 "play", track, (char *)0);
 }
 
+int disorder_eclient_playafter(disorder_eclient *c,
+                               const char *target,
+                               int ntracks,
+                               const char **tracks,
+                               disorder_eclient_no_response *completed,
+                               void *v) {
+  struct vector vec;
+  int n;
+
+  if(!target)
+    target = "";
+  vector_init(&vec);
+  vector_append(&vec, (char *)"playafter");
+  vector_append(&vec, (char *)target);
+  for(n = 0; n < ntracks; ++n)
+    vector_append(&vec, (char *)tracks[n]);
+  stash_command_vector(c, 0/*queuejump*/, no_response_opcallback, completed, v,
+                       -1, 0, vec.nvec, vec.vec);
+  disorder_eclient_polled(c, 0);
+  return 0;
+}
+
 int disorder_eclient_pause(disorder_eclient *c,
                            disorder_eclient_no_response *completed,
                            void *v) {
@@ -1334,6 +1360,31 @@ int disorder_eclient_nop(disorder_eclient *c,
                 "nop", (char *)0);
 }
 
+int disorder_eclient_get_global(disorder_eclient *c,
+                                disorder_eclient_string_response *completed,
+                                const char *pref,
+                                void *v) {
+  return simple(c, string_response_opcallback, (void (*)())completed, v,
+                "get-global", pref, (char *)0);
+}
+
+int disorder_eclient_set_global(disorder_eclient *c,
+                                disorder_eclient_no_response *completed,
+                                const char *pref,
+                                const char *value,
+                                void *v) {
+  return simple(c, no_response_opcallback, (void (*)())completed, v,
+                "set-global", pref, value, (char *)0);
+}
+
+int disorder_eclient_unset_global(disorder_eclient *c,
+                                  disorder_eclient_no_response *completed,
+                                  const char *pref,
+                                  void *v) {
+  return simple(c, no_response_opcallback, (void (*)())completed, v,
+                "unset-global", pref, (char *)0);
+}
+
 /** @brief Get the last @p max added tracks
  * @param c Client
  * @param completed Called with list
@@ -1465,6 +1516,20 @@ int disorder_eclient_adduser(disorder_eclient *c,
                 "adduser", user, password, rights, (char *)0);
 }
 
+/** @brief Adopt a track
+ * @param c Client
+ * @param completed Called on completion
+ * @param id Track ID
+ * @param v Passed to @p completed
+ */
+int disorder_eclient_adopt(disorder_eclient *c,
+                           disorder_eclient_no_response *completed,
+                           const char *id,
+                           void *v) {
+  return simple(c, no_response_opcallback, (void (*)())completed, v, 
+                "adopt", id, (char *)0);
+}
+
 /** @brief Get the list of playlists
  * @param c Client
  * @param completed Called with list of playlists
@@ -1877,6 +1942,18 @@ char *disorder_eclient_interpret_state(unsigned long statebits) {
   return d->vec;
 }
 
+static void logentry_adopted(disorder_eclient *c,
+                             int attribute((unused)) nvec, char **vec) {
+  if(c->log_callbacks->adopted) 
+    c->log_callbacks->adopted(c->log_v, vec[0], vec[1]);
+}
+
+static void logentry_global_pref(disorder_eclient *c,
+                                 int nvec, char **vec) {
+  if(c->log_callbacks->global_pref) 
+    c->log_callbacks->global_pref(c->log_v, vec[0], nvec > 1 ? vec[1] : 0);
+}
+
 /*
 Local Variables:
 c-basic-offset:2