]> Dogcows Code - chaz/openbox/commitdiff
Menu uber patch
authorScott Moynes <smoynes@nexus.carleton.ca>
Fri, 9 May 2003 23:15:28 +0000 (23:15 +0000)
committerScott Moynes <smoynes@nexus.carleton.ca>
Fri, 9 May 2003 23:15:28 +0000 (23:15 +0000)
Since we have no menu parser see menu_startup() to customize

12 files changed:
configure.ac
openbox/event.c
openbox/menu.c
openbox/menu.h
openbox/menu_render.c
openbox/plugin.c
openbox/plugin.h
openbox/timer.c
plugins/Makefile.am
plugins/menu/Makefile.in [new file with mode: 0644]
plugins/menu/timed_menu.c [new file with mode: 0644]
plugins/menu/timed_menu.h [new file with mode: 0644]

index 9b914efa36d369da9093f54009849f72dd62aeb9..23c8ca40987bf841f70dca20c37ca0b4c03082cc 100644 (file)
@@ -72,6 +72,7 @@ AC_CONFIG_FILES([Makefile
                 plugins/placement/Makefile
                 plugins/mouse/Makefile
                 plugins/keyboard/Makefile
+                plugins/menu/Makefile])
                 tools/Makefile
                 tools/slit/Makefile])
 AC_OUTPUT
index 2e2d5c0c744ee2d66eb112e7dbde6bd45c78f30e..5dd1f7057f6361a211858914fe6943f5974d4713 100644 (file)
@@ -378,6 +378,7 @@ static void event_process(XEvent *e)
     window = event_get_window(e);
     if (!(client = g_hash_table_lookup(client_map, &window)))
         menu = g_hash_table_lookup(menu_map, &window);
+
     event_set_lasttime(e);
     event_hack_mods(e);
     if (event_ignore(e, client))
@@ -858,10 +859,12 @@ static void event_handle_menu(Menu *menu, XEvent *e)
     g_message("EVENT %d", e->type);
     switch (e->type) {
     case ButtonPress:
+       g_message("BUTTON PRESS");
         if (e->xbutton.button == 3)
             menu_hide(menu);
         break;
     case ButtonRelease:
+       g_message("BUTTON RELEASED");
         if (!menu->shown) break;
 
 /*        grab_pointer_window(FALSE, None, menu->frame);*/
@@ -879,16 +882,21 @@ static void event_handle_menu(Menu *menu, XEvent *e)
                 e->xbutton.y < (signed)(h+b)) {
                 menu_entry_fire(entry);
             }
-        }
+       
         break;
     case EnterNotify:
     case LeaveNotify:
         g_message("enter/leave");
         entry = menu_find_entry(menu, e->xcrossing.window);
         if (entry) {
-            entry->hilite = e->type == EnterNotify;
+            if (menu->mouseover)
+                menu->mouseover(entry, e->type == EnterNotify);
+            else
+                menu_control_mouseover(entry, e->type == EnterNotify);
+           
             menu_entry_render(entry);
         }
         break;
+       }
     }
 }
index 88eef9c558d5278ef51625daf0d8100494b5b003..b271cf31e811220688f906fb4821a321de291471 100644 (file)
@@ -3,11 +3,15 @@
 #include "stacking.h"
 #include "grab.h"
 #include "render/theme.h"
+#include "screen.h"
+#include "geom.h"
+#include "plugin.h"
 
 static GHashTable *menu_hash = NULL;
 GHashTable *menu_map = NULL;
 
-#define FRAME_EVENTMASK (ButtonMotionMask | EnterWindowMask | LeaveWindowMask)
+#define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask | \
+                        LeaveWindowMask)
 #define TITLE_EVENTMASK (ButtonPressMask | ButtonMotionMask)
 #define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
                          ButtonPressMask | ButtonReleaseMask)
@@ -60,6 +64,8 @@ void menu_entry_free(MenuEntry *self)
 void menu_startup()
 {
     Menu *m;
+    Menu *s;
+    Menu *t;
     Action *a;
 
     menu_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -67,15 +73,50 @@ void menu_startup()
                                       (GDestroyNotify)menu_destroy_hash_value);
     menu_map = g_hash_table_new(g_int_hash, g_int_equal);
 
-    m = menu_new("sex menu", "root", NULL);
+    m = menu_new(NULL, "root", NULL);
     a = action_from_string("execute");
     a->data.execute.path = g_strdup("xterm");
     menu_add_entry(m, menu_entry_new("xterm", a));
     a = action_from_string("restart");
     menu_add_entry(m, menu_entry_new("restart", a));
-    menu_add_entry(m, menu_entry_new("--", NULL));
+    menu_add_entry(m, menu_entry_new_separator("--"));
     a = action_from_string("exit");
     menu_add_entry(m, menu_entry_new("exit", a));
+    s = menu_new("subsex menu", "submenu", m);
+    a = action_from_string("execute");
+    a->data.execute.path = g_strdup("xclock");
+    menu_add_entry(s, menu_entry_new("xclock", a));
+
+    menu_add_entry(m, menu_entry_new_submenu("subz", s));
+
+    /*
+    t = (Menu *)plugin_create("timed_menu");
+    a = action_from_string("execute");
+    a->data.execute.path = g_strdup("xeyes");
+    menu_add_entry(t, menu_entry_new("xeyes", a));*/
+
+    s = menu_new("empty", "chub", m);
+    menu_add_entry(m, menu_entry_new_submenu("empty", s));
+
+    s = menu_new("", "s-club", m);
+    menu_add_entry(m, menu_entry_new_submenu("empty", s));
+
+    s = menu_new(NULL, "h-club", m);
+    menu_add_entry(m, menu_entry_new_submenu("empty", s));
+
+    s = menu_new(NULL, "g-club", m);
+
+    a = action_from_string("execute");
+    a->data.execute.path = g_strdup("xterm");
+    menu_add_entry(s, menu_entry_new("xterm", a));
+    a = action_from_string("restart");
+    menu_add_entry(s, menu_entry_new("restart", a));
+    menu_add_entry(s, menu_entry_new_separator("--"));
+    a = action_from_string("exit");
+    menu_add_entry(s, menu_entry_new("exit", a));
+
+    menu_add_entry(m, menu_entry_new_submenu("long", s));
 
     m = menu_new("client menu", "client", NULL);
     a = action_from_string("iconify");
@@ -86,6 +127,7 @@ void menu_startup()
     menu_add_entry(m, menu_entry_new("(un)maximize", a));
     a = action_from_string("close");
     menu_add_entry(m, menu_entry_new("close", a));
+
 }
 
 void menu_shutdown()
@@ -113,18 +155,22 @@ Menu *menu_new_full(char *label, char *name, Menu *parent,
     self->label = g_strdup(label);
     self->name = g_strdup(name);
     self->parent = parent;
+    self->open_submenu = NULL;
 
     self->entries = NULL;
     self->shown = FALSE;
-    self->invalid = FALSE;
-    /* default controllers? */
-    
+    self->invalid = TRUE;
+
+    /* default controllers */
     self->show = show;
     self->hide = NULL;
     self->update = update;
     self->mouseover = NULL;
     self->selected = NULL;
 
+    self->plugin = NULL;
+    self->plugin_data = NULL;
+
     attrib.override_redirect = TRUE;
     attrib.event_mask = FRAME_EVENTMASK;
     self->frame = createWindow(ob_root, CWOverrideRedirect|CWEventMask, &attrib);
@@ -133,6 +179,7 @@ Menu *menu_new_full(char *label, char *name, Menu *parent,
     self->items = createWindow(self->frame, 0, &attrib);
 
     XSetWindowBorderWidth(ob_display, self->frame, theme_bwidth);
+    XSetWindowBackground(ob_display, self->frame, theme_b_color->pixel);
     XSetWindowBorderWidth(ob_display, self->title, theme_bwidth);
     XSetWindowBorder(ob_display, self->frame, theme_b_color->pixel);
     XSetWindowBorder(ob_display, self->title, theme_b_color->pixel);
@@ -207,35 +254,42 @@ void menu_add_entry(Menu *menu, MenuEntry *entry)
 void menu_show(char *name, int x, int y, Client *client)
 {
     Menu *self;
-
+  
     self = g_hash_table_lookup(menu_hash, name);
     if (!self) {
         g_warning("Attempted to show menu '%s' but it does not exist.",
                   name);
         return;
     }
+    
+    menu_show_full(self, x, y, client);
+}  
 
-    if (self->invalid) {
-      if (self->update) {
-        self->update(self);
-      } else {
-        menu_render(self);
-      }
-    }
+void menu_show_full(Menu *self, int x, int y, Client *client)
+{
+    g_assert(self != NULL);
+       
+    menu_render(self);
     
     self->client = client;
 
     if (self->show) {
-      self->show(self, x, y, client);
+       self->show(self, x, y, client);
     } else {
       menu_control_show(self, x, y, client);
     }
 }
 
+
 void menu_hide(Menu *self) {
     if (self->shown) {
         XUnmapWindow(ob_display, self->frame);
         self->shown = FALSE;
+       if (self->open_submenu)
+           menu_hide(self->open_submenu);
+       if (self->parent && self->parent->open_submenu == self)
+           self->parent->open_submenu = NULL;
+
     }
 }
 
@@ -251,29 +305,6 @@ MenuEntry *menu_find_entry(Menu *menu, Window win)
     return NULL;
 }
 
-void menu_entry_render(MenuEntry *self)
-{
-    Menu *menu = self->parent;
-    Appearance *a;
-
-    a = !self->enabled ? self->a_disabled :
-        (self->hilite && self->action ? self->a_hilite : self->a_item);
-
-    RECT_SET(a->area, 0, 0, menu->width,
-             menu->item_h);
-    RECT_SET(a->texture[0].position, menu->bullet_w,
-             0, menu->width - 2 * menu->bullet_w,
-             menu->item_h);
-
-    XMoveResizeWindow(ob_display, self->item, 0, self->y,
-                      menu->width, menu->item_h);
-    a->surface.data.planar.parent = menu->a_items;
-    a->surface.data.planar.parentx = 0;
-    a->surface.data.planar.parenty = self->y;
-
-    paint(self->item, a);
-}
-
 void menu_entry_fire(MenuEntry *self)
 {
     Menu *m;
@@ -294,11 +325,52 @@ void menu_entry_fire(MenuEntry *self)
 */
 
 void menu_control_show(Menu *self, int x, int y, Client *client) {
-  XMoveWindow(ob_display, self->frame, x, y);
+    g_assert(!self->invalid);
+    
+    XMoveWindow(ob_display, self->frame, 
+               MIN(x, screen_physical_size.width - self->size.width), 
+               MIN(y, screen_physical_size.height - self->size.height));
+    POINT_SET(self->location, 
+             MIN(x, screen_physical_size.width - self->size.width), 
+             MIN(y, screen_physical_size.height - self->size.height));
+
+    if (!self->shown) {
+       stacking_raise_internal(self->frame);
+       XMapWindow(ob_display, self->frame);
+       self->shown = TRUE;
+    } else if (self->shown && self->open_submenu) {
+       menu_hide(self->open_submenu);
+    }
+}
 
-  if (!self->shown) {
-    stacking_raise_internal(self->frame);
-    XMapWindow(ob_display, self->frame);
-    self->shown = TRUE;
-  }
+void menu_control_mouseover(MenuEntry *self, gboolean enter) {
+    int x;
+    self->hilite = enter;
+  
+    if (enter) {
+       if (self->parent->open_submenu && self->submenu 
+           != self->parent->open_submenu)
+           menu_hide(self->parent->open_submenu);
+       
+       if (self->submenu) {
+           self->parent->open_submenu = self->submenu;
+
+           /* shouldn't be invalid since it must be displayed */
+           g_assert(!self->parent->invalid);
+           /* TODO: I don't understand why these bevels should be here.
+              Something must be wrong in the width calculation */
+           x = self->parent->location.x + self->parent->size.width + 
+               theme_bevel;
+
+           /* need to get the width. is this bad?*/
+           menu_render(self->submenu);
+
+           if (self->submenu->size.width + x > screen_physical_size.width)
+               x = self->parent->location.x - self->submenu->size.width - 
+                   theme_bevel;
+           
+           menu_show_full(self->submenu, x,
+                          self->parent->location.y + self->y, NULL);
+       } 
+    }
 }
index 1a3f002a7184d86dd9edf292b48340929d4647d8..081b3528db0f65f78a30cf78d50d3a9e3e43afed 100644 (file)
@@ -3,15 +3,19 @@
 
 #include "action.h"
 #include "render/render.h"
+#include "geom.h"
 
 #include <glib.h>
 
 extern GHashTable *menu_map;
 
 struct Menu;
+struct MenuEntry;
 
 typedef void(*menu_controller_show)(struct Menu *self, int x, int y, Client *);
 typedef void(*menu_controller_update)(struct Menu *self);
+typedef void(*menu_controller_mouseover)(struct MenuEntry *self, 
+                                         gboolean enter);
 
 typedef struct Menu {
     char *label;
@@ -23,6 +27,8 @@ typedef struct Menu {
     gboolean invalid;
 
     struct Menu *parent;
+    
+    struct Menu *open_submenu;
 
     /* place a menu on screen */
     menu_controller_show show;
@@ -30,7 +36,7 @@ typedef struct Menu {
 
     /* render a menu */
     menu_controller_update update;
-    void (*mouseover)( /* some bummu */);
+    menu_controller_mouseover mouseover;
     void (*selected)( /* some bummu */);
 
 
@@ -44,7 +50,12 @@ typedef struct Menu {
     Appearance *a_items;
     int bullet_w;
     int item_h;
-    int width;
+    Point location;
+    Size size;
+
+    /* plugin stuff */
+    char *plugin;
+    void *plugin_data;
 } Menu;
 
 typedef enum MenuEntryRenderType {
@@ -89,6 +100,8 @@ Menu *menu_new_full(char *label, char *name, Menu *parent,
 void menu_free(char *name);
 
 void menu_show(char *name, int x, int y, Client *client);
+void menu_show_full(Menu *menu, int x, int y, Client *client);
+
 void menu_hide(Menu *self);
 
 MenuEntry *menu_entry_new_full(char *label, Action *action,
@@ -96,7 +109,16 @@ MenuEntry *menu_entry_new_full(char *label, Action *action,
                                gpointer submenu);
 
 #define menu_entry_new(label, action) \
-  menu_entry_new_full(label, action, MenuEntryRenderType_None, NULL)
+menu_entry_new_full(label, action, MenuEntryRenderType_None, NULL)
+
+#define menu_entry_new_separator(label) \
+menu_entry_new_full(label, NULL, MenuEntryRenderType_Separator, NULL)
+
+#define menu_entry_new_submenu(label, submenu) \
+menu_entry_new_full(label, NULL, MenuEntryRenderType_Submenu, submenu)
+
+#define menu_entry_new_boolean(label, action) \
+menu_entry_new_full(label, action, MenuEntryRenderType_Boolean, NULL)
 
 void menu_entry_free(MenuEntry *entry);
 
@@ -112,4 +134,5 @@ void menu_entry_fire(MenuEntry *self);
 
 void menu_render(Menu *self);
 
+void menu_control_mouseover(MenuEntry *entry, gboolean enter);
 #endif
index cf961f24c8acdc1f471845d65c35020d1dc2b59d..6a95fcbb0a792adba11d9e5225cd192ff1358d72 100644 (file)
@@ -4,21 +4,36 @@
 #include "openbox.h"
 #include "render/theme.h"
 
+void menu_render_full(Menu *self);
+
 void menu_render(Menu *self) {
+    if (self->invalid) {
+       if (self->update) {
+           self->update(self);
+       } else {
+           menu_render_full(self);
+       }
+    }
+}
+           
+
+void menu_render_full(Menu *self) {
     GList *it;
-    int items_h;
+    int items_h = 0;
     int nitems = 0; /* each item, only one is used */
     int item_y;
 
-    self->width = 1;
-    self->item_h = 0;
+    self->size.width = 1;
+    self->item_h = 1;
 
     /* set texture data and size them mofos out */
-    self->a_title->texture[0].data.text.string = self->label;
-    appearance_minsize(self->a_title, &self->title_min_w, &self->title_h);
-    self->title_min_w += theme_bevel * 2;
-    self->title_h += theme_bevel * 2;
-    self->width = MAX(self->width, self->title_min_w);
+    if (self->label) {
+       self->a_title->texture[0].data.text.string = self->label;
+       appearance_minsize(self->a_title, &self->title_min_w, &self->title_h);
+       self->title_min_w += theme_bevel * 2;
+       self->title_h += theme_bevel * 2;
+       self->size.width = MAX(self->size.width, self->title_min_w);
+    }
 
     for (it = self->entries; it; it = it->next) {
         MenuEntry *e = it->data;
@@ -26,39 +41,44 @@ void menu_render(Menu *self) {
 
         e->a_item->texture[0].data.text.string = e->label;
         appearance_minsize(e->a_item, &e->min_w, &self->item_h);
-        self->width = MAX(self->width, e->min_w);
+        self->size.width = MAX(self->size.width, e->min_w);
 
         e->a_disabled->texture[0].data.text.string = e->label;
         appearance_minsize(e->a_disabled, &e->min_w, &h);
         self->item_h = MAX(self->item_h, h);
-        self->width = MAX(self->width, e->min_w);
-
+        self->size.width = MAX(self->size.width, e->min_w);
+       
         e->a_hilite->texture[0].data.text.string = e->label;
         appearance_minsize(e->a_hilite, &e->min_w, &h);
         self->item_h = MAX(self->item_h, h);
-        self->width = MAX(self->width, e->min_w);
+        self->size.width = MAX(self->size.width, e->min_w);
 
         e->min_w += theme_bevel * 2;
         ++nitems;
     }
     self->bullet_w = self->item_h + theme_bevel;
-    self->width += 2 * self->bullet_w;
+    self->size.width += 2 * self->bullet_w + 2 * theme_bevel;
     self->item_h += theme_bevel * 2;
-    items_h = self->item_h * nitems;
+    items_h = self->item_h * MAX(nitems, 1);
+
+    if (self->label) {
+       RECT_SET(self->a_title->area, 0, 0, self->size.width, self->title_h);
+       RECT_SET(self->a_title->texture[0].position, 0, 0, self->size.width,
+                self->title_h);
+    }
 
-    RECT_SET(self->a_title->area, 0, 0, self->width, self->title_h);
-    RECT_SET(self->a_title->texture[0].position, 0, 0, self->width,
-             self->title_h);
-    RECT_SET(self->a_items->area, 0, 0, self->width, items_h);
+    RECT_SET(self->a_items->area, 0, 0, self->size.width, items_h);
 
-    XResizeWindow(ob_display, self->frame, self->width, 
-                  self->title_h + items_h);
-    XMoveResizeWindow(ob_display, self->title, -theme_bwidth, -theme_bwidth,
-                      self->width, self->title_h);
+    XResizeWindow(ob_display, self->frame, self->size.width,
+                 MAX(self->title_h + items_h, 1));
+    if (self->label)
+       XMoveResizeWindow(ob_display, self->title, -theme_bwidth,
+                         -theme_bwidth, self->size.width, self->title_h);
     XMoveResizeWindow(ob_display, self->items, 0, self->title_h + theme_bwidth,
-                      self->width, items_h);
+                      self->size.width, items_h);
 
-    paint(self->title, self->a_title);
+    if (self->label)
+       paint(self->title, self->a_title);
     paint(self->items, self->a_items);
 
     item_y = 0;
@@ -67,6 +87,52 @@ void menu_render(Menu *self) {
         menu_entry_render(it->data);
         item_y += self->item_h;
     }
-
+    
+    self->size.height = item_y;
     self->invalid = FALSE;
 }
+
+void menu_entry_render(MenuEntry *self)
+{
+    Menu *menu = self->parent;
+    Appearance *a;
+    
+    switch (self->render_type) {
+    case MenuEntryRenderType_Submenu:
+       /* TODO: submenu mask */
+    case MenuEntryRenderType_Boolean:
+       /* TODO: boolean check */
+       a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item) 
+           : self->a_disabled;
+       break;
+    case MenuEntryRenderType_None:
+       a = self->enabled ? (self->hilite ? self->a_hilite : self->a_item )
+           : self->a_disabled;
+       break;
+    case MenuEntryRenderType_Separator:
+       a = self->a_item;
+       break;
+
+    default:
+       g_message("unhandled render_type");
+       a = !self->enabled ? self->a_disabled :
+        (self->hilite && 
+         (self->action || self->render_type == MenuEntryRenderType_Submenu) ? 
+         self->a_hilite : self->a_item);
+       break;
+    }
+
+    RECT_SET(a->area, 0, 0, menu->size.width,
+             menu->item_h);
+    RECT_SET(a->texture[0].position, menu->bullet_w,
+             0, menu->size.width - 2 * menu->bullet_w,
+             menu->item_h);
+
+    XMoveResizeWindow(ob_display, self->item, 0, self->y,
+                      menu->size.width, menu->item_h);
+    a->surface.data.planar.parent = menu->a_items;
+    a->surface.data.planar.parentx = 0;
+    a->surface.data.planar.parenty = self->y;
+
+    paint(self->item, a);
+}
index c3e21ec49c81fcf29a60ab7d963d36c5653e0cf1..a5055de9a1088a27dd2a227219b277d605d6000f 100644 (file)
@@ -4,6 +4,8 @@
 typedef void (*PluginSetupConfig)();
 typedef void (*PluginStartup)();
 typedef void (*PluginShutdown)();
+typedef void *(*PluginCreate)(/* TODO */);
+typedef void (*PluginDestroy)(void *);
 
 typedef struct {
     GModule *module;
@@ -12,14 +14,18 @@ typedef struct {
     PluginSetupConfig config;
     PluginStartup startup;
     PluginShutdown shutdown;
+    PluginCreate create;
+    PluginDestroy destroy;
 } Plugin;
 
-static gpointer load_sym(GModule *module, char *name, char *symbol)
+static gpointer load_sym(GModule *module, char *name, char *symbol,
+                        gboolean allow_fail)
 {
     gpointer var;
     if (!g_module_symbol(module, symbol, &var)) {
-        g_warning("Failed to load symbol '%s' from plugin '%s'",
-                  symbol, name);
+        if (!allow_fail)
+           g_warning("Failed to load symbol '%s' from plugin '%s'",
+                     symbol, name);
         var = NULL;
     }
     return var;
@@ -50,9 +56,14 @@ static Plugin *plugin_new(char *name)
     }
 
     p->config = (PluginSetupConfig)load_sym(p->module, name,
-                                            "plugin_setup_config");
-    p->startup = (PluginStartup)load_sym(p->module, name, "plugin_startup");
-    p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown");
+                                            "plugin_setup_config", FALSE);
+    p->startup = (PluginStartup)load_sym(p->module, name, "plugin_startup",
+                                        FALSE);
+    p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown",
+                                          FALSE);
+    p->create = (PluginCreate)load_sym(p->module, name, "plugin_create", TRUE);
+    p->destroy = (PluginDestroy)load_sym(p->module, name, "plugin_destroy",
+                                        TRUE);
 
     if (p->config == NULL || p->startup == NULL || p->shutdown == NULL) {
         g_module_close(p->module);
@@ -85,12 +96,13 @@ void plugin_shutdown()
     g_datalist_clear(&plugins);
 }
 
-gboolean plugin_open(char *name)
+gboolean plugin_open_full(char *name, gboolean reopen)
 {
     Plugin *p;
 
     if (g_datalist_get_data(&plugins, name) != NULL) {
-        g_warning("plugin '%s' already loaded, can't load again", name);
+       if (!reopen) 
+           g_warning("plugin '%s' already loaded, can't load again", name);
         return TRUE;
     }
 
@@ -105,6 +117,14 @@ gboolean plugin_open(char *name)
     return TRUE;
 }
 
+gboolean plugin_open(char *name) {
+    return plugin_open_full(name, FALSE);
+}
+
+gboolean plugin_open_reopen(char *name) {
+    return plugin_open_full(name, TRUE);
+}
+
 void plugin_close(char *name)
 {
     g_datalist_remove_data(&plugins, name);
@@ -156,3 +176,41 @@ void plugin_loadall()
         g_io_channel_unref(io);
     }
 }
+
+void *plugin_create(char *name /* TODO */)
+{
+    Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name);
+
+    if (p == NULL) {
+       g_warning("Unable to find plugin for create: %s", name);
+       return NULL;
+    }
+
+    if (p->create == NULL || p->destroy == NULL) {
+       g_critical("Unsupported create/destroy: %s", name);
+       return NULL;
+    }
+
+    return p->create();
+}
+
+void plugin_destroy(char *name, void *data)
+{
+    Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name);
+
+    if (p == NULL) {
+       g_critical("Unable to find plugin for destroy: %s", name);
+       /* really shouldn't happen, but attempt to free something anyway? */
+       g_free(data);
+       return;
+    }
+
+    if (p->destroy == NULL || p->create == NULL) {
+       g_critical("Unsupported create/destroy: %s", name);
+       /* really, really shouldn't happen, but attempt to free anyway? */
+       g_free(data);
+       return;
+    }
+
+    p->destroy(data);
+}
index 8595fbacc2c0159ef46ded7354845fe1f095a68e..733f564b27c08ccaed9addf61468d5d68fa1726c 100644 (file)
@@ -7,7 +7,15 @@ void plugin_shutdown();
 void plugin_loadall();
 void plugin_startall();
 
+/* default plugin */
 gboolean plugin_open(char *name);
+/* load a plugin, but don't warn about reopens. for menus */
+gboolean plugin_open_reopen(char *name);
 void plugin_close(char *name);
 
+/* call plugin's generic constructor */
+void *plugin_create(char *name /* TODO */);
+/* free memory allocated by plugin_create() */
+void plugin_destroy(char *name, void *object);
+
 #endif
index b6a82cd37fe7eba1443f3268265d70d6ffe0d4fc..e459154465ce2e615b01e3d4cd424734b91b1952 100644 (file)
@@ -15,7 +15,7 @@ static long timecompare(GTimeVal *a, GTimeVal *b)
     long r;
 
     if ((r = b->tv_sec - a->tv_sec)) return r;
-    return b->tv_usec - a->tv_sec;
+    return b->tv_usec - a->tv_usec;
     
 }
 
@@ -108,7 +108,7 @@ void timer_dispatch(GTimeVal **wait)
        
        /* the queue is sorted, so if this timer shouldn't fire, none are 
           ready */
-        if (timecompare(&now, &NEAREST_TIMEOUT) <= 0)
+        if (timecompare(&NEAREST_TIMEOUT, &now) <= 0)
            break;
 
        /* we set the last fired time to delay msec after the previous firing,
index 2ef58f1503159ffa21ef4893d9760abdb0f731a6..37863dbe846291dda4d47718ab7e4054bf53cb34 100644 (file)
@@ -1,6 +1,6 @@
-plugindir=$(libdir)/openbox/plugins
+XFplugindir=$(libdir)/openbox/plugins
 
-SUBDIRS = keyboard mouse placement
+SUBDIRS = keyboard mouse placement menu
 
 CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
 -DPLUGINDIR=\"$(plugindir)\"
diff --git a/plugins/menu/Makefile.in b/plugins/menu/Makefile.in
new file mode 100644 (file)
index 0000000..ce9b31e
--- /dev/null
@@ -0,0 +1,475 @@
+# Makefile.in generated by automake 1.7.4 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BISON = @BISON@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+
+CPPFLAGS = $(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
+         -DG_LOG_DOMAIN=\"Plugin-Timed-Menu\"
+
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FLEX = @FLEX@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+VIDMODE_CFLAGS = @VIDMODE_CFLAGS@
+VIDMODE_LIBS = @VIDMODE_LIBS@
+XFT_CFLAGS = @XFT_CFLAGS@
+XFT_LIBS = @XFT_LIBS@
+XGETTEXT = @XGETTEXT@
+XINERAMA_LIBS = @XINERAMA_LIBS@
+XKB_CFLAGS = @XKB_CFLAGS@
+XKB_LIBS = @XKB_LIBS@
+XRANDR_CFLAGS = @XRANDR_CFLAGS@
+XRANDR_LIBS = @XRANDR_LIBS@
+XSHAPE_CFLAGS = @XSHAPE_CFLAGS@
+XSHAPE_LIBS = @XSHAPE_LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+plugindir = $(libdir)/openbox/plugins
+
+INCLUDES = -I../..
+
+plugin_LTLIBRARIES = timed_menu.la
+
+timed_menu_la_LDFLAGS = -module -avoid-version
+timed_menu_la_SOURCES = timed_menu.c
+
+noinst_HEADERS = timed_menu.h
+
+MAINTAINERCLEANFILES = Makefile.in
+subdir = plugins/menu
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(plugin_LTLIBRARIES)
+
+timed_menu_la_LIBADD =
+am_timed_menu_la_OBJECTS = timed_menu.lo
+timed_menu_la_OBJECTS = $(am_timed_menu_la_OBJECTS)
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/timed_menu.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(timed_menu_la_SOURCES)
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in
+SOURCES = $(timed_menu_la_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --foreign  plugins/menu/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+pluginLTLIBRARIES_INSTALL = $(INSTALL)
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(plugindir)
+       @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           f="`echo $$p | sed -e 's|^.*/||'`"; \
+           echo " $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(plugindir)/$$f"; \
+           $(LIBTOOL) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(plugindir)/$$f; \
+         else :; fi; \
+       done
+
+uninstall-pluginLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/$$p"; \
+         $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(plugindir)/$$p; \
+       done
+
+clean-pluginLTLIBRARIES:
+       -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+       @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" = "$$p" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+timed_menu.la: $(timed_menu_la_OBJECTS) $(timed_menu_la_DEPENDENCIES) 
+       $(LINK) -rpath $(plugindir) $(timed_menu_la_LDFLAGS) $(timed_menu_la_OBJECTS) $(timed_menu_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timed_menu.Plo@am__quote@
+
+distclean-depend:
+       -rm -rf ./$(DEPDIR)
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(plugindir)
+
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
+       mostlyclean-am
+
+distclean: distclean-am
+
+distclean-am: clean-am distclean-compile distclean-depend \
+       distclean-generic distclean-libtool distclean-local \
+       distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-pluginLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-pluginLTLIBRARIES ctags distclean \
+       distclean-compile distclean-depend distclean-generic \
+       distclean-libtool distclean-local distclean-tags distdir dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-man install-pluginLTLIBRARIES \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \
+       pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am \
+       uninstall-pluginLTLIBRARIES
+
+
+distclean-local:
+       $(RM) *\~ *.orig *.rej .\#*
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/plugins/menu/timed_menu.c b/plugins/menu/timed_menu.c
new file mode 100644 (file)
index 0000000..2c26434
--- /dev/null
@@ -0,0 +1,73 @@
+#include "kernel/menu.h"
+#include "kernel/timer.h"
+#include "timed_menu.h"
+#include "kernel/action.h"
+
+static char *PLUGIN_NAME = "timed_menu";
+
+typedef enum {
+    TIMED_MENU_PIPE
+} Timed_Menu_Type;
+
+/* we can use various GIO channels to support reading menus (can we add them to
+   the event loop? )
+   stat() based update
+   exec() based read
+*/
+typedef struct {
+    Timed_Menu_Type type;
+    Timer *timer; /* timer code handles free */
+} Timed_Menu_Data;
+
+
+void plugin_setup_config() { }
+void plugin_startup()
+{ }
+void plugin_shutdown() { }
+
+void timed_menu_timeout_handler(void *data)
+{
+    Action *a;
+    printf("woop timer %s\n", ((Menu *)data)->name);
+    ((Menu *)data)->invalid = TRUE;
+
+    if (((Menu *)data)->shown) {
+       a = action_from_string("execute");
+       a->data.execute.path = g_strdup("xeyes");
+       menu_add_entry((Menu *)data, menu_entry_new("xeyes", a));
+
+       menu_show_full( (Menu *)data, ((Menu *)data)->location.x,
+                       ((Menu *)data)->location.y, NULL);
+    } else {
+       GList *it;
+
+       for (it = ((Menu *)data)->entries; it; it = it->next) {
+           MenuEntry *entry = it->data;
+           menu_entry_free(entry);
+       }
+       ((Menu *)data)->entries = NULL;
+    }
+}
+
+void *plugin_create()
+{
+    Timed_Menu_Data *d = g_new(Timed_Menu_Data, 1);
+    Menu *m = menu_new("", PLUGIN_NAME, NULL);
+    
+    m->plugin = PLUGIN_NAME;
+
+    d->type = TIMED_MENU_PIPE;
+    d->timer = timer_start(1000000, &timed_menu_timeout_handler, m);
+    
+    m->plugin_data = (void *)d;
+  
+    return (void *)m;
+}
+
+void plugin_destroy (void *m)
+{
+    /* this will be freed by timer_* */
+    timer_stop( ((Timed_Menu_Data *)((Menu *)m)->plugin_data)->timer);
+    
+    g_free( ((Menu *)m)->plugin_data );
+}
diff --git a/plugins/menu/timed_menu.h b/plugins/menu/timed_menu.h
new file mode 100644 (file)
index 0000000..a7d16c1
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef __TIMED_MENU_H
+#define __TIMED_MENU_H
+
+#endif // __TIMED_MENU_H
This page took 0.052109 seconds and 4 git commands to generate.