summaryrefslogtreecommitdiffstats
path: root/plugins/python_wrapper/pygobject.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/python_wrapper/pygobject.h')
-rw-r--r--plugins/python_wrapper/pygobject.h669
1 files changed, 669 insertions, 0 deletions
diff --git a/plugins/python_wrapper/pygobject.h b/plugins/python_wrapper/pygobject.h
new file mode 100644
index 0000000..145d1c6
--- /dev/null
+++ b/plugins/python_wrapper/pygobject.h
@@ -0,0 +1,669 @@
+/* -*- Mode: C; c-basic-offset: 4 -*- */
+/*
+ * Remmina - The GTK+ Remote Desktop Client
+ * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. * If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. * If you
+ * do not wish to do so, delete this exception statement from your
+ * version. * If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ *
+ */
+
+#ifndef _PYGOBJECT_H_
+#define _PYGOBJECT_H_
+
+#include <Python.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* PyGClosure is a _private_ structure */
+typedef void (* PyClosureExceptionHandler) (GValue *ret, guint n_param_values, const GValue *params);
+typedef struct _PyGClosure PyGClosure;
+typedef struct _PyGObjectData PyGObjectData;
+
+struct _PyGClosure {
+ GClosure closure;
+ PyObject *callback;
+ PyObject *extra_args; /* tuple of extra args to pass to callback */
+ PyObject *swap_data; /* other object for gtk_signal_connect__object */
+ PyClosureExceptionHandler exception_handler;
+};
+
+typedef enum {
+ PYGOBJECT_USING_TOGGLE_REF = 1 << 0,
+ PYGOBJECT_IS_FLOATING_REF = 1 << 1
+} PyGObjectFlags;
+
+ /* closures is just an alias for what is found in the
+ * PyGObjectData */
+typedef struct {
+ PyObject_HEAD
+ GObject *obj;
+ PyObject *inst_dict; /* the instance dictionary -- must be last */
+ PyObject *weakreflist; /* list of weak references */
+
+ /*< private >*/
+ /* using union to preserve ABI compatibility (structure size
+ * must not change) */
+ union {
+ GSList *closures; /* stale field; no longer updated DO-NOT-USE! */
+ PyGObjectFlags flags;
+ } private_flags;
+
+} PyGObject;
+
+#define pygobject_get(v) (((PyGObject *)(v))->obj)
+#define pygobject_check(v,base) (PyObject_TypeCheck(v,base))
+
+typedef struct {
+ PyObject_HEAD
+ gpointer boxed;
+ GType gtype;
+ gboolean free_on_dealloc;
+} PyGBoxed;
+
+#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)
+
+typedef struct {
+ PyObject_HEAD
+ gpointer pointer;
+ GType gtype;
+} PyGPointer;
+
+#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);
+
+typedef struct {
+ PyObject_HEAD
+ GParamSpec *pspec;
+} PyGParamSpec;
+
+#define PyGParamSpec_Get(v) (((PyGParamSpec *)v)->pspec)
+#define PyGParamSpec_Check(v) (PyObject_TypeCheck(v, &PyGParamSpec_Type))
+
+typedef int (*PyGClassInitFunc) (gpointer gclass, PyTypeObject *pyclass);
+typedef PyTypeObject * (*PyGTypeRegistrationFunction) (const gchar *name,
+ gpointer data);
+
+struct _PyGObject_Functions {
+ /*
+ * All field names in here are considered private,
+ * use the macros below instead, which provides stability
+ */
+ void (* register_class)(PyObject *dict, const gchar *class_name,
+ GType gtype, PyTypeObject *type, PyObject *bases);
+ void (* register_wrapper)(PyObject *self);
+ PyTypeObject *(* lookup_class)(GType type);
+ PyObject *(* newgobj)(GObject *obj);
+
+ GClosure *(* closure_new)(PyObject *callback, PyObject *extra_args,
+ PyObject *swap_data);
+ void (* object_watch_closure)(PyObject *self, GClosure *closure);
+ GDestroyNotify destroy_notify;
+
+ GType (* type_from_object)(PyObject *obj);
+ PyObject *(* type_wrapper_new)(GType type);
+
+ gint (* enum_get_value)(GType enum_type, PyObject *obj, gint *val);
+ gint (* flags_get_value)(GType flag_type, PyObject *obj, gint *val);
+ void (* register_gtype_custom)(GType gtype,
+ PyObject *(* from_func)(const GValue *value),
+ int (* to_func)(GValue *value, PyObject *obj));
+ int (* value_from_pyobject)(GValue *value, PyObject *obj);
+ PyObject *(* value_as_pyobject)(const GValue *value, gboolean copy_boxed);
+
+ void (* register_interface)(PyObject *dict, const gchar *class_name,
+ GType gtype, PyTypeObject *type);
+
+ PyTypeObject *boxed_type;
+ void (* register_boxed)(PyObject *dict, const gchar *class_name,
+ GType boxed_type, PyTypeObject *type);
+ 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,
+ const gchar *strip_prefix);
+
+ const gchar *(* constant_strip_prefix)(const gchar *name,
+ const gchar *strip_prefix);
+
+ gboolean (* error_check)(GError **error);
+
+ /* hooks to register handlers for getting GDK threads to cooperate
+ * with python threading */
+ void (* set_thread_block_funcs) (PyGThreadBlockFunc block_threads_func,
+ PyGThreadBlockFunc unblock_threads_func);
+ PyGThreadBlockFunc block_threads;
+ PyGThreadBlockFunc unblock_threads;
+ PyTypeObject *paramspec_type;
+ PyObject *(* paramspec_new)(GParamSpec *spec);
+ GParamSpec *(*paramspec_get)(PyObject *tuple);
+ int (*pyobj_to_unichar_conv)(PyObject *pyobj, void* ptr);
+ gboolean (*parse_constructor_args)(GType obj_type,
+ char **arg_names,
+ char **prop_names,
+ GParameter *params,
+ guint *nparams,
+ PyObject **py_args);
+ PyObject *(* param_gvalue_as_pyobject) (const GValue* gvalue,
+ gboolean copy_boxed,
+ const GParamSpec* pspec);
+ int (* gvalue_from_param_pyobject) (GValue* value,
+ PyObject* py_obj,
+ const GParamSpec* pspec);
+ PyTypeObject *enum_type;
+ PyObject *(*enum_add)(PyObject *module,
+ const char *type_name_,
+ const char *strip_prefix,
+ GType gtype);
+ PyObject* (*enum_from_gtype)(GType gtype, int value);
+
+ PyTypeObject *flags_type;
+ PyObject *(*flags_add)(PyObject *module,
+ const char *type_name_,
+ const char *strip_prefix,
+ GType gtype);
+ PyObject* (*flags_from_gtype)(GType gtype, int value);
+
+ gboolean threads_enabled;
+ int (*enable_threads) (void);
+
+ int (*gil_state_ensure) (void);
+ void (*gil_state_release) (int flag);
+
+ void (*register_class_init) (GType gtype, PyGClassInitFunc class_init);
+ void (*register_interface_info) (GType gtype, const GInterfaceInfo *info);
+ void (*closure_set_exception_handler) (GClosure *closure, PyClosureExceptionHandler handler);
+
+ void (*add_warning_redirection) (const char *domain,
+ PyObject *warning);
+ void (*disable_warning_redirections) (void);
+ void (*type_register_custom)(const gchar *type_name,
+ PyGTypeRegistrationFunction callback,
+ gpointer data);
+ gboolean (*gerror_exception_check) (GError **error);
+ PyObject* (*option_group_new) (GOptionGroup *group);
+ GType (* type_from_object_strict) (PyObject *obj, gboolean strict);
+};
+
+#ifndef _INSIDE_PYGOBJECT_
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_PYGOBJECT)
+extern struct _PyGObject_Functions *_PyGObject_API;
+#else
+struct _PyGObject_Functions *_PyGObject_API;
+#endif
+
+#define pygobject_register_class (_PyGObject_API->register_class)
+#define pygobject_register_wrapper (_PyGObject_API->register_wrapper)
+#define pygobject_lookup_class (_PyGObject_API->lookup_class)
+#define pygobject_new (_PyGObject_API->newgobj)
+#define pyg_closure_new (_PyGObject_API->closure_new)
+#define pygobject_watch_closure (_PyGObject_API->object_watch_closure)
+#define pyg_closure_set_exception_handler (_PyGObject_API->closure_set_exception_handler)
+#define pyg_destroy_notify (_PyGObject_API->destroy_notify)
+#define pyg_type_from_object_strict (_PyGObject_API->type_from_object_strict)
+#define pyg_type_from_object (_PyGObject_API->type_from_object)
+#define pyg_type_wrapper_new (_PyGObject_API->type_wrapper_new)
+#define pyg_enum_get_value (_PyGObject_API->enum_get_value)
+#define pyg_flags_get_value (_PyGObject_API->flags_get_value)
+#define pyg_register_gtype_custom (_PyGObject_API->register_gtype_custom)
+#define pyg_value_from_pyobject (_PyGObject_API->value_from_pyobject)
+#define pyg_value_as_pyobject (_PyGObject_API->value_as_pyobject)
+#define pyg_register_interface (_PyGObject_API->register_interface)
+#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_error_check (_PyGObject_API->error_check)
+#define pyg_set_thread_block_funcs (_PyGObject_API->set_thread_block_funcs)
+#define PyGParamSpec_Type (*_PyGObject_API->paramspec_type)
+#define pyg_param_spec_new (_PyGObject_API->paramspec_new)
+#define pyg_param_spec_from_object (_PyGObject_API->paramspec_get)
+#define pyg_pyobj_to_unichar_conv (_PyGObject_API->pyobj_to_unichar_conv)
+#define pyg_parse_constructor_args (_PyGObject_API->parse_constructor_args)
+#define pyg_param_gvalue_as_pyobject (_PyGObject_API->value_as_pyobject)
+#define pyg_param_gvalue_from_pyobject (_PyGObject_API->gvalue_from_param_pyobject)
+#define PyGEnum_Type (*_PyGObject_API->enum_type)
+#define pyg_enum_add (_PyGObject_API->enum_add)
+#define pyg_enum_from_gtype (_PyGObject_API->enum_from_gtype)
+#define PyGFlags_Type (*_PyGObject_API->flags_type)
+#define pyg_flags_add (_PyGObject_API->flags_add)
+#define pyg_flags_from_gtype (_PyGObject_API->flags_from_gtype)
+#define pyg_enable_threads (_PyGObject_API->enable_threads)
+#define pyg_gil_state_ensure (_PyGObject_API->gil_state_ensure)
+#define pyg_gil_state_release (_PyGObject_API->gil_state_release)
+#define pyg_register_class_init (_PyGObject_API->register_class_init)
+#define pyg_register_interface_info (_PyGObject_API->register_interface_info)
+#define pyg_add_warning_redirection (_PyGObject_API->add_warning_redirection)
+#define pyg_disable_warning_redirections (_PyGObject_API->disable_warning_redirections)
+#define pyg_type_register_custom_callback (_PyGObject_API->type_register_custom)
+#define pyg_gerror_exception_check (_PyGObject_API->gerror_exception_check)
+#define pyg_option_group_new (_PyGObject_API->option_group_new)
+
+#define pyg_block_threads() G_STMT_START { \
+ if (_PyGObject_API->block_threads != NULL) \
+ (* _PyGObject_API->block_threads)(); \
+ } G_STMT_END
+#define pyg_unblock_threads() G_STMT_START { \
+ if (_PyGObject_API->unblock_threads != NULL) \
+ (* _PyGObject_API->unblock_threads)(); \
+ } G_STMT_END
+
+#define pyg_threads_enabled (_PyGObject_API->threads_enabled)
+
+#define pyg_begin_allow_threads \
+ G_STMT_START { \
+ PyThreadState *_save = NULL; \
+ if (_PyGObject_API->threads_enabled) \
+ _save = PyEval_SaveThread();
+#define pyg_end_allow_threads \
+ if (_PyGObject_API->threads_enabled) \
+ PyEval_RestoreThread(_save); \
+ } G_STMT_END
+
+
+/**
+ * pygobject_init:
+ * @req_major: minimum version major number, or -1
+ * @req_minor: minimum version minor number, or -1
+ * @req_micro: minimum version micro number, or -1
+ *
+ * Imports and initializes the 'gobject' python module. Can
+ * optionally check for a required minimum version if @req_major,
+ * @req_minor, and @req_micro are all different from -1.
+ *
+ * Returns: a new reference to the gobject module on success, NULL in
+ * case of failure (and raises ImportError).
+ **/
+static inline PyObject *
+pygobject_init(int req_major, int req_minor, int req_micro)
+{
+ PyObject *gobject, *cobject;
+
+ gobject = PyImport_ImportModule("gi._gobject");
+ if (!gobject) {
+ if (PyErr_Occurred())
+ {
+ PyObject *type, *value, *traceback;
+ PyObject *py_orig_exc;
+ PyErr_Fetch(&type, &value, &traceback);
+ py_orig_exc = PyObject_Repr(value);
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+
+
+#if PY_VERSION_HEX < 0x03000000
+ PyErr_Format(PyExc_ImportError,
+ "could not import gobject (error was: %s)",
+ PyString_AsString(py_orig_exc));
+#else
+ {
+ /* Can not use PyErr_Format because it doesn't have
+ * a format string for dealing with PyUnicode objects
+ * like PyUnicode_FromFormat has
+ */
+ PyObject *errmsg = PyUnicode_FromFormat("could not import gobject (error was: %U)",
+ py_orig_exc);
+
+ if (errmsg) {
+ PyErr_SetObject(PyExc_ImportError,
+ errmsg);
+ Py_DECREF(errmsg);
+ }
+ /* if errmsg is NULL then we might have OOM
+ * PyErr should already be set and trying to
+ * return our own error would be futile
+ */
+ }
+#endif
+ Py_DECREF(py_orig_exc);
+ } else {
+ PyErr_SetString(PyExc_ImportError,
+ "could not import gobject (no error given)");
+ }
+ return NULL;
+ }
+
+ cobject = PyObject_GetAttrString(gobject, "_PyGObject_API");
+#if PY_VERSION_HEX >= 0x03000000
+ if (cobject && PyCapsule_CheckExact(cobject))
+ _PyGObject_API = (struct _PyGObject_Functions *) PyCapsule_GetPointer(cobject, "gobject._PyGObject_API");
+
+#else
+ if (cobject && PyCObject_Check(cobject))
+ _PyGObject_API = (struct _PyGObject_Functions *) PyCObject_AsVoidPtr(cobject);
+#endif
+ else {
+ PyErr_SetString(PyExc_ImportError,
+ "could not import gobject (could not find _PyGObject_API object)");
+ Py_DECREF(gobject);
+ return NULL;
+ }
+
+ if (req_major != -1)
+ {
+ int found_major, found_minor, found_micro;
+ PyObject *version;
+
+ version = PyObject_GetAttrString(gobject, "pygobject_version");
+ if (!version) {
+ PyErr_SetString(PyExc_ImportError,
+ "could not import gobject (version too old)");
+ Py_DECREF(gobject);
+ return NULL;
+ }
+ if (!PyArg_ParseTuple(version, "iii",
+ &found_major, &found_minor, &found_micro)) {
+ PyErr_SetString(PyExc_ImportError,
+ "could not import gobject (version has invalid format)");
+ Py_DECREF(version);
+ Py_DECREF(gobject);
+ return NULL;
+ }
+ Py_DECREF(version);
+ if (req_major != found_major ||
+ req_minor > found_minor ||
+ (req_minor == found_minor && req_micro > found_micro)) {
+ PyErr_Format(PyExc_ImportError,
+ "could not import gobject (version mismatch, %d.%d.%d is required, "
+ "found %d.%d.%d)", req_major, req_minor, req_micro,
+ found_major, found_minor, found_micro);
+ Py_DECREF(gobject);
+ return NULL;
+ }
+ }
+ return gobject;
+}
+
+/**
+ * PYLIST_FROMGLIBLIST:
+ * @type: the type of the GLib list e.g. #GList or #GSList
+ * @prefix: the prefix of functions that manipulate a list of the type
+ * given by type.
+ *
+ * A macro that creates a type specific code block which converts a GLib
+ * list (#GSList or #GList) to a Python list. The first two args of the macro
+ * are used to specify the type and list function prefix so that the type
+ * specific macros can be generated.
+ *
+ * The rest of the args are for the standard args for the type specific
+ * macro(s) created from this macro.
+ */
+ #define PYLIST_FROMGLIBLIST(type,prefix,py_list,list,item_convert_func,\
+ list_free,list_item_free) \
+G_STMT_START \
+{ \
+ gint i, len; \
+ PyObject *item; \
+ void (*glib_list_free)(type*) = list_free; \
+ GFunc glib_list_item_free = (GFunc)list_item_free; \
+ \
+ len = prefix##_length(list); \
+ py_list = PyList_New(len); \
+ for (i = 0; i < len; i++) { \
+ gpointer list_item = prefix##_nth_data(list, i); \
+ \
+ item = item_convert_func; \
+ PyList_SetItem(py_list, i, item); \
+ } \
+ if (glib_list_item_free != NULL) \
+ prefix##_foreach(list, glib_list_item_free, NULL); \
+ if (glib_list_free != NULL) \
+ glib_list_free(list); \
+} G_STMT_END
+
+/**
+ * PYLIST_FROMGLIST:
+ * @py_list: the name of the Python list
+ *
+ * @list: the #GList to be converted to a Python list
+ *
+ * @item_convert_func: the function that converts a list item to a Python
+ * object. The function must refer to the list item using "@list_item" and
+ * must return a #PyObject* object. An example conversion function is:
+ * [[
+ * PyString_FromString(list_item)
+ * ]]
+ * A more elaborate function is:
+ * [[
+ * pyg_boxed_new(GTK_TYPE_RECENT_INFO, list_item, TRUE, TRUE)
+ * ]]
+ * @list_free: the name of a function that takes a single arg (the list) and
+ * frees its memory. Can be NULL if the list should not be freed. An example
+ * is:
+ * [[
+ * g_list_free
+ * ]]
+ * @list_item_free: the name of a #GFunc function that frees the memory used
+ * by the items in the list or %NULL if the list items do not have to be
+ * freed. A simple example is:
+ * [[
+ * g_free
+ * ]]
+ *
+ * A macro that adds code that converts a #GList to a Python list.
+ *
+ */
+#define PYLIST_FROMGLIST(py_list,list,item_convert_func,list_free,\
+ list_item_free) \
+ PYLIST_FROMGLIBLIST(GList,g_list,py_list,list,item_convert_func,\
+ list_free,list_item_free)
+
+/**
+ * PYLIST_FROMGSLIST:
+ * @py_list: the name of the Python list
+ *
+ * @list: the #GSList to be converted to a Python list
+ *
+ * @item_convert_func: the function that converts a list item to a Python
+ * object. The function must refer to the list item using "@list_item" and
+ * must return a #PyObject* object. An example conversion function is:
+ * [[
+ * PyString_FromString(list_item)
+ * ]]
+ * A more elaborate function is:
+ * [[
+ * pyg_boxed_new(GTK_TYPE_RECENT_INFO, list_item, TRUE, TRUE)
+ * ]]
+ * @list_free: the name of a function that takes a single arg (the list) and
+ * frees its memory. Can be %NULL if the list should not be freed. An example
+ * is:
+ * [[
+ * g_list_free
+ * ]]
+ * @list_item_free: the name of a #GFunc function that frees the memory used
+ * by the items in the list or %NULL if the list items do not have to be
+ * freed. A simple example is:
+ * [[
+ * g_free
+ * ]]
+ *
+ * A macro that adds code that converts a #GSList to a Python list.
+ *
+ */
+#define PYLIST_FROMGSLIST(py_list,list,item_convert_func,list_free,\
+ list_item_free) \
+ PYLIST_FROMGLIBLIST(GSList,g_slist,py_list,list,item_convert_func,\
+ list_free,list_item_free)
+
+/**
+ * PYLIST_ASGLIBLIST
+ * @type: the type of the GLib list e.g. GList or GSList
+ * @prefix: the prefix of functions that manipulate a list of the type
+ * given by type e.g. g_list or g_slist
+ *
+ * A macro that creates a type specific code block to be used to convert a
+ * Python list to a GLib list (GList or GSList). The first two args of the
+ * macro are used to specify the type and list function prefix so that the
+ * type specific macros can be generated.
+ *
+ * The rest of the args are for the standard args for the type specific
+ * macro(s) created from this macro.
+ */
+#define PYLIST_ASGLIBLIST(type,prefix,py_list,list,check_func,\
+ convert_func,child_free_func,errormsg,errorreturn) \
+G_STMT_START \
+{ \
+ Py_ssize_t i, n_list; \
+ GFunc glib_child_free_func = (GFunc)child_free_func; \
+ \
+ if (!(py_list = PySequence_Fast(py_list, ""))) { \
+ errormsg; \
+ return errorreturn; \
+ } \
+ n_list = PySequence_Fast_GET_SIZE(py_list); \
+ for (i = 0; i < n_list; i++) { \
+ PyObject *py_item = PySequence_Fast_GET_ITEM(py_list, i); \
+ \
+ if (!check_func) { \
+ if (glib_child_free_func) \
+ prefix##_foreach(list, glib_child_free_func, NULL); \
+ prefix##_free(list); \
+ Py_DECREF(py_list); \
+ errormsg; \
+ return errorreturn; \
+ } \
+ list = prefix##_prepend(list, convert_func); \
+ }; \
+ Py_DECREF(py_list); \
+ list = prefix##_reverse(list); \
+} \
+G_STMT_END
+/**
+ * PYLIST_ASGLIST
+ * @py_list: the Python list to be converted
+ * @list: the #GList list to be converted
+ * @check_func: the expression that takes a #PyObject* arg (must be named
+ * @py_item) and returns an int value indicating if the Python object matches
+ * the required list item type (0 - %False or 1 - %True). An example is:
+ * [[
+ * (PyString_Check(py_item)||PyUnicode_Check(py_item))
+ * ]]
+ * @convert_func: the function that takes a #PyObject* arg (must be named
+ * py_item) and returns a pointer to the converted list object. An example
+ * is:
+ * [[
+ * pygobject_get(py_item)
+ * ]]
+ * @child_free_func: the name of a #GFunc function that frees a GLib list
+ * item or %NULL if the list item does not have to be freed. This function is
+ * used to help free the items in a partially created list if there is an
+ * error. An example is:
+ * [[
+ * g_free
+ * ]]
+ * @errormsg: a function that sets up a Python error message. An example is:
+ * [[
+ * PyErr_SetString(PyExc_TypeError, "strings must be a sequence of" "strings
+ * or unicode objects")
+ * ]]
+ * @errorreturn: the value to return if an error occurs, e.g.:
+ * [[
+ * %NULL
+ * ]]
+ *
+ * A macro that creates code that converts a Python list to a #GList. The
+ * returned list must be freed using the appropriate list free function when
+ * it's no longer needed. If an error occurs the child_free_func is used to
+ * release the memory used by the list items and then the list memory is
+ * freed.
+ */
+#define PYLIST_ASGLIST(py_list,list,check_func,convert_func,child_free_func,\
+ errormsg,errorreturn) \
+ PYLIST_ASGLIBLIST(GList,g_list,py_list,list,check_func,convert_func,\
+ child_free_func,errormsg,errorreturn)
+
+/**
+ * PYLIST_ASGSLIST
+ * @py_list: the Python list to be converted
+ * @list: the #GSList list to be converted
+ * @check_func: the expression that takes a #PyObject* arg (must be named
+ * @py_item) and returns an int value indicating if the Python object matches
+ * the required list item type (0 - %False or 1 - %True). An example is:
+ * [[
+ * (PyString_Check(py_item)||PyUnicode_Check(py_item))
+ * ]]
+ * @convert_func: the function that takes a #PyObject* arg (must be named
+ * py_item) and returns a pointer to the converted list object. An example
+ * is:
+ * [[
+ * pygobject_get(py_item)
+ * ]]
+ * @child_free_func: the name of a #GFunc function that frees a GLib list
+ * item or %NULL if the list item does not have to be freed. This function is
+ * used to help free the items in a partially created list if there is an
+ * error. An example is:
+ * [[
+ * g_free
+ * ]]
+ * @errormsg: a function that sets up a Python error message. An example is:
+ * [[
+ * PyErr_SetString(PyExc_TypeError, "strings must be a sequence of" "strings
+ * or unicode objects")
+ * ]]
+ * @errorreturn: the value to return if an error occurs, e.g.:
+ * [[
+ * %NULL
+ * ]]
+ *
+ * A macro that creates code that converts a Python list to a #GSList. The
+ * returned list must be freed using the appropriate list free function when
+ * it's no longer needed. If an error occurs the child_free_func is used to
+ * release the memory used by the list items and then the list memory is
+ * freed.
+ */
+#define PYLIST_ASGSLIST(py_list,list,check_func,convert_func,child_free_func,\
+ errormsg,errorreturn) \
+ PYLIST_ASGLIBLIST(GSList,g_slist,py_list,list,check_func,convert_func,\
+ child_free_func,errormsg,errorreturn)
+
+#endif /* !_INSIDE_PYGOBJECT_ */
+
+G_END_DECLS
+
+#endif /* !_PYGOBJECT_H_ */