* USA
*/
-#include <Python.h>
-#include <glib-object.h>
-
-#include "config.h"
-#include "pyglib.h"
-#include "pyginterface.h"
-#include "pygi-repository.h"
-#include "pyglib.h"
-#include "pygtype.h"
-#include "pygenum.h"
-#include "pygboxed.h"
-#include "pygflags.h"
-#include "pygi-error.h"
-#include "pygi-foreign.h"
-#include "pygi-resulttuple.h"
-#include "pygi-source.h"
-#include "pygi-ccallback.h"
-#include "pygi-closure.h"
-#include "pygi-type.h"
-#include "pygi-boxed.h"
-#include "pygi-info.h"
-#include "pygi-struct.h"
-#include "pygobject-object.h"
-#include "pygoptioncontext.h"
-#include "pygoptiongroup.h"
-#include "pygspawn.h"
-#include "gobjectmodule.h"
-#include "pygparamspec.h"
-#include "pygpointer.h"
+#include "pygi-private.h"
+#include "pygi.h"
+#include <pygobject.h>
#include <pyglib-python-compat.h>
-PyObject *PyGIWarning;
-PyObject *PyGIDeprecationWarning;
-PyObject *_PyGIDefaultArgPlaceholder;
-
-
-/* Defined by PYGLIB_MODULE_START */
-extern PyObject *pyglib__gobject_module_create (void);
-
-/* Returns a new flag/enum type or %NULL */
-static PyObject *
-flags_enum_from_gtype (GType g_type,
- PyObject * (add_func) (PyObject *, const char *,
- const char *, GType))
-{
- PyObject *new_type;
- GIRepository *repository;
- GIBaseInfo *info;
- const gchar *type_name;
-
- repository = g_irepository_get_default ();
- info = g_irepository_find_by_gtype (repository, g_type);
- if (info != NULL) {
- type_name = g_base_info_get_name (info);
- new_type = add_func (NULL, type_name, NULL, g_type);
- g_base_info_unref (info);
- } else {
- type_name = g_type_name (g_type);
- new_type = add_func (NULL, type_name, NULL, g_type);
- }
-
- return new_type;
-}
-
-
static PyObject *
_wrap_pyg_enum_add (PyObject *self,
PyObject *args,
return NULL;
}
- return flags_enum_from_gtype (g_type, pyg_enum_add);
+ return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
}
static PyObject *
gint n_values;
GEnumValue *g_enum_values;
int i;
- const gchar *namespace;
const gchar *type_name;
- gchar *full_name;
GType g_type;
if (!PyArg_ParseTupleAndKeywords (args, kwargs,
info = (GIEnumInfo *)py_info->info;
n_values = g_enum_info_get_n_values (info);
-
- /* The new memory is zero filled which fulfills the registration
- * function requirement that the last item is zeroed out as a terminator.
- */
g_enum_values = g_new0 (GEnumValue, n_values + 1);
for (i = 0; i < n_values; i++) {
g_base_info_unref ((GIBaseInfo *) value_info);
}
- /* Obfuscate the full_name by prefixing it with "Py" to avoid conflicts
- * with real GTypes. See: https://bugzilla.gnome.org/show_bug.cgi?id=692515
- */
- namespace = g_base_info_get_namespace ((GIBaseInfo *) info);
- type_name = g_base_info_get_name ((GIBaseInfo *) info);
- full_name = g_strconcat ("Py", namespace, type_name, NULL);
-
- /* If enum registration fails, free all the memory allocated
- * for the values array. This needs to leak when successful
- * as GObject keeps a reference to the data as specified in the docs.
- */
- g_type = g_enum_register_static (full_name, g_enum_values);
- if (g_type == G_TYPE_INVALID) {
- for (i = 0; i < n_values; i++) {
- GEnumValue *enum_value = &g_enum_values[i];
-
- /* Only free value_name if it is different from value_nick to avoid
- * a double free. The pointer might have been is re-used in the case
- * c_identifier was NULL in the above loop.
- */
- if (enum_value->value_name != enum_value->value_nick)
- g_free ((gchar *) enum_value->value_name);
- g_free ((gchar *) enum_value->value_nick);
- }
+ g_enum_values[n_values].value = 0;
+ g_enum_values[n_values].value_nick = NULL;
+ g_enum_values[n_values].value_name = NULL;
- PyErr_Format (PyExc_RuntimeError, "Unable to register enum '%s'", full_name);
-
- g_free (g_enum_values);
- g_free (full_name);
- return NULL;
- }
+ type_name = g_base_info_get_name ((GIBaseInfo *) info);
+ type_name = g_strdup (type_name);
+ g_type = g_enum_register_static (type_name, g_enum_values);
- g_free (full_name);
- return pyg_enum_add (NULL, type_name, NULL, g_type);
+ return pyg_enum_add (NULL, g_type_name (g_type), NULL, g_type);
}
static PyObject *
return NULL;
}
- return flags_enum_from_gtype (g_type, pyg_flags_add);
+ return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
}
static PyObject *
gint n_values;
GFlagsValue *g_flags_values;
int i;
- const gchar *namespace;
const gchar *type_name;
- gchar *full_name;
GType g_type;
if (!PyArg_ParseTupleAndKeywords (args, kwargs,
info = (GIEnumInfo *)py_info->info;
n_values = g_enum_info_get_n_values (info);
-
- /* The new memory is zero filled which fulfills the registration
- * function requirement that the last item is zeroed out as a terminator.
- */
g_flags_values = g_new0 (GFlagsValue, n_values + 1);
for (i = 0; i < n_values; i++) {
g_base_info_unref ((GIBaseInfo *) value_info);
}
- /* Obfuscate the full_name by prefixing it with "Py" to avoid conflicts
- * with real GTypes. See: https://bugzilla.gnome.org/show_bug.cgi?id=692515
- */
- namespace = g_base_info_get_namespace ((GIBaseInfo *) info);
- type_name = g_base_info_get_name ((GIBaseInfo *) info);
- full_name = g_strconcat ("Py", namespace, type_name, NULL);
-
- /* If enum registration fails, free all the memory allocated
- * for the values array. This needs to leak when successful
- * as GObject keeps a reference to the data as specified in the docs.
- */
- g_type = g_flags_register_static (full_name, g_flags_values);
- if (g_type == G_TYPE_INVALID) {
- for (i = 0; i < n_values; i++) {
- GFlagsValue *flags_value = &g_flags_values[i];
-
- /* Only free value_name if it is different from value_nick to avoid
- * a double free. The pointer might have been is re-used in the case
- * c_identifier was NULL in the above loop.
- */
- if (flags_value->value_name != flags_value->value_nick)
- g_free ((gchar *) flags_value->value_name);
- g_free ((gchar *) flags_value->value_nick);
- }
+ g_flags_values[n_values].value = 0;
+ g_flags_values[n_values].value_nick = NULL;
+ g_flags_values[n_values].value_name = NULL;
- PyErr_Format (PyExc_RuntimeError, "Unable to register flags '%s'", full_name);
-
- g_free (g_flags_values);
- g_free (full_name);
- return NULL;
- }
+ type_name = g_base_info_get_name ((GIBaseInfo *) info);
+ type_name = g_strdup (type_name);
+ g_type = g_flags_register_static (type_name, g_flags_values);
- g_free (full_name);
- return pyg_flags_add (NULL, type_name, NULL, g_type);
+ return pyg_flags_add (NULL, g_type_name (g_type), NULL, g_type);
}
static void
initialize_interface (GTypeInterface *iface, PyTypeObject *pytype)
{
- /* pygobject prints a warning if interface_init is NULL */
+ // pygobject prints a warning if interface_init is NULL
}
static PyObject *
#endif
static PyObject *
-_wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
+_wrap_pyg_variant_new_tuple (PyObject *self, PyObject *args)
{
- char *type_string;
- PyObject *py_type;
+ PyObject *py_values;
+ GVariant **values = NULL;
+ GVariant *variant = NULL;
PyObject *py_variant = NULL;
+ PyObject *py_type;
+ gssize i;
- if (!PyArg_ParseTuple (args, "s:variant_type_from_string",
- &type_string)) {
+ if (!PyArg_ParseTuple (args, "O!:variant_new_tuple",
+ &PyTuple_Type, &py_values)) {
return NULL;
}
- py_type = _pygi_type_import_by_name ("GLib", "VariantType");
+ py_type = _pygi_type_import_by_name ("GLib", "Variant");
+
+ values = g_newa (GVariant*, PyTuple_Size (py_values));
+
+ for (i = 0; i < PyTuple_Size (py_values); i++) {
+ PyObject *value = PyTuple_GET_ITEM (py_values, i);
+
+ if (!PyObject_IsInstance (value, py_type)) {
+ PyErr_Format (PyExc_TypeError, "argument %" G_GSSIZE_FORMAT " is not a GLib.Variant", i);
+ return NULL;
+ }
+
+ values[i] = (GVariant *) ( (PyGPointer *) value)->pointer;
+ }
- /* Pass the string directly and force a boxed copy. This works because
- * GVariantType is just a char pointer. */
- py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string,
- TRUE, /* copy_boxed */
- 0); /* slice_allocated */
+ variant = g_variant_new_tuple (values, PyTuple_Size (py_values));
+
+ py_variant = _pygi_struct_new ( (PyTypeObject *) py_type, variant, FALSE);
return py_variant;
}
static PyObject *
-_wrap_pyg_source_new (PyObject *self, PyObject *args)
+_wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
{
- return pyg_source_new ();
-}
-
-#define CHUNK_SIZE 8192
+ char *type_string;
+ PyObject *py_type;
+ PyObject *py_variant = NULL;
-static PyObject*
-pyg_channel_read(PyObject* self, PyObject *args, PyObject *kwargs)
-{
- int max_count = -1;
- PyObject *py_iochannel, *ret_obj = NULL;
- gsize total_read = 0;
- GError* error = NULL;
- GIOStatus status = G_IO_STATUS_NORMAL;
- GIOChannel *iochannel = NULL;
-
- if (!PyArg_ParseTuple (args, "Oi:pyg_channel_read", &py_iochannel, &max_count)) {
- return NULL;
- }
- if (!pyg_boxed_check (py_iochannel, G_TYPE_IO_CHANNEL)) {
- PyErr_SetString(PyExc_TypeError, "first argument is not a GLib.IOChannel");
+ if (!PyArg_ParseTuple (args, "s:variant_type_from_string",
+ &type_string)) {
return NULL;
}
-
- if (max_count == 0)
- return PYGLIB_PyBytes_FromString("");
-
- iochannel = pyg_boxed_get (py_iochannel, GIOChannel);
-
- while (status == G_IO_STATUS_NORMAL
- && (max_count == -1 || total_read < (gsize)max_count)) {
- gsize single_read;
- char* buf;
- gsize buf_size;
-
- if (max_count == -1)
- buf_size = CHUNK_SIZE;
- else {
- buf_size = max_count - total_read;
- if (buf_size > CHUNK_SIZE)
- buf_size = CHUNK_SIZE;
- }
-
- if ( ret_obj == NULL ) {
- ret_obj = PYGLIB_PyBytes_FromStringAndSize((char *)NULL, buf_size);
- if (ret_obj == NULL)
- goto failure;
- }
- else if (buf_size + total_read > (gsize)PYGLIB_PyBytes_Size(ret_obj)) {
- if (PYGLIB_PyBytes_Resize(&ret_obj, buf_size + total_read) == -1)
- goto failure;
- }
-
- buf = PYGLIB_PyBytes_AsString(ret_obj) + total_read;
-
- Py_BEGIN_ALLOW_THREADS;
- status = g_io_channel_read_chars (iochannel, buf, buf_size, &single_read, &error);
- Py_END_ALLOW_THREADS;
-
- if (pygi_error_check (&error))
- goto failure;
-
- total_read += single_read;
- }
-
- if ( total_read != (gsize)PYGLIB_PyBytes_Size(ret_obj) ) {
- if (PYGLIB_PyBytes_Resize(&ret_obj, total_read) == -1)
- goto failure;
- }
- return ret_obj;
+ py_type = _pygi_type_import_by_name ("GLib", "VariantType");
+
+ py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE);
- failure:
- Py_XDECREF(ret_obj);
- return NULL;
+ return py_variant;
}
static PyMethodDef _gi_functions[] = {
{ "register_interface_info", (PyCFunction) _wrap_pyg_register_interface_info, METH_VARARGS },
{ "hook_up_vfunc_implementation", (PyCFunction) _wrap_pyg_hook_up_vfunc_implementation, METH_VARARGS },
+ { "variant_new_tuple", (PyCFunction) _wrap_pyg_variant_new_tuple, METH_VARARGS },
{ "variant_type_from_string", (PyCFunction) _wrap_pyg_variant_type_from_string, METH_VARARGS },
- { "source_new", (PyCFunction) _wrap_pyg_source_new, METH_NOARGS },
- { "source_set_callback", (PyCFunction) pyg_source_set_callback, METH_VARARGS },
- { "io_channel_read", (PyCFunction) pyg_channel_read, METH_VARARGS },
- { "require_foreign", (PyCFunction) pygi_require_foreign, METH_VARARGS | METH_KEYWORDS },
- { "spawn_async",
- (PyCFunction)pyglib_spawn_async, METH_VARARGS|METH_KEYWORDS,
- "spawn_async(argv, envp=None, working_directory=None,\n"
- " flags=0, child_setup=None, user_data=None,\n"
- " standard_input=None, standard_output=None,\n"
- " standard_error=None) -> (pid, stdin, stdout, stderr)\n"
- "\n"
- "Execute a child program asynchronously within a glib.MainLoop()\n"
- "See the reference manual for a complete reference.\n" },
- { "type_name", pyg_type_name, METH_VARARGS },
- { "type_from_name", pyg_type_from_name, METH_VARARGS },
- { "type_is_a", pyg_type_is_a, METH_VARARGS },
- { "type_register", _wrap_pyg_type_register, METH_VARARGS },
- { "signal_new", pyg_signal_new, METH_VARARGS },
- { "list_properties",
- pyg_object_class_list_properties, METH_VARARGS },
- { "new",
- (PyCFunction)pyg_object_new, METH_VARARGS|METH_KEYWORDS },
- { "signal_accumulator_true_handled",
- (PyCFunction)pyg_signal_accumulator_true_handled, METH_VARARGS },
- { "add_emission_hook",
- (PyCFunction)pyg_add_emission_hook, METH_VARARGS },
- { "_install_metaclass",
- (PyCFunction)pyg__install_metaclass, METH_O },
- { "_gvalue_get",
- (PyCFunction)pyg__gvalue_get, METH_O },
- { "_gvalue_set",
- (PyCFunction)pyg__gvalue_set, METH_VARARGS },
{ NULL, NULL, 0 }
};
static struct PyGI_API CAPI = {
- pygi_register_foreign_struct,
+ pygi_type_import_by_g_type_real,
+ pygi_get_property_value_real,
+ pygi_set_property_value_real,
+ pygi_signal_closure_new_real,
+ pygi_register_foreign_struct_real,
};
PYGLIB_MODULE_START(_gi, "_gi")
{
PyObject *api;
- PyObject *module_dict = PyModule_GetDict (module);
- /* Always enable Python threads since we cannot predict which GI repositories
- * might accept Python callbacks run within non-Python threads or might trigger
- * toggle ref notifications.
- * See: https://bugzilla.gnome.org/show_bug.cgi?id=709223
- */
- PyEval_InitThreads ();
+ if (pygobject_init (-1, -1, -1) == NULL) {
+ return PYGLIB_MODULE_ERROR_RETURN;
+ }
- PyModule_AddStringConstant(module, "__package__", "gi._gi");
+ if (_pygobject_import() < 0) {
+ return PYGLIB_MODULE_ERROR_RETURN;
+ }
- pygi_foreign_init ();
- pygi_error_register_types (module);
_pygi_repository_register_types (module);
_pygi_info_register_types (module);
_pygi_struct_register_types (module);
_pygi_boxed_register_types (module);
_pygi_ccallback_register_types (module);
- pygi_resulttuple_register_types (module);
-
- pyglib_spawn_register_types (module_dict);
- pyglib_option_context_register_types (module_dict);
- pyglib_option_group_register_types (module_dict);
-
- pygobject_register_api (module_dict);
- pygobject_register_constants (module);
- pygobject_register_features (module_dict);
- pygobject_register_version_tuples (module_dict);
- pygobject_register_warnings (module_dict);
- pygobject_type_register_types (module_dict);
- pygobject_object_register_types (module_dict);
- pygobject_interface_register_types (module_dict);
- pygobject_paramspec_register_types (module_dict);
- pygobject_boxed_register_types (module_dict);
- pygobject_pointer_register_types (module_dict);
- pygobject_enum_register_types (module_dict);
- pygobject_flags_register_types (module_dict);
-
- PyGIWarning = PyErr_NewException ("gi.PyGIWarning", PyExc_Warning, NULL);
-
- /* Use RuntimeWarning as the base class of PyGIDeprecationWarning
- * for unstable (odd minor version) and use DeprecationWarning for
- * stable (even minor version). This is so PyGObject deprecations
- * behave the same as regular Python deprecations in stable releases.
- */
-#if PYGOBJECT_MINOR_VERSION % 2
- PyGIDeprecationWarning = PyErr_NewException("gi.PyGIDeprecationWarning",
- PyExc_RuntimeWarning, NULL);
-#else
- PyGIDeprecationWarning = PyErr_NewException("gi.PyGIDeprecationWarning",
- PyExc_DeprecationWarning, NULL);
-#endif
-
- /* Place holder object used to fill in "from Python" argument lists
- * for values not supplied by the caller but support a GI default.
- */
- _PyGIDefaultArgPlaceholder = PyObject_New(PyObject, &PyType_Type);
-
- Py_INCREF (PyGIWarning);
- PyModule_AddObject (module, "PyGIWarning", PyGIWarning);
-
- Py_INCREF(PyGIDeprecationWarning);
- PyModule_AddObject(module, "PyGIDeprecationWarning", PyGIDeprecationWarning);
+ _pygi_argument_init();
api = PYGLIB_CPointer_WrapPointer ( (void *) &CAPI, "gi._API");
if (api == NULL) {