From: Dana Jansens Date: Tue, 18 Mar 2003 03:11:55 +0000 (+0000) Subject: plugins work. X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=4ed3fb89150d05e6fa134798315269c62de1bed9;p=chaz%2Fopenbox plugins work. start a focus plugin. --- diff --git a/engines/engineinterface.h b/engines/engineinterface.h index 2a364e22..96796edd 100644 --- a/engines/engineinterface.h +++ b/engines/engineinterface.h @@ -50,13 +50,4 @@ typedef void EngineFrameHide(Frame *self); /* get_context */ typedef GQuark EngineGetContext(Client *client, Window win); -/* frame_mouse_enter */ -typedef void EngineMouseEnter(Frame *self, Window win); -/* frame_mouse_leave */ -typedef void EngineMouseLeave(Frame *self, Window win); -/* frame_mouse_press */ -typedef void EngineMousePress(Frame *self, Window win, int x, int y); -/* frame_mouse_release */ -typedef void EngineMouseRelease(Frame *self, Window win, int x, int y); - #endif diff --git a/openbox/Makefile.am b/openbox/Makefile.am index 765cef21..b91e5259 100644 --- a/openbox/Makefile.am +++ b/openbox/Makefile.am @@ -20,11 +20,11 @@ ob3_LDADD=@LIBINTL@ ../render/librender.a ob3_LDFLAGS=-export-dynamic ob3_SOURCES=client.c event.c extensions.c focus.c frame.c openbox.c prop.c \ screen.c stacking.c xerror.c themerc.c timer.c dispatch.c \ - engine.c + engine.c plugin.c noinst_HEADERS=client.h event.h extensions.h focus.h frame.h geom.h gettext.h \ openbox.h prop.h screen.h stacking.h xerror.h themerc.h dispatch.h \ - timer.h engine.h + timer.h engine.h plugin.h MAINTAINERCLEANFILES= Makefile.in diff --git a/openbox/dispatch.c b/openbox/dispatch.c index c1c9f783..7b71369d 100644 --- a/openbox/dispatch.c +++ b/openbox/dispatch.c @@ -3,6 +3,11 @@ #include +typedef struct { + EventHandler h; + void *data; +} Func; + static GSList **funcs; void dispatch_startup() @@ -26,8 +31,11 @@ void dispatch_shutdown() { guint i; EventType j; + GSList *it; for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) { + for (it = funcs[i]; it != NULL; it = it->next) + g_free(it->data); g_slist_free(funcs[i]); funcs[i] = NULL; } @@ -35,19 +43,47 @@ void dispatch_shutdown() g_free(funcs); } -void dispatch_register(EventHandler h, EventMask mask) +void dispatch_register(EventMask mask, EventHandler h, void *data) { guint i; EventType j; + GSList *it, *next; + EventMask m; + Func *f; - while (mask) { + /* add to masks it needs to be registered for */ + m = mask; + while (m) { for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) - if (mask & j) { - funcs[i] = g_slist_append(funcs[i], h); - mask ^= j; /* remove from the mask */ + if (m & j) { + for (it = funcs[i]; it != NULL; it = it->next) { + f = it->data; + if (f->h == h && f->data == data) + break; + } + if (it == NULL) { /* wasn't already regged */ + f = g_new(Func, 1); + f->h = h; + f->data = data; + funcs[i] = g_slist_append(funcs[i], f); + } + m ^= j; /* remove from the mask */ } g_assert(j >= EVENT_RANGE); /* an invalid event is in the mask */ } + + /* remove from masks its not registered for anymore */ + for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) { + if (!(j & mask)) + for (it = funcs[i]; it != NULL; it = next) { + next = it->next; + f = it->data; + if (f->h == h && f->data == data) { + g_free(f); + funcs[i] = g_slist_delete_link(funcs[i], it); + } + } + } } void dispatch_x(XEvent *xe, Client *c) @@ -101,8 +137,10 @@ void dispatch_x(XEvent *xe, Client *c) ++i; } - for (it = funcs[i]; it != NULL; it = it->next) - ((EventHandler)it->data)(&obe); + for (it = funcs[i]; it != NULL; it = it->next) { + Func *f = it->data; + f->h(&obe, f->data); + } } void dispatch_client(EventType e, Client *c) @@ -122,8 +160,10 @@ void dispatch_client(EventType e, Client *c) ++i; } - for (it = funcs[i]; it != NULL; it = it->next) - ((EventHandler)it->data)(&obe); + for (it = funcs[i]; it != NULL; it = it->next) { + Func *f = it->data; + f->h(&obe, f->data); + } } void dispatch_ob(EventType e) @@ -140,8 +180,10 @@ void dispatch_ob(EventType e) ++i; } - for (it = funcs[i]; it != NULL; it = it->next) - ((EventHandler)it->data)(&obe); + for (it = funcs[i]; it != NULL; it = it->next) { + Func *f = it->data; + f->h(&obe, f->data); + } } void dispatch_signal(int signal) @@ -160,6 +202,8 @@ void dispatch_signal(int signal) ++i; } - for (it = funcs[i]; it != NULL; it = it->next) - ((EventHandler)it->data)(&obe); + for (it = funcs[i]; it != NULL; it = it->next) { + Func *f = it->data; + f->h(&obe, f->data); + } } diff --git a/openbox/dispatch.h b/openbox/dispatch.h index 794c0f44..396558db 100644 --- a/openbox/dispatch.h +++ b/openbox/dispatch.h @@ -29,12 +29,10 @@ typedef enum { Event_Ob_Desktop = 1 << 15, /* changed desktops */ Event_Ob_NumDesktops = 1 << 16, /* changed the number of desktops */ Event_Ob_ShowDesktop = 1 << 17, /* entered/left show-the-desktop mode */ - Event_Ob_Startup = 1 << 18, /* startup under way */ - Event_Ob_Shutdown = 1 << 19, /* shutdown under way */ - Event_Signal = 1 << 20, /* a signal from the OS */ + Event_Signal = 1 << 18, /* a signal from the OS */ - EVENT_RANGE = 1 << 21 + EVENT_RANGE = 1 << 19 } EventType; typedef struct { @@ -53,11 +51,11 @@ typedef struct { EventData data; } ObEvent; -typedef void (*EventHandler)(const ObEvent *e); +typedef void (*EventHandler)(const ObEvent *e, void *data); typedef unsigned int EventMask; -void dispatch_register(EventHandler h, EventMask mask); +void dispatch_register(EventMask mask, EventHandler h, void *data); void dispatch_x(XEvent *e, Client *c); void dispatch_client(EventType e, Client *c); diff --git a/openbox/engine.c b/openbox/engine.c index f9fd2cf1..3457da18 100644 --- a/openbox/engine.c +++ b/openbox/engine.c @@ -52,10 +52,6 @@ static gboolean load(char *name) LOADSYM(frame_show, engine_frame_show); LOADSYM(frame_hide, engine_frame_hide); LOADSYM(get_context, engine_get_context); - LOADSYM(frame_mouse_enter, engine_mouse_enter); - LOADSYM(frame_mouse_leave, engine_mouse_leave); - LOADSYM(frame_mouse_press, engine_mouse_press); - LOADSYM(frame_mouse_release, engine_mouse_release); if (!estartup()) return FALSE; diff --git a/openbox/engine.h b/openbox/engine.h index d29cf804..067f02fb 100644 --- a/openbox/engine.h +++ b/openbox/engine.h @@ -24,9 +24,4 @@ EngineFrameHide *engine_frame_hide; EngineGetContext *engine_get_context; -EngineMouseEnter *engine_mouse_enter; -EngineMouseLeave *engine_mouse_leave; -EngineMousePress *engine_mouse_press; -EngineMouseRelease *engine_mouse_release; - #endif diff --git a/openbox/openbox.c b/openbox/openbox.c index e6ee8860..b1065929 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -10,6 +10,7 @@ #include "gettext.h" #include "engine.h" #include "themerc.h" +#include "plugin.h" #include "timer.h" #include "../render/render.h" #include "../render/font.h" @@ -47,7 +48,7 @@ gboolean ob_remote = FALSE; gboolean ob_sync = TRUE; Cursors ob_cursors; -void signal_handler(const ObEvent *e); +void signal_handler(const ObEvent *e, void *data); int main(int argc, char **argv) { @@ -65,7 +66,7 @@ int main(int argc, char **argv) /* start our event dispatcher and register for signals */ dispatch_startup(); - dispatch_register(signal_handler, Event_Signal); + dispatch_register(Event_Signal, signal_handler, NULL); /* set up signal handler */ sigemptyset(&sigset); @@ -136,8 +137,10 @@ int main(int argc, char **argv) screen_startup(); focus_startup(); client_startup(); + plugin_startup(); - dispatch_ob(Event_Ob_Startup); + /* XXX load all plugins!! */ + plugin_open("foo"); /* get all the existing windows */ client_manage_all(); @@ -150,8 +153,7 @@ int main(int argc, char **argv) client_unmanage_all(); - dispatch_ob(Event_Ob_Shutdown); - + plugin_shutdown(); client_shutdown(); screen_shutdown(); event_shutdown(); @@ -170,7 +172,7 @@ int main(int argc, char **argv) return 0; } -void signal_handler(const ObEvent *e) +void signal_handler(const ObEvent *e, void *data) { switch (e->data.signal) { case SIGUSR1: diff --git a/openbox/plugin.c b/openbox/plugin.c new file mode 100644 index 00000000..d4c19b12 --- /dev/null +++ b/openbox/plugin.c @@ -0,0 +1,103 @@ +#include +#include + +typedef void (*PluginStartup)(); +typedef void (*PluginShutdown)(); + +typedef struct { + GModule *module; + char *name; + + PluginStartup startup; + PluginShutdown shutdown; +} Plugin; + +static gpointer load_sym(GModule *module, char *name, char *symbol) +{ + gpointer var = NULL; + if (!g_module_symbol(module, symbol, &var)) + g_warning("Failed to load symbol '%s' from plugin '%s'", symbol, name); + return var; +} + +static Plugin *plugin_new(char *name) +{ + Plugin *p; + char *path; + + p = g_new(Plugin, 1); + + path = g_build_filename(PLUGINDIR, name, NULL); + p->module = g_module_open(path, G_MODULE_BIND_LAZY); + g_free(path); + + if (p->module == NULL) { + path = g_build_filename(g_get_home_dir(), ".openbox", "plugins", name, + NULL); + p->module = g_module_open(path, G_MODULE_BIND_LAZY); + g_free(path); + } + + if (p->module == NULL) { + g_free(p); + return NULL; + } + + p->startup = load_sym(p->module, name, "startup"); + p->shutdown = load_sym(p->module, name, "shutdown"); + + if (p->startup == NULL || p->shutdown == NULL) { + g_module_close(p->module); + g_free(p); + return NULL; + } + + p->name = g_strdup(name); + return p; +} + +static void plugin_free(Plugin *p) +{ + p->shutdown(); + + g_free(p->name); + g_module_close(p->module); +} + + +static GData *plugins = NULL; + +void plugin_startup() +{ + g_datalist_init(&plugins); +} + +void plugin_shutdown() +{ + g_datalist_clear(&plugins); +} + +gboolean plugin_open(char *name) +{ + Plugin *p; + + if (g_datalist_get_data(&plugins, name) != NULL) { + g_warning("plugin '%s' already loaded, can't load again", name); + return TRUE; + } + + p = plugin_new(name); + if (p == NULL) { + g_warning("failed to load plugin '%s'", name); + return FALSE; + } + + g_datalist_set_data_full(&plugins, name, p, (GDestroyNotify) plugin_free); + p->startup(); + return TRUE; +} + +void plugin_close(char *name) +{ + g_datalist_remove_data(&plugins, name); +} diff --git a/openbox/plugin.h b/openbox/plugin.h new file mode 100644 index 00000000..d5cb2f6f --- /dev/null +++ b/openbox/plugin.h @@ -0,0 +1,10 @@ +#ifndef __plugin_h +#define __plugin_h + +void plugin_startup(); +void plugin_shutdown(); + +gboolean plugin_open(char *name); +void plugin_close(char *name); + +#endif diff --git a/plugins/Makefile.am b/plugins/Makefile.am index c0ad9c98..78ff2ccf 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -4,10 +4,10 @@ CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \ -DPLUGINDIR=\"$(plugindir)\" \ -DG_LOG_DOMAIN=\"Openbox-Plugin\" -#engine_LTLIBRARIES=openbox.la +plugin_LTLIBRARIES=focus.la -#openbox_la_LDFLAGS=-module -avoid-version -#openbox_la_SOURCES=openbox.c theme.c +focus_la_LDFLAGS=-module -avoid-version +focus_la_SOURCES=focus.c noinst_HEADERS= diff --git a/plugins/focus.c b/plugins/focus.c new file mode 100644 index 00000000..37df40b7 --- /dev/null +++ b/plugins/focus.c @@ -0,0 +1,9 @@ +#include "../kernel/dispatch.h" + +void startup() +{ +} + +void shutdown() +{ +}