diff options
author | Christopher Davis <loafier@gmail.com> | 2006-07-24 03:05:54 +0000 |
---|---|---|
committer | Christopher Davis <loafier@gmail.com> | 2006-07-24 03:05:54 +0000 |
commit | d01927add7ccbc6d98e31c87640b8711e2d60d4a (patch) | |
tree | af03854b61cc1e87e0da408f1ba78742bd61d703 /pystatusbar.c | |
parent | 5eaed0dbf78fca2bcf185da0abf1dbf41722deb2 (diff) | |
download | irssi-python-d01927add7ccbc6d98e31c87640b8711e2d60d4a.tar.gz irssi-python-d01927add7ccbc6d98e31c87640b8711e2d60d4a.tar.xz irssi-python-d01927add7ccbc6d98e31c87640b8711e2d60d4a.zip |
working on status bars
git-svn-id: http://svn.irssi.org/repos/irssi-python@4299 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'pystatusbar.c')
-rw-r--r-- | pystatusbar.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/pystatusbar.c b/pystatusbar.c new file mode 100644 index 0000000..2ec5d1c --- /dev/null +++ b/pystatusbar.c @@ -0,0 +1,126 @@ +#include "pystatusbar.h" +#include "pyirssi.h" + +typedef struct +{ + char *name; + PyObject *script; + PyObject *handler; +} PY_BAR_ITEM_REC; + +/* Map: item name -> bar item obj */ +static GHashTable *py_bar_items = NULL; + +static void py_add_bar_handler(const char *iname, PyObject *script, PyObject *handler) +{ + PY_BAR_ITEM_REC *sitem; + + sitem = g_new0(PY_BAR_ITEM_REC, 1); + sitem->name = g_strdup(iname); + sitem->script = script; + sitem->handler = handler; + Py_INCREF(script); + Py_INCREF(handler); + + g_hash_table_insert(py_bar_items, sitem->name, sitem); +} + +static void py_destroy_handler(PY_BAR_ITEM_REC *sitem) +{ + statusbar_item_unregister(sitem->name); + + g_free(sitem->name); /* destroy key */ + Py_DECREF(sitem->script); + Py_DECREF(sitem->handler); + g_free(sitem); +} + +static void py_statusbar_proxy_call(SBAR_ITEM_REC *item, int sizeonly, PY_BAR_ITEM_REC *sitem) +{ + PyObject *pybaritem; + PyObject *ret; + + g_return_if_fail(PyCallable_Check(sitem->handler)); + + pybaritem = Py_None; /* FIXME: add statusbaritem object */ + + ret = PyObject_CallFunction(sitem->handler, "Oi", pybaritem, sizeonly); + + if (!ret) + { + PyErr_Print(); + pystatusbar_item_unregister(sitem->name); + } + else + Py_DECREF(ret); +} + +static void py_statusbar_proxy(SBAR_ITEM_REC *item, int sizeonly) +{ + PY_BAR_ITEM_REC *sitem; + + sitem = g_hash_table_lookup(py_bar_items, item->config->name); + if (sitem) + py_statusbar_proxy_call(item, sizeonly, sitem); + else + { + statusbar_item_default_handler(item, sizeonly, NULL, "", TRUE); + g_critical("unknown handler for Python statusbar proxy: %s", item->config->name); + } +} + +int pystatusbar_item_register(PyObject *script, const char *sitem, + const char *value, PyObject *func) +{ + if (func) + py_add_bar_handler(sitem, script, func); + + statusbar_item_register(sitem, value, func? py_statusbar_proxy : NULL); + + return 1; +} + +/* remove selected status bar item handler */ +void pystatusbar_item_unregister(const char *iname) +{ + if (!g_hash_table_remove(py_bar_items, iname)) + statusbar_item_unregister(iname); +} + +/* remove all statusbar item handlers for script */ +/* XXX: Only status bar items registered with a handler are stored in the hash table. + * Items registered with only a value are not stored, so there is no way to unregister + * them when the script is unloaded. + */ +static int py_check_clean(char *key, PY_BAR_ITEM_REC *value, PyObject *script) +{ + if (value->script == script) + return 1; + + return 0; +} + +void pystatusbar_cleanup_script(PyObject *script) +{ + g_hash_table_foreach_remove(py_bar_items, (GHRFunc)py_check_clean, script); +} + +void pystatusbar_init(void) +{ + g_return_if_fail(py_bar_items == NULL); + + /* key is freed by destroy_handler */ + py_bar_items = g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, (GDestroyNotify)py_destroy_handler); +} + +/* XXX: this must be called after cleaning up all the loaded scripts */ +void pystatusbar_deinit(void) +{ + g_return_if_fail(py_bar_items != NULL); + g_return_if_fail(g_hash_table_size(py_bar_items) != 0); + + g_hash_table_destroy(py_bar_items); + py_bar_items = NULL; +} + |