all repos — openbox @ b10548f0ddf7ac9deb85372332686c6d8651a1f6

openbox fork - make it a bit more like ryudo

openbox/plugin.c (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#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;
    if (!g_module_symbol(module, symbol, &var)) {
        g_warning("Failed to load symbol '%s' from plugin '%s'",
                  symbol, name);
        var = NULL;
    }
    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, 0);
    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, 0);
	g_free(path);
    }

    if (p->module == NULL) {
        g_free(p);
        return NULL;
    }

    p->startup = load_sym(p->module, name, "plugin_startup");
    p->shutdown = load_sym(p->module, name, "plugin_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);
}