]> Dogcows Code - chaz/openbox/blobdiff - openbox/hooks.c
Make clang happier
[chaz/openbox] / openbox / hooks.c
index 35d8d694f39b8b0324a8ac15b20e429ae718e810..53586db8ad3f919aa76c946304f260ab51afa70e 100644 (file)
 #include "hooks.h"
-#include <glib.h>
-
-/*
- *
- * Define the 'Hook' class type
- *
- */
-#define IS_HOOK(v)  ((v)->ob_type == &HookType)
-
-staticforward PyTypeObject HookType;
-
-typedef struct HookObject {
-    PyObject_HEAD
-    GSList *funcs;
-} HookObject;
-
-static int hook_init(HookObject *self, PyObject *args, PyObject *kwds)
-{
-    char *keywords[] = { 0 };
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, ":__init__", keywords))
-       return -1;
-    self->funcs = NULL;
-    return 0;
-}
-
-static void hook_dealloc(HookObject *self)
-{
-    GSList *it;
-
-    for (it = self->funcs; it != NULL; it = it->next)
-       Py_DECREF((PyObject*) it->data);
-     
-    PyObject_Del((PyObject*) self);
-}
+#include "actions.h"
+#include "client.h"
+#include "focus.h"
+#include "debug.h"
+#include "obt/display.h"
 
-static PyObject *hook_fire(HookObject *self, PyObject *args)
-{
-    GSList *it;
+#include <glib.h>
 
-    if (!IS_HOOK(self)) {
-       PyErr_SetString(PyExc_TypeError,
-                       "descriptor 'fire' requires a 'Hook' object");
-       return NULL;
-    }
+static GSList *hooks[OB_NUM_HOOKS];
+static const gchar *names[OB_NUM_HOOKS];
 
-    for (it = self->funcs; it != NULL; it = it->next) {
-       PyObject *ret = PyObject_CallObject(it->data, args);
-       if (ret == NULL)
-           return NULL;
-       Py_DECREF(ret);
-    }
+typedef struct {
+    ObHook hook;
+    struct _ObClient *client;
+} ObHookQueue;
 
-    Py_INCREF(Py_None);
-    return Py_None;
-}
+#define QUEUE_SIZE 20
+ObHookQueue run_queue[QUEUE_SIZE];
+gint        queue_size;
 
-static PyObject *hook_append(HookObject *self, PyObject *args)
+void hooks_startup(gboolean reconfig)
 {
-    PyObject *func;
-     
-    if (!IS_HOOK(self)) {
-       PyErr_SetString(PyExc_TypeError,
-                       "descriptor 'append' requires a 'Hook' object");
-       return NULL;
-    }
-    if (!PyArg_ParseTuple(args, "O:append", &func))
-       return NULL;
-    if (!PyCallable_Check(func)) {
-       PyErr_SetString(PyExc_TypeError,
-                       "descriptor 'append' requires a callable argument");
-       return NULL;
-    }
-    self->funcs = g_slist_append(self->funcs, func);
-    Py_INCREF(func);
-
-    Py_INCREF(Py_None);
-    return Py_None;
+    gint i;
+
+    for (i = 0; i < OB_NUM_HOOKS; ++i)
+        hooks[i] = NULL;
+
+    queue_size = 0;
+
+    names[OB_HOOK_WIN_NEW] = "WindowNew";
+    names[OB_HOOK_WIN_CLOSE] = "WindowClosed";
+    names[OB_HOOK_WIN_VISIBLE] = "WindowVisible";
+    names[OB_HOOK_WIN_INVISIBLE] = "WindowInvisible";
+    names[OB_HOOK_WIN_ICONIC] = "WindowIconified";
+    names[OB_HOOK_WIN_UNICONIC] = "WindowUniconified";
+    names[OB_HOOK_WIN_MAX] = "WindowMaximized";
+    names[OB_HOOK_WIN_UNMAX] = "WindowUnmaximized";
+    names[OB_HOOK_WIN_SHADE] = "WindowShaded";
+    names[OB_HOOK_WIN_UNSHADE] = "WindowUnshaded";
+    names[OB_HOOK_WIN_FOCUS] = "WindowFocused";
+    names[OB_HOOK_WIN_UNFOCUS] = "WindowUnfocused";
+    names[OB_HOOK_WIN_DESK_CHANGE] = "WindowOnNewDesktop";
+    names[OB_HOOK_WIN_DECORATED] = "WindowDecorated";
+    names[OB_HOOK_WIN_UNDECORATED] = "WindowUndecorated";
+    names[OB_HOOK_SCREEN_DESK_CHANGE] = "DesktopChanged";
 }
 
-static PyObject *hook_remove(HookObject *self, PyObject *args)
+void hooks_shutdown(gboolean reconfig)
 {
-    PyObject *func;
-    GSList *it;
-     
-    if (!IS_HOOK(self)) {
-       PyErr_SetString(PyExc_TypeError,
-                       "descriptor 'remove' requires a 'Hook' object");
-       return NULL;
-    }
-    if (!PyArg_ParseTuple(args, "O:remove", &func))
-       return NULL;
-    if (!PyCallable_Check(func)) {
-       PyErr_SetString(PyExc_TypeError,
-                       "descriptor 'remove' requires a callable argument");
-       return NULL;
-    }
-
-    it = g_slist_find(self->funcs, func);
-    if (it != NULL) {
-       self->funcs = g_slist_delete_link(self->funcs, it);
-       Py_DECREF(func);
+    gint i;
 
-       Py_INCREF(Py_None);
-       return Py_None;
-    }
-    PyErr_SetString(PyExc_TypeError,
-                   "given callable object was not found in Hook");
-    return NULL;
+    for (i = 0; i < OB_NUM_HOOKS; ++i)
+        while (hooks[i]) {
+            actions_act_unref(hooks[i]->data);
+            hooks[i] = g_slist_delete_link(hooks[i], hooks[i]);
+        }
 }
 
-static PyObject *hook_call(HookObject *self, PyObject *args)
+ObHook hooks_hook_from_name(const gchar *n)
 {
-    GSList *it, *next;
-    gboolean stop = FALSE;
-
-    if (!IS_HOOK(self)) {
-       PyErr_SetString(PyExc_TypeError,
-                       "descriptor '__call__' requires a 'Hook' object");
-       return NULL;
-    }
+    gint i;
 
-    for (it = self->funcs; !stop && it != NULL;) {
-       next = it->next; /* incase the hook removes itself */
-
-       PyObject *ret = PyObject_CallObject(it->data, args);
-       if (ret == NULL)
-           return NULL;
-       if (ret != Py_None)
-           stop = TRUE;
-       Py_DECREF(ret);
-
-       it = next;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
+    for (i = 1; i < OB_NUM_HOOKS; ++i)
+        if (!g_ascii_strcasecmp(n, names[i]))
+            return (ObHook)i;
+    return OB_HOOK_INVALID;
 }
 
-static PyTypeObject HookType = {
-    PyObject_HEAD_INIT(NULL)
-    0,
-    "Hook",
-    sizeof(HookObject),
-    0,
-    (destructor) hook_dealloc, /*tp_dealloc*/
-    0,                         /*tp_print*/
-    0,                         /*tp_getattr*/
-    0,                         /*tp_setattr*/
-    0,                         /*tp_compare*/
-    0,                         /*tp_repr*/
-    0,                         /*tp_as_number*/
-    0,                         /*tp_as_sequence*/
-    0,                         /*tp_as_mapping*/
-    0,                         /*tp_hash */
-};
-
-static PyMethodDef HookMethods[] = {
-    {"append", (PyCFunction)hook_append, METH_VARARGS,
-     "hook.add(func) -- Add a function to the hook." },
-    {"remove", (PyCFunction)hook_remove, METH_VARARGS,
-     "hook.remove(func) -- Remove a function from the hook." },
-    { NULL, NULL, 0, NULL }
-};
-
-
-/*
- *
- * Module initialization/finalization
- *
- */
-
-static PyObject *hooks, *hooksdict;
-
-static PyMethodDef HooksMethods[] = {
-    { NULL, NULL, 0, NULL }
-};
-
-struct HookObject *hooks_create(char *name)
+void hooks_queue(ObHook hook, struct _ObClient *client)
 {
-    HookObject *hook;
-    int ret;
+    ObHookQueue *q;
 
-    hook = PyObject_New(HookObject, &HookType);
-    hook->funcs = NULL;
+    g_assert(hook < OB_NUM_HOOKS && hook > OB_HOOK_INVALID);
 
-    /* add it to the hooks module */
-    ret = PyDict_SetItemString(hooksdict, name, (PyObject*) hook);
-    g_assert(ret != -1);
+    //ob_debug("Queing hook %s for client 0x%x", names[hook],
+    //         (client ? client->window : 0));
+    q = &run_queue[queue_size++];
+    q->hook = hook;
+    q->client = client;
 
-    return hook;
+    if (queue_size == QUEUE_SIZE)
+        /* queue is full */
+        hooks_run_queue();
 }
 
-void hooks_startup()
+void hooks_run(ObHook hook, struct _ObClient *c)
 {
-    HookType.ob_type = &PyType_Type;
-    HookType.tp_methods = HookMethods;
-    HookType.tp_alloc = PyType_GenericAlloc;
-    HookType.tp_new = PyType_GenericNew;
-    HookType.tp_init = (initproc) hook_init;
-    HookType.tp_call = (ternaryfunc) hook_call;
-    PyType_Ready(&HookType);
-
-    Py_InitModule("hooks", HooksMethods);
-
-    /* get the hooks module/dict */
-    hooks = PyImport_ImportModule("hooks"); /* new */
-    g_assert(hooks != NULL);
-    hooksdict = PyModule_GetDict(hooks); /* borrowed */
-    g_assert(hooksdict != NULL);
-
-    /* add the Hook type to the hooks module */
-    PyDict_SetItemString(hooksdict, "Hook", (PyObject*) &HookType);
-
-    hook_startup = hooks_create("startup");
-    hook_shutdown = hooks_create("shutdown");
-    hook_visibledesktop = hooks_create("visibledesktop");
-    hook_numdesktops = hooks_create("numdesktops");
-    hook_desktopnames = hooks_create("desktopnames");
-    hook_showdesktop = hooks_create("showdesktop");
-    hook_screenconfiguration = hooks_create("screenconfiguration");
-    hook_screenarea = hooks_create("screenarea");
-    hook_managed = hooks_create("managed");
-    hook_closed = hooks_create("closed");
-    hook_bell = hooks_create("bell");
-    hook_urgent = hooks_create("urgent");
-    hook_pointerenter = hooks_create("pointerenter");
-    hook_pointerleave = hooks_create("pointerleave");
-    hook_focused = hooks_create("focused");
-    hook_requestactivate = hooks_create("requestactivate");
-    hook_title = hooks_create("title");
-    hook_desktop = hooks_create("desktop");
-    hook_iconic = hooks_create("iconic");
-    hook_shaded = hooks_create("shaded");
-    hook_maximized = hooks_create("maximized");
-    hook_fullscreen = hooks_create("fullscreen");
-    hook_visible = hooks_create("visible");
-    hook_configuration = hooks_create("configuration");
+    hooks_queue(hook, c);
+    hooks_run_queue();
 }
 
-void hooks_shutdown()
+void hooks_add(ObHook hook, struct _ObActionsAct *act)
 {
-    Py_DECREF(hook_startup);
-    Py_DECREF(hook_shutdown);
-    Py_DECREF(hook_visibledesktop);
-    Py_DECREF(hook_numdesktops);
-    Py_DECREF(hook_desktopnames);
-    Py_DECREF(hook_showdesktop);
-    Py_DECREF(hook_screenconfiguration);
-    Py_DECREF(hook_screenarea);
-    Py_DECREF(hook_managed);
-    Py_DECREF(hook_closed);
-    Py_DECREF(hook_bell);
-    Py_DECREF(hook_urgent);
-    Py_DECREF(hook_pointerenter);
-    Py_DECREF(hook_pointerleave);
-    Py_DECREF(hook_focused);
-    Py_DECREF(hook_requestactivate);
-    Py_DECREF(hook_title);
-    Py_DECREF(hook_desktop);
-    Py_DECREF(hook_iconic);
-    Py_DECREF(hook_shaded);
-    Py_DECREF(hook_maximized);
-    Py_DECREF(hook_fullscreen);
-    Py_DECREF(hook_visible);
-    Py_DECREF(hook_configuration);
+    g_assert(hook < OB_NUM_HOOKS && hook > OB_HOOK_INVALID);
 
-    Py_DECREF(hooks);
+    /* append so they are executed in the same order as they appear in the
+       config file */
+    hooks[hook] = g_slist_append(hooks[hook], act);
 }
 
-void hooks_fire(struct HookObject *hook, PyObject *args)
+void hooks_run_queue(void)
 {
-    PyObject *ret = hook_call(hook, args);
-    if (ret == NULL)
-       PyErr_Print();
-    Py_XDECREF(ret);
-}
-
-void hooks_fire_client(struct HookObject *hook, struct Client *client)
-{
-    PyObject *args;
-
-    if (client != NULL) {
-       PyObject *c = clientwrap_new(client);
-       g_assert(c != NULL);
-       args = Py_BuildValue("(O)", c);
-       Py_DECREF(c);
-    } else {
-       args = Py_BuildValue("(O)", Py_None);
+    gint i;
+
+    for (i = 0; i < queue_size; ++i) {
+        const ObHookQueue *q = &run_queue[i];
+
+        //ob_debug("Running hook %s for client 0x%x", names[q->hook],
+        //         (q->client ? q->client->window : 0));
+        actions_run_acts(hooks[q->hook],
+                         OB_USER_ACTION_HOOK,
+                         0, -1, -1, 0,
+                         OB_FRAME_CONTEXT_NONE,
+                         q->client);
     }
-
-    g_assert(args != NULL);
-    hooks_fire(hook, args);
-    Py_DECREF(args);
+    queue_size = 0;
 }
This page took 0.028221 seconds and 4 git commands to generate.