示例#1
0
文件: gvaluetypes.c 项目: zsx/glib
/**
 * g_value_set_int64:
 * @value: a valid #GValue of type %G_TYPE_INT64
 * @v_int64: 64bit integer value to be set
 *
 * Set the contents of a %G_TYPE_INT64 #GValue to @v_int64.
 */
gint64
g_value_get_int64 (const GValue *value)
{
  g_return_val_if_fail (G_VALUE_HOLDS_INT64 (value), 0);
  
  return value->data[0].v_int64;
}
示例#2
0
int
ce_get_property_default (NMSetting *setting, const char *property_name)
{
	GParamSpec *spec;
	GValue value = { 0, };

	g_return_val_if_fail (NM_IS_SETTING (setting), -1);

	spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name);
	g_return_val_if_fail (spec != NULL, -1);

	g_value_init (&value, spec->value_type);
	g_param_value_set_default (spec, &value);

	if (G_VALUE_HOLDS_CHAR (&value))
		return (int) g_value_get_schar (&value);
	else if (G_VALUE_HOLDS_INT (&value))
		return g_value_get_int (&value);
	else if (G_VALUE_HOLDS_INT64 (&value))
		return (int) g_value_get_int64 (&value);
	else if (G_VALUE_HOLDS_LONG (&value))
		return (int) g_value_get_long (&value);
	else if (G_VALUE_HOLDS_UINT (&value))
		return (int) g_value_get_uint (&value);
	else if (G_VALUE_HOLDS_UINT64 (&value))
		return (int) g_value_get_uint64 (&value);
	else if (G_VALUE_HOLDS_ULONG (&value))
		return (int) g_value_get_ulong (&value);
	else if (G_VALUE_HOLDS_UCHAR (&value))
		return (int) g_value_get_uchar (&value);
	g_return_val_if_fail (FALSE, 0);
	return 0;
}
示例#3
0
文件: gvaluetypes.c 项目: zsx/glib
/**
 * g_value_get_int64:
 * @value: a valid #GValue of type %G_TYPE_INT64
 *
 * Get the contents of a %G_TYPE_INT64 #GValue.
 *
 * Returns: 64bit integer contents of @value
 */
void
g_value_set_int64 (GValue *value,
		   gint64  v_int64)
{
  g_return_if_fail (G_VALUE_HOLDS_INT64 (value));
  
  value->data[0].v_int64 = v_int64;
}
/**
 * gdata_freebase_topic_value_get_int:
 * @value: a #GDataFreebaseTopicValue
 *
 * Returns a #gint64 value held in @value. It is only valid to call this if the #GType is a %G_TYPE_INT64
 *
 * Returns: the #gint64 value
 *
 * Since: 0.15.1
 **/
gint64
gdata_freebase_topic_value_get_int (GDataFreebaseTopicValue *value)
{
	g_return_val_if_fail (value != NULL, 0);
	g_return_val_if_fail (G_VALUE_HOLDS_INT64 (&value->value), 0);

	return g_value_get_int64 (&value->value);
}
示例#5
0
static GVariant *
g_settings_set_mapping_int (const GValue       *value,
                            const GVariantType *expected_type)
{
  GVariant *variant = NULL;
  gint64 l;

  if (G_VALUE_HOLDS_INT (value))
    l = g_value_get_int (value);
  else if (G_VALUE_HOLDS_INT64 (value))
    l = g_value_get_int64 (value);
  else
    return NULL;

  if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
    {
      if (G_MININT16 <= l && l <= G_MAXINT16)
        variant = g_variant_new_int16 ((gint16) l);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
    {
      if (0 <= l && l <= G_MAXUINT16)
        variant = g_variant_new_uint16 ((guint16) l);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
    {
      if (G_MININT32 <= l && l <= G_MAXINT32)
        variant = g_variant_new_int32 ((gint) l);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
    {
      if (0 <= l && l <= G_MAXUINT32)
        variant = g_variant_new_uint32 ((guint) l);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
    {
      if (G_MININT64 <= l && l <= G_MAXINT64)
        variant = g_variant_new_int64 ((gint64) l);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
    {
      if (0 <= l && l <= G_MAXUINT64)
        variant = g_variant_new_uint64 ((guint64) l);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
    {
      if (0 <= l && l <= G_MAXUINT32)
        variant = g_variant_new_handle ((guint) l);
    }
  else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
    variant = g_variant_new_double ((gdouble) l);

  return variant;
}
示例#6
0
gint64
ol_get_int64_from_hash_table (GHashTable *hash_table, const gchar *key)
{
  if (!hash_table)
    return -1;
  GValue *value;
  value = (GValue *) g_hash_table_lookup(hash_table, key);
  if (value != NULL && G_VALUE_HOLDS_INT64(value))
    return  g_value_get_int64 (value);
  else
    return -1;
}
static gint64 get_int64 (GHashTable *dict, const char *key)
{
        GValue *val;

        val = g_hash_table_lookup (dict, key);
        if (val == NULL) {
                return 0;
        }
        if (!G_VALUE_HOLDS_INT64 (val)) {
                return 0;
        }
        return g_value_get_int64 (val);
}
示例#8
0
static gboolean
g_settings_get_mapping_unsigned_int (GValue   *value,
                                     GVariant *variant)
{
  const GVariantType *type;
  guint64 u;

  type = g_variant_get_type (variant);

  if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
    u = g_variant_get_uint16 (variant);
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
    u = g_variant_get_uint32 (variant);
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
    u = g_variant_get_uint64 (variant);
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
    u = g_variant_get_handle (variant);
  else
    return FALSE;

  if (G_VALUE_HOLDS_INT (value))
    {
      g_value_set_int (value, u);
      return (u <= G_MAXINT32);
    }
  else if (G_VALUE_HOLDS_UINT (value))
    {
      g_value_set_uint (value, u);
      return (u <= G_MAXUINT32);
    }
  else if (G_VALUE_HOLDS_INT64 (value))
    {
      g_value_set_int64 (value, u);
      return (u <= G_MAXINT64);
    }
  else if (G_VALUE_HOLDS_UINT64 (value))
    {
      g_value_set_uint64 (value, u);
      return (u <= G_MAXUINT64);
    }
  else if (G_VALUE_HOLDS_DOUBLE (value))
    {
      g_value_set_double (value, u);
      return TRUE;
    }

  return FALSE;
}
示例#9
0
/**
 * grl_related_keys_get_int64:
 * @relkeys: set of related keys to inspect
 * @key: (type GrlKeyID): key to use
 *
 * Returns the value associated with @key from @relkeys. If @key has no value,
 * or value is not a gint64, or @key is not in @relkeys, then 0 is returned.
 *
 * Returns: int64 value associated with @key, or 0 in other case.
 *
 * Since: 0.2.12
 **/
gint64
grl_related_keys_get_int64 (GrlRelatedKeys *relkeys,
                            GrlKeyID key)
{
  const GValue *value;

  g_return_val_if_fail (GRL_IS_RELATED_KEYS (relkeys), 0);

  value = grl_related_keys_get (relkeys, key);

  if (!value || !G_VALUE_HOLDS_INT64 (value)) {
    return 0;
  } else {
    return g_value_get_int64 (value);
  }
}
示例#10
0
static gboolean
g_settings_get_mapping_int (GValue   *value,
                            GVariant *variant)
{
  const GVariantType *type;
  gint64 l;

  type = g_variant_get_type (variant);

  if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
    l = g_variant_get_int16 (variant);
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
    l = g_variant_get_int32 (variant);
  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
    l = g_variant_get_int64 (variant);
  else
    return FALSE;

  if (G_VALUE_HOLDS_INT (value))
    {
      g_value_set_int (value, l);
      return (G_MININT32 <= l && l <= G_MAXINT32);
    }
  else if (G_VALUE_HOLDS_UINT (value))
    {
      g_value_set_uint (value, l);
      return (0 <= l && l <= G_MAXUINT32);
    }
  else if (G_VALUE_HOLDS_INT64 (value))
    {
      g_value_set_int64 (value, l);
      return (G_MININT64 <= l && l <= G_MAXINT64);
    }
  else if (G_VALUE_HOLDS_UINT64 (value))
    {
      g_value_set_uint64 (value, l);
      return (0 <= l && l <= G_MAXUINT64);
    }
  else if (G_VALUE_HOLDS_DOUBLE (value))
    {
      g_value_set_double (value, l);
      return TRUE;
    }

  return FALSE;
}
static void cd_mpris2_get_time_elapsed (void)
{
	GValue v = G_VALUE_INIT;
	cairo_dock_dbus_get_property_in_value_with_timeout (myData.dbus_proxy_player, "org.mpris.MediaPlayer2.Player", "Position", &v, 250); // will be call each second, 250ms is already a big timeout, we can wait the next call.
	if (G_VALUE_HOLDS_INT64 (&v))
		myData.iCurrentTime =  g_value_get_int64 (&v) / 1e6;
	else if (G_VALUE_HOLDS_UINT64 (&v))
		myData.iCurrentTime =  g_value_get_uint64 (&v) / 1e6;
	else if (G_VALUE_HOLDS_INT (&v))
		myData.iCurrentTime =  g_value_get_int (&v) / 1e6;
	else if (G_VALUE_HOLDS_STRING (&v))  // this is bad ! (gmusicbrowser v1.1.7)
		myData.iCurrentTime = atoi (g_value_get_string (&v)) / 1e6;
	else
	{
		if (G_IS_VALUE(&v)) //  when changing song, we don't receive this value => no need to display a warning message each time
			cd_warning ("wrong type for the 'Position' property, please report this bug to the %s team", myData.pCurrentHandler->appclass);
		myData.iCurrentTime = -1;
	}
}
示例#12
0
JNIEXPORT jlong JNICALL
Java_org_gnome_glib_GValue_g_1value_1get_1long
(
	JNIEnv* env,
	jclass cls,
	jlong _value
)
{
	GValue* value;
	gint64 result;

	// translate value
	value =	(GValue*) _value;
	if (!G_VALUE_HOLDS_INT64(value)) {
		bindings_java_throw(env, "You've asked for the long value of a GValue, but it's not a G_TYPE_INT64!");
		return 0;
	}

	// call function
	result = g_value_get_int64(value);

	// and return
	return (jlong) result;
}
示例#13
0
static GtkCellEditable *
parasite_property_cell_renderer_start_editing(GtkCellRenderer *renderer,
        GdkEvent *event,
        GtkWidget *widget,
        const gchar *path,
        GdkRectangle *background_area,
        GdkRectangle *cell_area,
        GtkCellRendererState flags)
{
    PangoFontDescription *font_desc;
    GtkCellEditable *editable = NULL;
    GObject *object;
    const char *name;
    GValue gvalue = {0};
    GParamSpec *prop;

    g_object_get(renderer,
                 "object", &object,
                 "name", &name,
                 NULL);

    prop = g_object_class_find_property(G_OBJECT_GET_CLASS(object), name);

    if (!(prop->flags & G_PARAM_WRITABLE))
        return NULL;

    g_value_init(&gvalue, prop->value_type);
    g_object_get_property(object, name, &gvalue);

    if (G_VALUE_HOLDS_ENUM(&gvalue) || G_VALUE_HOLDS_BOOLEAN(&gvalue))
    {
        GtkWidget *combobox = gtk_combo_box_new_text();
        gtk_widget_show(combobox);
        g_object_set(G_OBJECT(combobox), "has-frame", FALSE, NULL);
        GList *renderers;

        if (G_VALUE_HOLDS_BOOLEAN(&gvalue))
        {
            gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), "FALSE");
            gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), "TRUE");

            gtk_combo_box_set_active(GTK_COMBO_BOX(combobox),
                                     g_value_get_boolean(&gvalue) ? 1 : 0);
        }
        else if (G_VALUE_HOLDS_ENUM(&gvalue))
        {
            gint value = g_value_get_enum(&gvalue);
            GEnumClass *enum_class = G_PARAM_SPEC_ENUM(prop)->enum_class;
            guint i;

            for (i = 0; i < enum_class->n_values; i++)
            {
                GEnumValue *enum_value = &enum_class->values[i];

                gtk_combo_box_append_text(GTK_COMBO_BOX(combobox),
                                          enum_value->value_name);

                if (enum_value->value == value)
                    gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), i);
            }

        }

        renderers = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(combobox));
        g_object_set(G_OBJECT(renderers->data), "scale", TREE_TEXT_SCALE, NULL);
        g_list_free(renderers);

        editable = GTK_CELL_EDITABLE(combobox);
    }
    else if (G_VALUE_HOLDS_STRING(&gvalue))
    {
        GtkWidget *entry = gtk_entry_new();
        gtk_widget_show(entry);
        gtk_entry_set_text(GTK_ENTRY(entry), g_value_get_string(&gvalue));

        editable = GTK_CELL_EDITABLE(entry);
    }
    else if (G_VALUE_HOLDS_INT(&gvalue)    ||
             G_VALUE_HOLDS_UINT(&gvalue)   ||
             G_VALUE_HOLDS_INT64(&gvalue)  ||
             G_VALUE_HOLDS_UINT64(&gvalue) ||
             G_VALUE_HOLDS_LONG(&gvalue)   ||
             G_VALUE_HOLDS_ULONG(&gvalue)  ||
             G_VALUE_HOLDS_DOUBLE(&gvalue))
    {
        double min, max, value;
        GtkWidget *spinbutton;
        guint digits = 0;

        if (G_VALUE_HOLDS_INT(&gvalue))
        {
            GParamSpecInt *paramspec = G_PARAM_SPEC_INT(prop);
            min = paramspec->minimum;
            max = paramspec->maximum;
            value = g_value_get_int(&gvalue);
        }
        else if (G_VALUE_HOLDS_UINT(&gvalue))
        {
            GParamSpecUInt *paramspec = G_PARAM_SPEC_UINT(prop);
            min = paramspec->minimum;
            max = paramspec->maximum;
            value = g_value_get_uint(&gvalue);
        }
        else if (G_VALUE_HOLDS_INT64(&gvalue))
        {
            GParamSpecInt64 *paramspec = G_PARAM_SPEC_INT64(prop);
            min = paramspec->minimum;
            max = paramspec->maximum;
            value = g_value_get_int64(&gvalue);
        }
        else if (G_VALUE_HOLDS_UINT64(&gvalue))
        {
            GParamSpecUInt64 *paramspec = G_PARAM_SPEC_UINT64(prop);
            min = paramspec->minimum;
            max = paramspec->maximum;
            value = g_value_get_uint64(&gvalue);
        }
        else if (G_VALUE_HOLDS_LONG(&gvalue))
        {
            GParamSpecLong *paramspec = G_PARAM_SPEC_LONG(prop);
            min = paramspec->minimum;
            max = paramspec->maximum;
            value = g_value_get_long(&gvalue);
        }
        else if (G_VALUE_HOLDS_ULONG(&gvalue))
        {
            GParamSpecULong *paramspec = G_PARAM_SPEC_ULONG(prop);
            min = paramspec->minimum;
            max = paramspec->maximum;
            value = g_value_get_ulong(&gvalue);
        }
        else if (G_VALUE_HOLDS_DOUBLE(&gvalue))
        {
            GParamSpecDouble *paramspec = G_PARAM_SPEC_DOUBLE(prop);
            min = paramspec->minimum;
            max = paramspec->maximum;
            value = g_value_get_double(&gvalue);
            digits = 2;
        }
        else
        {
            // Shouldn't really be able to happen.
            return NULL;
        }

        spinbutton = gtk_spin_button_new_with_range(min, max, 1);
        gtk_widget_show(spinbutton);
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbutton), value);
        gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spinbutton), digits);

        editable = GTK_CELL_EDITABLE(spinbutton);
    }

    font_desc = pango_font_description_new();
    pango_font_description_set_size(font_desc, 8 * PANGO_SCALE);
    gtk_widget_modify_font(GTK_WIDGET(editable), font_desc);
    pango_font_description_free(font_desc);

    g_value_unset(&gvalue);

    g_signal_connect(G_OBJECT(editable), "editing_done",
                     G_CALLBACK(parasite_property_cell_renderer_stop_editing),
                     renderer);

    g_object_set_data_full(G_OBJECT(editable), "_prop_name", g_strdup(name),
                           g_free);
    g_object_set_data(G_OBJECT(editable), "_prop_object", object);

    return editable;
}
static gboolean _extract_metadata (GHashTable *pMetadata)
{
	gboolean bTrackHasChanged = FALSE;
	GValue *v;
	const gchar *str = NULL;
	
	v = g_hash_table_lookup (pMetadata, "mpris:trackid");  // a string or a dbus object path that uniquely identifies the track within the scope of the playlist
	if (v != NULL)
	{
		if (G_VALUE_HOLDS (v, DBUS_TYPE_G_OBJECT_PATH)) // now this attribute should be of D-Bus type "o"
			str = (gchar*) g_value_get_boxed (v);
		else if (G_VALUE_HOLDS_STRING (v)) // but can be a string... e.g. with Rhythmbox
			str = g_value_get_string (v);
		bTrackHasChanged = _is_a_new_track (str);
	}

	v = g_hash_table_lookup (pMetadata, "mpris:length");  // length of the track, in microseconds (signed 64-bit integer)
	if (v != NULL)
	{
		if (G_VALUE_HOLDS_INT64 (v)) // should be a int64
			myData.iSongLength = g_value_get_int64 (v) / 1000000;
		else if (G_VALUE_HOLDS_INT (v)) // but some players doesn't respect that... maybe a limitation?
			myData.iSongLength = g_value_get_int (v) / 1000000;
		else
			cd_warning ("Length has a wrong type");
		cd_debug ("Length: %d", myData.iSongLength);
	}

	gchar *cOldArtist = myData.cArtist;
	myData.cArtist = NULL;
	v = (GValue *) g_hash_table_lookup(pMetadata, "xesam:artist");
	if (v != NULL && G_VALUE_HOLDS(v, G_TYPE_STRV))
	{
		gchar **artists = g_value_get_boxed(v);
		if (artists != NULL)
			myData.cArtist = g_strjoinv (NULL, artists);
	}
	cd_message ("  cArtist <- %s", myData.cArtist);
	
	// maybe the user has renamed the tags of the current song...
	if (! bTrackHasChanged && cairo_dock_strings_differ (myData.cArtist, cOldArtist))
		bTrackHasChanged = TRUE;
	g_free (cOldArtist);
	
	g_free (myData.cAlbum);
	myData.cAlbum = NULL;
	v = (GValue *) g_hash_table_lookup(pMetadata, "xesam:album");
	if (v != NULL && G_VALUE_HOLDS_STRING(v))
	{
		str = g_value_get_string(v);
		if (str && *str != '\0')
			myData.cAlbum = g_strdup (str);
	}
	cd_message ("  cAlbum <- %s", myData.cAlbum);

	gchar *cOldTitle = myData.cTitle;
	myData.cTitle = NULL;
	v = (GValue *) g_hash_table_lookup(pMetadata, "xesam:title");
	if (v != NULL && G_VALUE_HOLDS_STRING(v))
	{
		str = g_value_get_string(v);
		if (str && *str != '\0')
			myData.cTitle = g_strdup (str);
	}
	cd_message ("  cTitle <- %s", myData.cTitle);

	/* some players doesn't support (well) the trackid. Even if this is not our
	 * problem, it can be interesting to also check if the title has changed.
	 */
	if (! bTrackHasChanged && cairo_dock_strings_differ (myData.cTitle, cOldTitle))
		bTrackHasChanged = TRUE;
	g_free (cOldTitle);
	
	g_free (myData.cPlayingUri);
	myData.cPlayingUri = NULL;
	v = (GValue *) g_hash_table_lookup(pMetadata, "xesam:url");
	if (!v)
		v = (GValue *) g_hash_table_lookup(pMetadata, "xesam:uri");
	if (v != NULL && G_VALUE_HOLDS_STRING(v))
	{
		str = g_value_get_string(v);
		if (str && *str != '\0')
			myData.cPlayingUri = g_strdup (str);
	}
	cd_message ("  cUri <- %s", myData.cPlayingUri);

	myData.iTrackNumber = 0;  // not really useful, it's the track-number in the album.
	v = (GValue *) g_hash_table_lookup(pMetadata, "xesam:trackNumber");
	if (v != NULL && G_VALUE_HOLDS_INT(v))
	{
		myData.iTrackNumber = g_value_get_int (v);
	}
	cd_message ("  iTrackNumber <- %d", myData.iTrackNumber);

	const gchar *cCoverPath = NULL;
	v = g_hash_table_lookup(pMetadata, "mpris:artUrl");
	if (v != NULL && G_VALUE_HOLDS_STRING(v))
	{
		cCoverPath = g_value_get_string(v);
	}
	cd_musicplayer_set_cover_path (cCoverPath);  // do it at the end (we have to know the artist and the album if (cCoverPath == NULL))

	/// we miss iTrackListIndex and tracklist-length ...
	
	
	return bTrackHasChanged;
}
示例#15
0
GVariant *
g_settings_set_mapping (const GValue       *value,
                        const GVariantType *expected_type,
                        gpointer            user_data)
{
  gchar *type_string;

  if (G_VALUE_HOLDS_BOOLEAN (value))
    {
      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
        return g_variant_new_boolean (g_value_get_boolean (value));
    }

  else if (G_VALUE_HOLDS_CHAR (value)  ||
           G_VALUE_HOLDS_UCHAR (value))
    {
      if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
        {
          if (G_VALUE_HOLDS_CHAR (value))
            return g_variant_new_byte (g_value_get_char (value));
          else
            return g_variant_new_byte (g_value_get_uchar (value));
        }
    }

  else if (G_VALUE_HOLDS_INT (value)   ||
           G_VALUE_HOLDS_INT64 (value))
    return g_settings_set_mapping_int (value, expected_type);

  else if (G_VALUE_HOLDS_DOUBLE (value))
    return g_settings_set_mapping_float (value, expected_type);

  else if (G_VALUE_HOLDS_UINT (value)  ||
           G_VALUE_HOLDS_UINT64 (value))
    return g_settings_set_mapping_unsigned_int (value, expected_type);

  else if (G_VALUE_HOLDS_STRING (value))
    {
      if (g_value_get_string (value) == NULL)
        return NULL;
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
        return g_variant_new_string (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
        return g_variant_new_bytestring (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
        return g_variant_new_object_path (g_value_get_string (value));
      else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
        return g_variant_new_signature (g_value_get_string (value));
    }

  else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
    {
      if (g_value_get_boxed (value) == NULL)
        return NULL;
      return g_variant_new_strv ((const gchar **) g_value_get_boxed (value),
                                 -1);
    }

  else if (G_VALUE_HOLDS_ENUM (value))
    {
      GEnumValue *enumval;
      GEnumClass *eclass;

      /* GParamSpecEnum holds a ref on the class so we just peek... */
      eclass = g_type_class_peek (G_VALUE_TYPE (value));
      enumval = g_enum_get_value (eclass, g_value_get_enum (value));

      if (enumval)
        return g_variant_new_string (enumval->value_nick);
      else
        return NULL;
    }

  else if (G_VALUE_HOLDS_FLAGS (value))
    {
      GVariantBuilder builder;
      GFlagsValue *flagsval;
      GFlagsClass *fclass;
      guint flags;

      fclass = g_type_class_peek (G_VALUE_TYPE (value));
      flags = g_value_get_flags (value);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
      while (flags)
        {
          flagsval = g_flags_get_first_value (fclass, flags);

          if (flagsval == NULL)
            {
              g_variant_builder_clear (&builder);
              return NULL;
            }

          g_variant_builder_add (&builder, "s", flagsval->value_nick);
          flags &= ~flagsval->value;
        }

      return g_variant_builder_end (&builder);
    }

  type_string = g_variant_type_dup_string (expected_type);
  g_critical ("No GSettings bind handler for type \"%s\".", type_string);
  g_free (type_string);

  return NULL;
}