/*
 * Generated by gdbus-codegen 2.49.4. DO NOT EDIT.
 *
 * The license of this code is the same as for the source it was derived from.
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include "./xdp-dbus.h"

#include <string.h>
#ifdef G_OS_UNIX
#  include <gio/gunixfdlist.h>
#endif

typedef struct
{
  GDBusArgInfo parent_struct;
  gboolean use_gvariant;
} _ExtendedGDBusArgInfo;

typedef struct
{
  GDBusMethodInfo parent_struct;
  const gchar *signal_name;
  gboolean pass_fdlist;
} _ExtendedGDBusMethodInfo;

typedef struct
{
  GDBusSignalInfo parent_struct;
  const gchar *signal_name;
} _ExtendedGDBusSignalInfo;

typedef struct
{
  GDBusPropertyInfo parent_struct;
  const gchar *hyphen_name;
  gboolean use_gvariant;
} _ExtendedGDBusPropertyInfo;

typedef struct
{
  GDBusInterfaceInfo parent_struct;
  const gchar *hyphen_name;
} _ExtendedGDBusInterfaceInfo;

typedef struct
{
  const _ExtendedGDBusPropertyInfo *info;
  guint prop_id;
  GValue orig_value; /* the value before the change */
} ChangedProperty;

static void
_changed_property_free (ChangedProperty *data)
{
  g_value_unset (&data->orig_value);
  g_free (data);
}

static gboolean
_g_strv_equal0 (gchar **a, gchar **b)
{
  gboolean ret = FALSE;
  guint n;
  if (a == NULL && b == NULL)
    {
      ret = TRUE;
      goto out;
    }
  if (a == NULL || b == NULL)
    goto out;
  if (g_strv_length (a) != g_strv_length (b))
    goto out;
  for (n = 0; a[n] != NULL; n++)
    if (g_strcmp0 (a[n], b[n]) != 0)
      goto out;
  ret = TRUE;
out:
  return ret;
}

static gboolean
_g_variant_equal0 (GVariant *a, GVariant *b)
{
  gboolean ret = FALSE;
  if (a == NULL && b == NULL)
    {
      ret = TRUE;
      goto out;
    }
  if (a == NULL || b == NULL)
    goto out;
  ret = g_variant_equal (a, b);
out:
  return ret;
}

G_GNUC_UNUSED static gboolean
_g_value_equal (const GValue *a, const GValue *b)
{
  gboolean ret = FALSE;
  g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));
  switch (G_VALUE_TYPE (a))
    {
      case G_TYPE_BOOLEAN:
        ret = (g_value_get_boolean (a) == g_value_get_boolean (b));
        break;
      case G_TYPE_UCHAR:
        ret = (g_value_get_uchar (a) == g_value_get_uchar (b));
        break;
      case G_TYPE_INT:
        ret = (g_value_get_int (a) == g_value_get_int (b));
        break;
      case G_TYPE_UINT:
        ret = (g_value_get_uint (a) == g_value_get_uint (b));
        break;
      case G_TYPE_INT64:
        ret = (g_value_get_int64 (a) == g_value_get_int64 (b));
        break;
      case G_TYPE_UINT64:
        ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));
        break;
      case G_TYPE_DOUBLE:
        {
          /* Avoid -Wfloat-equal warnings by doing a direct bit compare */
          gdouble da = g_value_get_double (a);
          gdouble db = g_value_get_double (b);
          ret = memcmp (&da, &db, sizeof (gdouble)) == 0;
        }
        break;
      case G_TYPE_STRING:
        ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);
        break;
      case G_TYPE_VARIANT:
        ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));
        break;
      default:
        if (G_VALUE_TYPE (a) == G_TYPE_STRV)
          ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));
        else
          g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));
        break;
    }
  return ret;
}

/* ------------------------------------------------------------------------
 * Code for interface org.freedesktop.portal.Documents
 * ------------------------------------------------------------------------
 */

/**
 * SECTION:GXdpDocuments
 * @title: GXdpDocuments
 * @short_description: Generated C code for the org.freedesktop.portal.Documents D-Bus interface
 *
 * This section contains code for working with the <link linkend="gdbus-interface-org-freedesktop-portal-Documents.top_of_page">org.freedesktop.portal.Documents</link> D-Bus interface in C.
 */

/* ---- Introspection data for org.freedesktop.portal.Documents ---- */

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_get_mount_point_OUT_ARG_path =
{
  {
    -1,
    (gchar *) "path",
    (gchar *) "ay",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_get_mount_point_OUT_ARG_pointers[] =
{
  &_gxdp_documents_method_info_get_mount_point_OUT_ARG_path,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_get_mount_point =
{
  {
    -1,
    (gchar *) "GetMountPoint",
    NULL,
    (GDBusArgInfo **) &_gxdp_documents_method_info_get_mount_point_OUT_ARG_pointers,
    NULL
  },
  "handle-get-mount-point",
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_IN_ARG_o_path_fd =
{
  {
    -1,
    (gchar *) "o_path_fd",
    (gchar *) "h",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_IN_ARG_reuse_existing =
{
  {
    -1,
    (gchar *) "reuse_existing",
    (gchar *) "b",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_IN_ARG_persistent =
{
  {
    -1,
    (gchar *) "persistent",
    (gchar *) "b",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_add_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_add_IN_ARG_o_path_fd,
  &_gxdp_documents_method_info_add_IN_ARG_reuse_existing,
  &_gxdp_documents_method_info_add_IN_ARG_persistent,
  NULL
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_OUT_ARG_doc_id =
{
  {
    -1,
    (gchar *) "doc_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_add_OUT_ARG_pointers[] =
{
  &_gxdp_documents_method_info_add_OUT_ARG_doc_id,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_add =
{
  {
    -1,
    (gchar *) "Add",
    (GDBusArgInfo **) &_gxdp_documents_method_info_add_IN_ARG_pointers,
    (GDBusArgInfo **) &_gxdp_documents_method_info_add_OUT_ARG_pointers,
    NULL
  },
  "handle-add",
  TRUE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_named_IN_ARG_o_path_parent_fd =
{
  {
    -1,
    (gchar *) "o_path_parent_fd",
    (gchar *) "h",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_named_IN_ARG_filename =
{
  {
    -1,
    (gchar *) "filename",
    (gchar *) "ay",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_named_IN_ARG_reuse_existing =
{
  {
    -1,
    (gchar *) "reuse_existing",
    (gchar *) "b",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_named_IN_ARG_persistent =
{
  {
    -1,
    (gchar *) "persistent",
    (gchar *) "b",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_add_named_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_add_named_IN_ARG_o_path_parent_fd,
  &_gxdp_documents_method_info_add_named_IN_ARG_filename,
  &_gxdp_documents_method_info_add_named_IN_ARG_reuse_existing,
  &_gxdp_documents_method_info_add_named_IN_ARG_persistent,
  NULL
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_add_named_OUT_ARG_doc_id =
{
  {
    -1,
    (gchar *) "doc_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_add_named_OUT_ARG_pointers[] =
{
  &_gxdp_documents_method_info_add_named_OUT_ARG_doc_id,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_add_named =
{
  {
    -1,
    (gchar *) "AddNamed",
    (GDBusArgInfo **) &_gxdp_documents_method_info_add_named_IN_ARG_pointers,
    (GDBusArgInfo **) &_gxdp_documents_method_info_add_named_OUT_ARG_pointers,
    NULL
  },
  "handle-add-named",
  TRUE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_grant_permissions_IN_ARG_doc_id =
{
  {
    -1,
    (gchar *) "doc_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_grant_permissions_IN_ARG_app_id =
{
  {
    -1,
    (gchar *) "app_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_grant_permissions_IN_ARG_permissions =
{
  {
    -1,
    (gchar *) "permissions",
    (gchar *) "as",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_grant_permissions_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_grant_permissions_IN_ARG_doc_id,
  &_gxdp_documents_method_info_grant_permissions_IN_ARG_app_id,
  &_gxdp_documents_method_info_grant_permissions_IN_ARG_permissions,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_grant_permissions =
{
  {
    -1,
    (gchar *) "GrantPermissions",
    (GDBusArgInfo **) &_gxdp_documents_method_info_grant_permissions_IN_ARG_pointers,
    NULL,
    NULL
  },
  "handle-grant-permissions",
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_revoke_permissions_IN_ARG_doc_id =
{
  {
    -1,
    (gchar *) "doc_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_revoke_permissions_IN_ARG_app_id =
{
  {
    -1,
    (gchar *) "app_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_revoke_permissions_IN_ARG_permissions =
{
  {
    -1,
    (gchar *) "permissions",
    (gchar *) "as",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_revoke_permissions_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_revoke_permissions_IN_ARG_doc_id,
  &_gxdp_documents_method_info_revoke_permissions_IN_ARG_app_id,
  &_gxdp_documents_method_info_revoke_permissions_IN_ARG_permissions,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_revoke_permissions =
{
  {
    -1,
    (gchar *) "RevokePermissions",
    (GDBusArgInfo **) &_gxdp_documents_method_info_revoke_permissions_IN_ARG_pointers,
    NULL,
    NULL
  },
  "handle-revoke-permissions",
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_delete_IN_ARG_doc_id =
{
  {
    -1,
    (gchar *) "doc_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_delete_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_delete_IN_ARG_doc_id,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_delete =
{
  {
    -1,
    (gchar *) "Delete",
    (GDBusArgInfo **) &_gxdp_documents_method_info_delete_IN_ARG_pointers,
    NULL,
    NULL
  },
  "handle-delete",
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_lookup_IN_ARG_filename =
{
  {
    -1,
    (gchar *) "filename",
    (gchar *) "ay",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_lookup_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_lookup_IN_ARG_filename,
  NULL
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_lookup_OUT_ARG_doc_id =
{
  {
    -1,
    (gchar *) "doc_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_lookup_OUT_ARG_pointers[] =
{
  &_gxdp_documents_method_info_lookup_OUT_ARG_doc_id,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_lookup =
{
  {
    -1,
    (gchar *) "Lookup",
    (GDBusArgInfo **) &_gxdp_documents_method_info_lookup_IN_ARG_pointers,
    (GDBusArgInfo **) &_gxdp_documents_method_info_lookup_OUT_ARG_pointers,
    NULL
  },
  "handle-lookup",
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_info_IN_ARG_doc_id =
{
  {
    -1,
    (gchar *) "doc_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_info_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_info_IN_ARG_doc_id,
  NULL
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_info_OUT_ARG_path =
{
  {
    -1,
    (gchar *) "path",
    (gchar *) "ay",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_info_OUT_ARG_apps =
{
  {
    -1,
    (gchar *) "apps",
    (gchar *) "a{sas}",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_info_OUT_ARG_pointers[] =
{
  &_gxdp_documents_method_info_info_OUT_ARG_path,
  &_gxdp_documents_method_info_info_OUT_ARG_apps,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_info =
{
  {
    -1,
    (gchar *) "Info",
    (GDBusArgInfo **) &_gxdp_documents_method_info_info_IN_ARG_pointers,
    (GDBusArgInfo **) &_gxdp_documents_method_info_info_OUT_ARG_pointers,
    NULL
  },
  "handle-info",
  FALSE
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_list_IN_ARG_app_id =
{
  {
    -1,
    (gchar *) "app_id",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_list_IN_ARG_pointers[] =
{
  &_gxdp_documents_method_info_list_IN_ARG_app_id,
  NULL
};

static const _ExtendedGDBusArgInfo _gxdp_documents_method_info_list_OUT_ARG_docs =
{
  {
    -1,
    (gchar *) "docs",
    (gchar *) "a{say}",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_documents_method_info_list_OUT_ARG_pointers[] =
{
  &_gxdp_documents_method_info_list_OUT_ARG_docs,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_documents_method_info_list =
{
  {
    -1,
    (gchar *) "List",
    (GDBusArgInfo **) &_gxdp_documents_method_info_list_IN_ARG_pointers,
    (GDBusArgInfo **) &_gxdp_documents_method_info_list_OUT_ARG_pointers,
    NULL
  },
  "handle-list",
  FALSE
};

static const _ExtendedGDBusMethodInfo * const _gxdp_documents_method_info_pointers[] =
{
  &_gxdp_documents_method_info_get_mount_point,
  &_gxdp_documents_method_info_add,
  &_gxdp_documents_method_info_add_named,
  &_gxdp_documents_method_info_grant_permissions,
  &_gxdp_documents_method_info_revoke_permissions,
  &_gxdp_documents_method_info_delete,
  &_gxdp_documents_method_info_lookup,
  &_gxdp_documents_method_info_info,
  &_gxdp_documents_method_info_list,
  NULL
};

static const _ExtendedGDBusInterfaceInfo _gxdp_documents_interface_info =
{
  {
    -1,
    (gchar *) "org.freedesktop.portal.Documents",
    (GDBusMethodInfo **) &_gxdp_documents_method_info_pointers,
    NULL,
    NULL,
    NULL
  },
  "documents",
};


/**
 * gxdp_documents_interface_info:
 *
 * Gets a machine-readable description of the <link linkend="gdbus-interface-org-freedesktop-portal-Documents.top_of_page">org.freedesktop.portal.Documents</link> D-Bus interface.
 *
 * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
 */
GDBusInterfaceInfo *
gxdp_documents_interface_info (void)
{
  return (GDBusInterfaceInfo *) &_gxdp_documents_interface_info.parent_struct;
}

/**
 * gxdp_documents_override_properties:
 * @klass: The class structure for a #GObject<!-- -->-derived class.
 * @property_id_begin: The property id to assign to the first overridden property.
 *
 * Overrides all #GObject properties in the #GXdpDocuments interface for a concrete class.
 * The properties are overridden in the order they are defined.
 *
 * Returns: The last property id.
 */
guint
gxdp_documents_override_properties (GObjectClass *klass, guint property_id_begin)
{
  return property_id_begin - 1;
}



/**
 * GXdpDocuments:
 *
 * Abstract interface type for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-Documents.top_of_page">org.freedesktop.portal.Documents</link>.
 */

/**
 * GXdpDocumentsIface:
 * @parent_iface: The parent interface.
 * @handle_add: Handler for the #GXdpDocuments::handle-add signal.
 * @handle_add_named: Handler for the #GXdpDocuments::handle-add-named signal.
 * @handle_delete: Handler for the #GXdpDocuments::handle-delete signal.
 * @handle_get_mount_point: Handler for the #GXdpDocuments::handle-get-mount-point signal.
 * @handle_grant_permissions: Handler for the #GXdpDocuments::handle-grant-permissions signal.
 * @handle_info: Handler for the #GXdpDocuments::handle-info signal.
 * @handle_list: Handler for the #GXdpDocuments::handle-list signal.
 * @handle_lookup: Handler for the #GXdpDocuments::handle-lookup signal.
 * @handle_revoke_permissions: Handler for the #GXdpDocuments::handle-revoke-permissions signal.
 *
 * Virtual table for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-Documents.top_of_page">org.freedesktop.portal.Documents</link>.
 */

typedef GXdpDocumentsIface GXdpDocumentsInterface;
G_DEFINE_INTERFACE (GXdpDocuments, gxdp_documents, G_TYPE_OBJECT);

static void
gxdp_documents_default_init (GXdpDocumentsIface *iface)
{
  /* GObject signals for incoming D-Bus method calls: */
  /**
   * GXdpDocuments::handle-get-mount-point:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GetMountPoint">GetMountPoint()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_get_mount_point() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-get-mount-point",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_get_mount_point),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    1,
    G_TYPE_DBUS_METHOD_INVOCATION);

  /**
   * GXdpDocuments::handle-add:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @fd_list: (allow-none): A #GUnixFDList or %NULL.
   * @arg_o_path_fd: Argument passed by remote caller.
   * @arg_reuse_existing: Argument passed by remote caller.
   * @arg_persistent: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Add">Add()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-add",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_add),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    5,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_UNIX_FD_LIST, G_TYPE_VARIANT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);

  /**
   * GXdpDocuments::handle-add-named:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @fd_list: (allow-none): A #GUnixFDList or %NULL.
   * @arg_o_path_parent_fd: Argument passed by remote caller.
   * @arg_filename: Argument passed by remote caller.
   * @arg_reuse_existing: Argument passed by remote caller.
   * @arg_persistent: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.AddNamed">AddNamed()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add_named() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-add-named",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_add_named),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    6,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_UNIX_FD_LIST, G_TYPE_VARIANT, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);

  /**
   * GXdpDocuments::handle-grant-permissions:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @arg_doc_id: Argument passed by remote caller.
   * @arg_app_id: Argument passed by remote caller.
   * @arg_permissions: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GrantPermissions">GrantPermissions()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_grant_permissions() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-grant-permissions",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_grant_permissions),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    4,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRV);

  /**
   * GXdpDocuments::handle-revoke-permissions:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @arg_doc_id: Argument passed by remote caller.
   * @arg_app_id: Argument passed by remote caller.
   * @arg_permissions: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.RevokePermissions">RevokePermissions()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_revoke_permissions() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-revoke-permissions",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_revoke_permissions),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    4,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRV);

  /**
   * GXdpDocuments::handle-delete:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @arg_doc_id: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Delete">Delete()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_delete() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-delete",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_delete),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    2,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING);

  /**
   * GXdpDocuments::handle-lookup:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @arg_filename: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Lookup">Lookup()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_lookup() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-lookup",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_lookup),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    2,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING);

  /**
   * GXdpDocuments::handle-info:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @arg_doc_id: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Info">Info()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_info() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-info",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_info),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    2,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING);

  /**
   * GXdpDocuments::handle-list:
   * @object: A #GXdpDocuments.
   * @invocation: A #GDBusMethodInvocation.
   * @arg_app_id: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-Documents.List">List()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_list() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-list",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpDocumentsIface, handle_list),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    2,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING);

}

/**
 * gxdp_documents_call_get_mount_point:
 * @proxy: A #GXdpDocumentsProxy.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GetMountPoint">GetMountPoint()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_get_mount_point_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_get_mount_point_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_get_mount_point (
    GXdpDocuments *proxy,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "GetMountPoint",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_get_mount_point_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @out_path: (out): Return location for return parameter or %NULL to ignore.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_get_mount_point().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_get_mount_point().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_get_mount_point_finish (
    GXdpDocuments *proxy,
    gchar **out_path,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(^ay)",
                 out_path);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_get_mount_point_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @out_path: (out): Return location for return parameter or %NULL to ignore.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GetMountPoint">GetMountPoint()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_get_mount_point() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_get_mount_point_sync (
    GXdpDocuments *proxy,
    gchar **out_path,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "GetMountPoint",
    g_variant_new ("()"),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(^ay)",
                 out_path);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_add:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_o_path_fd: Argument to pass with the method invocation.
 * @arg_reuse_existing: Argument to pass with the method invocation.
 * @arg_persistent: Argument to pass with the method invocation.
 * @fd_list: (allow-none): A #GUnixFDList or %NULL.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Add">Add()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_add_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_add_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_add (
    GXdpDocuments *proxy,
    GVariant *arg_o_path_fd,
    gboolean arg_reuse_existing,
    gboolean arg_persistent,
    GUnixFDList *fd_list,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call_with_unix_fd_list (G_DBUS_PROXY (proxy),
    "Add",
    g_variant_new ("(@hbb)",
                   arg_o_path_fd,
                   arg_reuse_existing,
                   arg_persistent),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    fd_list,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_add_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @out_doc_id: (out): Return location for return parameter or %NULL to ignore.
 * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_add().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_add().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_add_finish (
    GXdpDocuments *proxy,
    gchar **out_doc_id,
    GUnixFDList **out_fd_list,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_with_unix_fd_list_finish (G_DBUS_PROXY (proxy), out_fd_list, res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(s)",
                 out_doc_id);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_add_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_o_path_fd: Argument to pass with the method invocation.
 * @arg_reuse_existing: Argument to pass with the method invocation.
 * @arg_persistent: Argument to pass with the method invocation.
 * @fd_list: (allow-none): A #GUnixFDList or %NULL.
 * @out_doc_id: (out): Return location for return parameter or %NULL to ignore.
 * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Add">Add()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_add() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_add_sync (
    GXdpDocuments *proxy,
    GVariant *arg_o_path_fd,
    gboolean arg_reuse_existing,
    gboolean arg_persistent,
    GUnixFDList  *fd_list,
    gchar **out_doc_id,
    GUnixFDList **out_fd_list,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (proxy),
    "Add",
    g_variant_new ("(@hbb)",
                   arg_o_path_fd,
                   arg_reuse_existing,
                   arg_persistent),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    fd_list,
    out_fd_list,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(s)",
                 out_doc_id);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_add_named:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_o_path_parent_fd: Argument to pass with the method invocation.
 * @arg_filename: Argument to pass with the method invocation.
 * @arg_reuse_existing: Argument to pass with the method invocation.
 * @arg_persistent: Argument to pass with the method invocation.
 * @fd_list: (allow-none): A #GUnixFDList or %NULL.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.AddNamed">AddNamed()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_add_named_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_add_named_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_add_named (
    GXdpDocuments *proxy,
    GVariant *arg_o_path_parent_fd,
    const gchar *arg_filename,
    gboolean arg_reuse_existing,
    gboolean arg_persistent,
    GUnixFDList *fd_list,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call_with_unix_fd_list (G_DBUS_PROXY (proxy),
    "AddNamed",
    g_variant_new ("(@h^aybb)",
                   arg_o_path_parent_fd,
                   arg_filename,
                   arg_reuse_existing,
                   arg_persistent),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    fd_list,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_add_named_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @out_doc_id: (out): Return location for return parameter or %NULL to ignore.
 * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_add_named().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_add_named().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_add_named_finish (
    GXdpDocuments *proxy,
    gchar **out_doc_id,
    GUnixFDList **out_fd_list,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_with_unix_fd_list_finish (G_DBUS_PROXY (proxy), out_fd_list, res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(s)",
                 out_doc_id);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_add_named_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_o_path_parent_fd: Argument to pass with the method invocation.
 * @arg_filename: Argument to pass with the method invocation.
 * @arg_reuse_existing: Argument to pass with the method invocation.
 * @arg_persistent: Argument to pass with the method invocation.
 * @fd_list: (allow-none): A #GUnixFDList or %NULL.
 * @out_doc_id: (out): Return location for return parameter or %NULL to ignore.
 * @out_fd_list: (out): Return location for a #GUnixFDList or %NULL.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.AddNamed">AddNamed()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_add_named() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_add_named_sync (
    GXdpDocuments *proxy,
    GVariant *arg_o_path_parent_fd,
    const gchar *arg_filename,
    gboolean arg_reuse_existing,
    gboolean arg_persistent,
    GUnixFDList  *fd_list,
    gchar **out_doc_id,
    GUnixFDList **out_fd_list,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_with_unix_fd_list_sync (G_DBUS_PROXY (proxy),
    "AddNamed",
    g_variant_new ("(@h^aybb)",
                   arg_o_path_parent_fd,
                   arg_filename,
                   arg_reuse_existing,
                   arg_persistent),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    fd_list,
    out_fd_list,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(s)",
                 out_doc_id);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_grant_permissions:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @arg_app_id: Argument to pass with the method invocation.
 * @arg_permissions: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GrantPermissions">GrantPermissions()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_grant_permissions_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_grant_permissions_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_grant_permissions (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    const gchar *arg_app_id,
    const gchar *const *arg_permissions,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "GrantPermissions",
    g_variant_new ("(ss^as)",
                   arg_doc_id,
                   arg_app_id,
                   arg_permissions),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_grant_permissions_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_grant_permissions().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_grant_permissions().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_grant_permissions_finish (
    GXdpDocuments *proxy,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_grant_permissions_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @arg_app_id: Argument to pass with the method invocation.
 * @arg_permissions: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GrantPermissions">GrantPermissions()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_grant_permissions() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_grant_permissions_sync (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    const gchar *arg_app_id,
    const gchar *const *arg_permissions,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "GrantPermissions",
    g_variant_new ("(ss^as)",
                   arg_doc_id,
                   arg_app_id,
                   arg_permissions),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_revoke_permissions:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @arg_app_id: Argument to pass with the method invocation.
 * @arg_permissions: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.RevokePermissions">RevokePermissions()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_revoke_permissions_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_revoke_permissions_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_revoke_permissions (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    const gchar *arg_app_id,
    const gchar *const *arg_permissions,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "RevokePermissions",
    g_variant_new ("(ss^as)",
                   arg_doc_id,
                   arg_app_id,
                   arg_permissions),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_revoke_permissions_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_revoke_permissions().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_revoke_permissions().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_revoke_permissions_finish (
    GXdpDocuments *proxy,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_revoke_permissions_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @arg_app_id: Argument to pass with the method invocation.
 * @arg_permissions: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.RevokePermissions">RevokePermissions()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_revoke_permissions() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_revoke_permissions_sync (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    const gchar *arg_app_id,
    const gchar *const *arg_permissions,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "RevokePermissions",
    g_variant_new ("(ss^as)",
                   arg_doc_id,
                   arg_app_id,
                   arg_permissions),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_delete:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Delete">Delete()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_delete_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_delete_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_delete (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "Delete",
    g_variant_new ("(s)",
                   arg_doc_id),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_delete_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_delete().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_delete().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_delete_finish (
    GXdpDocuments *proxy,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_delete_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Delete">Delete()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_delete() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_delete_sync (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "Delete",
    g_variant_new ("(s)",
                   arg_doc_id),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "()");
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_lookup:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_filename: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Lookup">Lookup()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_lookup_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_lookup_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_lookup (
    GXdpDocuments *proxy,
    const gchar *arg_filename,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "Lookup",
    g_variant_new ("(^ay)",
                   arg_filename),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_lookup_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @out_doc_id: (out): Return location for return parameter or %NULL to ignore.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_lookup().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_lookup().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_lookup_finish (
    GXdpDocuments *proxy,
    gchar **out_doc_id,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(s)",
                 out_doc_id);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_lookup_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_filename: Argument to pass with the method invocation.
 * @out_doc_id: (out): Return location for return parameter or %NULL to ignore.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Lookup">Lookup()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_lookup() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_lookup_sync (
    GXdpDocuments *proxy,
    const gchar *arg_filename,
    gchar **out_doc_id,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "Lookup",
    g_variant_new ("(^ay)",
                   arg_filename),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(s)",
                 out_doc_id);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_info:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Info">Info()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_info_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_info_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_info (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "Info",
    g_variant_new ("(s)",
                   arg_doc_id),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_info_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @out_path: (out): Return location for return parameter or %NULL to ignore.
 * @out_apps: (out): Return location for return parameter or %NULL to ignore.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_info().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_info().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_info_finish (
    GXdpDocuments *proxy,
    gchar **out_path,
    GVariant **out_apps,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(^ay@a{sas})",
                 out_path,
                 out_apps);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_info_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_doc_id: Argument to pass with the method invocation.
 * @out_path: (out): Return location for return parameter or %NULL to ignore.
 * @out_apps: (out): Return location for return parameter or %NULL to ignore.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Info">Info()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_info() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_info_sync (
    GXdpDocuments *proxy,
    const gchar *arg_doc_id,
    gchar **out_path,
    GVariant **out_apps,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "Info",
    g_variant_new ("(s)",
                   arg_doc_id),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(^ay@a{sas})",
                 out_path,
                 out_apps);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_list:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_app_id: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.List">List()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_call_list_finish() to get the result of the operation.
 *
 * See gxdp_documents_call_list_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_documents_call_list (
    GXdpDocuments *proxy,
    const gchar *arg_app_id,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "List",
    g_variant_new ("(s)",
                   arg_app_id),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_documents_call_list_finish:
 * @proxy: A #GXdpDocumentsProxy.
 * @out_docs: (out): Return location for return parameter or %NULL to ignore.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_call_list().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_documents_call_list().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_list_finish (
    GXdpDocuments *proxy,
    GVariant **out_docs,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(@a{say})",
                 out_docs);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_call_list_sync:
 * @proxy: A #GXdpDocumentsProxy.
 * @arg_app_id: Argument to pass with the method invocation.
 * @out_docs: (out): Return location for return parameter or %NULL to ignore.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-Documents.List">List()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_call_list() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_documents_call_list_sync (
    GXdpDocuments *proxy,
    const gchar *arg_app_id,
    GVariant **out_docs,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "List",
    g_variant_new ("(s)",
                   arg_app_id),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(@a{say})",
                 out_docs);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_documents_complete_get_mount_point:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 * @path: Parameter to return.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GetMountPoint">GetMountPoint()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_get_mount_point (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation,
    const gchar *path)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("(^ay)",
                   path));
}

/**
 * gxdp_documents_complete_add:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 * @fd_list: (allow-none): A #GUnixFDList or %NULL.
 * @doc_id: Parameter to return.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Add">Add()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_add (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation,
    GUnixFDList *fd_list,
    const gchar *doc_id)
{
  g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,
    g_variant_new ("(s)",
                   doc_id),
    fd_list);
}

/**
 * gxdp_documents_complete_add_named:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 * @fd_list: (allow-none): A #GUnixFDList or %NULL.
 * @doc_id: Parameter to return.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.AddNamed">AddNamed()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_add_named (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation,
    GUnixFDList *fd_list,
    const gchar *doc_id)
{
  g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,
    g_variant_new ("(s)",
                   doc_id),
    fd_list);
}

/**
 * gxdp_documents_complete_grant_permissions:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.GrantPermissions">GrantPermissions()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_grant_permissions (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("()"));
}

/**
 * gxdp_documents_complete_revoke_permissions:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.RevokePermissions">RevokePermissions()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_revoke_permissions (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("()"));
}

/**
 * gxdp_documents_complete_delete:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Delete">Delete()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_delete (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("()"));
}

/**
 * gxdp_documents_complete_lookup:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 * @doc_id: Parameter to return.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Lookup">Lookup()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_lookup (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation,
    const gchar *doc_id)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("(s)",
                   doc_id));
}

/**
 * gxdp_documents_complete_info:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 * @path: Parameter to return.
 * @apps: Parameter to return.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.Info">Info()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_info (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation,
    const gchar *path,
    GVariant *apps)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("(^ay@a{sas})",
                   path,
                   apps));
}

/**
 * gxdp_documents_complete_list:
 * @object: A #GXdpDocuments.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 * @docs: Parameter to return.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-Documents.List">List()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_documents_complete_list (
    GXdpDocuments *object,
    GDBusMethodInvocation *invocation,
    GVariant *docs)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("(@a{say})",
                   docs));
}

/* ------------------------------------------------------------------------ */

/**
 * GXdpDocumentsProxy:
 *
 * The #GXdpDocumentsProxy structure contains only private data and should only be accessed using the provided API.
 */

/**
 * GXdpDocumentsProxyClass:
 * @parent_class: The parent class.
 *
 * Class structure for #GXdpDocumentsProxy.
 */

struct _GXdpDocumentsProxyPrivate
{
  GData *qdata;
};

static void gxdp_documents_proxy_iface_init (GXdpDocumentsIface *iface);

#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (GXdpDocumentsProxy, gxdp_documents_proxy, G_TYPE_DBUS_PROXY,
                         G_ADD_PRIVATE (GXdpDocumentsProxy)
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_DOCUMENTS, gxdp_documents_proxy_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (GXdpDocumentsProxy, gxdp_documents_proxy, G_TYPE_DBUS_PROXY,
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_DOCUMENTS, gxdp_documents_proxy_iface_init));

#endif
static void
gxdp_documents_proxy_finalize (GObject *object)
{
  GXdpDocumentsProxy *proxy = GXDP_DOCUMENTS_PROXY (object);
  g_datalist_clear (&proxy->priv->qdata);
  G_OBJECT_CLASS (gxdp_documents_proxy_parent_class)->finalize (object);
}

static void
gxdp_documents_proxy_get_property (GObject      *object,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
}

static void
gxdp_documents_proxy_set_property (GObject      *object,
  guint         prop_id,
  const GValue *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
}

static void
gxdp_documents_proxy_g_signal (GDBusProxy *proxy,
  const gchar *sender_name G_GNUC_UNUSED,
  const gchar *signal_name,
  GVariant *parameters)
{
  _ExtendedGDBusSignalInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint n;
  guint signal_id;
  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_gxdp_documents_interface_info.parent_struct, signal_name);
  if (info == NULL)
    return;
  num_params = g_variant_n_children (parameters);
  paramv = g_new0 (GValue, num_params + 1);
  g_value_init (&paramv[0], GXDP_TYPE_DOCUMENTS);
  g_value_set_object (&paramv[0], proxy);
  g_variant_iter_init (&iter, parameters);
  n = 1;
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, GXDP_TYPE_DOCUMENTS);
  g_signal_emitv (paramv, signal_id, 0, NULL);
  for (n = 0; n < num_params + 1; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static void
gxdp_documents_proxy_g_properties_changed (GDBusProxy *_proxy,
  GVariant *changed_properties,
  const gchar *const *invalidated_properties)
{
  GXdpDocumentsProxy *proxy = GXDP_DOCUMENTS_PROXY (_proxy);
  guint n;
  const gchar *key;
  GVariantIter *iter;
  _ExtendedGDBusPropertyInfo *info;
  g_variant_get (changed_properties, "a{sv}", &iter);
  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_documents_interface_info.parent_struct, key);
      g_datalist_remove_data (&proxy->priv->qdata, key);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
  g_variant_iter_free (iter);
  for (n = 0; invalidated_properties[n] != NULL; n++)
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_documents_interface_info.parent_struct, invalidated_properties[n]);
      g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
}

static void
gxdp_documents_proxy_init (GXdpDocumentsProxy *proxy)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  proxy->priv = gxdp_documents_proxy_get_instance_private (proxy);
#else
  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, GXDP_TYPE_DOCUMENTS_PROXY, GXdpDocumentsProxyPrivate);
#endif

  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), gxdp_documents_interface_info ());
}

static void
gxdp_documents_proxy_class_init (GXdpDocumentsProxyClass *klass)
{
  GObjectClass *gobject_class;
  GDBusProxyClass *proxy_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize     = gxdp_documents_proxy_finalize;
  gobject_class->get_property = gxdp_documents_proxy_get_property;
  gobject_class->set_property = gxdp_documents_proxy_set_property;

  proxy_class = G_DBUS_PROXY_CLASS (klass);
  proxy_class->g_signal = gxdp_documents_proxy_g_signal;
  proxy_class->g_properties_changed = gxdp_documents_proxy_g_properties_changed;

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (GXdpDocumentsProxyPrivate));
#endif
}

static void
gxdp_documents_proxy_iface_init (GXdpDocumentsIface *iface)
{
}

/**
 * gxdp_documents_proxy_new:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-Documents.top_of_page">org.freedesktop.portal.Documents</link>. See g_dbus_proxy_new() for more details.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_proxy_new_finish() to get the result of the operation.
 *
 * See gxdp_documents_proxy_new_sync() for the synchronous, blocking version of this constructor.
 */
void
gxdp_documents_proxy_new (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (GXDP_TYPE_DOCUMENTS_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.Documents", NULL);
}

/**
 * gxdp_documents_proxy_new_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_proxy_new().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with gxdp_documents_proxy_new().
 *
 * Returns: (transfer full) (type GXdpDocumentsProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpDocuments *
gxdp_documents_proxy_new_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return GXDP_DOCUMENTS (ret);
  else
    return NULL;
}

/**
 * gxdp_documents_proxy_new_sync:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Synchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-Documents.top_of_page">org.freedesktop.portal.Documents</link>. See g_dbus_proxy_new_sync() for more details.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_proxy_new() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type GXdpDocumentsProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpDocuments *
gxdp_documents_proxy_new_sync (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (GXDP_TYPE_DOCUMENTS_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.Documents", NULL);
  if (ret != NULL)
    return GXDP_DOCUMENTS (ret);
  else
    return NULL;
}


/**
 * gxdp_documents_proxy_new_for_bus:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Like gxdp_documents_proxy_new() but takes a #GBusType instead of a #GDBusConnection.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_documents_proxy_new_for_bus_finish() to get the result of the operation.
 *
 * See gxdp_documents_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.
 */
void
gxdp_documents_proxy_new_for_bus (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (GXDP_TYPE_DOCUMENTS_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.Documents", NULL);
}

/**
 * gxdp_documents_proxy_new_for_bus_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_documents_proxy_new_for_bus().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with gxdp_documents_proxy_new_for_bus().
 *
 * Returns: (transfer full) (type GXdpDocumentsProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpDocuments *
gxdp_documents_proxy_new_for_bus_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return GXDP_DOCUMENTS (ret);
  else
    return NULL;
}

/**
 * gxdp_documents_proxy_new_for_bus_sync:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Like gxdp_documents_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See gxdp_documents_proxy_new_for_bus() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type GXdpDocumentsProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpDocuments *
gxdp_documents_proxy_new_for_bus_sync (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (GXDP_TYPE_DOCUMENTS_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.Documents", NULL);
  if (ret != NULL)
    return GXDP_DOCUMENTS (ret);
  else
    return NULL;
}


/* ------------------------------------------------------------------------ */

/**
 * GXdpDocumentsSkeleton:
 *
 * The #GXdpDocumentsSkeleton structure contains only private data and should only be accessed using the provided API.
 */

/**
 * GXdpDocumentsSkeletonClass:
 * @parent_class: The parent class.
 *
 * Class structure for #GXdpDocumentsSkeleton.
 */

struct _GXdpDocumentsSkeletonPrivate
{
  GValue *properties;
  GList *changed_properties;
  GSource *changed_properties_idle_source;
  GMainContext *context;
  GMutex lock;
};

static void
_gxdp_documents_skeleton_handle_method_call (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name,
  const gchar *method_name,
  GVariant *parameters,
  GDBusMethodInvocation *invocation,
  gpointer user_data)
{
  GXdpDocumentsSkeleton *skeleton = GXDP_DOCUMENTS_SKELETON (user_data);
  _ExtendedGDBusMethodInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint num_extra;
  guint n;
  guint signal_id;
  GValue return_value = G_VALUE_INIT;
  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);
  g_assert (info != NULL);
  num_params = g_variant_n_children (parameters);
  num_extra = info->pass_fdlist ? 3 : 2;  paramv = g_new0 (GValue, num_params + num_extra);
  n = 0;
  g_value_init (&paramv[n], GXDP_TYPE_DOCUMENTS);
  g_value_set_object (&paramv[n++], skeleton);
  g_value_init (&paramv[n], G_TYPE_DBUS_METHOD_INVOCATION);
  g_value_set_object (&paramv[n++], invocation);
  if (info->pass_fdlist)
    {
#ifdef G_OS_UNIX
      g_value_init (&paramv[n], G_TYPE_UNIX_FD_LIST);
      g_value_set_object (&paramv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));
#else
      g_assert_not_reached ();
#endif
    }
  g_variant_iter_init (&iter, parameters);
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, GXDP_TYPE_DOCUMENTS);
  g_value_init (&return_value, G_TYPE_BOOLEAN);
  g_signal_emitv (paramv, signal_id, 0, &return_value);
  if (!g_value_get_boolean (&return_value))
    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);
  g_value_unset (&return_value);
  for (n = 0; n < num_params + num_extra; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static GVariant *
_gxdp_documents_skeleton_handle_get_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GError **error,
  gpointer user_data)
{
  GXdpDocumentsSkeleton *skeleton = GXDP_DOCUMENTS_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  GVariant *ret;
  ret = NULL;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_documents_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      g_value_init (&value, pspec->value_type);
      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));
      g_value_unset (&value);
    }
  return ret;
}

static gboolean
_gxdp_documents_skeleton_handle_set_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GVariant *variant,
  GError **error,
  gpointer user_data)
{
  GXdpDocumentsSkeleton *skeleton = GXDP_DOCUMENTS_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  gboolean ret;
  ret = FALSE;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_documents_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      if (info->use_gvariant)
        g_value_set_variant (&value, variant);
      else
        g_dbus_gvariant_to_gvalue (variant, &value);
      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      g_value_unset (&value);
      ret = TRUE;
    }
  return ret;
}

static const GDBusInterfaceVTable _gxdp_documents_skeleton_vtable =
{
  _gxdp_documents_skeleton_handle_method_call,
  _gxdp_documents_skeleton_handle_get_property,
  _gxdp_documents_skeleton_handle_set_property,
  {NULL}
};

static GDBusInterfaceInfo *
gxdp_documents_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return gxdp_documents_interface_info ();
}

static GDBusInterfaceVTable *
gxdp_documents_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return (GDBusInterfaceVTable *) &_gxdp_documents_skeleton_vtable;
}

static GVariant *
gxdp_documents_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)
{
  GXdpDocumentsSkeleton *skeleton = GXDP_DOCUMENTS_SKELETON (_skeleton);

  GVariantBuilder builder;
  guint n;
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  if (_gxdp_documents_interface_info.parent_struct.properties == NULL)
    goto out;
  for (n = 0; _gxdp_documents_interface_info.parent_struct.properties[n] != NULL; n++)
    {
      GDBusPropertyInfo *info = _gxdp_documents_interface_info.parent_struct.properties[n];
      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
        {
          GVariant *value;
          value = _gxdp_documents_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.freedesktop.portal.Documents", info->name, NULL, skeleton);
          if (value != NULL)
            {
              g_variant_take_ref (value);
              g_variant_builder_add (&builder, "{sv}", info->name, value);
              g_variant_unref (value);
            }
        }
    }
out:
  return g_variant_builder_end (&builder);
}

static void
gxdp_documents_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)
{
}

static void gxdp_documents_skeleton_iface_init (GXdpDocumentsIface *iface);
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (GXdpDocumentsSkeleton, gxdp_documents_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_ADD_PRIVATE (GXdpDocumentsSkeleton)
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_DOCUMENTS, gxdp_documents_skeleton_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (GXdpDocumentsSkeleton, gxdp_documents_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_DOCUMENTS, gxdp_documents_skeleton_iface_init));

#endif
static void
gxdp_documents_skeleton_finalize (GObject *object)
{
  GXdpDocumentsSkeleton *skeleton = GXDP_DOCUMENTS_SKELETON (object);
  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
  if (skeleton->priv->changed_properties_idle_source != NULL)
    g_source_destroy (skeleton->priv->changed_properties_idle_source);
  g_main_context_unref (skeleton->priv->context);
  g_mutex_clear (&skeleton->priv->lock);
  G_OBJECT_CLASS (gxdp_documents_skeleton_parent_class)->finalize (object);
}

static void
gxdp_documents_skeleton_init (GXdpDocumentsSkeleton *skeleton)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  skeleton->priv = gxdp_documents_skeleton_get_instance_private (skeleton);
#else
  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, GXDP_TYPE_DOCUMENTS_SKELETON, GXdpDocumentsSkeletonPrivate);
#endif

  g_mutex_init (&skeleton->priv->lock);
  skeleton->priv->context = g_main_context_ref_thread_default ();
}

static void
gxdp_documents_skeleton_class_init (GXdpDocumentsSkeletonClass *klass)
{
  GObjectClass *gobject_class;
  GDBusInterfaceSkeletonClass *skeleton_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = gxdp_documents_skeleton_finalize;

  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
  skeleton_class->get_info = gxdp_documents_skeleton_dbus_interface_get_info;
  skeleton_class->get_properties = gxdp_documents_skeleton_dbus_interface_get_properties;
  skeleton_class->flush = gxdp_documents_skeleton_dbus_interface_flush;
  skeleton_class->get_vtable = gxdp_documents_skeleton_dbus_interface_get_vtable;

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (GXdpDocumentsSkeletonPrivate));
#endif
}

static void
gxdp_documents_skeleton_iface_init (GXdpDocumentsIface *iface)
{
}

/**
 * gxdp_documents_skeleton_new:
 *
 * Creates a skeleton object for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-Documents.top_of_page">org.freedesktop.portal.Documents</link>.
 *
 * Returns: (transfer full) (type GXdpDocumentsSkeleton): The skeleton object.
 */
GXdpDocuments *
gxdp_documents_skeleton_new (void)
{
  return GXDP_DOCUMENTS (g_object_new (GXDP_TYPE_DOCUMENTS_SKELETON, NULL));
}

/* ------------------------------------------------------------------------
 * Code for interface org.freedesktop.portal.NetworkMonitor
 * ------------------------------------------------------------------------
 */

/**
 * SECTION:GXdpNetworkMonitor
 * @title: GXdpNetworkMonitor
 * @short_description: Generated C code for the org.freedesktop.portal.NetworkMonitor D-Bus interface
 *
 * This section contains code for working with the <link linkend="gdbus-interface-org-freedesktop-portal-NetworkMonitor.top_of_page">org.freedesktop.portal.NetworkMonitor</link> D-Bus interface in C.
 */

/* ---- Introspection data for org.freedesktop.portal.NetworkMonitor ---- */

static const _ExtendedGDBusArgInfo _gxdp_network_monitor_signal_info_changed_ARG_available =
{
  {
    -1,
    (gchar *) "available",
    (gchar *) "b",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_network_monitor_signal_info_changed_ARG_pointers[] =
{
  &_gxdp_network_monitor_signal_info_changed_ARG_available,
  NULL
};

static const _ExtendedGDBusSignalInfo _gxdp_network_monitor_signal_info_changed =
{
  {
    -1,
    (gchar *) "changed",
    (GDBusArgInfo **) &_gxdp_network_monitor_signal_info_changed_ARG_pointers,
    NULL
  },
  "changed"
};

static const _ExtendedGDBusSignalInfo * const _gxdp_network_monitor_signal_info_pointers[] =
{
  &_gxdp_network_monitor_signal_info_changed,
  NULL
};

static const _ExtendedGDBusPropertyInfo _gxdp_network_monitor_property_info_available =
{
  {
    -1,
    (gchar *) "available",
    (gchar *) "b",
    G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
    NULL
  },
  "available",
  FALSE
};

static const _ExtendedGDBusPropertyInfo _gxdp_network_monitor_property_info_metered =
{
  {
    -1,
    (gchar *) "metered",
    (gchar *) "b",
    G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
    NULL
  },
  "metered",
  FALSE
};

static const _ExtendedGDBusPropertyInfo _gxdp_network_monitor_property_info_connectivity =
{
  {
    -1,
    (gchar *) "connectivity",
    (gchar *) "u",
    G_DBUS_PROPERTY_INFO_FLAGS_READABLE,
    NULL
  },
  "connectivity",
  FALSE
};

static const _ExtendedGDBusPropertyInfo * const _gxdp_network_monitor_property_info_pointers[] =
{
  &_gxdp_network_monitor_property_info_available,
  &_gxdp_network_monitor_property_info_metered,
  &_gxdp_network_monitor_property_info_connectivity,
  NULL
};

static const _ExtendedGDBusInterfaceInfo _gxdp_network_monitor_interface_info =
{
  {
    -1,
    (gchar *) "org.freedesktop.portal.NetworkMonitor",
    NULL,
    (GDBusSignalInfo **) &_gxdp_network_monitor_signal_info_pointers,
    (GDBusPropertyInfo **) &_gxdp_network_monitor_property_info_pointers,
    NULL
  },
  "network-monitor",
};


/**
 * gxdp_network_monitor_interface_info:
 *
 * Gets a machine-readable description of the <link linkend="gdbus-interface-org-freedesktop-portal-NetworkMonitor.top_of_page">org.freedesktop.portal.NetworkMonitor</link> D-Bus interface.
 *
 * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
 */
GDBusInterfaceInfo *
gxdp_network_monitor_interface_info (void)
{
  return (GDBusInterfaceInfo *) &_gxdp_network_monitor_interface_info.parent_struct;
}

/**
 * gxdp_network_monitor_override_properties:
 * @klass: The class structure for a #GObject<!-- -->-derived class.
 * @property_id_begin: The property id to assign to the first overridden property.
 *
 * Overrides all #GObject properties in the #GXdpNetworkMonitor interface for a concrete class.
 * The properties are overridden in the order they are defined.
 *
 * Returns: The last property id.
 */
guint
gxdp_network_monitor_override_properties (GObjectClass *klass, guint property_id_begin)
{
  g_object_class_override_property (klass, property_id_begin++, "available");
  g_object_class_override_property (klass, property_id_begin++, "metered");
  g_object_class_override_property (klass, property_id_begin++, "connectivity");
  return property_id_begin - 1;
}



/**
 * GXdpNetworkMonitor:
 *
 * Abstract interface type for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-NetworkMonitor.top_of_page">org.freedesktop.portal.NetworkMonitor</link>.
 */

/**
 * GXdpNetworkMonitorIface:
 * @parent_iface: The parent interface.
 * @get_available: Getter for the #GXdpNetworkMonitor:available property.
 * @get_connectivity: Getter for the #GXdpNetworkMonitor:connectivity property.
 * @get_metered: Getter for the #GXdpNetworkMonitor:metered property.
 * @changed: Handler for the #GXdpNetworkMonitor::changed signal.
 *
 * Virtual table for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-NetworkMonitor.top_of_page">org.freedesktop.portal.NetworkMonitor</link>.
 */

typedef GXdpNetworkMonitorIface GXdpNetworkMonitorInterface;
G_DEFINE_INTERFACE (GXdpNetworkMonitor, gxdp_network_monitor, G_TYPE_OBJECT);

static void
gxdp_network_monitor_default_init (GXdpNetworkMonitorIface *iface)
{
  /* GObject signals for received D-Bus signals: */
  /**
   * GXdpNetworkMonitor::changed:
   * @object: A #GXdpNetworkMonitor.
   * @arg_available: Argument.
   *
   * On the client-side, this signal is emitted whenever the D-Bus signal <link linkend="gdbus-signal-org-freedesktop-portal-NetworkMonitor.changed">"changed"</link> is received.
   *
   * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal.
   */
  g_signal_new ("changed",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpNetworkMonitorIface, changed),
    NULL,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_NONE,
    1, G_TYPE_BOOLEAN);

  /* GObject properties for D-Bus properties: */
  /**
   * GXdpNetworkMonitor:available:
   *
   * Represents the D-Bus property <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.available">"available"</link>.
   *
   * Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side.
   */
  g_object_interface_install_property (iface,
    g_param_spec_boolean ("available", "available", "available", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GXdpNetworkMonitor:metered:
   *
   * Represents the D-Bus property <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.metered">"metered"</link>.
   *
   * Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side.
   */
  g_object_interface_install_property (iface,
    g_param_spec_boolean ("metered", "metered", "metered", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GXdpNetworkMonitor:connectivity:
   *
   * Represents the D-Bus property <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.connectivity">"connectivity"</link>.
   *
   * Since the D-Bus property for this #GObject property is readable but not writable, it is meaningful to read from it on both the client- and service-side. It is only meaningful, however, to write to it on the service-side.
   */
  g_object_interface_install_property (iface,
    g_param_spec_uint ("connectivity", "connectivity", "connectivity", 0, G_MAXUINT32, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

/**
 * gxdp_network_monitor_get_available: (skip)
 * @object: A #GXdpNetworkMonitor.
 *
 * Gets the value of the <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.available">"available"</link> D-Bus property.
 *
 * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
 *
 * Returns: The property value.
 */
gboolean 
gxdp_network_monitor_get_available (GXdpNetworkMonitor *object)
{
  return GXDP_NETWORK_MONITOR_GET_IFACE (object)->get_available (object);
}

/**
 * gxdp_network_monitor_set_available: (skip)
 * @object: A #GXdpNetworkMonitor.
 * @value: The value to set.
 *
 * Sets the <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.available">"available"</link> D-Bus property to @value.
 *
 * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
 */
void
gxdp_network_monitor_set_available (GXdpNetworkMonitor *object, gboolean value)
{
  g_object_set (G_OBJECT (object), "available", value, NULL);
}

/**
 * gxdp_network_monitor_get_metered: (skip)
 * @object: A #GXdpNetworkMonitor.
 *
 * Gets the value of the <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.metered">"metered"</link> D-Bus property.
 *
 * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
 *
 * Returns: The property value.
 */
gboolean 
gxdp_network_monitor_get_metered (GXdpNetworkMonitor *object)
{
  return GXDP_NETWORK_MONITOR_GET_IFACE (object)->get_metered (object);
}

/**
 * gxdp_network_monitor_set_metered: (skip)
 * @object: A #GXdpNetworkMonitor.
 * @value: The value to set.
 *
 * Sets the <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.metered">"metered"</link> D-Bus property to @value.
 *
 * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
 */
void
gxdp_network_monitor_set_metered (GXdpNetworkMonitor *object, gboolean value)
{
  g_object_set (G_OBJECT (object), "metered", value, NULL);
}

/**
 * gxdp_network_monitor_get_connectivity: (skip)
 * @object: A #GXdpNetworkMonitor.
 *
 * Gets the value of the <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.connectivity">"connectivity"</link> D-Bus property.
 *
 * Since this D-Bus property is readable, it is meaningful to use this function on both the client- and service-side.
 *
 * Returns: The property value.
 */
guint 
gxdp_network_monitor_get_connectivity (GXdpNetworkMonitor *object)
{
  return GXDP_NETWORK_MONITOR_GET_IFACE (object)->get_connectivity (object);
}

/**
 * gxdp_network_monitor_set_connectivity: (skip)
 * @object: A #GXdpNetworkMonitor.
 * @value: The value to set.
 *
 * Sets the <link linkend="gdbus-property-org-freedesktop-portal-NetworkMonitor.connectivity">"connectivity"</link> D-Bus property to @value.
 *
 * Since this D-Bus property is not writable, it is only meaningful to use this function on the service-side.
 */
void
gxdp_network_monitor_set_connectivity (GXdpNetworkMonitor *object, guint value)
{
  g_object_set (G_OBJECT (object), "connectivity", value, NULL);
}

/**
 * gxdp_network_monitor_emit_changed:
 * @object: A #GXdpNetworkMonitor.
 * @arg_available: Argument to pass with the signal.
 *
 * Emits the <link linkend="gdbus-signal-org-freedesktop-portal-NetworkMonitor.changed">"changed"</link> D-Bus signal.
 */
void
gxdp_network_monitor_emit_changed (
    GXdpNetworkMonitor *object,
    gboolean arg_available)
{
  g_signal_emit_by_name (object, "changed", arg_available);
}

/* ------------------------------------------------------------------------ */

/**
 * GXdpNetworkMonitorProxy:
 *
 * The #GXdpNetworkMonitorProxy structure contains only private data and should only be accessed using the provided API.
 */

/**
 * GXdpNetworkMonitorProxyClass:
 * @parent_class: The parent class.
 *
 * Class structure for #GXdpNetworkMonitorProxy.
 */

struct _GXdpNetworkMonitorProxyPrivate
{
  GData *qdata;
};

static void gxdp_network_monitor_proxy_iface_init (GXdpNetworkMonitorIface *iface);

#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (GXdpNetworkMonitorProxy, gxdp_network_monitor_proxy, G_TYPE_DBUS_PROXY,
                         G_ADD_PRIVATE (GXdpNetworkMonitorProxy)
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_NETWORK_MONITOR, gxdp_network_monitor_proxy_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (GXdpNetworkMonitorProxy, gxdp_network_monitor_proxy, G_TYPE_DBUS_PROXY,
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_NETWORK_MONITOR, gxdp_network_monitor_proxy_iface_init));

#endif
static void
gxdp_network_monitor_proxy_finalize (GObject *object)
{
  GXdpNetworkMonitorProxy *proxy = GXDP_NETWORK_MONITOR_PROXY (object);
  g_datalist_clear (&proxy->priv->qdata);
  G_OBJECT_CLASS (gxdp_network_monitor_proxy_parent_class)->finalize (object);
}

static void
gxdp_network_monitor_proxy_get_property (GObject      *object,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
  const _ExtendedGDBusPropertyInfo *info;
  GVariant *variant;
  g_assert (prop_id != 0 && prop_id - 1 < 3);
  info = _gxdp_network_monitor_property_info_pointers[prop_id - 1];
  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (object), info->parent_struct.name);
  if (info->use_gvariant)
    {
      g_value_set_variant (value, variant);
    }
  else
    {
      if (variant != NULL)
        g_dbus_gvariant_to_gvalue (variant, value);
    }
  if (variant != NULL)
    g_variant_unref (variant);
}

static void
gxdp_network_monitor_proxy_set_property_cb (GDBusProxy *proxy,
  GAsyncResult *res,
  gpointer      user_data)
{
  const _ExtendedGDBusPropertyInfo *info = user_data;
  GError *error;
  GVariant *_ret;
  error = NULL;
  _ret = g_dbus_proxy_call_finish (proxy, res, &error);
  if (!_ret)
    {
      g_warning ("Error setting property '%s' on interface org.freedesktop.portal.NetworkMonitor: %s (%s, %d)",
                 info->parent_struct.name, 
                 error->message, g_quark_to_string (error->domain), error->code);
      g_error_free (error);
    }
  else
    {
      g_variant_unref (_ret);
    }
}

static void
gxdp_network_monitor_proxy_set_property (GObject      *object,
  guint         prop_id,
  const GValue *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
  const _ExtendedGDBusPropertyInfo *info;
  GVariant *variant;
  g_assert (prop_id != 0 && prop_id - 1 < 3);
  info = _gxdp_network_monitor_property_info_pointers[prop_id - 1];
  variant = g_dbus_gvalue_to_gvariant (value, G_VARIANT_TYPE (info->parent_struct.signature));
  g_dbus_proxy_call (G_DBUS_PROXY (object),
    "org.freedesktop.DBus.Properties.Set",
    g_variant_new ("(ssv)", "org.freedesktop.portal.NetworkMonitor", info->parent_struct.name, variant),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    NULL, (GAsyncReadyCallback) gxdp_network_monitor_proxy_set_property_cb, (GDBusPropertyInfo *) &info->parent_struct);
  g_variant_unref (variant);
}

static void
gxdp_network_monitor_proxy_g_signal (GDBusProxy *proxy,
  const gchar *sender_name G_GNUC_UNUSED,
  const gchar *signal_name,
  GVariant *parameters)
{
  _ExtendedGDBusSignalInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint n;
  guint signal_id;
  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_gxdp_network_monitor_interface_info.parent_struct, signal_name);
  if (info == NULL)
    return;
  num_params = g_variant_n_children (parameters);
  paramv = g_new0 (GValue, num_params + 1);
  g_value_init (&paramv[0], GXDP_TYPE_NETWORK_MONITOR);
  g_value_set_object (&paramv[0], proxy);
  g_variant_iter_init (&iter, parameters);
  n = 1;
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, GXDP_TYPE_NETWORK_MONITOR);
  g_signal_emitv (paramv, signal_id, 0, NULL);
  for (n = 0; n < num_params + 1; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static void
gxdp_network_monitor_proxy_g_properties_changed (GDBusProxy *_proxy,
  GVariant *changed_properties,
  const gchar *const *invalidated_properties)
{
  GXdpNetworkMonitorProxy *proxy = GXDP_NETWORK_MONITOR_PROXY (_proxy);
  guint n;
  const gchar *key;
  GVariantIter *iter;
  _ExtendedGDBusPropertyInfo *info;
  g_variant_get (changed_properties, "a{sv}", &iter);
  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_network_monitor_interface_info.parent_struct, key);
      g_datalist_remove_data (&proxy->priv->qdata, key);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
  g_variant_iter_free (iter);
  for (n = 0; invalidated_properties[n] != NULL; n++)
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_network_monitor_interface_info.parent_struct, invalidated_properties[n]);
      g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
}

static gboolean 
gxdp_network_monitor_proxy_get_available (GXdpNetworkMonitor *object)
{
  GXdpNetworkMonitorProxy *proxy = GXDP_NETWORK_MONITOR_PROXY (object);
  GVariant *variant;
  gboolean value = 0;
  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "available");
  if (variant != NULL)
    {
      value = g_variant_get_boolean (variant);
      g_variant_unref (variant);
    }
  return value;
}

static gboolean 
gxdp_network_monitor_proxy_get_metered (GXdpNetworkMonitor *object)
{
  GXdpNetworkMonitorProxy *proxy = GXDP_NETWORK_MONITOR_PROXY (object);
  GVariant *variant;
  gboolean value = 0;
  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "metered");
  if (variant != NULL)
    {
      value = g_variant_get_boolean (variant);
      g_variant_unref (variant);
    }
  return value;
}

static guint 
gxdp_network_monitor_proxy_get_connectivity (GXdpNetworkMonitor *object)
{
  GXdpNetworkMonitorProxy *proxy = GXDP_NETWORK_MONITOR_PROXY (object);
  GVariant *variant;
  guint value = 0;
  variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "connectivity");
  if (variant != NULL)
    {
      value = g_variant_get_uint32 (variant);
      g_variant_unref (variant);
    }
  return value;
}

static void
gxdp_network_monitor_proxy_init (GXdpNetworkMonitorProxy *proxy)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  proxy->priv = gxdp_network_monitor_proxy_get_instance_private (proxy);
#else
  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, GXDP_TYPE_NETWORK_MONITOR_PROXY, GXdpNetworkMonitorProxyPrivate);
#endif

  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), gxdp_network_monitor_interface_info ());
}

static void
gxdp_network_monitor_proxy_class_init (GXdpNetworkMonitorProxyClass *klass)
{
  GObjectClass *gobject_class;
  GDBusProxyClass *proxy_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize     = gxdp_network_monitor_proxy_finalize;
  gobject_class->get_property = gxdp_network_monitor_proxy_get_property;
  gobject_class->set_property = gxdp_network_monitor_proxy_set_property;

  proxy_class = G_DBUS_PROXY_CLASS (klass);
  proxy_class->g_signal = gxdp_network_monitor_proxy_g_signal;
  proxy_class->g_properties_changed = gxdp_network_monitor_proxy_g_properties_changed;

  gxdp_network_monitor_override_properties (gobject_class, 1);

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (GXdpNetworkMonitorProxyPrivate));
#endif
}

static void
gxdp_network_monitor_proxy_iface_init (GXdpNetworkMonitorIface *iface)
{
  iface->get_available = gxdp_network_monitor_proxy_get_available;
  iface->get_metered = gxdp_network_monitor_proxy_get_metered;
  iface->get_connectivity = gxdp_network_monitor_proxy_get_connectivity;
}

/**
 * gxdp_network_monitor_proxy_new:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-NetworkMonitor.top_of_page">org.freedesktop.portal.NetworkMonitor</link>. See g_dbus_proxy_new() for more details.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_network_monitor_proxy_new_finish() to get the result of the operation.
 *
 * See gxdp_network_monitor_proxy_new_sync() for the synchronous, blocking version of this constructor.
 */
void
gxdp_network_monitor_proxy_new (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (GXDP_TYPE_NETWORK_MONITOR_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.NetworkMonitor", NULL);
}

/**
 * gxdp_network_monitor_proxy_new_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_network_monitor_proxy_new().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with gxdp_network_monitor_proxy_new().
 *
 * Returns: (transfer full) (type GXdpNetworkMonitorProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpNetworkMonitor *
gxdp_network_monitor_proxy_new_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return GXDP_NETWORK_MONITOR (ret);
  else
    return NULL;
}

/**
 * gxdp_network_monitor_proxy_new_sync:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Synchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-NetworkMonitor.top_of_page">org.freedesktop.portal.NetworkMonitor</link>. See g_dbus_proxy_new_sync() for more details.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See gxdp_network_monitor_proxy_new() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type GXdpNetworkMonitorProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpNetworkMonitor *
gxdp_network_monitor_proxy_new_sync (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (GXDP_TYPE_NETWORK_MONITOR_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.NetworkMonitor", NULL);
  if (ret != NULL)
    return GXDP_NETWORK_MONITOR (ret);
  else
    return NULL;
}


/**
 * gxdp_network_monitor_proxy_new_for_bus:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Like gxdp_network_monitor_proxy_new() but takes a #GBusType instead of a #GDBusConnection.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_network_monitor_proxy_new_for_bus_finish() to get the result of the operation.
 *
 * See gxdp_network_monitor_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.
 */
void
gxdp_network_monitor_proxy_new_for_bus (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (GXDP_TYPE_NETWORK_MONITOR_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.NetworkMonitor", NULL);
}

/**
 * gxdp_network_monitor_proxy_new_for_bus_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_network_monitor_proxy_new_for_bus().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with gxdp_network_monitor_proxy_new_for_bus().
 *
 * Returns: (transfer full) (type GXdpNetworkMonitorProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpNetworkMonitor *
gxdp_network_monitor_proxy_new_for_bus_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return GXDP_NETWORK_MONITOR (ret);
  else
    return NULL;
}

/**
 * gxdp_network_monitor_proxy_new_for_bus_sync:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Like gxdp_network_monitor_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See gxdp_network_monitor_proxy_new_for_bus() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type GXdpNetworkMonitorProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpNetworkMonitor *
gxdp_network_monitor_proxy_new_for_bus_sync (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (GXDP_TYPE_NETWORK_MONITOR_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.NetworkMonitor", NULL);
  if (ret != NULL)
    return GXDP_NETWORK_MONITOR (ret);
  else
    return NULL;
}


/* ------------------------------------------------------------------------ */

/**
 * GXdpNetworkMonitorSkeleton:
 *
 * The #GXdpNetworkMonitorSkeleton structure contains only private data and should only be accessed using the provided API.
 */

/**
 * GXdpNetworkMonitorSkeletonClass:
 * @parent_class: The parent class.
 *
 * Class structure for #GXdpNetworkMonitorSkeleton.
 */

struct _GXdpNetworkMonitorSkeletonPrivate
{
  GValue *properties;
  GList *changed_properties;
  GSource *changed_properties_idle_source;
  GMainContext *context;
  GMutex lock;
};

static void
_gxdp_network_monitor_skeleton_handle_method_call (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name,
  const gchar *method_name,
  GVariant *parameters,
  GDBusMethodInvocation *invocation,
  gpointer user_data)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (user_data);
  _ExtendedGDBusMethodInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint num_extra;
  guint n;
  guint signal_id;
  GValue return_value = G_VALUE_INIT;
  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);
  g_assert (info != NULL);
  num_params = g_variant_n_children (parameters);
  num_extra = info->pass_fdlist ? 3 : 2;  paramv = g_new0 (GValue, num_params + num_extra);
  n = 0;
  g_value_init (&paramv[n], GXDP_TYPE_NETWORK_MONITOR);
  g_value_set_object (&paramv[n++], skeleton);
  g_value_init (&paramv[n], G_TYPE_DBUS_METHOD_INVOCATION);
  g_value_set_object (&paramv[n++], invocation);
  if (info->pass_fdlist)
    {
#ifdef G_OS_UNIX
      g_value_init (&paramv[n], G_TYPE_UNIX_FD_LIST);
      g_value_set_object (&paramv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));
#else
      g_assert_not_reached ();
#endif
    }
  g_variant_iter_init (&iter, parameters);
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, GXDP_TYPE_NETWORK_MONITOR);
  g_value_init (&return_value, G_TYPE_BOOLEAN);
  g_signal_emitv (paramv, signal_id, 0, &return_value);
  if (!g_value_get_boolean (&return_value))
    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);
  g_value_unset (&return_value);
  for (n = 0; n < num_params + num_extra; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static GVariant *
_gxdp_network_monitor_skeleton_handle_get_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GError **error,
  gpointer user_data)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  GVariant *ret;
  ret = NULL;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_network_monitor_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      g_value_init (&value, pspec->value_type);
      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));
      g_value_unset (&value);
    }
  return ret;
}

static gboolean
_gxdp_network_monitor_skeleton_handle_set_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GVariant *variant,
  GError **error,
  gpointer user_data)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  gboolean ret;
  ret = FALSE;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_network_monitor_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      if (info->use_gvariant)
        g_value_set_variant (&value, variant);
      else
        g_dbus_gvariant_to_gvalue (variant, &value);
      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      g_value_unset (&value);
      ret = TRUE;
    }
  return ret;
}

static const GDBusInterfaceVTable _gxdp_network_monitor_skeleton_vtable =
{
  _gxdp_network_monitor_skeleton_handle_method_call,
  _gxdp_network_monitor_skeleton_handle_get_property,
  _gxdp_network_monitor_skeleton_handle_set_property,
  {NULL}
};

static GDBusInterfaceInfo *
gxdp_network_monitor_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return gxdp_network_monitor_interface_info ();
}

static GDBusInterfaceVTable *
gxdp_network_monitor_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return (GDBusInterfaceVTable *) &_gxdp_network_monitor_skeleton_vtable;
}

static GVariant *
gxdp_network_monitor_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (_skeleton);

  GVariantBuilder builder;
  guint n;
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  if (_gxdp_network_monitor_interface_info.parent_struct.properties == NULL)
    goto out;
  for (n = 0; _gxdp_network_monitor_interface_info.parent_struct.properties[n] != NULL; n++)
    {
      GDBusPropertyInfo *info = _gxdp_network_monitor_interface_info.parent_struct.properties[n];
      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
        {
          GVariant *value;
          value = _gxdp_network_monitor_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.freedesktop.portal.NetworkMonitor", info->name, NULL, skeleton);
          if (value != NULL)
            {
              g_variant_take_ref (value);
              g_variant_builder_add (&builder, "{sv}", info->name, value);
              g_variant_unref (value);
            }
        }
    }
out:
  return g_variant_builder_end (&builder);
}

static gboolean _gxdp_network_monitor_emit_changed (gpointer user_data);

static void
gxdp_network_monitor_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (_skeleton);
  gboolean emit_changed = FALSE;

  g_mutex_lock (&skeleton->priv->lock);
  if (skeleton->priv->changed_properties_idle_source != NULL)
    {
      g_source_destroy (skeleton->priv->changed_properties_idle_source);
      skeleton->priv->changed_properties_idle_source = NULL;
      emit_changed = TRUE;
    }
  g_mutex_unlock (&skeleton->priv->lock);

  if (emit_changed)
    _gxdp_network_monitor_emit_changed (skeleton);
}

static void
_gxdp_network_monitor_on_signal_changed (
    GXdpNetworkMonitor *object,
    gboolean arg_available)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);

  GList      *connections, *l;
  GVariant   *signal_variant;
  connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));

  signal_variant = g_variant_ref_sink (g_variant_new ("(b)",
                   arg_available));
  for (l = connections; l != NULL; l = l->next)
    {
      GDBusConnection *connection = l->data;
      g_dbus_connection_emit_signal (connection,
        NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.freedesktop.portal.NetworkMonitor", "changed",
        signal_variant, NULL);
    }
  g_variant_unref (signal_variant);
  g_list_free_full (connections, g_object_unref);
}

static void gxdp_network_monitor_skeleton_iface_init (GXdpNetworkMonitorIface *iface);
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (GXdpNetworkMonitorSkeleton, gxdp_network_monitor_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_ADD_PRIVATE (GXdpNetworkMonitorSkeleton)
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_NETWORK_MONITOR, gxdp_network_monitor_skeleton_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (GXdpNetworkMonitorSkeleton, gxdp_network_monitor_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_NETWORK_MONITOR, gxdp_network_monitor_skeleton_iface_init));

#endif
static void
gxdp_network_monitor_skeleton_finalize (GObject *object)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);
  guint n;
  for (n = 0; n < 3; n++)
    g_value_unset (&skeleton->priv->properties[n]);
  g_free (skeleton->priv->properties);
  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
  if (skeleton->priv->changed_properties_idle_source != NULL)
    g_source_destroy (skeleton->priv->changed_properties_idle_source);
  g_main_context_unref (skeleton->priv->context);
  g_mutex_clear (&skeleton->priv->lock);
  G_OBJECT_CLASS (gxdp_network_monitor_skeleton_parent_class)->finalize (object);
}

static void
gxdp_network_monitor_skeleton_get_property (GObject      *object,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);
  g_assert (prop_id != 0 && prop_id - 1 < 3);
  g_mutex_lock (&skeleton->priv->lock);
  g_value_copy (&skeleton->priv->properties[prop_id - 1], value);
  g_mutex_unlock (&skeleton->priv->lock);
}

static gboolean
_gxdp_network_monitor_emit_changed (gpointer user_data)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (user_data);
  GList *l;
  GVariantBuilder builder;
  GVariantBuilder invalidated_builder;
  guint num_changes;

  g_mutex_lock (&skeleton->priv->lock);
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));
  for (l = skeleton->priv->changed_properties, num_changes = 0; l != NULL; l = l->next)
    {
      ChangedProperty *cp = l->data;
      GVariant *variant;
      const GValue *cur_value;

      cur_value = &skeleton->priv->properties[cp->prop_id - 1];
      if (!_g_value_equal (cur_value, &cp->orig_value))
        {
          variant = g_dbus_gvalue_to_gvariant (cur_value, G_VARIANT_TYPE (cp->info->parent_struct.signature));
          g_variant_builder_add (&builder, "{sv}", cp->info->parent_struct.name, variant);
          g_variant_unref (variant);
          num_changes++;
        }
    }
  if (num_changes > 0)
    {
      GList *connections, *ll;
      GVariant *signal_variant;
      signal_variant = g_variant_ref_sink (g_variant_new ("(sa{sv}as)", "org.freedesktop.portal.NetworkMonitor",
                                           &builder, &invalidated_builder));
      connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton));
      for (ll = connections; ll != NULL; ll = ll->next)
        {
          GDBusConnection *connection = ll->data;

          g_dbus_connection_emit_signal (connection,
                                         NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)),
                                         "org.freedesktop.DBus.Properties",
                                         "PropertiesChanged",
                                         signal_variant,
                                         NULL);
        }
      g_variant_unref (signal_variant);
      g_list_free_full (connections, g_object_unref);
    }
  else
    {
      g_variant_builder_clear (&builder);
      g_variant_builder_clear (&invalidated_builder);
    }
  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
  skeleton->priv->changed_properties = NULL;
  skeleton->priv->changed_properties_idle_source = NULL;
  g_mutex_unlock (&skeleton->priv->lock);
  return FALSE;
}

static void
_gxdp_network_monitor_schedule_emit_changed (GXdpNetworkMonitorSkeleton *skeleton, const _ExtendedGDBusPropertyInfo *info, guint prop_id, const GValue *orig_value)
{
  ChangedProperty *cp;
  GList *l;
  cp = NULL;
  for (l = skeleton->priv->changed_properties; l != NULL; l = l->next)
    {
      ChangedProperty *i_cp = l->data;
      if (i_cp->info == info)
        {
          cp = i_cp;
          break;
        }
    }
  if (cp == NULL)
    {
      cp = g_new0 (ChangedProperty, 1);
      cp->prop_id = prop_id;
      cp->info = info;
      skeleton->priv->changed_properties = g_list_prepend (skeleton->priv->changed_properties, cp);
      g_value_init (&cp->orig_value, G_VALUE_TYPE (orig_value));
      g_value_copy (orig_value, &cp->orig_value);
    }
}

static void
gxdp_network_monitor_skeleton_notify (GObject      *object,
  GParamSpec *pspec G_GNUC_UNUSED)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);
  g_mutex_lock (&skeleton->priv->lock);
  if (skeleton->priv->changed_properties != NULL &&
      skeleton->priv->changed_properties_idle_source == NULL)
    {
      skeleton->priv->changed_properties_idle_source = g_idle_source_new ();
      g_source_set_priority (skeleton->priv->changed_properties_idle_source, G_PRIORITY_DEFAULT);
      g_source_set_callback (skeleton->priv->changed_properties_idle_source, _gxdp_network_monitor_emit_changed, g_object_ref (skeleton), (GDestroyNotify) g_object_unref);
      g_source_set_name (skeleton->priv->changed_properties_idle_source, "[generated] _gxdp_network_monitor_emit_changed");
      g_source_attach (skeleton->priv->changed_properties_idle_source, skeleton->priv->context);
      g_source_unref (skeleton->priv->changed_properties_idle_source);
    }
  g_mutex_unlock (&skeleton->priv->lock);
}

static void
gxdp_network_monitor_skeleton_set_property (GObject      *object,
  guint         prop_id,
  const GValue *value,
  GParamSpec   *pspec)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);
  g_assert (prop_id != 0 && prop_id - 1 < 3);
  g_mutex_lock (&skeleton->priv->lock);
  g_object_freeze_notify (object);
  if (!_g_value_equal (value, &skeleton->priv->properties[prop_id - 1]))
    {
      if (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)) != NULL)
        _gxdp_network_monitor_schedule_emit_changed (skeleton, _gxdp_network_monitor_property_info_pointers[prop_id - 1], prop_id, &skeleton->priv->properties[prop_id - 1]);
      g_value_copy (value, &skeleton->priv->properties[prop_id - 1]);
      g_object_notify_by_pspec (object, pspec);
    }
  g_mutex_unlock (&skeleton->priv->lock);
  g_object_thaw_notify (object);
}

static void
gxdp_network_monitor_skeleton_init (GXdpNetworkMonitorSkeleton *skeleton)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  skeleton->priv = gxdp_network_monitor_skeleton_get_instance_private (skeleton);
#else
  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, GXDP_TYPE_NETWORK_MONITOR_SKELETON, GXdpNetworkMonitorSkeletonPrivate);
#endif

  g_mutex_init (&skeleton->priv->lock);
  skeleton->priv->context = g_main_context_ref_thread_default ();
  skeleton->priv->properties = g_new0 (GValue, 3);
  g_value_init (&skeleton->priv->properties[0], G_TYPE_BOOLEAN);
  g_value_init (&skeleton->priv->properties[1], G_TYPE_BOOLEAN);
  g_value_init (&skeleton->priv->properties[2], G_TYPE_UINT);
}

static gboolean 
gxdp_network_monitor_skeleton_get_available (GXdpNetworkMonitor *object)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);
  gboolean value;
  g_mutex_lock (&skeleton->priv->lock);
  value = g_value_get_boolean (&(skeleton->priv->properties[0]));
  g_mutex_unlock (&skeleton->priv->lock);
  return value;
}

static gboolean 
gxdp_network_monitor_skeleton_get_metered (GXdpNetworkMonitor *object)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);
  gboolean value;
  g_mutex_lock (&skeleton->priv->lock);
  value = g_value_get_boolean (&(skeleton->priv->properties[1]));
  g_mutex_unlock (&skeleton->priv->lock);
  return value;
}

static guint 
gxdp_network_monitor_skeleton_get_connectivity (GXdpNetworkMonitor *object)
{
  GXdpNetworkMonitorSkeleton *skeleton = GXDP_NETWORK_MONITOR_SKELETON (object);
  guint value;
  g_mutex_lock (&skeleton->priv->lock);
  value = g_value_get_uint (&(skeleton->priv->properties[2]));
  g_mutex_unlock (&skeleton->priv->lock);
  return value;
}

static void
gxdp_network_monitor_skeleton_class_init (GXdpNetworkMonitorSkeletonClass *klass)
{
  GObjectClass *gobject_class;
  GDBusInterfaceSkeletonClass *skeleton_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = gxdp_network_monitor_skeleton_finalize;
  gobject_class->get_property = gxdp_network_monitor_skeleton_get_property;
  gobject_class->set_property = gxdp_network_monitor_skeleton_set_property;
  gobject_class->notify       = gxdp_network_monitor_skeleton_notify;


  gxdp_network_monitor_override_properties (gobject_class, 1);

  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
  skeleton_class->get_info = gxdp_network_monitor_skeleton_dbus_interface_get_info;
  skeleton_class->get_properties = gxdp_network_monitor_skeleton_dbus_interface_get_properties;
  skeleton_class->flush = gxdp_network_monitor_skeleton_dbus_interface_flush;
  skeleton_class->get_vtable = gxdp_network_monitor_skeleton_dbus_interface_get_vtable;

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (GXdpNetworkMonitorSkeletonPrivate));
#endif
}

static void
gxdp_network_monitor_skeleton_iface_init (GXdpNetworkMonitorIface *iface)
{
  iface->changed = _gxdp_network_monitor_on_signal_changed;
  iface->get_available = gxdp_network_monitor_skeleton_get_available;
  iface->get_metered = gxdp_network_monitor_skeleton_get_metered;
  iface->get_connectivity = gxdp_network_monitor_skeleton_get_connectivity;
}

/**
 * gxdp_network_monitor_skeleton_new:
 *
 * Creates a skeleton object for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-NetworkMonitor.top_of_page">org.freedesktop.portal.NetworkMonitor</link>.
 *
 * Returns: (transfer full) (type GXdpNetworkMonitorSkeleton): The skeleton object.
 */
GXdpNetworkMonitor *
gxdp_network_monitor_skeleton_new (void)
{
  return GXDP_NETWORK_MONITOR (g_object_new (GXDP_TYPE_NETWORK_MONITOR_SKELETON, NULL));
}

/* ------------------------------------------------------------------------
 * Code for interface org.freedesktop.portal.ProxyResolver
 * ------------------------------------------------------------------------
 */

/**
 * SECTION:GXdpProxyResolver
 * @title: GXdpProxyResolver
 * @short_description: Generated C code for the org.freedesktop.portal.ProxyResolver D-Bus interface
 *
 * This section contains code for working with the <link linkend="gdbus-interface-org-freedesktop-portal-ProxyResolver.top_of_page">org.freedesktop.portal.ProxyResolver</link> D-Bus interface in C.
 */

/* ---- Introspection data for org.freedesktop.portal.ProxyResolver ---- */

static const _ExtendedGDBusArgInfo _gxdp_proxy_resolver_method_info_lookup_IN_ARG_uri =
{
  {
    -1,
    (gchar *) "uri",
    (gchar *) "s",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_proxy_resolver_method_info_lookup_IN_ARG_pointers[] =
{
  &_gxdp_proxy_resolver_method_info_lookup_IN_ARG_uri,
  NULL
};

static const _ExtendedGDBusArgInfo _gxdp_proxy_resolver_method_info_lookup_OUT_ARG_proxies =
{
  {
    -1,
    (gchar *) "proxies",
    (gchar *) "as",
    NULL
  },
  FALSE
};

static const _ExtendedGDBusArgInfo * const _gxdp_proxy_resolver_method_info_lookup_OUT_ARG_pointers[] =
{
  &_gxdp_proxy_resolver_method_info_lookup_OUT_ARG_proxies,
  NULL
};

static const _ExtendedGDBusMethodInfo _gxdp_proxy_resolver_method_info_lookup =
{
  {
    -1,
    (gchar *) "Lookup",
    (GDBusArgInfo **) &_gxdp_proxy_resolver_method_info_lookup_IN_ARG_pointers,
    (GDBusArgInfo **) &_gxdp_proxy_resolver_method_info_lookup_OUT_ARG_pointers,
    NULL
  },
  "handle-lookup",
  FALSE
};

static const _ExtendedGDBusMethodInfo * const _gxdp_proxy_resolver_method_info_pointers[] =
{
  &_gxdp_proxy_resolver_method_info_lookup,
  NULL
};

static const _ExtendedGDBusInterfaceInfo _gxdp_proxy_resolver_interface_info =
{
  {
    -1,
    (gchar *) "org.freedesktop.portal.ProxyResolver",
    (GDBusMethodInfo **) &_gxdp_proxy_resolver_method_info_pointers,
    NULL,
    NULL,
    NULL
  },
  "proxy-resolver",
};


/**
 * gxdp_proxy_resolver_interface_info:
 *
 * Gets a machine-readable description of the <link linkend="gdbus-interface-org-freedesktop-portal-ProxyResolver.top_of_page">org.freedesktop.portal.ProxyResolver</link> D-Bus interface.
 *
 * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
 */
GDBusInterfaceInfo *
gxdp_proxy_resolver_interface_info (void)
{
  return (GDBusInterfaceInfo *) &_gxdp_proxy_resolver_interface_info.parent_struct;
}

/**
 * gxdp_proxy_resolver_override_properties:
 * @klass: The class structure for a #GObject<!-- -->-derived class.
 * @property_id_begin: The property id to assign to the first overridden property.
 *
 * Overrides all #GObject properties in the #GXdpProxyResolver interface for a concrete class.
 * The properties are overridden in the order they are defined.
 *
 * Returns: The last property id.
 */
guint
gxdp_proxy_resolver_override_properties (GObjectClass *klass, guint property_id_begin)
{
  return property_id_begin - 1;
}



/**
 * GXdpProxyResolver:
 *
 * Abstract interface type for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-ProxyResolver.top_of_page">org.freedesktop.portal.ProxyResolver</link>.
 */

/**
 * GXdpProxyResolverIface:
 * @parent_iface: The parent interface.
 * @handle_lookup: Handler for the #GXdpProxyResolver::handle-lookup signal.
 *
 * Virtual table for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-ProxyResolver.top_of_page">org.freedesktop.portal.ProxyResolver</link>.
 */

typedef GXdpProxyResolverIface GXdpProxyResolverInterface;
G_DEFINE_INTERFACE (GXdpProxyResolver, gxdp_proxy_resolver, G_TYPE_OBJECT);

static void
gxdp_proxy_resolver_default_init (GXdpProxyResolverIface *iface)
{
  /* GObject signals for incoming D-Bus method calls: */
  /**
   * GXdpProxyResolver::handle-lookup:
   * @object: A #GXdpProxyResolver.
   * @invocation: A #GDBusMethodInvocation.
   * @arg_uri: Argument passed by remote caller.
   *
   * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-org-freedesktop-portal-ProxyResolver.Lookup">Lookup()</link> D-Bus method.
   *
   * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_proxy_resolver_complete_lookup() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned.
   *
   * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run.
   */
  g_signal_new ("handle-lookup",
    G_TYPE_FROM_INTERFACE (iface),
    G_SIGNAL_RUN_LAST,
    G_STRUCT_OFFSET (GXdpProxyResolverIface, handle_lookup),
    g_signal_accumulator_true_handled,
    NULL,
    g_cclosure_marshal_generic,
    G_TYPE_BOOLEAN,
    2,
    G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING);

}

/**
 * gxdp_proxy_resolver_call_lookup:
 * @proxy: A #GXdpProxyResolverProxy.
 * @arg_uri: Argument to pass with the method invocation.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-ProxyResolver.Lookup">Lookup()</link> D-Bus method on @proxy.
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_proxy_resolver_call_lookup_finish() to get the result of the operation.
 *
 * See gxdp_proxy_resolver_call_lookup_sync() for the synchronous, blocking version of this method.
 */
void
gxdp_proxy_resolver_call_lookup (
    GXdpProxyResolver *proxy,
    const gchar *arg_uri,
    GCancellable *cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data)
{
  g_dbus_proxy_call (G_DBUS_PROXY (proxy),
    "Lookup",
    g_variant_new ("(s)",
                   arg_uri),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    callback,
    user_data);
}

/**
 * gxdp_proxy_resolver_call_lookup_finish:
 * @proxy: A #GXdpProxyResolverProxy.
 * @out_proxies: (out): Return location for return parameter or %NULL to ignore.
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_proxy_resolver_call_lookup().
 * @error: Return location for error or %NULL.
 *
 * Finishes an operation started with gxdp_proxy_resolver_call_lookup().
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_proxy_resolver_call_lookup_finish (
    GXdpProxyResolver *proxy,
    gchar ***out_proxies,
    GAsyncResult *res,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(^as)",
                 out_proxies);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_proxy_resolver_call_lookup_sync:
 * @proxy: A #GXdpProxyResolverProxy.
 * @arg_uri: Argument to pass with the method invocation.
 * @out_proxies: (out): Return location for return parameter or %NULL to ignore.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL.
 *
 * Synchronously invokes the <link linkend="gdbus-method-org-freedesktop-portal-ProxyResolver.Lookup">Lookup()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received.
 *
 * See gxdp_proxy_resolver_call_lookup() for the asynchronous version of this method.
 *
 * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set.
 */
gboolean
gxdp_proxy_resolver_call_lookup_sync (
    GXdpProxyResolver *proxy,
    const gchar *arg_uri,
    gchar ***out_proxies,
    GCancellable *cancellable,
    GError **error)
{
  GVariant *_ret;
  _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy),
    "Lookup",
    g_variant_new ("(s)",
                   arg_uri),
    G_DBUS_CALL_FLAGS_NONE,
    -1,
    cancellable,
    error);
  if (_ret == NULL)
    goto _out;
  g_variant_get (_ret,
                 "(^as)",
                 out_proxies);
  g_variant_unref (_ret);
_out:
  return _ret != NULL;
}

/**
 * gxdp_proxy_resolver_complete_lookup:
 * @object: A #GXdpProxyResolver.
 * @invocation: (transfer full): A #GDBusMethodInvocation.
 * @proxies: Parameter to return.
 *
 * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-org-freedesktop-portal-ProxyResolver.Lookup">Lookup()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar.
 *
 * This method will free @invocation, you cannot use it afterwards.
 */
void
gxdp_proxy_resolver_complete_lookup (
    GXdpProxyResolver *object,
    GDBusMethodInvocation *invocation,
    const gchar *const *proxies)
{
  g_dbus_method_invocation_return_value (invocation,
    g_variant_new ("(^as)",
                   proxies));
}

/* ------------------------------------------------------------------------ */

/**
 * GXdpProxyResolverProxy:
 *
 * The #GXdpProxyResolverProxy structure contains only private data and should only be accessed using the provided API.
 */

/**
 * GXdpProxyResolverProxyClass:
 * @parent_class: The parent class.
 *
 * Class structure for #GXdpProxyResolverProxy.
 */

struct _GXdpProxyResolverProxyPrivate
{
  GData *qdata;
};

static void gxdp_proxy_resolver_proxy_iface_init (GXdpProxyResolverIface *iface);

#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (GXdpProxyResolverProxy, gxdp_proxy_resolver_proxy, G_TYPE_DBUS_PROXY,
                         G_ADD_PRIVATE (GXdpProxyResolverProxy)
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_PROXY_RESOLVER, gxdp_proxy_resolver_proxy_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (GXdpProxyResolverProxy, gxdp_proxy_resolver_proxy, G_TYPE_DBUS_PROXY,
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_PROXY_RESOLVER, gxdp_proxy_resolver_proxy_iface_init));

#endif
static void
gxdp_proxy_resolver_proxy_finalize (GObject *object)
{
  GXdpProxyResolverProxy *proxy = GXDP_PROXY_RESOLVER_PROXY (object);
  g_datalist_clear (&proxy->priv->qdata);
  G_OBJECT_CLASS (gxdp_proxy_resolver_proxy_parent_class)->finalize (object);
}

static void
gxdp_proxy_resolver_proxy_get_property (GObject      *object,
  guint         prop_id,
  GValue       *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
}

static void
gxdp_proxy_resolver_proxy_set_property (GObject      *object,
  guint         prop_id,
  const GValue *value,
  GParamSpec   *pspec G_GNUC_UNUSED)
{
}

static void
gxdp_proxy_resolver_proxy_g_signal (GDBusProxy *proxy,
  const gchar *sender_name G_GNUC_UNUSED,
  const gchar *signal_name,
  GVariant *parameters)
{
  _ExtendedGDBusSignalInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint n;
  guint signal_id;
  info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_gxdp_proxy_resolver_interface_info.parent_struct, signal_name);
  if (info == NULL)
    return;
  num_params = g_variant_n_children (parameters);
  paramv = g_new0 (GValue, num_params + 1);
  g_value_init (&paramv[0], GXDP_TYPE_PROXY_RESOLVER);
  g_value_set_object (&paramv[0], proxy);
  g_variant_iter_init (&iter, parameters);
  n = 1;
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, GXDP_TYPE_PROXY_RESOLVER);
  g_signal_emitv (paramv, signal_id, 0, NULL);
  for (n = 0; n < num_params + 1; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static void
gxdp_proxy_resolver_proxy_g_properties_changed (GDBusProxy *_proxy,
  GVariant *changed_properties,
  const gchar *const *invalidated_properties)
{
  GXdpProxyResolverProxy *proxy = GXDP_PROXY_RESOLVER_PROXY (_proxy);
  guint n;
  const gchar *key;
  GVariantIter *iter;
  _ExtendedGDBusPropertyInfo *info;
  g_variant_get (changed_properties, "a{sv}", &iter);
  while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_proxy_resolver_interface_info.parent_struct, key);
      g_datalist_remove_data (&proxy->priv->qdata, key);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
  g_variant_iter_free (iter);
  for (n = 0; invalidated_properties[n] != NULL; n++)
    {
      info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_proxy_resolver_interface_info.parent_struct, invalidated_properties[n]);
      g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]);
      if (info != NULL)
        g_object_notify (G_OBJECT (proxy), info->hyphen_name);
    }
}

static void
gxdp_proxy_resolver_proxy_init (GXdpProxyResolverProxy *proxy)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  proxy->priv = gxdp_proxy_resolver_proxy_get_instance_private (proxy);
#else
  proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, GXDP_TYPE_PROXY_RESOLVER_PROXY, GXdpProxyResolverProxyPrivate);
#endif

  g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), gxdp_proxy_resolver_interface_info ());
}

static void
gxdp_proxy_resolver_proxy_class_init (GXdpProxyResolverProxyClass *klass)
{
  GObjectClass *gobject_class;
  GDBusProxyClass *proxy_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize     = gxdp_proxy_resolver_proxy_finalize;
  gobject_class->get_property = gxdp_proxy_resolver_proxy_get_property;
  gobject_class->set_property = gxdp_proxy_resolver_proxy_set_property;

  proxy_class = G_DBUS_PROXY_CLASS (klass);
  proxy_class->g_signal = gxdp_proxy_resolver_proxy_g_signal;
  proxy_class->g_properties_changed = gxdp_proxy_resolver_proxy_g_properties_changed;

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (GXdpProxyResolverProxyPrivate));
#endif
}

static void
gxdp_proxy_resolver_proxy_iface_init (GXdpProxyResolverIface *iface)
{
}

/**
 * gxdp_proxy_resolver_proxy_new:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Asynchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-ProxyResolver.top_of_page">org.freedesktop.portal.ProxyResolver</link>. See g_dbus_proxy_new() for more details.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_proxy_resolver_proxy_new_finish() to get the result of the operation.
 *
 * See gxdp_proxy_resolver_proxy_new_sync() for the synchronous, blocking version of this constructor.
 */
void
gxdp_proxy_resolver_proxy_new (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (GXDP_TYPE_PROXY_RESOLVER_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.ProxyResolver", NULL);
}

/**
 * gxdp_proxy_resolver_proxy_new_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_proxy_resolver_proxy_new().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with gxdp_proxy_resolver_proxy_new().
 *
 * Returns: (transfer full) (type GXdpProxyResolverProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpProxyResolver *
gxdp_proxy_resolver_proxy_new_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return GXDP_PROXY_RESOLVER (ret);
  else
    return NULL;
}

/**
 * gxdp_proxy_resolver_proxy_new_sync:
 * @connection: A #GDBusConnection.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection.
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Synchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-ProxyResolver.top_of_page">org.freedesktop.portal.ProxyResolver</link>. See g_dbus_proxy_new_sync() for more details.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See gxdp_proxy_resolver_proxy_new() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type GXdpProxyResolverProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpProxyResolver *
gxdp_proxy_resolver_proxy_new_sync (
    GDBusConnection     *connection,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (GXDP_TYPE_PROXY_RESOLVER_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.ProxyResolver", NULL);
  if (ret != NULL)
    return GXDP_PROXY_RESOLVER (ret);
  else
    return NULL;
}


/**
 * gxdp_proxy_resolver_proxy_new_for_bus:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
 * @user_data: User data to pass to @callback.
 *
 * Like gxdp_proxy_resolver_proxy_new() but takes a #GBusType instead of a #GDBusConnection.
 *
 * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from.
 * You can then call gxdp_proxy_resolver_proxy_new_for_bus_finish() to get the result of the operation.
 *
 * See gxdp_proxy_resolver_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor.
 */
void
gxdp_proxy_resolver_proxy_new_for_bus (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GAsyncReadyCallback  callback,
    gpointer             user_data)
{
  g_async_initable_new_async (GXDP_TYPE_PROXY_RESOLVER_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.ProxyResolver", NULL);
}

/**
 * gxdp_proxy_resolver_proxy_new_for_bus_finish:
 * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to gxdp_proxy_resolver_proxy_new_for_bus().
 * @error: Return location for error or %NULL
 *
 * Finishes an operation started with gxdp_proxy_resolver_proxy_new_for_bus().
 *
 * Returns: (transfer full) (type GXdpProxyResolverProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpProxyResolver *
gxdp_proxy_resolver_proxy_new_for_bus_finish (
    GAsyncResult        *res,
    GError             **error)
{
  GObject *ret;
  GObject *source_object;
  source_object = g_async_result_get_source_object (res);
  ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error);
  g_object_unref (source_object);
  if (ret != NULL)
    return GXDP_PROXY_RESOLVER (ret);
  else
    return NULL;
}

/**
 * gxdp_proxy_resolver_proxy_new_for_bus_sync:
 * @bus_type: A #GBusType.
 * @flags: Flags from the #GDBusProxyFlags enumeration.
 * @name: A bus name (well-known or unique).
 * @object_path: An object path.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: Return location for error or %NULL
 *
 * Like gxdp_proxy_resolver_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection.
 *
 * The calling thread is blocked until a reply is received.
 *
 * See gxdp_proxy_resolver_proxy_new_for_bus() for the asynchronous version of this constructor.
 *
 * Returns: (transfer full) (type GXdpProxyResolverProxy): The constructed proxy object or %NULL if @error is set.
 */
GXdpProxyResolver *
gxdp_proxy_resolver_proxy_new_for_bus_sync (
    GBusType             bus_type,
    GDBusProxyFlags      flags,
    const gchar         *name,
    const gchar         *object_path,
    GCancellable        *cancellable,
    GError             **error)
{
  GInitable *ret;
  ret = g_initable_new (GXDP_TYPE_PROXY_RESOLVER_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "org.freedesktop.portal.ProxyResolver", NULL);
  if (ret != NULL)
    return GXDP_PROXY_RESOLVER (ret);
  else
    return NULL;
}


/* ------------------------------------------------------------------------ */

/**
 * GXdpProxyResolverSkeleton:
 *
 * The #GXdpProxyResolverSkeleton structure contains only private data and should only be accessed using the provided API.
 */

/**
 * GXdpProxyResolverSkeletonClass:
 * @parent_class: The parent class.
 *
 * Class structure for #GXdpProxyResolverSkeleton.
 */

struct _GXdpProxyResolverSkeletonPrivate
{
  GValue *properties;
  GList *changed_properties;
  GSource *changed_properties_idle_source;
  GMainContext *context;
  GMutex lock;
};

static void
_gxdp_proxy_resolver_skeleton_handle_method_call (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name,
  const gchar *method_name,
  GVariant *parameters,
  GDBusMethodInvocation *invocation,
  gpointer user_data)
{
  GXdpProxyResolverSkeleton *skeleton = GXDP_PROXY_RESOLVER_SKELETON (user_data);
  _ExtendedGDBusMethodInfo *info;
  GVariantIter iter;
  GVariant *child;
  GValue *paramv;
  guint num_params;
  guint num_extra;
  guint n;
  guint signal_id;
  GValue return_value = G_VALUE_INIT;
  info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);
  g_assert (info != NULL);
  num_params = g_variant_n_children (parameters);
  num_extra = info->pass_fdlist ? 3 : 2;  paramv = g_new0 (GValue, num_params + num_extra);
  n = 0;
  g_value_init (&paramv[n], GXDP_TYPE_PROXY_RESOLVER);
  g_value_set_object (&paramv[n++], skeleton);
  g_value_init (&paramv[n], G_TYPE_DBUS_METHOD_INVOCATION);
  g_value_set_object (&paramv[n++], invocation);
  if (info->pass_fdlist)
    {
#ifdef G_OS_UNIX
      g_value_init (&paramv[n], G_TYPE_UNIX_FD_LIST);
      g_value_set_object (&paramv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation)));
#else
      g_assert_not_reached ();
#endif
    }
  g_variant_iter_init (&iter, parameters);
  while ((child = g_variant_iter_next_value (&iter)) != NULL)
    {
      _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra];
      if (arg_info->use_gvariant)
        {
          g_value_init (&paramv[n], G_TYPE_VARIANT);
          g_value_set_variant (&paramv[n], child);
          n++;
        }
      else
        g_dbus_gvariant_to_gvalue (child, &paramv[n++]);
      g_variant_unref (child);
    }
  signal_id = g_signal_lookup (info->signal_name, GXDP_TYPE_PROXY_RESOLVER);
  g_value_init (&return_value, G_TYPE_BOOLEAN);
  g_signal_emitv (paramv, signal_id, 0, &return_value);
  if (!g_value_get_boolean (&return_value))
    g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name);
  g_value_unset (&return_value);
  for (n = 0; n < num_params + num_extra; n++)
    g_value_unset (&paramv[n]);
  g_free (paramv);
}

static GVariant *
_gxdp_proxy_resolver_skeleton_handle_get_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GError **error,
  gpointer user_data)
{
  GXdpProxyResolverSkeleton *skeleton = GXDP_PROXY_RESOLVER_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  GVariant *ret;
  ret = NULL;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_proxy_resolver_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      g_value_init (&value, pspec->value_type);
      g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature));
      g_value_unset (&value);
    }
  return ret;
}

static gboolean
_gxdp_proxy_resolver_skeleton_handle_set_property (
  GDBusConnection *connection G_GNUC_UNUSED,
  const gchar *sender G_GNUC_UNUSED,
  const gchar *object_path G_GNUC_UNUSED,
  const gchar *interface_name G_GNUC_UNUSED,
  const gchar *property_name,
  GVariant *variant,
  GError **error,
  gpointer user_data)
{
  GXdpProxyResolverSkeleton *skeleton = GXDP_PROXY_RESOLVER_SKELETON (user_data);
  GValue value = G_VALUE_INIT;
  GParamSpec *pspec;
  _ExtendedGDBusPropertyInfo *info;
  gboolean ret;
  ret = FALSE;
  info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_gxdp_proxy_resolver_interface_info.parent_struct, property_name);
  g_assert (info != NULL);
  pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name);
  if (pspec == NULL)
    {
      g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name);
    }
  else
    {
      if (info->use_gvariant)
        g_value_set_variant (&value, variant);
      else
        g_dbus_gvariant_to_gvalue (variant, &value);
      g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value);
      g_value_unset (&value);
      ret = TRUE;
    }
  return ret;
}

static const GDBusInterfaceVTable _gxdp_proxy_resolver_skeleton_vtable =
{
  _gxdp_proxy_resolver_skeleton_handle_method_call,
  _gxdp_proxy_resolver_skeleton_handle_get_property,
  _gxdp_proxy_resolver_skeleton_handle_set_property,
  {NULL}
};

static GDBusInterfaceInfo *
gxdp_proxy_resolver_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return gxdp_proxy_resolver_interface_info ();
}

static GDBusInterfaceVTable *
gxdp_proxy_resolver_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton G_GNUC_UNUSED)
{
  return (GDBusInterfaceVTable *) &_gxdp_proxy_resolver_skeleton_vtable;
}

static GVariant *
gxdp_proxy_resolver_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton)
{
  GXdpProxyResolverSkeleton *skeleton = GXDP_PROXY_RESOLVER_SKELETON (_skeleton);

  GVariantBuilder builder;
  guint n;
  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
  if (_gxdp_proxy_resolver_interface_info.parent_struct.properties == NULL)
    goto out;
  for (n = 0; _gxdp_proxy_resolver_interface_info.parent_struct.properties[n] != NULL; n++)
    {
      GDBusPropertyInfo *info = _gxdp_proxy_resolver_interface_info.parent_struct.properties[n];
      if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE)
        {
          GVariant *value;
          value = _gxdp_proxy_resolver_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "org.freedesktop.portal.ProxyResolver", info->name, NULL, skeleton);
          if (value != NULL)
            {
              g_variant_take_ref (value);
              g_variant_builder_add (&builder, "{sv}", info->name, value);
              g_variant_unref (value);
            }
        }
    }
out:
  return g_variant_builder_end (&builder);
}

static void
gxdp_proxy_resolver_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton)
{
}

static void gxdp_proxy_resolver_skeleton_iface_init (GXdpProxyResolverIface *iface);
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
G_DEFINE_TYPE_WITH_CODE (GXdpProxyResolverSkeleton, gxdp_proxy_resolver_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_ADD_PRIVATE (GXdpProxyResolverSkeleton)
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_PROXY_RESOLVER, gxdp_proxy_resolver_skeleton_iface_init));

#else
G_DEFINE_TYPE_WITH_CODE (GXdpProxyResolverSkeleton, gxdp_proxy_resolver_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                         G_IMPLEMENT_INTERFACE (GXDP_TYPE_PROXY_RESOLVER, gxdp_proxy_resolver_skeleton_iface_init));

#endif
static void
gxdp_proxy_resolver_skeleton_finalize (GObject *object)
{
  GXdpProxyResolverSkeleton *skeleton = GXDP_PROXY_RESOLVER_SKELETON (object);
  g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free);
  if (skeleton->priv->changed_properties_idle_source != NULL)
    g_source_destroy (skeleton->priv->changed_properties_idle_source);
  g_main_context_unref (skeleton->priv->context);
  g_mutex_clear (&skeleton->priv->lock);
  G_OBJECT_CLASS (gxdp_proxy_resolver_skeleton_parent_class)->finalize (object);
}

static void
gxdp_proxy_resolver_skeleton_init (GXdpProxyResolverSkeleton *skeleton)
{
#if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
  skeleton->priv = gxdp_proxy_resolver_skeleton_get_instance_private (skeleton);
#else
  skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, GXDP_TYPE_PROXY_RESOLVER_SKELETON, GXdpProxyResolverSkeletonPrivate);
#endif

  g_mutex_init (&skeleton->priv->lock);
  skeleton->priv->context = g_main_context_ref_thread_default ();
}

static void
gxdp_proxy_resolver_skeleton_class_init (GXdpProxyResolverSkeletonClass *klass)
{
  GObjectClass *gobject_class;
  GDBusInterfaceSkeletonClass *skeleton_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->finalize = gxdp_proxy_resolver_skeleton_finalize;

  skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
  skeleton_class->get_info = gxdp_proxy_resolver_skeleton_dbus_interface_get_info;
  skeleton_class->get_properties = gxdp_proxy_resolver_skeleton_dbus_interface_get_properties;
  skeleton_class->flush = gxdp_proxy_resolver_skeleton_dbus_interface_flush;
  skeleton_class->get_vtable = gxdp_proxy_resolver_skeleton_dbus_interface_get_vtable;

#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38
  g_type_class_add_private (klass, sizeof (GXdpProxyResolverSkeletonPrivate));
#endif
}

static void
gxdp_proxy_resolver_skeleton_iface_init (GXdpProxyResolverIface *iface)
{
}

/**
 * gxdp_proxy_resolver_skeleton_new:
 *
 * Creates a skeleton object for the D-Bus interface <link linkend="gdbus-interface-org-freedesktop-portal-ProxyResolver.top_of_page">org.freedesktop.portal.ProxyResolver</link>.
 *
 * Returns: (transfer full) (type GXdpProxyResolverSkeleton): The skeleton object.
 */
GXdpProxyResolver *
gxdp_proxy_resolver_skeleton_new (void)
{
  return GXDP_PROXY_RESOLVER (g_object_new (GXDP_TYPE_PROXY_RESOLVER_SKELETON, NULL));
}

