plugins work.
start a focus plugin.
This commit is contained in:
parent
cb73f209c9
commit
4ed3fb8915
11 changed files with 196 additions and 48 deletions
|
@ -50,13 +50,4 @@ typedef void EngineFrameHide(Frame *self);
|
||||||
/* get_context */
|
/* get_context */
|
||||||
typedef GQuark EngineGetContext(Client *client, Window win);
|
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
|
#endif
|
||||||
|
|
|
@ -20,11 +20,11 @@ ob3_LDADD=@LIBINTL@ ../render/librender.a
|
||||||
ob3_LDFLAGS=-export-dynamic
|
ob3_LDFLAGS=-export-dynamic
|
||||||
ob3_SOURCES=client.c event.c extensions.c focus.c frame.c openbox.c prop.c \
|
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 \
|
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 \
|
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 \
|
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
|
MAINTAINERCLEANFILES= Makefile.in
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EventHandler h;
|
||||||
|
void *data;
|
||||||
|
} Func;
|
||||||
|
|
||||||
static GSList **funcs;
|
static GSList **funcs;
|
||||||
|
|
||||||
void dispatch_startup()
|
void dispatch_startup()
|
||||||
|
@ -26,8 +31,11 @@ void dispatch_shutdown()
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
EventType j;
|
EventType j;
|
||||||
|
GSList *it;
|
||||||
|
|
||||||
for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1) {
|
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]);
|
g_slist_free(funcs[i]);
|
||||||
funcs[i] = NULL;
|
funcs[i] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -35,19 +43,47 @@ void dispatch_shutdown()
|
||||||
g_free(funcs);
|
g_free(funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatch_register(EventHandler h, EventMask mask)
|
void dispatch_register(EventMask mask, EventHandler h, void *data)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
EventType j;
|
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)
|
for (i = 0, j = 1; j < EVENT_RANGE; ++i, j <<= 1)
|
||||||
if (mask & j) {
|
if (m & j) {
|
||||||
funcs[i] = g_slist_append(funcs[i], h);
|
for (it = funcs[i]; it != NULL; it = it->next) {
|
||||||
mask ^= j; /* remove from the mask */
|
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 */
|
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)
|
void dispatch_x(XEvent *xe, Client *c)
|
||||||
|
@ -101,8 +137,10 @@ void dispatch_x(XEvent *xe, Client *c)
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = funcs[i]; it != NULL; it = it->next)
|
for (it = funcs[i]; it != NULL; it = it->next) {
|
||||||
((EventHandler)it->data)(&obe);
|
Func *f = it->data;
|
||||||
|
f->h(&obe, f->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatch_client(EventType e, Client *c)
|
void dispatch_client(EventType e, Client *c)
|
||||||
|
@ -122,8 +160,10 @@ void dispatch_client(EventType e, Client *c)
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = funcs[i]; it != NULL; it = it->next)
|
for (it = funcs[i]; it != NULL; it = it->next) {
|
||||||
((EventHandler)it->data)(&obe);
|
Func *f = it->data;
|
||||||
|
f->h(&obe, f->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatch_ob(EventType e)
|
void dispatch_ob(EventType e)
|
||||||
|
@ -140,8 +180,10 @@ void dispatch_ob(EventType e)
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = funcs[i]; it != NULL; it = it->next)
|
for (it = funcs[i]; it != NULL; it = it->next) {
|
||||||
((EventHandler)it->data)(&obe);
|
Func *f = it->data;
|
||||||
|
f->h(&obe, f->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatch_signal(int signal)
|
void dispatch_signal(int signal)
|
||||||
|
@ -160,6 +202,8 @@ void dispatch_signal(int signal)
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = funcs[i]; it != NULL; it = it->next)
|
for (it = funcs[i]; it != NULL; it = it->next) {
|
||||||
((EventHandler)it->data)(&obe);
|
Func *f = it->data;
|
||||||
|
f->h(&obe, f->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,10 @@ typedef enum {
|
||||||
Event_Ob_Desktop = 1 << 15, /* changed desktops */
|
Event_Ob_Desktop = 1 << 15, /* changed desktops */
|
||||||
Event_Ob_NumDesktops = 1 << 16, /* changed the number of desktops */
|
Event_Ob_NumDesktops = 1 << 16, /* changed the number of desktops */
|
||||||
Event_Ob_ShowDesktop = 1 << 17, /* entered/left show-the-desktop mode */
|
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;
|
} EventType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -53,11 +51,11 @@ typedef struct {
|
||||||
EventData data;
|
EventData data;
|
||||||
} ObEvent;
|
} ObEvent;
|
||||||
|
|
||||||
typedef void (*EventHandler)(const ObEvent *e);
|
typedef void (*EventHandler)(const ObEvent *e, void *data);
|
||||||
|
|
||||||
typedef unsigned int EventMask;
|
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_x(XEvent *e, Client *c);
|
||||||
void dispatch_client(EventType e, Client *c);
|
void dispatch_client(EventType e, Client *c);
|
||||||
|
|
|
@ -52,10 +52,6 @@ static gboolean load(char *name)
|
||||||
LOADSYM(frame_show, engine_frame_show);
|
LOADSYM(frame_show, engine_frame_show);
|
||||||
LOADSYM(frame_hide, engine_frame_hide);
|
LOADSYM(frame_hide, engine_frame_hide);
|
||||||
LOADSYM(get_context, engine_get_context);
|
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())
|
if (!estartup())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -24,9 +24,4 @@ EngineFrameHide *engine_frame_hide;
|
||||||
|
|
||||||
EngineGetContext *engine_get_context;
|
EngineGetContext *engine_get_context;
|
||||||
|
|
||||||
EngineMouseEnter *engine_mouse_enter;
|
|
||||||
EngineMouseLeave *engine_mouse_leave;
|
|
||||||
EngineMousePress *engine_mouse_press;
|
|
||||||
EngineMouseRelease *engine_mouse_release;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "themerc.h"
|
#include "themerc.h"
|
||||||
|
#include "plugin.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "../render/render.h"
|
#include "../render/render.h"
|
||||||
#include "../render/font.h"
|
#include "../render/font.h"
|
||||||
|
@ -47,7 +48,7 @@ gboolean ob_remote = FALSE;
|
||||||
gboolean ob_sync = TRUE;
|
gboolean ob_sync = TRUE;
|
||||||
Cursors ob_cursors;
|
Cursors ob_cursors;
|
||||||
|
|
||||||
void signal_handler(const ObEvent *e);
|
void signal_handler(const ObEvent *e, void *data);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -65,7 +66,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* start our event dispatcher and register for signals */
|
/* start our event dispatcher and register for signals */
|
||||||
dispatch_startup();
|
dispatch_startup();
|
||||||
dispatch_register(signal_handler, Event_Signal);
|
dispatch_register(Event_Signal, signal_handler, NULL);
|
||||||
|
|
||||||
/* set up signal handler */
|
/* set up signal handler */
|
||||||
sigemptyset(&sigset);
|
sigemptyset(&sigset);
|
||||||
|
@ -136,8 +137,10 @@ int main(int argc, char **argv)
|
||||||
screen_startup();
|
screen_startup();
|
||||||
focus_startup();
|
focus_startup();
|
||||||
client_startup();
|
client_startup();
|
||||||
|
plugin_startup();
|
||||||
|
|
||||||
dispatch_ob(Event_Ob_Startup);
|
/* XXX load all plugins!! */
|
||||||
|
plugin_open("foo");
|
||||||
|
|
||||||
/* get all the existing windows */
|
/* get all the existing windows */
|
||||||
client_manage_all();
|
client_manage_all();
|
||||||
|
@ -150,8 +153,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
client_unmanage_all();
|
client_unmanage_all();
|
||||||
|
|
||||||
dispatch_ob(Event_Ob_Shutdown);
|
plugin_shutdown();
|
||||||
|
|
||||||
client_shutdown();
|
client_shutdown();
|
||||||
screen_shutdown();
|
screen_shutdown();
|
||||||
event_shutdown();
|
event_shutdown();
|
||||||
|
@ -170,7 +172,7 @@ int main(int argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void signal_handler(const ObEvent *e)
|
void signal_handler(const ObEvent *e, void *data)
|
||||||
{
|
{
|
||||||
switch (e->data.signal) {
|
switch (e->data.signal) {
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
|
|
103
openbox/plugin.c
Normal file
103
openbox/plugin.c
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
#include <glib.h>
|
||||||
|
#include <gmodule.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
10
openbox/plugin.h
Normal file
10
openbox/plugin.h
Normal file
|
@ -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
|
|
@ -4,10 +4,10 @@ CPPFLAGS=$(XFT_CFLAGS) $(GLIB_CFLAGS) @CPPFLAGS@ \
|
||||||
-DPLUGINDIR=\"$(plugindir)\" \
|
-DPLUGINDIR=\"$(plugindir)\" \
|
||||||
-DG_LOG_DOMAIN=\"Openbox-Plugin\"
|
-DG_LOG_DOMAIN=\"Openbox-Plugin\"
|
||||||
|
|
||||||
#engine_LTLIBRARIES=openbox.la
|
plugin_LTLIBRARIES=focus.la
|
||||||
|
|
||||||
#openbox_la_LDFLAGS=-module -avoid-version
|
focus_la_LDFLAGS=-module -avoid-version
|
||||||
#openbox_la_SOURCES=openbox.c theme.c
|
focus_la_SOURCES=focus.c
|
||||||
|
|
||||||
noinst_HEADERS=
|
noinst_HEADERS=
|
||||||
|
|
||||||
|
|
9
plugins/focus.c
Normal file
9
plugins/focus.c
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "../kernel/dispatch.h"
|
||||||
|
|
||||||
|
void startup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown()
|
||||||
|
{
|
||||||
|
}
|
Loading…
Reference in a new issue