summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Davis <loafier@gmail.com>2006-07-26 10:18:15 +0000
committerChristopher Davis <loafier@gmail.com>2006-07-26 10:18:15 +0000
commitc0ac6d60c5319a08148d743fd03ba3f66b22dfe0 (patch)
treec6ef42493a981f530f498c50d7573ae028c84a6a
parentd01927add7ccbc6d98e31c87640b8711e2d60d4a (diff)
downloadirssi-python-c0ac6d60c5319a08148d743fd03ba3f66b22dfe0.tar.gz
irssi-python-c0ac6d60c5319a08148d743fd03ba3f66b22dfe0.tar.xz
irssi-python-c0ac6d60c5319a08148d743fd03ba3f66b22dfe0.zip
got statusbar working, needs a bit more testing
git-svn-id: http://svn.irssi.org/repos/irssi-python@4301 dbcabf3a-b0e7-0310-adc4-f8d773084564
-rw-r--r--Makefile4
-rw-r--r--objects/Makefile4
-rw-r--r--objects/factory.c3
-rw-r--r--objects/factory.h1
-rw-r--r--objects/pyscript-object.c30
-rw-r--r--objects/pyscript-object.h1
-rw-r--r--objects/statusbar-item-object.c217
-rw-r--r--objects/statusbar-item-object.h22
-rw-r--r--pycore.c3
-rw-r--r--pyirssi.h1
-rw-r--r--pymodule.c52
-rw-r--r--pystatusbar.c20
-rw-r--r--pystatusbar.h6
13 files changed, 351 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index fbed8e1..dad96b9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CC = gcc
PYTHON = /usr/include/python2.4
-IRSSI = /usr/local/include/irssi
+IRSSI = /home/chrisd/irssi-0.8.10
CFLAGS = -fpic -ggdb -Wall -I$(PYTHON) -I$(IRSSI) -I$(IRSSI)/src \
-I$(IRSSI)/src/fe-common/core -I$(IRSSI)/src/core -I$(IRSSI)/src/fe-text \
@@ -12,7 +12,7 @@ CFLAGS = -fpic -ggdb -Wall -I$(PYTHON) -I$(IRSSI) -I$(IRSSI)/src \
LDFLAGS = -fpic /usr/lib/libpython2.4.so
OBJ = pycore.o pyutils.o pymodule.o pyloader.o pysignals.o pysource.o \
-pythemes.o
+pythemes.o pystatusbar.o
pyirssi: pyobjects.a $(OBJ)
$(CC) -shared -o libirssi_python.so $(OBJ) objects/pyobjects.a $(LDFLAGS)
diff --git a/objects/Makefile b/objects/Makefile
index 39f6195..db2c7bb 100644
--- a/objects/Makefile
+++ b/objects/Makefile
@@ -1,7 +1,7 @@
CC = gcc
PYTHON = /usr/include/python2.4
-IRSSI = /usr/local/include/irssi
+IRSSI = /home/chrisd/irssi-0.8.10
CFLAGS = -fpic -ggdb -Wall -I$(PYTHON) -I$(IRSSI) -I$(IRSSI)/src \
-I$(IRSSI)/src/fe-common/core -I$(IRSSI)/src/core -I$(IRSSI)/src/fe-text \
-I$(IRSSI)/src/irc -I$(IRSSI)/src/irc/core -I$(IRSSI)/src/irc/dcc \
@@ -16,7 +16,7 @@ rawlog-object.o log-object.o logitem-object.o ignore-object.o \
dcc-object.o dcc-chat-object.o dcc-get-object.o dcc-send-object.o \
netsplit-object.o netsplit-server-object.o netsplit-channel-object.o \
notifylist-object.o process-object.o command-object.o theme-object.o \
-factory.o
+statusbar-item-object.o factory.o
pyobjects.a: $(OBJ)
ar r pyobjects.a $(OBJ)
diff --git a/objects/factory.c b/objects/factory.c
index bfc19ab..25ac611 100644
--- a/objects/factory.c
+++ b/objects/factory.c
@@ -122,6 +122,9 @@ static int init_objects(void)
if (!theme_object_init())
return 0;
+ if (!statusbar_item_object_init())
+ return 0;
+
return 1;
}
diff --git a/objects/factory.h b/objects/factory.h
index b7eb0e7..28b1e03 100644
--- a/objects/factory.h
+++ b/objects/factory.h
@@ -33,6 +33,7 @@
#include "process-object.h"
#include "command-object.h"
#include "theme-object.h"
+#include "statusbar-item-object.h"
int factory_init(void);
void factory_deinit(void);
diff --git a/objects/pyscript-object.c b/objects/pyscript-object.c
index d51761b..d2750bf 100644
--- a/objects/pyscript-object.c
+++ b/objects/pyscript-object.c
@@ -6,6 +6,7 @@
#include "pymodule.h"
#include "pysource.h"
#include "pythemes.h"
+#include "pystatusbar.h"
/* handle cycles...
Can't think of any reason why the user would put script into one of the lists
@@ -543,6 +544,25 @@ static PyObject *PyScript_theme_register(PyScript *self, PyObject *args, PyObjec
Py_RETURN_NONE;
}
+PyDoc_STRVAR(PyScript_statusbar_item_register_doc,
+ "statusbar_item_register(name, value=None, func=None) -> None\n"
+);
+static PyObject *PyScript_statusbar_item_register(PyScript *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"name", "value", "func", NULL};
+ char *name = "";
+ char *value = NULL;
+ PyObject *func = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|zO", kwlist,
+ &name, &value, &func))
+ return NULL;
+
+ pystatusbar_item_register((PyObject *)self, name, value, func);
+
+ Py_RETURN_NONE;
+}
+
/* Methods for object */
static PyMethodDef PyScript_methods[] = {
{"command_bind", (PyCFunction)PyScript_command_bind, METH_VARARGS | METH_KEYWORDS,
@@ -579,6 +599,8 @@ static PyMethodDef PyScript_methods[] = {
PyScript_settings_remove_doc},
{"theme_register", (PyCFunction)PyScript_theme_register, METH_VARARGS | METH_KEYWORDS,
PyScript_theme_register_doc},
+ {"statusbar_item_register", (PyCFunction)PyScript_statusbar_item_register, METH_VARARGS | METH_KEYWORDS,
+ PyScript_statusbar_item_register_doc},
{NULL} /* Sentinel */
};
@@ -738,6 +760,13 @@ void pyscript_remove_themes(PyObject *script)
pythemes_unregister(pyscript_get_name(script));
}
+void pyscript_remove_statusbars(PyObject *script)
+{
+ g_return_if_fail(pyscript_check(script));
+
+ pystatusbar_cleanup_script(script);
+}
+
void pyscript_clear_modules(PyObject *script)
{
PyScript *self;
@@ -755,6 +784,7 @@ void pyscript_cleanup(PyObject *script)
pyscript_remove_sources(script);
pyscript_remove_settings(script);
pyscript_remove_themes(script);
+ pyscript_remove_statusbars(script);
pyscript_clear_modules(script);
}
diff --git a/objects/pyscript-object.h b/objects/pyscript-object.h
index 644571d..624a578 100644
--- a/objects/pyscript-object.h
+++ b/objects/pyscript-object.h
@@ -22,6 +22,7 @@ void pyscript_remove_signals(PyObject *script);
void pyscript_remove_sources(PyObject *script);
void pyscript_remove_settings(PyObject *script);
void pyscript_remove_themes(PyObject *script);
+void pyscript_remove_statusbars(PyObject *script);
void pyscript_clear_modules(PyObject *script);
void pyscript_cleanup(PyObject *script);
#define pyscript_check(op) PyObject_TypeCheck(op, &PyScriptType)
diff --git a/objects/statusbar-item-object.c b/objects/statusbar-item-object.c
new file mode 100644
index 0000000..14b0208
--- /dev/null
+++ b/objects/statusbar-item-object.c
@@ -0,0 +1,217 @@
+#include <Python.h>
+#include "pyirssi.h"
+#include "pymodule.h"
+#include "factory.h"
+#include "statusbar-item-object.h"
+
+/* monitor "statusbar item destroyed" signal */
+static void statusbar_item_cleanup(SBAR_ITEM_REC *sbar_item)
+{
+ PyStatusbarItem *pysbar_item = signal_get_user_data();
+
+ if (sbar_item == pysbar_item->data)
+ {
+ pysbar_item->data = NULL;
+ pysbar_item->cleanup_installed = 0;
+ signal_remove_data("statusbar item_destroy", statusbar_item_cleanup, pysbar_item);
+ }
+}
+
+static void PyStatusbarItem_dealloc(PyStatusbarItem *self)
+{
+ if (self->cleanup_installed)
+ signal_remove_data("sbar_itemlist remove", statusbar_item_cleanup, self);
+
+ self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *PyStatusbarItem_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyStatusbarItem *self;
+
+ self = (PyStatusbarItem *)type->tp_alloc(type, 0);
+ if (!self)
+ return NULL;
+
+ return (PyObject *)self;
+}
+
+/* Getter */
+PyDoc_STRVAR(PyStatusbarItem_min_size_doc,
+ "min size"
+);
+static PyObject *PyStatusbarItem_min_size_get(PyStatusbarItem *self, void *closure)
+{
+ RET_NULL_IF_INVALID(self->data);
+ return PyInt_FromLong(self->data->min_size);
+}
+
+PyDoc_STRVAR(PyStatusbarItem_max_size_doc,
+ "max size"
+);
+static PyObject *PyStatusbarItem_max_size_get(PyStatusbarItem *self, void *closure)
+{
+ RET_NULL_IF_INVALID(self->data);
+ return PyInt_FromLong(self->data->max_size);
+}
+
+PyDoc_STRVAR(PyStatusbarItem_xpos_doc,
+ "x position"
+);
+static PyObject *PyStatusbarItem_xpos_get(PyStatusbarItem *self, void *closure)
+{
+ RET_NULL_IF_INVALID(self->data);
+ return PyInt_FromLong(self->data->xpos);
+}
+
+PyDoc_STRVAR(PyStatusbarItem_size_doc,
+ "size"
+);
+static PyObject *PyStatusbarItem_size_get(PyStatusbarItem *self, void *closure)
+{
+ RET_NULL_IF_INVALID(self->data);
+ return PyInt_FromLong(self->data->size);
+}
+
+PyDoc_STRVAR(PyStatusbarItem_window_doc,
+ "parent window for statusbar item"
+);
+static PyObject *PyStatusbarItem_window_get(PyStatusbarItem *self, void *closure)
+{
+ RET_NULL_IF_INVALID(self->data);
+ RET_AS_OBJ_OR_NONE(self->window);
+}
+
+/* specialized getters/setters */
+static PyGetSetDef PyStatusbarItem_getseters[] = {
+ {"min_size", (getter)PyStatusbarItem_min_size_get, NULL,
+ PyStatusbarItem_min_size_doc, NULL},
+ {"max_size", (getter)PyStatusbarItem_max_size_get, NULL,
+ PyStatusbarItem_max_size_doc, NULL},
+ {"xpos", (getter)PyStatusbarItem_xpos_get, NULL,
+ PyStatusbarItem_xpos_doc, NULL},
+ {"size", (getter)PyStatusbarItem_size_get, NULL,
+ PyStatusbarItem_size_doc, NULL},
+ {"window", (getter)PyStatusbarItem_window_get, NULL,
+ PyStatusbarItem_window_doc, NULL},
+ {NULL}
+};
+
+/* Methods */
+PyDoc_STRVAR(PyStatusbarItem_default_handler_doc,
+ "default_handler(get_size_only, str=None, data="", escape_vars=True) -> None\n"
+ "\n"
+ "Run default handler of item to print to statusbar\n"
+);
+static PyObject *PyStatusbarItem_default_handler(PyStatusbarItem *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"get_size_only", "str", "data", "escape_vars", NULL};
+ int get_size_only = 0;
+ char *str = NULL;
+ char *data = "";
+ int escape_vars = TRUE;
+
+ RET_NULL_IF_INVALID(self->data);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|zsi", kwlist,
+ &get_size_only, &str, &data, &escape_vars))
+ return NULL;
+
+ if (str && !*str)
+ str = NULL;
+
+ statusbar_item_default_handler(self->data, get_size_only, str, data, escape_vars);
+
+ Py_RETURN_NONE;
+}
+
+/* Methods for object */
+static PyMethodDef PyStatusbarItem_methods[] = {
+ {"default_handler", (PyCFunction)PyStatusbarItem_default_handler, METH_VARARGS | METH_KEYWORDS,
+ PyStatusbarItem_default_handler_doc},
+ {NULL} /* Sentinel */
+};
+
+PyTypeObject PyStatusbarItemType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "StatusbarItem", /*tp_name*/
+ sizeof(PyStatusbarItem), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)PyStatusbarItem_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 */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "PyStatusbarItem objects", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ PyStatusbarItem_methods, /* tp_methods */
+ 0, /* tp_members */
+ PyStatusbarItem_getseters, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ PyStatusbarItem_new, /* tp_new */
+};
+
+
+/* sbar_item factory function */
+PyObject *pystatusbar_item_new(void *sbar_item)
+{
+ SBAR_ITEM_REC *si;
+ PyStatusbarItem *pysbar_item;
+ PyObject *window = NULL;
+
+ si = sbar_item;
+ if (si->bar->parent_window)
+ {
+ window = pywindow_new(si->bar->parent_window);
+ if (!window)
+ return NULL;
+ }
+
+ pysbar_item = py_inst(PyStatusbarItem, PyStatusbarItemType);
+ if (!pysbar_item)
+ return NULL;
+
+ pysbar_item->window = window;
+
+ pysbar_item->data = sbar_item;
+ pysbar_item->cleanup_installed = 1;
+ signal_add_last_data("statusbar item destroyed", statusbar_item_cleanup, pysbar_item);
+
+ return (PyObject *)pysbar_item;
+}
+
+int statusbar_item_object_init(void)
+{
+ g_return_val_if_fail(py_module != NULL, 0);
+
+ if (PyType_Ready(&PyStatusbarItemType) < 0)
+ return 0;
+
+ Py_INCREF(&PyStatusbarItemType);
+ PyModule_AddObject(py_module, "StatusbarItem", (PyObject *)&PyStatusbarItemType);
+
+ return 1;
+}
diff --git a/objects/statusbar-item-object.h b/objects/statusbar-item-object.h
new file mode 100644
index 0000000..19243f4
--- /dev/null
+++ b/objects/statusbar-item-object.h
@@ -0,0 +1,22 @@
+#ifndef _SBAR_ITEM_OBJECT_H_
+#define _SBAR_ITEM_OBJECT_H_
+
+#include <Python.h>
+#include "base-objects.h"
+
+/* forward */
+struct SBAR_ITEM_REC;
+
+typedef struct
+{
+ PyIrssiFinal_HEAD(struct SBAR_ITEM_REC)
+ PyObject *window;
+} PyStatusbarItem;
+
+extern PyTypeObject PyStatusbarItemType;
+
+int statusbar_item_object_init(void);
+PyObject *pystatusbar_item_new(void *sbar_item);
+#define pystatusbar_item_check(op) PyObject_TypeCheck(op, &PyStatusbarItemType)
+
+#endif
diff --git a/pycore.c b/pycore.c
index cce5fb2..ef57ff5 100644
--- a/pycore.c
+++ b/pycore.c
@@ -8,6 +8,7 @@
#include "pymodule.h"
#include "pysignals.h"
#include "pythemes.h"
+#include "pystatusbar.h"
#include "factory.h"
/*XXX: copy parse into utils */
@@ -119,6 +120,7 @@ void irssi_python_init(void)
Py_InitializeEx(0);
pysignals_init();
+ pystatusbar_init();
if (!pyloader_init() || !pymodule_init() || !factory_init() || !pythemes_init())
{
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Failed to load Python");
@@ -150,6 +152,7 @@ void irssi_python_deinit(void)
pymodule_deinit();
pyloader_deinit();
+ pystatusbar_deinit();
pysignals_deinit();
Py_Finalize();
}
diff --git a/pyirssi.h b/pyirssi.h
index b4fb17c..ea8c79a 100644
--- a/pyirssi.h
+++ b/pyirssi.h
@@ -8,6 +8,7 @@
#include "commands.h"
#include "settings.h"
#include "printtext.h"
+#include "statusbar.h"
#include "window-items.h"
#include "window-activity.h"
#include "levels.h"
diff --git a/pymodule.c b/pymodule.c
index 34413a5..2f6b79c 100644
--- a/pymodule.c
+++ b/pymodule.c
@@ -7,6 +7,7 @@
#include "pysignals.h"
#include "pyloader.h"
#include "pythemes.h"
+#include "pystatusbar.h"
/*
* This module is some what different than the Perl's.
@@ -1373,6 +1374,51 @@ static PyObject *py_current_theme(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+PyDoc_STRVAR(py_statusbar_items_redraw_doc,
+ "statusbar_items_redraw(name) -> None\n"
+);
+static PyObject *py_statusbar_items_redraw(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"name", NULL};
+ char *name = "";
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
+ &name))
+ return NULL;
+
+ statusbar_items_redraw(name);
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(py_statusbars_recreate_items_doc,
+ "statusbars_recreate_items() -> None"
+);
+static PyObject *py_statusbars_recreate_items(PyObject *self, PyObject *args)
+{
+ statusbars_recreate_items();
+
+ Py_RETURN_NONE;
+}
+
+/* XXX: we can unregister any statusbar items, not just the ones from this script */
+PyDoc_STRVAR(py_statusbar_item_unregister_doc,
+ "statusbar_item_unregister(name) -> None"
+);
+static PyObject *py_statusbar_item_unregister(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"name", NULL};
+ char *name = "";
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist,
+ &name))
+ return NULL;
+
+ pystatusbar_item_unregister(name);
+
+ Py_RETURN_NONE;
+}
+
static PyMethodDef ModuleMethods[] = {
{"prnt", (PyCFunction)py_prnt, METH_VARARGS | METH_KEYWORDS,
py_prnt_doc},
@@ -1530,6 +1576,12 @@ static PyMethodDef ModuleMethods[] = {
py_themes_reload_doc},
{"current_theme", (PyCFunction)py_current_theme, METH_NOARGS,
py_current_theme_doc},
+ {"statusbar_items_redraw", (PyCFunction)py_statusbar_items_redraw, METH_VARARGS | METH_KEYWORDS,
+ py_statusbar_items_redraw_doc},
+ {"statusbars_recreate_items", (PyCFunction)py_statusbars_recreate_items, METH_NOARGS,
+ py_statusbars_recreate_items_doc},
+ {"statusbar_item_unregister", (PyCFunction)py_statusbar_item_unregister, METH_VARARGS | METH_KEYWORDS,
+ py_statusbar_item_unregister_doc},
{NULL, NULL, 0, NULL} /* Sentinel */
};
diff --git a/pystatusbar.c b/pystatusbar.c
index 2ec5d1c..8537718 100644
--- a/pystatusbar.c
+++ b/pystatusbar.c
@@ -1,5 +1,6 @@
#include "pystatusbar.h"
#include "pyirssi.h"
+#include "factory.h"
typedef struct
{
@@ -42,10 +43,14 @@ static void py_statusbar_proxy_call(SBAR_ITEM_REC *item, int sizeonly, PY_BAR_IT
g_return_if_fail(PyCallable_Check(sitem->handler));
- pybaritem = Py_None; /* FIXME: add statusbaritem object */
+ pybaritem = pystatusbar_item_new(item);
+ if (!pybaritem)
+ {
+ PyErr_Print();
+ pystatusbar_item_unregister(sitem->name);
+ }
ret = PyObject_CallFunction(sitem->handler, "Oi", pybaritem, sizeonly);
-
if (!ret)
{
PyErr_Print();
@@ -69,15 +74,16 @@ static void py_statusbar_proxy(SBAR_ITEM_REC *item, int sizeonly)
}
}
-int pystatusbar_item_register(PyObject *script, const char *sitem,
+void pystatusbar_item_register(PyObject *script, const char *sitem,
const char *value, PyObject *func)
{
if (func)
+ {
+ g_return_if_fail(PyCallable_Check(func));
py_add_bar_handler(sitem, script, func);
-
- statusbar_item_register(sitem, value, func? py_statusbar_proxy : NULL);
+ }
- return 1;
+ statusbar_item_register(sitem, value, func? py_statusbar_proxy : NULL);
}
/* remove selected status bar item handler */
@@ -118,7 +124,7 @@ void pystatusbar_init(void)
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_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
index 686375f..9749c9f 100644
--- a/pystatusbar.h
+++ b/pystatusbar.h
@@ -1,9 +1,11 @@
#ifndef _PYSTATUSBAR_H_
#define _PYSTATUSBAR_H_
-int pystatusbar_item_register(PyObject *script, const char *sitem,
+#include <Python.h>
+
+void pystatusbar_item_register(PyObject *script, const char *sitem,
const char *value, PyObject *func);
-int pystatusbar_item_unregister(const char *iname);
+void pystatusbar_item_unregister(const char *iname);
void pystatusbar_cleanup_script(PyObject *script);
void pystatusbar_init(void);
void pystatusbar_deinit(void);