diff options
author | Christopher Davis <loafier@gmail.com> | 2006-07-26 10:18:15 +0000 |
---|---|---|
committer | Christopher Davis <loafier@gmail.com> | 2006-07-26 10:18:15 +0000 |
commit | c0ac6d60c5319a08148d743fd03ba3f66b22dfe0 (patch) | |
tree | c6ef42493a981f530f498c50d7573ae028c84a6a | |
parent | d01927add7ccbc6d98e31c87640b8711e2d60d4a (diff) | |
download | irssi-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-- | Makefile | 4 | ||||
-rw-r--r-- | objects/Makefile | 4 | ||||
-rw-r--r-- | objects/factory.c | 3 | ||||
-rw-r--r-- | objects/factory.h | 1 | ||||
-rw-r--r-- | objects/pyscript-object.c | 30 | ||||
-rw-r--r-- | objects/pyscript-object.h | 1 | ||||
-rw-r--r-- | objects/statusbar-item-object.c | 217 | ||||
-rw-r--r-- | objects/statusbar-item-object.h | 22 | ||||
-rw-r--r-- | pycore.c | 3 | ||||
-rw-r--r-- | pyirssi.h | 1 | ||||
-rw-r--r-- | pymodule.c | 52 | ||||
-rw-r--r-- | pystatusbar.c | 20 | ||||
-rw-r--r-- | pystatusbar.h | 6 |
13 files changed, 351 insertions, 13 deletions
@@ -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 @@ -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(); } @@ -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" @@ -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); |