]> Dogcows Code - chaz/openbox/blobdiff - plugins/menu/timed_menu.c
move the client and client-list menus into the 'kernel'
[chaz/openbox] / plugins / menu / timed_menu.c
index db642fc173152b8d486904d702188a62120c71ab..83ae5aa87f7aa720de6ddc5a7d655f64800f329c 100644 (file)
@@ -1,3 +1,35 @@
+/*
+ * $Header$
+ *
+ * Timed menu plugin
+ * Provides a menu from either a periodically executing process or by
+ * periodically checking the timestamp of a file and loading if it has changed.
+ *
+ * Examples:
+ * Piped timed menu:
+ * rc3:
+ *  <menu id="name" label="Piped menu" plugin="timed_menu" timeout="120"
+ *   command="obcommand.py -c bsetbg -d ~/.openbox/backgrounds/" />
+ * timeout is in seconds
+ *
+ * Output of command:
+ * <timed_menu>
+ *    <item label="GLOVE.png">
+ *       <action name="execute">
+ *          <execute>
+ *             bsetbg "/home/woodblock/.openbox/backgrounds/GLOVE.png"
+ *          </execute>
+ *       </action>
+ *    </item>
+ *  </fifo_menu>
+ *
+ * stat() menu:
+ *  <menu id="name" label="Stat menu" plugin="timed_menu" type="stat"
+ *  timeout="120" file="~/.openbox/stat_menu" />
+ * stat_menu contents: same as timed menu
+ * 
+ */
 #include <glib.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -27,7 +59,7 @@ typedef enum {
 typedef struct {
     Timed_Menu_Type type;
     ObTimer *timer;
-    char *command; /* for the PIPE */
+    char *command; /* command to run or file to stat() */
     char *buf; /* buffer to hold partially read menu */
     unsigned long buflen; /* how many bytes are in the buffer */
     int fd; /* file descriptor to read menu from */
@@ -43,7 +75,6 @@ void plugin_shutdown() { }
 
 void timed_menu_clean_up(ObMenu *m) {
     if (TIMED_MENU_DATA(m)->buf != NULL) {
-        fprintf(stderr, "%s", TIMED_MENU_DATA(m)->buf);
         g_free(TIMED_MENU_DATA(m)->buf);
         TIMED_MENU_DATA(m)->buf = NULL;
     }
@@ -60,8 +91,6 @@ void timed_menu_clean_up(ObMenu *m) {
         waitpid(TIMED_MENU_DATA(m)->pid, NULL, 0);
         TIMED_MENU_DATA(m)->pid = -1;
     }
-
-    TIMED_MENU_DATA(m)->mtime = 0;
 }
 
 void timed_menu_read_pipe(int fd, void *d)
@@ -96,20 +125,23 @@ void timed_menu_read_pipe(int fd, void *d)
                     TIMED_MENU_DATA(menu)->buf + TIMED_MENU_DATA(menu)->buflen,
                     num_realloc);
     if (num_read == 0) {
-         menu->invalid = TRUE;
+        ObParseInst *i;
+        xmlDocPtr doc;
+        xmlNodePtr node;
+
+        menu->invalid = TRUE;
         menu_clear(menu);
 
         TIMED_MENU_DATA(menu)->buf[TIMED_MENU_DATA(menu)->buflen] = '\0';
 
-        xmlDocPtr doc = xmlParseMemory(TIMED_MENU_DATA(menu)->buf,
-                                       TIMED_MENU_DATA(menu)->buflen);
+        i = parse_startup();
 
-        xmlNodePtr node = xmlDocGetRootElement(doc);
+        if (parse_load_mem(TIMED_MENU_DATA(menu)->buf,
+                           TIMED_MENU_DATA(menu)->buflen,
+                           "timed_menu", &doc, &node))
+            parse_menu_full(i, doc, node, menu, FALSE);
 
-        if (!xmlStrcasecmp(node->name, (const xmlChar*) "timed_menu")) {
-            if ((node = parse_find_node("item", node->xmlChildrenNode)))
-                parse_menu_full(doc, node, menu, FALSE);
-        }
+        parse_shutdown(i);
 
         timed_menu_clean_up(menu);
     } else if (num_read > 0) {
@@ -121,7 +153,7 @@ void timed_menu_read_pipe(int fd, void *d)
     }
 }
 
-void timed_menu_timeout_handler(void *d)
+void timed_menu_timeout_handler(ObTimer *t, void *d)
 {
     ObMenu *data = d;
     if (!data->shown && TIMED_MENU_DATA(data)->fd == -1) {
@@ -173,9 +205,25 @@ void timed_menu_timeout_handler(void *d)
                 }
 
                 if (stat_buf.st_mtime > TIMED_MENU_DATA(data)->mtime) {
+                    ObParseInst *i;
+                    xmlDocPtr doc;
+                    xmlNodePtr node;
+
                     g_warning("file changed");
                     TIMED_MENU_DATA(data)->mtime = stat_buf.st_mtime;
-                    /* TODO: parse */
+       
+                    data->invalid = TRUE;
+                    menu_clear(data);
+
+                    i = parse_startup();
+
+                    if (parse_load(TIMED_MENU_DATA(data)->command,
+                                   "timed_menu", &doc, &node))
+                        parse_menu_full(i, doc, node, data, FALSE);
+
+                    parse_shutdown(i);
+
+                    timed_menu_clean_up(data);
                 }
             }
         }
@@ -187,6 +235,8 @@ void *plugin_create(PluginMenuCreateData *data)
     char *id;
     char *label;
     char *timeout;
+    char *type;
+    
     Timed_Menu_Data *d;
     ObMenu *m;
     
@@ -206,9 +256,19 @@ void *plugin_create(PluginMenuCreateData *data)
                            (label != NULL ? label : ""),
                            m));
 
-    if (!parse_attr_string("command", data->node, &d->command)) {
-        d->command = g_strdup("");
-    }
+    d->type = TIMED_MENU_PIPE;
+
+    if (parse_attr_string("type", data->node, &type) &&
+        !g_strcasecmp(type, "stat")) {
+        d->type = TIMED_MENU_STAT;
+        
+        if (!parse_attr_string("file", data->node, &d->command)) {
+            d->command = g_strdup("");
+        }
+    } else
+        if (!parse_attr_string("command", data->node, &d->command)) {
+            d->command = g_strdup("");
+        }
 
     if (parse_attr_string("timeout", data->node, &timeout)) {
         char *endptr;
@@ -219,7 +279,6 @@ void *plugin_create(PluginMenuCreateData *data)
     } else
         d->timer = timer_start(600 * 1000000, &timed_menu_timeout_handler, m);
 
-    d->type = TIMED_MENU_PIPE;
     d->buf = NULL;
     d->buflen = 0;
     d->fd = -1;
@@ -228,7 +287,7 @@ void *plugin_create(PluginMenuCreateData *data)
     
     m->plugin_data = (void *)d;
 
-    timed_menu_timeout_handler(m);
+    timed_menu_timeout_handler(NULL, m);
     return (void *)m;
 }
 
This page took 0.026078 seconds and 4 git commands to generate.