summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>2002-02-05 07:13:20 +0000
committerJames Henstridge <jamesh@src.gnome.org>2002-02-05 07:13:20 +0000
commita8aff2c7e2887e7b6454b2fb80acac96ad362e59 (patch)
tree1ddb8f876ce9b4e905077b609c05129e10846f73
parent88c8c2e51fa241063b3b920c52ba8d63334ad142 (diff)
downloadpygobject-a8aff2c7e2887e7b6454b2fb80acac96ad362e59.tar.gz
pygobject-a8aff2c7e2887e7b6454b2fb80acac96ad362e59.tar.xz
pygobject-a8aff2c7e2887e7b6454b2fb80acac96ad362e59.zip
register pointer types as well.
2002-02-05 James Henstridge <james@daa.com.au> * codegen/codegen.py (register_types): register pointer types as well. * codegen/argtypes.py (PointerArg): handling for pointer arg types. (ArgMatcher.register_pointer): add function to register pointer types. * gtk/gtk.override (_wrap_gtk_ctree__get_selection): GtkCTreeNode is not a boxed type. (_wrap_gtk_ctree_base_nodes): same. (_wrap_gtk_ctree_insert_node): same. (_wrap_gtk_ctree_find_by_row_data): same. (_wrap_gtk_ctree_find_all_by_row_data): same. (_wrap_gtk_ctree_node_get_text): same. (_wrap_gtk_ctree_node_get_pixmap): same. (_wrap_gtk_ctree_node_get_pixtext): same. (_wrap_gtk_ctree_get_node_info): same. (_wrap_gtk_ctree_node_set_row_data): same. (_wrap_gtk_ctree_node_get_row_data): same here. (_wrap_gtk_ctree_getattr): same here. * codegen/codegen.py (write_source): register pointer types as pointers. * pango.override (_wrap_pango_font_description_new): ignore some private (well, pango module API) functions. * gtk/gtk-types.defs (CTreeNode): make this a pointer type. * codegen/codegen.py (write_pointer_method): new method to write methods for GPointer types. (write_pointer_constructor): new function for writing constructor for GPointer types. (write_pointer_getsets): new function for writing getters for pointer objects (this should be merged with the GObject and GBoxed versions ...). (write_pointer): add new function, which calls all the GPointer related functions. (write_source): write pointer types. * gobjectmodule.c (initgobject): actually ready the GPointer type. * gtk/gtk-types.defs (CTreeNode): get rid of fields here. They will be covered by the custom getattr() function, so no need to duplicate. * codegen/codegen.py (write_boxed_getsets): convert to use getsets for boxed objects. (write_boxed): use write_boxed_getsets() to write the getsets, while allowing boxed objects to specify a getattr() function. 2002-02-04 James Henstridge <james@daa.com.au> * gobjectmodule.c (initgobject): add GPointer to the module dict. (pygobject_api_functions): and to the API vtable. * pygobject.h (pyg_constant_strip_prefix): and add it to the public header. * pygobject-private.h (pyg_pointer_new): add stuff to private header ... * pygboxed.c (PyGPointer): add code to handle base GPointer type. * codegen/defsparser.py (DefsParser.__init__): add self.pointers attribute. (DefsParser.define_pointer): handle (define-pointer ...). (DefsParser.write_defs): handle pointer types. * codegen/definitions.py (PointerDef): new definition type for G_TYPE_POINTER subclasses.
-rw-r--r--gobject/gobjectmodule.c12
-rw-r--r--gobject/pygboxed.c171
-rw-r--r--gobject/pygobject-private.h5
-rw-r--r--gobject/pygobject.h19
4 files changed, 201 insertions, 6 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 7ed3164..5b62189 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -1320,6 +1320,10 @@ struct _PyGObject_Functions pygobject_api_functions = {
pyg_register_boxed,
pyg_boxed_new,
+ &PyGPointer_Type,
+ pyg_register_pointer,
+ pyg_pointer_new,
+
pyg_enum_add_constants,
pyg_flags_add_constants,
@@ -1382,6 +1386,14 @@ initgobject(void)
o=pyg_type_wrapper_new(G_TYPE_BOXED));
Py_DECREF(o);
+ PyGPointer_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyGPointer_Type))
+ return;
+ PyDict_SetItemString(d, "GPointer", (PyObject *)&PyGPointer_Type);
+ PyDict_SetItemString(PyGPointer_Type.tp_dict, "__gtype__",
+ o=pyg_type_wrapper_new(G_TYPE_POINTER));
+ Py_DECREF(o);
+
tuple = Py_BuildValue ("(iii)", glib_major_version, glib_minor_version,
glib_micro_version);
PyDict_SetItemString(d, "glib_version", tuple);
diff --git a/gobject/pygboxed.c b/gobject/pygboxed.c
index 378c9a0..5b3f56d 100644
--- a/gobject/pygboxed.c
+++ b/gobject/pygboxed.c
@@ -107,7 +107,7 @@ PyTypeObject PyGBoxed_Type = {
(PyObject *)0, /* tp_bases */
};
-static GHashTable *boxed_types = NULL;
+static GQuark boxed_type_id = 0;
void
pyg_register_boxed(PyObject *dict, const gchar *class_name,
@@ -119,8 +119,8 @@ pyg_register_boxed(PyObject *dict, const gchar *class_name,
g_return_if_fail(class_name != NULL);
g_return_if_fail(boxed_type != 0);
- if (!boxed_types)
- boxed_types = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (!boxed_type_id)
+ boxed_type_id = g_quark_from_static_string("PyGBoxed::class");
if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_boxed_dealloc;
@@ -136,7 +136,7 @@ pyg_register_boxed(PyObject *dict, const gchar *class_name,
o=pyg_type_wrapper_new(boxed_type));
Py_DECREF(o);
- g_hash_table_insert(boxed_types, GUINT_TO_POINTER(boxed_type), type);
+ g_type_set_qdata(boxed_type, boxed_type_id, type);
PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
}
@@ -156,7 +156,7 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed,
return Py_None;
}
- tp = g_hash_table_lookup(boxed_types, GUINT_TO_POINTER(boxed_type));
+ tp = g_type_get_qdata(boxed_type, boxed_type_id);
if (!tp)
tp = (PyTypeObject *)&PyGBoxed_Type; /* fallback */
self = PyObject_NEW(PyGBoxed, tp);
@@ -172,3 +172,164 @@ pyg_boxed_new(GType boxed_type, gpointer boxed, gboolean copy_boxed,
return (PyObject *)self;
}
+
+/* ------------------ G_TYPE_POINTER derivatives ------------------ */
+
+static void
+pyg_pointer_dealloc(PyGPointer *self)
+{
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static int
+pyg_pointer_compare(PyGPointer *self, PyGPointer *v)
+{
+ if (self->pointer == v->pointer) return 0;
+ if (self->pointer > v->pointer) return -1;
+ return 1;
+}
+
+static long
+pyg_pointer_hash(PyGPointer *self)
+{
+ return (long)self->pointer;
+}
+
+static PyObject *
+pyg_pointer_repr(PyGPointer *self)
+{
+ gchar buf[128];
+
+ g_snprintf(buf, sizeof(buf), "<%s at 0x%lx>", g_type_name(self->gtype),
+ (long)self->pointer);
+ return PyString_FromString(buf);
+}
+
+static int
+pyg_pointer_init(PyGPointer *self, PyObject *args, PyObject *kwargs)
+{
+ gchar buf[512];
+
+ if (!PyArg_ParseTuple(args, ":GPointer.__init__"))
+ return -1;
+
+ self->pointer = NULL;
+ self->gtype = 0;
+
+ g_snprintf(buf, sizeof(buf), "%s can not be constructed", self->ob_type->tp_name);
+ PyErr_SetString(PyExc_NotImplementedError, buf);
+ return -1;
+}
+
+static void
+pyg_pointer_free(PyObject *op)
+{
+ PyObject_FREE(op);
+}
+
+PyTypeObject PyGPointer_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "gobject.GPointer", /* tp_name */
+ sizeof(PyGPointer), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)pyg_pointer_dealloc, /* tp_dealloc */
+ (printfunc)0, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)pyg_pointer_compare, /* tp_compare */
+ (reprfunc)pyg_pointer_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)pyg_pointer_hash, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)0, /* tp_str */
+ (getattrofunc)0, /* tp_getattro */
+ (setattrofunc)0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ NULL, /* Documentation string */
+ (traverseproc)0, /* tp_traverse */
+ (inquiry)0, /* tp_clear */
+ (richcmpfunc)0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)0, /* tp_iter */
+ (iternextfunc)0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ (PyTypeObject *)0, /* tp_base */
+ (PyObject *)0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)pyg_pointer_init, /* tp_init */
+ PyType_GenericAlloc, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+ pyg_pointer_free, /* tp_free */
+ (inquiry)0, /* tp_is_gc */
+ (PyObject *)0, /* tp_bases */
+};
+
+static GQuark pointer_type_id = 0;
+
+void
+pyg_register_pointer(PyObject *dict, const gchar *class_name,
+ GType pointer_type, PyTypeObject *type)
+{
+ PyObject *o;
+
+ g_return_if_fail(dict != NULL);
+ g_return_if_fail(class_name != NULL);
+ g_return_if_fail(pointer_type != 0);
+
+ if (!pointer_type_id)
+ pointer_type_id = g_quark_from_static_string("PyGPointer::class");
+
+ if (!type->tp_dealloc) type->tp_dealloc = (destructor)pyg_pointer_dealloc;
+
+ type->ob_type = &PyType_Type;
+ type->tp_base = &PyGPointer_Type;
+
+ if (PyType_Ready(type) < 0) {
+ g_warning("could not get type `%s' ready", type->tp_name);
+ return;
+ }
+
+ PyDict_SetItemString(type->tp_dict, "__gtype__",
+ o=pyg_type_wrapper_new(pointer_type));
+ Py_DECREF(o);
+
+ g_type_set_qdata(pointer_type, pointer_type_id, type);
+
+ PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
+}
+
+PyObject *
+pyg_pointer_new(GType pointer_type, gpointer pointer)
+{
+ PyGPointer *self;
+ PyTypeObject *tp;
+
+ g_return_val_if_fail(pointer_type != 0, NULL);
+
+ if (!pointer) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ tp = g_type_get_qdata(pointer_type, pointer_type_id);
+ if (!tp)
+ tp = (PyTypeObject *)&PyGPointer_Type; /* fallback */
+ self = PyObject_NEW(PyGPointer, tp);
+
+ if (self == NULL)
+ return NULL;
+
+ self->pointer = pointer;
+ self->gtype = pointer_type;
+
+ return (PyObject *)self;
+}
diff --git a/gobject/pygobject-private.h b/gobject/pygobject-private.h
index 6390fc6..b6d9135 100644
--- a/gobject/pygobject-private.h
+++ b/gobject/pygobject-private.h
@@ -68,5 +68,10 @@ void pyg_register_boxed (PyObject *dict, const gchar *class_name,
PyObject * pyg_boxed_new (GType boxed_type, gpointer boxed,
gboolean copy_boxed, gboolean own_ref);
+extern PyTypeObject PyGPointer_Type;
+
+void pyg_register_pointer (PyObject *dict, const gchar *class_name,
+ GType pointer_type, PyTypeObject *type);
+PyObject * pyg_pointer_new (GType pointer_type, gpointer pointer);
#endif
diff --git a/gobject/pygobject.h b/gobject/pygobject.h
index 9918dd3..69af1af 100644
--- a/gobject/pygobject.h
+++ b/gobject/pygobject.h
@@ -25,9 +25,18 @@ typedef struct {
gboolean free_on_dealloc;
} PyGBoxed;
+typedef struct {
+ PyObject_HEAD
+ gpointer pointer;
+ GType gtype;
+} PyGPointer;
+
#define pyg_boxed_get(v,t) ((t *)((PyGBoxed *)(v))->boxed)
#define pyg_boxed_check(v,typecode) (PyObject_TypeCheck(v, &PyGBoxed_Type) && ((PyGBoxed *)(v))->gtype == typecode)
+#define pyg_pointer_get(v,t) ((t *)((PyGPointer *)(v))->pointer)
+#define pyg_pointer_check(v,typecode) (PyObject_TypeCheck(v, &PyGPointer_Type) && ((PyGPointer *)(v))->gtype == typecode)
+
typedef void (*PyGFatalExceptionFunc) (void);
typedef void (*PyGThreadBlockFunc) (void);
@@ -62,6 +71,11 @@ struct _PyGObject_Functions {
PyObject *(* boxed_new)(GType boxed_type, gpointer boxed,
gboolean copy_boxed, gboolean own_ref);
+ PyTypeObject *pointer_type;
+ void (* register_pointer)(PyObject *dict, const gchar *class_name,
+ GType pointer_type, PyTypeObject *type);
+ PyObject *(* pointer_new)(GType boxed_type, gpointer pointer);
+
void (* enum_add_constants)(PyObject *module, GType enum_type,
const gchar *strip_prefix);
void (* flags_add_constants)(PyObject *module, GType flags_type,
@@ -105,9 +119,12 @@ struct _PyGObject_Functions *_PyGObject_API;
#define PyGBoxed_Type (*_PyGObject_API->boxed_type)
#define pyg_register_boxed (_PyGObject_API->register_boxed)
#define pyg_boxed_new (_PyGObject_API->boxed_new)
+#define PyGPointer_Type (*_PyGObject_API->pointer_type)
+#define pyg_register_pointer (_PyGObject_API->register_pointer)
+#define pyg_pointer_new (_PyGObject_API->pointer_new)
#define pyg_enum_add_constants (_PyGObject_API->enum_add_constants)
#define pyg_flags_add_constants (_PyGObject_API->flags_add_constants)
-#define pyg_constant_strip_prefix (_PyGObject_API->constant_strip_prefix)
+#define pyg_constant_strip_prefix (_PyGObject_API->constant_strip_prefix)
#define pyg_error_check (_PyGObject_API->error_check)
#define pyg_set_thread_block_funcs (_PyGObject_API->set_thread_block_funcs)