summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>2001-05-06 16:51:48 +0000
committerJames Henstridge <jamesh@src.gnome.org>2001-05-06 16:51:48 +0000
commit4a9a14997dc9d70e8e77a1c37ec3e06a109af300 (patch)
tree728a24234a2ebe7e081755b5e83f14e4aa0dd6f3
parent2fa1a292a8c3056183f7e0ac77ce46551c58b853 (diff)
downloadpygobject-4a9a14997dc9d70e8e77a1c37ec3e06a109af300.tar.gz
2001-05-06 James Henstridge <james@daa.com.au>
2001-05-07 James Henstridge <james@daa.com.au> * examples/gobject/signal.py: 2001-05-06 James Henstridge <james@daa.com.au> * gobjectmodule.c (pygobject__init__): make the __init__ function choose what GType to pass to g_object_new based on the __gtype__ attribute. (pygobject_methods): make __gobject_init__ an alias for GObject.__init__. (pyg_type_register): new function for registering new GTypes. (pyg_type_register): register the type as "module+class" rather than "module.class", as the second form is considered bad (would like to use the second form though. * configure.in: require 1.3.5 versions of glib and gtk+.
-rw-r--r--examples/signal.py8
-rw-r--r--gobject/gobjectmodule.c106
2 files changed, 109 insertions, 5 deletions
diff --git a/examples/signal.py b/examples/signal.py
index b98bca77..c52f0ad8 100644
--- a/examples/signal.py
+++ b/examples/signal.py
@@ -1,10 +1,12 @@
-import ltihooks, ExtensionClass
import gobject
class C(gobject.GObject):
+ def __init__(self):
+ self.__gobject_init__() # default constructor using our new GType
def do_my_signal(self, arg):
print "C: class closure for `my_signal' called with argument", arg
+gobject.type_register(C)
gobject.signal_new("my_signal", C, gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (gobject.TYPE_INT, ))
@@ -13,6 +15,8 @@ class D(C):
print "D: class closure for `my_signal' called. Chaining up to C"
C.do_my_signal(self, arg)
+gobject.type_register(D)
+
def my_signal_handler(object, arg, *extra):
print "handler for `my_signal' called with argument", arg, \
"and extra args", extra
@@ -20,8 +24,6 @@ def my_signal_handler(object, arg, *extra):
inst = C()
inst2 = D()
-print "instance id 0x%x" % id(inst)
-
inst.connect("my_signal", my_signal_handler, 1, 2, 3)
inst.emit("my_signal", 42)
inst2.emit("my_signal", 42)
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 660db722..daaab4bf 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -922,10 +922,28 @@ pygobject__class_init__(PyObject *something, PyObject *args)
static PyObject *
pygobject__init__(PyGObject *self, PyObject *args)
{
- GType object_type = G_TYPE_OBJECT;
+ PyObject *gtype;
+ GType object_type;
- if (!PyArg_ParseTuple(args, "|i:GObject.__init__", &object_type))
+ if (!PyArg_ParseTuple(args, ":GObject.__init__", &object_type))
return NULL;
+
+ gtype = PyObject_GetAttrString((PyObject *)self, "__gtype__");
+ if (!gtype) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "required __gtype__ attribute missing");
+ return NULL;
+ }
+ object_type = (GType) PyInt_AsLong(gtype);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ Py_DECREF(gtype);
+ PyErr_SetString(PyExc_TypeError,
+ "__gtype__ attribute not an integer");
+ return NULL;
+ }
+ Py_DECREF(gtype);
self->obj = g_object_new(object_type, NULL);
if (!self->obj) {
PyErr_SetString(PyExc_RuntimeError, "could not create object");
@@ -1338,6 +1356,7 @@ pygobject_stop_emission(PyGObject *self, PyObject *args)
static PyMethodDef pygobject_methods[] = {
{ "__class_init__", (PyCFunction)pygobject__class_init__, METH_VARARGS|METH_CLASS_METHOD },
{ "__init__", (PyCFunction)pygobject__init__, METH_VARARGS },
+ { "__gobject_init__", (PyCFunction)pygobject__init__, METH_VARARGS },
{ "get_property", (PyCFunction)pygobject_get_property, METH_VARARGS },
{ "set_property", (PyCFunction)pygobject_set_property, METH_VARARGS },
{ "freeze_notify", (PyCFunction)pygobject_freeze_notify, METH_VARARGS },
@@ -1491,6 +1510,88 @@ pyg_type_interfaces (PyObject *self, PyObject *args)
return NULL;
}
+static PyObject *
+pyg_type_register(PyObject *self, PyObject *args)
+{
+ PyObject *class, *gtype, *module;
+ GType parent_type, instance_type;
+ gchar *type_name = NULL;
+ GTypeQuery query;
+ GTypeInfo type_info = {
+ 0, /* class_size */
+
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+
+ (GClassInitFunc) NULL,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+
+ 0, /* instance_size */
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL
+ };
+
+ if (!PyArg_ParseTuple(args, "O:gobject.type_register", &class))
+ return NULL;
+ if (!ExtensionClassSubclass_Check(class, &PyGObject_Type)) {
+ PyErr_SetString(PyExc_TypeError,"argument must be a GObject subclass");
+ return NULL;
+ }
+
+ /* find the GType of the parent */
+ gtype = PyObject_GetAttrString(class, "__gtype__");
+ if (!gtype) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError,
+ "required __gtype__ attribute missing");
+ return NULL;
+ }
+ parent_type = (GType) PyInt_AsLong(gtype);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ Py_DECREF(gtype);
+ PyErr_SetString(PyExc_TypeError,
+ "__gtype__ attribute not an integer");
+ return NULL;
+ }
+ Py_DECREF(gtype);
+
+ /* make name for new widget */
+ module = PyObject_GetAttrString(class, "__module__");
+ if (module && PyString_Check(module)) {
+ type_name = g_strconcat(PyString_AsString(module), "+",
+ ((PyExtensionClass *)class)->tp_name, NULL);
+ } else {
+ if (module)
+ Py_DECREF(module);
+ else
+ PyErr_Clear();
+ type_name = g_strdup(((PyExtensionClass *)class)->tp_name);
+ }
+
+ /* fill in missing values of GTypeInfo struct */
+ g_type_query(parent_type, &query);
+ type_info.class_size = query.class_size;
+ type_info.instance_size = query.instance_size;
+
+ /* create new typecode */
+ instance_type = g_type_register_static(parent_type, type_name,
+ &type_info, 0);
+ g_free(type_name);
+ if (instance_type == 0) {
+ PyErr_SetString(PyExc_RuntimeError, "could not create new GType");
+ return NULL;
+ }
+
+ /* set new value of __gtype__ on class */
+ gtype = PyInt_FromLong(instance_type);
+ PyObject_SetAttrString(class, "__gtype__", gtype);
+ Py_DECREF(gtype);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
static PyObject *
pyg_signal_new(PyObject *self, PyObject *args)
@@ -1578,6 +1679,7 @@ static PyMethodDef pygobject_functions[] = {
{ "type_is_a", pyg_type_is_a, METH_VARARGS },
{ "type_children", pyg_type_children, METH_VARARGS },
{ "type_interfaces", pyg_type_interfaces, METH_VARARGS },
+ { "type_register", pyg_type_register, METH_VARARGS },
{ "signal_new", pyg_signal_new, METH_VARARGS },
{ NULL, NULL, 0 }
};