diff options
author | James Henstridge <james@daa.com.au> | 2002-02-05 07:13:20 +0000 |
---|---|---|
committer | James Henstridge <jamesh@src.gnome.org> | 2002-02-05 07:13:20 +0000 |
commit | a8aff2c7e2887e7b6454b2fb80acac96ad362e59 (patch) | |
tree | 1ddb8f876ce9b4e905077b609c05129e10846f73 | |
parent | 88c8c2e51fa241063b3b920c52ba8d63334ad142 (diff) | |
download | pygobject-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.c | 12 | ||||
-rw-r--r-- | gobject/pygboxed.c | 171 | ||||
-rw-r--r-- | gobject/pygobject-private.h | 5 | ||||
-rw-r--r-- | gobject/pygobject.h | 19 |
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) |