]> Dogcows Code - chaz/openbox/commitdiff
Added a fifo_menu plugin
authorScott Moynes <smoynes@nexus.carleton.ca>
Sun, 18 May 2003 23:36:13 +0000 (23:36 +0000)
committerScott Moynes <smoynes@nexus.carleton.ca>
Sun, 18 May 2003 23:36:13 +0000 (23:36 +0000)
openbox/menu.c
plugins/menu/Makefile.am
plugins/menu/fifo_menu.c [new file with mode: 0644]
plugins/menu/fifo_menu.h [new file with mode: 0644]

index 3373616fef026758c2789ffe8bbe6872eefcc9e8..98f5fed14f44c04248d4c0742a4bbf6bbfc57fa5 100644 (file)
@@ -97,6 +97,11 @@ void menu_startup()
         menu_add_entry(t, menu_entry_new("xeyes", a));
         menu_add_entry(m, menu_entry_new_submenu("timed", t));
     }
+
+    t = (Menu *)plugin_create("fifo_menu");
+    if (t) {
+        menu_add_entry(m, menu_entry_new_submenu("fifo", t));
+    }
     
     s = menu_new("empty", "chub", m);
     menu_add_entry(m, menu_entry_new_submenu("empty", s));
index 5392f6e671fd3d8db1435ad53ef0e112263ccbb0..dbd29822ddf93ce0e788c3a5e0b10614813ec0c7 100644 (file)
@@ -5,12 +5,15 @@ CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) $(LIBSN_CFLAGS) @CPPFLAGS@ \
 
 INCLUDES=-I../..
 
-plugin_LTLIBRARIES=timed_menu.la
+plugin_LTLIBRARIES=timed_menu.la fifo_menu.la
 
 timed_menu_la_LDFLAGS=-module -avoid-version
 timed_menu_la_SOURCES=timed_menu.c
 
-noinst_HEADERS=timed_menu.h
+fifo_menu_la_LDFLAGS=-module -avoid-version
+fifo_menu_la_SOURCES=fifo_menu.c
+
+noinst_HEADERS=timed_menu.h fifo_menu.h
 
 MAINTAINERCLEANFILES=Makefile.in
 
diff --git a/plugins/menu/fifo_menu.c b/plugins/menu/fifo_menu.c
new file mode 100644 (file)
index 0000000..e508107
--- /dev/null
@@ -0,0 +1,208 @@
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "kernel/menu.h"
+#include "kernel/event.h"
+
+static char *PLUGIN_NAME = "fifo_menu";
+
+typedef struct Fifo_Menu_Data{
+    char *fifo;
+    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 */
+    event_fd_handler *handler;
+} Fifo_Menu_Data;
+
+#define FIFO_MENU(m) ((Menu *)m)
+#define FIFO_MENU_DATA(m) ((Fifo_Menu_Data *)((Menu *)m)->plugin_data)
+
+
+void fifo_menu_clean_up(Menu *m) {
+    if (FIFO_MENU_DATA(m)->buf != NULL) {
+        g_free(FIFO_MENU_DATA(m)->buf);
+        FIFO_MENU_DATA(m)->buf = NULL;
+        FIFO_MENU_DATA(m)->buflen = 0;
+    }
+
+    if (FIFO_MENU_DATA(m)->fd != -1) {
+        close(FIFO_MENU_DATA(m)->fd);
+        FIFO_MENU_DATA(m)->fd = -1;
+    }
+}
+
+void plugin_setup_config() { }
+void plugin_startup()
+{ }
+void plugin_shutdown() { }
+
+void fifo_menu_handler(int fd, Menu *menu) {
+    char *tmpbuf = NULL;
+    unsigned long num_read;
+#ifdef DEBUG
+    /* because gdb is dumb */
+    Fifo_Menu_Data *d = FIFO_MENU_DATA(menu);
+#endif
+    
+    /* if the menu is shown this will go into busy loop :(
+     fix me*/
+    if (!menu->shown) { 
+        unsigned long num_realloc;
+        /* if we have less than a quarter BUFSIZ left, allocate more */
+        num_realloc = (BUFSIZ - (FIFO_MENU_DATA(menu)->buflen % BUFSIZ) <
+                       BUFSIZ >> 2) ?
+            0 : BUFSIZ;
+    
+        tmpbuf = g_try_realloc(FIFO_MENU_DATA(menu)->buf,             
+                               FIFO_MENU_DATA(menu)->buflen + num_realloc);
+
+        if (tmpbuf == NULL) {
+            g_warning("Unable to allocate memory for read()");
+            return;
+        }
+    
+        FIFO_MENU_DATA(menu)->buf = tmpbuf;
+    
+        num_read = read(fd,
+                        FIFO_MENU_DATA(menu)->buf + FIFO_MENU_DATA(menu)->buflen,
+                        num_realloc);
+
+        if (num_read == 0) { /* eof */
+            unsigned long count = 0;
+            char *found = NULL;
+
+            menu->invalid = TRUE;
+            menu_clear(menu);
+
+            /* TEMP: list them */
+            while (NULL !=
+                   (found = strchr(&FIFO_MENU_DATA(menu)->buf[count], '\n'))) {
+                FIFO_MENU_DATA(menu)->buf
+                    [found - FIFO_MENU_DATA(menu)->buf] = '\0';
+                menu_add_entry(menu,
+                               menu_entry_new_separator
+                               (&FIFO_MENU_DATA(menu)->buf[count]));
+                count = found - FIFO_MENU_DATA(menu)->buf + 1;
+            }
+
+            FIFO_MENU_DATA(menu)->buf[FIFO_MENU_DATA(menu)->buflen] = '\0';
+            fifo_menu_clean_up(menu);
+
+            event_remove_fd(FIFO_MENU_DATA(menu)->handler->fd);
+        
+            if ((FIFO_MENU_DATA(menu)->fd =
+                 open(FIFO_MENU_DATA(menu)->fifo, O_NONBLOCK | O_RDONLY)) == -1) {
+                g_warning("Can't reopen FIFO");
+                fifo_menu_clean_up(menu);
+                return;
+            }
+
+            FIFO_MENU_DATA(menu)->handler->fd = FIFO_MENU_DATA(menu)->fd;
+        
+            event_add_fd_handler(FIFO_MENU_DATA(menu)->handler);
+        } else if (num_read > 0) {
+            FIFO_MENU_DATA(menu)->buflen += num_read;
+            FIFO_MENU_DATA(menu)->buf[FIFO_MENU_DATA(menu)->buflen] = '\0';
+        }
+    }
+}
+
+void plugin_destroy (Menu *m)
+{
+    fifo_menu_clean_up(m);
+    if (FIFO_MENU_DATA(m)->handler != NULL) {
+        g_free(FIFO_MENU_DATA(m)->handler);
+        FIFO_MENU_DATA(m)->handler = NULL;
+    }
+
+    if (FIFO_MENU_DATA(m)->fifo != NULL) {
+        g_free(FIFO_MENU_DATA(m)->fifo);
+        FIFO_MENU_DATA(m)->fifo = NULL;
+    }
+
+    g_free(m->plugin_data);
+
+    menu_free(m->name);
+}
+
+void *plugin_create() /* TODO: need config */
+{
+    char *fifo;
+    char *dir;
+    event_fd_handler *h;
+    
+    Fifo_Menu_Data *d = g_new(Fifo_Menu_Data, 1);
+    Menu *m = menu_new("", PLUGIN_NAME, NULL);
+
+    d->fd = -1;
+    d->buf = NULL;
+    d->buflen = 0;
+    d->handler = NULL;
+    
+    m->plugin = PLUGIN_NAME;
+
+    d->fd = -1;
+    
+    m->plugin_data = (void *)d;
+
+    dir = g_build_filename(g_get_home_dir(), ".openbox", PLUGIN_NAME, NULL);
+
+    if (mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO) == -1 && errno != EEXIST) {
+/* technically, if ~/.openbox/fifo_menu exists and isn't a directory
+   this will fail, but we don't care because mkfifo will fail and warn
+   anyway */
+        g_warning("Can't create %s: %s", dir, strerror(errno));
+        g_free(dir);
+        plugin_destroy(m);
+        return NULL;
+    }
+
+    fifo = g_build_filename(g_get_home_dir(), ".openbox", PLUGIN_NAME,
+                            m->name, NULL);
+    if (mkfifo(fifo, S_IRUSR | S_IWUSR |
+               S_IRGRP | S_IWGRP | /* let umask do its thing */
+               S_IROTH | S_IWOTH) == -1 && errno != EEXIST) {
+        g_warning("Can't create FIFO %s: %s", fifo, strerror(errno));
+        g_free(fifo);
+        g_free(d);
+        menu_free(m->name);
+        return NULL;
+    }
+
+/* open in non-blocking mode so we don't wait for a process to open FIFO
+   for writing */
+    if ((d->fd = open(fifo, O_NONBLOCK | O_RDONLY)) == -1) { 
+        g_warning("Can't open FIFO %s: %s", fifo, strerror(errno));
+        g_free(fifo);
+        g_free(d);
+        menu_free(m->name);
+        return NULL;
+    }
+
+    d->fifo = fifo;
+    
+    h = g_new(event_fd_handler, 1);
+
+    if (h == NULL) {
+        g_warning("Out of memory");
+        close(d->fd);
+        g_free(fifo);
+        g_free(d);
+        menu_free(m->name);
+        return NULL;
+    }
+    
+    h->fd = d->fd;
+    h->data = m;
+    h->handler = fifo_menu_handler;
+    d->handler = h;
+    
+    event_add_fd_handler(h);
+    
+    g_free(dir);
+    return (void *)m;
+}
diff --git a/plugins/menu/fifo_menu.h b/plugins/menu/fifo_menu.h
new file mode 100644 (file)
index 0000000..12eb332
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef __FIFO_MENU_H
+#define __FIFO_MENU_H
+
+#endif
This page took 0.027541 seconds and 4 git commands to generate.