summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Davis <loafier@gmail.com>2006-07-24 03:05:54 +0000
committerChristopher Davis <loafier@gmail.com>2006-07-24 03:05:54 +0000
commitd01927add7ccbc6d98e31c87640b8711e2d60d4a (patch)
treeaf03854b61cc1e87e0da408f1ba78742bd61d703
parent5eaed0dbf78fca2bcf185da0abf1dbf41722deb2 (diff)
downloadirssi-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
-rw-r--r--pystatusbar.c126
-rw-r--r--pystatusbar.h11
2 files changed, 137 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;
+}
+
diff --git a/pystatusbar.h b/pystatusbar.h
new file mode 100644
index 0000000..686375f
--- /dev/null
+++ b/pystatusbar.h
@@ -0,0 +1,11 @@
+#ifndef _PYSTATUSBAR_H_
+#define _PYSTATUSBAR_H_
+
+int pystatusbar_item_register(PyObject *script, const char *sitem,
+ const char *value, PyObject *func);
+int pystatusbar_item_unregister(const char *iname);
+void pystatusbar_cleanup_script(PyObject *script);
+void pystatusbar_init(void);
+void pystatusbar_deinit(void);
+
+#endif