Esempio n. 1
0
/**
 * g_dbus_object_skeleton_set_object_path:
 * @object: A #GDBusObjectSkeleton.
 * @object_path: A valid D-Bus object path.
 *
 * Sets the object path for @object.
 *
 * Since: 2.30
 */
void
g_dbus_object_skeleton_set_object_path (GDBusObjectSkeleton *object,
                                        const gchar     *object_path)
{
  g_return_if_fail (G_IS_DBUS_OBJECT_SKELETON (object));
  g_return_if_fail (object_path == NULL || g_variant_is_object_path (object_path));
  g_mutex_lock (object->priv->lock);
  /* TODO: fail if object is currently exported */
  if (g_strcmp0 (object->priv->object_path, object_path) != 0)
    {
      g_free (object->priv->object_path);
      object->priv->object_path = g_strdup (object_path);
      g_mutex_unlock (object->priv->lock);
      g_object_notify (G_OBJECT (object), "object-path");
    }
  else
    {
      g_mutex_unlock (object->priv->lock);
    }
}
/* < internal >
 * _g_dbus_method_invocation_new:
 * @sender: (allow-none): The bus name that invoked the method or %NULL if @connection is not a bus connection.
 * @object_path: The object path the method was invoked on.
 * @interface_name: The name of the D-Bus interface the method was invoked on.
 * @method_name: The name of the method that was invoked.
 * @method_info: (allow-none): Information about the method call or %NULL.
 * @property_info: (allow-none): Information about the property or %NULL.
 * @connection: The #GDBusConnection the method was invoked on.
 * @message: The D-Bus message as a #GDBusMessage.
 * @parameters: The parameters as a #GVariant tuple.
 * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_object().
 *
 * Creates a new #GDBusMethodInvocation object.
 *
 * Returns: A #GDBusMethodInvocation. Free with g_object_unref().
 *
 * Since: 2.26
 */
GDBusMethodInvocation *
_g_dbus_method_invocation_new (const gchar             *sender,
                               const gchar             *object_path,
                               const gchar             *interface_name,
                               const gchar             *method_name,
                               const GDBusMethodInfo   *method_info,
                               const GDBusPropertyInfo *property_info,
                               GDBusConnection         *connection,
                               GDBusMessage            *message,
                               GVariant                *parameters,
                               gpointer                 user_data)
{
  GDBusMethodInvocation *invocation;

  g_return_val_if_fail (sender == NULL || g_dbus_is_name (sender), NULL);
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  g_return_val_if_fail (interface_name == NULL || g_dbus_is_interface_name (interface_name), NULL);
  g_return_val_if_fail (g_dbus_is_member_name (method_name), NULL);
  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
  g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
  g_return_val_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);

  invocation = G_DBUS_METHOD_INVOCATION (g_object_new (G_TYPE_DBUS_METHOD_INVOCATION, NULL));
  invocation->sender = g_strdup (sender);
  invocation->object_path = g_strdup (object_path);
  invocation->interface_name = g_strdup (interface_name);
  invocation->method_name = g_strdup (method_name);
  if (method_info)
    invocation->method_info = g_dbus_method_info_ref ((GDBusMethodInfo *)method_info);
  if (property_info)
    invocation->property_info = g_dbus_property_info_ref ((GDBusPropertyInfo *)property_info);
  invocation->connection = g_object_ref (connection);
  invocation->message = g_object_ref (message);
  invocation->parameters = g_variant_ref (parameters);
  invocation->user_data = user_data;

  return invocation;
}
Esempio n. 3
0
static gboolean
terminal_factory_impl_create_instance (TerminalFactory *factory,
                                       GDBusMethodInvocation *invocation,
                                       GVariant *options)
{
  TerminalApp *app = terminal_app_get ();
  TerminalSettingsList *profiles_list;
  GDBusObjectManagerServer *object_manager;
  TerminalWindow *window;
  TerminalScreen *screen;
  TerminalReceiverImpl *impl;
  TerminalObjectSkeleton *skeleton;
  char *object_path;
  GSettings *profile = NULL;
  const char *profile_uuid, *title, *encoding;
  gboolean zoom_set = FALSE;
  gdouble zoom = 1.0;
  guint window_id;
  gboolean show_menubar;
  gboolean active;
  gboolean have_new_window, present_window, present_window_set;
  GError *err = NULL;

  /* Look up the profile */
  if (!g_variant_lookup (options, "profile", "&s", &profile_uuid))
    profile_uuid = NULL;

  if (!g_variant_lookup (options, "encoding", "&s", &encoding))
    encoding = NULL; /* use profile encoding */

  profiles_list = terminal_app_get_profiles_list (app);
  profile = terminal_profiles_list_ref_profile_by_uuid (profiles_list, profile_uuid, &err);
  if (profile == NULL)
    {
      g_dbus_method_invocation_return_gerror (invocation, err);
      g_error_free (err);
      goto out;
    }

  if (g_variant_lookup (options, "window-id", "u", &window_id)) {
    GtkWindow *win;

    win = gtk_application_get_window_by_id (GTK_APPLICATION (app), window_id);

    if (!TERMINAL_IS_WINDOW (win)) {
      g_dbus_method_invocation_return_error (invocation,
                                             G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "Nonexisting window %u referenced",
                                             window_id);
      goto out;
    }

    window = TERMINAL_WINDOW (win);
    have_new_window = FALSE;
  } else {
    const char *startup_id, *display_name, *role;
    gboolean start_maximized, start_fullscreen;
    int screen_number;
    GdkScreen *gdk_screen;

    /* Create a new window */

    if (!g_variant_lookup (options, "display", "^&ay", &display_name)) {
      g_dbus_method_invocation_return_error_literal (invocation, 
                                                     G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                                     "No display specified");
      goto out;
    }

    screen_number = 0;
    gdk_screen = terminal_util_get_screen_by_display_name (display_name, screen_number);
    if (gdk_screen == NULL) {
      g_dbus_method_invocation_return_error (invocation, 
                                             G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
                                             "No screen %d on display \"%s\"",
                                             screen_number, display_name);
      goto out;
    }

    window = terminal_app_new_window (app, gdk_screen);

    if (g_variant_lookup (options, "desktop-startup-id", "^&ay", &startup_id))
      gtk_window_set_startup_id (GTK_WINDOW (window), startup_id);

    /* Overwrite the default, unique window role set in terminal_window_init */
    if (g_variant_lookup (options, "role", "&s", &role))
      gtk_window_set_role (GTK_WINDOW (window), role);

    if (g_variant_lookup (options, "show-menubar", "b", &show_menubar))
      terminal_window_set_menubar_visible (window, show_menubar);

    if (g_variant_lookup (options, "fullscreen-window", "b", &start_fullscreen) &&
        start_fullscreen) {
      gtk_window_fullscreen (GTK_WINDOW (window));
    }
    if (g_variant_lookup (options, "maximize-window", "b", &start_maximized) &&
        start_maximized) {
      gtk_window_maximize (GTK_WINDOW (window));
    }

    have_new_window = TRUE;
  }

  g_assert (window != NULL);

  if (!g_variant_lookup (options, "title", "&s", &title))
    title = NULL;
  if (g_variant_lookup (options, "zoom", "d", &zoom))
    zoom_set = TRUE;

  screen = terminal_screen_new (profile, encoding, NULL, title, NULL, NULL,
                                zoom_set ? zoom : 1.0);
  terminal_window_add_screen (window, screen, -1);

  object_path = get_object_path_for_screen (window, screen);
  g_assert (g_variant_is_object_path (object_path));

  skeleton = terminal_object_skeleton_new (object_path);
  impl = terminal_receiver_impl_new (screen);
  terminal_object_skeleton_set_receiver (skeleton, TERMINAL_RECEIVER (impl));
  g_object_unref (impl);

  object_manager = terminal_app_get_object_manager (app);
  g_dbus_object_manager_server_export (object_manager, G_DBUS_OBJECT_SKELETON (skeleton));
  g_object_set_data_full (G_OBJECT (screen), RECEIVER_IMPL_SKELETON_DATA_KEY,
                          skeleton, (GDestroyNotify) g_object_unref);
  g_signal_connect (screen, "destroy",
                    G_CALLBACK (screen_destroy_cb), app);

  if (g_variant_lookup (options, "active", "b", &active) &&
      active) {
    terminal_window_switch_screen (window, screen);
    gtk_widget_grab_focus (GTK_WIDGET (screen));
  }

  if (g_variant_lookup (options, "present-window", "b", &present_window))
    present_window_set = TRUE;
  else
    present_window_set = FALSE;

  if (have_new_window) {
    const char *geometry;

    if (g_variant_lookup (options, "geometry", "&s", &geometry) &&
        !terminal_window_parse_geometry (window, geometry))
      _terminal_debug_print (TERMINAL_DEBUG_GEOMETRY,
                             "Invalid geometry string \"%s\"", geometry);
  }

  if (have_new_window || (present_window_set && present_window))
    gtk_window_present (GTK_WINDOW (window));

  terminal_factory_complete_create_instance (factory, invocation, object_path);

  g_free (object_path);

out:
  if (profile)
    g_object_unref (profile);

  return TRUE; /* handled */
}
Esempio n. 4
0
/**
 * Initialize GATT descriptor fields.
 *
 * This function initializes the @c CAGattDescriptor object fields.
 *
 * @param[out] c               Information about GATT characteristic
 *                             to which the descriptor belongs.
 * @param[in]  connection      D-Bus connection to the bus on which
 *                             the descriptor will be exported.
 * @param[in]  s               Information about GATT service
 *                             information to which the descriptor
 *                             belongs.
 * @param[in]  descriptor_path @c GattDescriptor1 object path for the
 *                             user description descriptor.
 * @param[in]  value           User description descriptor value,
 *                             e.g. @c "OIC Node Request" or
 *                             @c "OIC Node Response".
 *
 * @note This function does not allocate the @a descriptor object
 *       itself.  The caller is responsible for allocating that
 *       memory.
 *
 * @todo Too many parameters.  Perhaps pass in a pointer to a struct
 *       instead.
 */
static bool CAGattDescriptorInitialize(CAGattCharacteristic * c,
                                       GDBusConnection * connection,
                                       CAGattService * s,
                                       char const * descriptor_path,
                                       char const * value)
{
    (void)s;
    CAGattDescriptor * const d = &c->descriptor;

    // Path of the form /org/iotivity/gatt/hci0/service0/char0/desc0.
    d->object_path =
        g_strdup_printf("%s/%s", c->object_path, descriptor_path);
    assert(g_variant_is_object_path(d->object_path));

    d->descriptor = gatt_descriptor1_skeleton_new();

    gatt_descriptor1_set_uuid(
        d->descriptor,
        CA_GATT_CHRC_USER_DESCRIPTION_DESC_UUID);

    gatt_descriptor1_set_characteristic(d->descriptor,
                                        c->object_path);

    gatt_descriptor1_set_value (d->descriptor,
                                g_variant_new_bytestring(value));

    // Readable, no encryption, no authorization.
    static char const * const flags[] = { "read", NULL };
    gatt_descriptor1_set_flags(d->descriptor, flags);

    /*
      Connect the signal handler that implements the
      orb.bluez.GattDescriptor1.ReadValue() method.
    */
    g_signal_connect(d->descriptor,
                     "handle-read-value",
                     G_CALLBACK(CAGattDescriptorReadValue),
                     NULL);

    // Export the descriptor interface on the bus.
    GError * error = NULL;
    if (!g_dbus_interface_skeleton_export(
            G_DBUS_INTERFACE_SKELETON(d->descriptor),
            connection,
            d->object_path,
            &error))
    {
        CAGattDescriptorDestroy(d);

        OIC_LOG_V(ERROR,
                  TAG,
                  "Unable to export D-Bus GATT descriptor "
                  "interface: %s",
                  error->message);

        g_error_free(error);

        return false;
    }

    return true;
}
// ret:
// 0: change to another session
// 1: stay current session
int
switch_to_greeter(gchar *seat_path, struct user_session_dbus *usd)
{
    int ret = 1;
    char **sessions = NULL;
    char *seat = NULL;
    char *display = NULL;
    char *cur_seat = NULL;
    gchar **strlist = NULL;
    char *new_user_session = NULL;
    GDBusProxy *seat_proxy = NULL;
    GDBusProxy *login1_proxy = NULL;
    GError *error = NULL;

    if (!g_variant_is_object_path(seat_path)) {
        g_warning("switchtogreeter:invalid object path\n");
        return 1;
    }

    seat_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
                 G_DBUS_PROXY_FLAGS_NONE,
                 NULL,
                 "org.freedesktop.DisplayManager",
                 seat_path,
                 "org.freedesktop.DisplayManager.Seat",
                 NULL,
                 &error);

    if (error != NULL) {
        g_warning("switchtogreeter:seat proxy %s\n", error->message);
        g_error_free(error);
        return 1;
    }
    error = NULL;

    printf("current seat path: %s\n", seat_path);
    strlist = g_strsplit(seat_path, "/", -1);
    while (*strlist) {
        cur_seat = *strlist;
        strlist++;
    }

    printf("current seat: %s\n", cur_seat);
    printf("usd->session_path: %s\n", usd->session_path);
    printf("usd->username: %s\n", usd->username);

    if (usd->session_path != NULL && usd->username != NULL) {
        sd_uid_get_sessions(name_to_uid(usd->username), 0, &sessions);
        while (*sessions) {
            sd_session_get_display(*sessions, &display);
            if (NULL == display){
                sessions++;
                continue;
            }

            sd_session_get_seat(*sessions, &seat);
            printf("session display %s %s\n", *sessions, display);
            if (seat != NULL && (0 == g_ascii_strcasecmp(seat, cur_seat))) {
                new_user_session = *sessions;
                printf("switchtogreeter: find sessions path %s %s \n", new_user_session, seat);
                break;
            }
            sessions++;
        }

        if (NULL == new_user_session) {
            g_error("switchtogreeter: can not find user sessions %s \n", usd->username);
            return 1;
        }
        printf("find user session: %s\n", new_user_session);

        login1_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
                       G_DBUS_PROXY_FLAGS_NONE,
                       NULL,
                       "org.freedesktop.login1",
                       "/org/freedesktop/login1",
                       "org.freedesktop.login1.Manager",
                       NULL,
                       &error);
        g_dbus_proxy_call_sync(login1_proxy,
                               "ActivateSession",
                               g_variant_new("(s)", new_user_session),
                               G_DBUS_CALL_FLAGS_NONE,
                               -1,
                               NULL,
                               &error);
        ret = 0;
    } else if (usd->username != NULL) {
        printf("SwitchToUser\n");
        usd->session_path = "";
        g_dbus_proxy_call_sync(seat_proxy,
                               "SwitchToUser",
                               g_variant_new("(ss)", usd->username, usd->session_path),
                               G_DBUS_CALL_FLAGS_NONE,
                               -1,
                               NULL,
                               &error);
        ret = 1;
    } else {
        g_dbus_proxy_call_sync(seat_proxy,
                               "SwitchToGreeter",
                               g_variant_new("()"),
                               G_DBUS_CALL_FLAGS_NONE,
                               -1,
                               NULL,
                               &error);
        ret = 1;
    }

    if (error != NULL) {
        g_warning("switchtogreeter:seat switchtogreeter %s\n", error->message);
        g_error_free(error);
    }
    error = NULL;

    g_object_unref(seat_proxy);
    return ret;
}
Esempio n. 6
0
static void
process_config_entries (GoaDaemon  *daemon,
                        GHashTable *group_name_to_key_file_data)
{
  GHashTableIter iter;
  const gchar *id;
  KeyFileData *key_file_data;
  GList *existing_object_paths;
  GList *config_object_paths;
  GList *added;
  GList *removed;
  GList *unchanged;
  GList *l;

  existing_object_paths = NULL;
  {
    GList *existing_objects;
    existing_objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager));
    for (l = existing_objects; l != NULL; l = l->next)
      {
        GoaObject *object = GOA_OBJECT (l->data);
        const gchar *object_path;
        object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
        if (g_str_has_prefix (object_path, "/org/gnome/OnlineAccounts/Accounts/"))
          existing_object_paths = g_list_prepend (existing_object_paths, g_strdup (object_path));
      }
    g_list_foreach (existing_objects, (GFunc) g_object_unref, NULL);
    g_list_free (existing_objects);
  }

  config_object_paths = NULL;
  g_hash_table_iter_init (&iter, group_name_to_key_file_data);
  while (g_hash_table_iter_next (&iter, (gpointer*) &id, (gpointer*) &key_file_data))
    {
      gchar *object_path;

      /* create and validate object path */
      object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id + sizeof "Account " - 1);
      if (strstr (id + sizeof "Account " - 1, "/") != NULL || !g_variant_is_object_path (object_path))
        {
          g_warning ("`%s' is not a valid account identifier", id);
          g_free (object_path);
          continue;
        }
      /* steals object_path variable */
      config_object_paths = g_list_prepend (config_object_paths, object_path);
    }

  existing_object_paths = g_list_sort (existing_object_paths, (GCompareFunc) g_strcmp0);
  config_object_paths = g_list_sort (config_object_paths, (GCompareFunc) g_strcmp0);
  diff_sorted_lists (existing_object_paths,
                     config_object_paths,
                     (GCompareFunc) g_strcmp0,
                     &added,
                     &removed,
                     &unchanged);

  for (l = removed; l != NULL; l = l->next)
    {
      const gchar *object_path = l->data;
      GoaObject *object;
      object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path));
      g_warn_if_fail (object != NULL);
      g_signal_handlers_disconnect_by_func (goa_object_peek_account (object),
                                            G_CALLBACK (on_account_handle_remove),
                                            daemon);
      g_debug ("removing %s", object_path);
      g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path));
    }
  for (l = added; l != NULL; l = l->next)
    {
      const gchar *object_path = l->data;
      GoaObjectSkeleton *object;
      gchar *group;

      g_debug ("adding %s", object_path);

      group = object_path_to_group (object_path);
      key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group);
      g_warn_if_fail (key_file_data != NULL);

      object = goa_object_skeleton_new (object_path);
      if (update_account_object (daemon,
                                 object,
                                 key_file_data->path,
                                 group,
                                 key_file_data->key_file,
                                 TRUE))
        {
          g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object));
          g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)),
                            "handle-remove",
                            G_CALLBACK (on_account_handle_remove),
                            daemon);
          g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)),
                            "handle-ensure-credentials",
                            G_CALLBACK (on_account_handle_ensure_credentials),
                            daemon);
        }
      g_object_unref (object);
      g_free (group);
    }
  for (l = unchanged; l != NULL; l = l->next)
    {
      const gchar *object_path = l->data;
      GoaObject *object;
      gchar *group;

      g_debug ("unchanged %s", object_path);

      group = object_path_to_group (object_path);
      key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group);
      g_warn_if_fail (key_file_data != NULL);

      object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path));
      g_warn_if_fail (object != NULL);
      if (!update_account_object (daemon,
                                  GOA_OBJECT_SKELETON (object),
                                  key_file_data->path,
                                  group,
                                  key_file_data->key_file,
                                  FALSE))
        {
          g_signal_handlers_disconnect_by_func (goa_object_peek_account (object),
                                                G_CALLBACK (on_account_handle_remove),
                                                daemon);
          g_signal_handlers_disconnect_by_func (goa_object_peek_account (object),
                                                G_CALLBACK (on_account_handle_ensure_credentials),
                                                daemon);
          g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path));
        }
      g_object_unref (object);
      g_free (group);
    }

  g_list_free (removed);
  g_list_free (added);
  g_list_free (unchanged);
  g_list_foreach (existing_object_paths, (GFunc) g_free, NULL);
  g_list_free (existing_object_paths);
  g_list_foreach (config_object_paths, (GFunc) g_free, NULL);
  g_list_free (config_object_paths);
}
Esempio n. 7
0
/**
 * @brief Create function handler
 * @param[in] object
 * @param[in] invocation
 * @param[in] instance
 * @param[in] type
 * @return true if metod handled
 */
static gboolean
handle_create_function(GadgetdGadgetFunctionManager	*object,
		        GDBusMethodInvocation		*invocation,
		        const gchar			*instance,
		        const gchar			*type)
{
	gchar _cleanup_g_free_ *function_path = NULL;
	const gchar *msg = NULL;
	GadgetFunctionManager *func_manager = GADGET_FUNCTION_MANAGER(object);
	GadgetdFunctionObject *function_object;
	GadgetDaemon *daemon;
	struct gd_gadget *gadget = func_manager->gadget;
	const gchar *gadget_name = usbg_get_gadget_name(gadget->g);
	gchar _cleanup_g_free_ *instance_path = NULL;
	gchar _cleanup_g_free_ *type_path = NULL;
	struct gd_function *func = NULL;
	gint ret;

	daemon = gadget_function_manager_get_daemon(GADGET_FUNCTION_MANAGER(object));

	INFO("handled create function");

	if (gadget == NULL || gadget_name == NULL) {
		msg = "Unable to get gadget";
		goto err;
	}

	ret = make_valid_object_path_part(instance, &instance_path);
	if (ret != GD_SUCCESS) {
		msg = "Invalid instance name";
		goto err;
	}

	ret = make_valid_object_path_part(type, &type_path);
	if (ret != GD_SUCCESS) {
		msg = "Invalid type name";
		goto err;
	}

	function_path = g_strdup_printf("%s/Function/%s/%s",
					func_manager->gadget_path,
					type_path,
					instance_path);

	if (function_path == NULL || !g_variant_is_object_path(function_path)) {
		msg = "Invalid function instance or type";
		goto err;
	}

	ret = gd_create_function(gadget, type, instance, &func, &msg);
	if (ret != GD_SUCCESS)
		goto err;

	function_object = gadgetd_function_object_new(function_path, func);
	if (function_object == NULL) {
		msg = "Unable to create function object";
		goto err;
	}

	g_dbus_object_manager_server_export(gadget_daemon_get_object_manager(daemon),
					    G_DBUS_OBJECT_SKELETON(function_object));

	/* send function path*/
	g_dbus_method_invocation_return_value(invocation,
					      g_variant_new("(o)",
					      function_path));
	return TRUE;

err:
	g_dbus_method_invocation_return_dbus_error(invocation,
			func_manager_iface,
			msg);
	return TRUE;
}
Esempio n. 8
0
static GVariant *
parse_json (JsonNode *node,
            const GVariantType *type,
            GError **error)
{
  const GVariantType *element_type;
  const gchar *str;

  if (!g_variant_type_is_definite (type))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                   "Indefinite type '%.*s' is not supported",
                   (int)g_variant_type_get_string_length (type),
                   g_variant_type_peek_string (type));
      return NULL;
    }

  if (g_variant_type_is_basic (type))
    {
      if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_BOOLEAN, error))
            return g_variant_new_boolean (json_node_get_boolean (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_byte (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint16 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint32 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_int64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, error))
            return g_variant_new_uint64 (json_node_get_int (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_INT64, NULL))
            return g_variant_new_double (json_node_get_int (node));
          else if (check_type (node, JSON_NODE_VALUE, G_TYPE_DOUBLE, error))
            return g_variant_new_double (json_node_get_double (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            return g_variant_new_string (json_node_get_string (node));
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_object_path (str))
                return g_variant_new_object_path (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid object path '%s'", str);
                  return NULL;
                }
            }
        }
      else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
        {
          if (check_type (node, JSON_NODE_VALUE, G_TYPE_STRING, error))
            {
              str = json_node_get_string (node);
              if (g_variant_is_signature (str))
                return g_variant_new_signature (str);
              else
                {
                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
                               "Invalid signature '%s'", str);
                  return NULL;
                }
            }
        }
      else
        {
          parse_not_supported (type, error);
        }
    }
  else if (g_variant_type_is_variant (type))
    {
      return parse_json_variant (node, error);
    }
  else if (g_variant_type_is_array (type))
    {
      element_type = g_variant_type_element (type);
      if (g_variant_type_is_dict_entry (element_type))
        return parse_json_dictionary (node, element_type, error);
      else
        return parse_json_array (node, element_type, error);
    }
  else if (g_variant_type_is_tuple (type))
    {
      return parse_json_tuple (node, g_variant_type_first (type), error);
    }
  else
    {
      parse_not_supported (type, error);
    }

  return NULL;
}