static void
param_value_array_init (GParamSpec *pspec)
{
  GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);

  aspec->element_spec = NULL;
  aspec->fixed_n_elements = 0; /* disable */
}
static void
param_value_array_finalize (GParamSpec *pspec)
{
  GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
  GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY));

  if (aspec->element_spec)
    {
      g_param_spec_unref (aspec->element_spec);
      aspec->element_spec = NULL;
    }

  parent_class->finalize (pspec);
}
static void
param_value_array_set_default (GParamSpec *pspec,
			       GValue     *value)
{
  GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);

  if (!value->data[0].v_pointer && aspec->fixed_n_elements)
    value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);

  if (value->data[0].v_pointer)
    {
      /* g_value_reset (value);  already done */
      value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements);
    }
}
static int
values_equal (GParamSpec *pspec,
              const GValue *va,
              const GValue *vb)
{
	/* g_param_values_cmp isn't good enough for some types, since e.g.
	 * it compares colours and font descriptions by pointer value, not
	 * with the correct compare functions. Providing extra
	 * PangoParamSpecFontDescription and GdkParamSpecColor wouldn't
	 * have fixed this either, since it's unclear how to _order_ them.
	 * Luckily we only need to check them for equality here.
	 */

	if (g_param_values_cmp (pspec, va, vb) == 0)
		return TRUE;

	if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_COLOR)
		return gdk_color_equal (g_value_get_boxed (va), g_value_get_boxed (vb));

	if (G_PARAM_SPEC_VALUE_TYPE (pspec) == PANGO_TYPE_FONT_DESCRIPTION)
		return pango_font_description_equal (g_value_get_boxed (va), g_value_get_boxed (vb));

	if (G_IS_PARAM_SPEC_VALUE_ARRAY (pspec) &&
	        G_PARAM_SPEC_VALUE_TYPE (G_PARAM_SPEC_VALUE_ARRAY (pspec)->element_spec) == GDK_TYPE_COLOR)
	{
		GValueArray *ara, *arb;
		guint i;

		ara = g_value_get_boxed (va);
		arb = g_value_get_boxed (vb);

		if (!ara || !arb || ara->n_values != arb->n_values)
			return FALSE;

		for (i = 0; i < ara->n_values; ++i)
			if (!gdk_color_equal (g_value_get_boxed (g_value_array_get_nth (ara, i)),
			                      g_value_get_boxed (g_value_array_get_nth (arb, i))))
				return FALSE;

		return TRUE;
	}

	return FALSE;
}
static gboolean
param_value_array_validate (GParamSpec *pspec,
			    GValue     *value)
{
  GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
  GValueArray *value_array = value->data[0].v_pointer;
  guint changed = 0;

  if (!value->data[0].v_pointer && aspec->fixed_n_elements)
    value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements);

  if (value->data[0].v_pointer)
    {
      /* ensure array size validity */
      changed += value_array_ensure_size (value_array, aspec->fixed_n_elements);
      
      /* ensure array values validity against a present element spec */
      if (aspec->element_spec)
	{
	  GParamSpec *element_spec = aspec->element_spec;
	  guint i;
	  
	  for (i = 0; i < value_array->n_values; i++)
	    {
	      GValue *element = value_array->values + i;
	      
	      /* need to fixup value type, or ensure that the array value is initialized at all */
	      if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec)))
		{
		  if (G_VALUE_TYPE (element) != 0)
		    g_value_unset (element);
		  g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
		  g_param_value_set_default (element_spec, element);
		  changed++;
		}
	      /* validate array value against element_spec */
	      changed += g_param_value_validate (element_spec, element);
	    }
	}
    }

  return changed;
}
static GTokenType
gimp_config_deserialize_value_array (GValue     *value,
                                     GimpConfig *config,
                                     GParamSpec *prop_spec,
                                     GScanner   *scanner)
{
  GParamSpecValueArray *array_spec;
  GValueArray          *array;
  GValue                array_value = { 0, };
  gint                  n_values;
  GTokenType            token;
  gint                  i;

  array_spec = G_PARAM_SPEC_VALUE_ARRAY (prop_spec);

  if (! gimp_scanner_parse_int (scanner, &n_values))
    return G_TOKEN_INT;

  array = g_value_array_new (n_values);

  for (i = 0; i < n_values; i++)
    {
      g_value_init (&array_value, array_spec->element_spec->value_type);

      token = gimp_config_deserialize_value (&array_value,
                                             config,
                                             array_spec->element_spec,
                                             scanner);

      if (token == G_TOKEN_RIGHT_PAREN)
        g_value_array_append (array, &array_value);

      g_value_unset (&array_value);

      if (token != G_TOKEN_RIGHT_PAREN)
        return token;
    }

  g_value_take_boxed (value, array);

  return G_TOKEN_RIGHT_PAREN;
}
static gint
param_value_array_values_cmp (GParamSpec   *pspec,
			      const GValue *value1,
			      const GValue *value2)
{
  GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec);
  GValueArray *value_array1 = value1->data[0].v_pointer;
  GValueArray *value_array2 = value2->data[0].v_pointer;

  if (!value_array1 || !value_array2)
    return value_array2 ? -1 : value_array1 != value_array2;

  if (value_array1->n_values != value_array2->n_values)
    return value_array1->n_values < value_array2->n_values ? -1 : 1;
  else if (!aspec->element_spec)
    {
      /* we need an element specification for comparisons, so there's not much
       * to compare here, try to at least provide stable lesser/greater result
       */
      return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values;
    }
  else /* value_array1->n_values == value_array2->n_values */
    {
      guint i;

      for (i = 0; i < value_array1->n_values; i++)
	{
	  GValue *element1 = value_array1->values + i;
	  GValue *element2 = value_array2->values + i;
	  gint cmp;

	  /* need corresponding element types, provide stable result otherwise */
	  if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
	    return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
	  cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
	  if (cmp)
	    return cmp;
	}
      return 0;
    }
}
Beispiel #8
0
static void
print_element_properties_info (GstElement * element)
{
  GParamSpec **property_specs;
  guint num_properties, i;
  gboolean readable;
  gboolean first_flag;

  property_specs = g_object_class_list_properties
      (G_OBJECT_GET_CLASS (element), &num_properties);
  n_print ("\n");
  n_print ("Element Properties:\n");

  for (i = 0; i < num_properties; i++) {
    GValue value = { 0, };
    GParamSpec *param = property_specs[i];

    readable = FALSE;

    g_value_init (&value, param->value_type);

    n_print ("  %-20s: %s\n", g_param_spec_get_name (param),
        g_param_spec_get_blurb (param));

    first_flag = TRUE;
    n_print ("%-23.23s flags: ", "");
    if (param->flags & G_PARAM_READABLE) {
      g_object_get_property (G_OBJECT (element), param->name, &value);
      readable = TRUE;
      g_print ("%s%s", (first_flag) ? "" : ", ", _("readable"));
      first_flag = FALSE;
    } else {
      /* if we can't read the property value, assume it's set to the default
       * (which might not be entirely true for sub-classes, but that's an
       * unlikely corner-case anyway) */
      g_param_value_set_default (param, &value);
    }
    if (param->flags & G_PARAM_WRITABLE) {
      g_print ("%s%s", (first_flag) ? "" : ", ", _("writable"));
      first_flag = FALSE;
    }
    if (param->flags & G_PARAM_DEPRECATED) {
      g_print ("%s%s", (first_flag) ? "" : ", ", _("deprecated"));
      first_flag = FALSE;
    }
    if (param->flags & GST_PARAM_CONTROLLABLE) {
      g_print (", %s", _("controllable"));
      first_flag = FALSE;
    }
    if (param->flags & GST_PARAM_MUTABLE_PLAYING) {
      g_print (", %s", _("changeable in NULL, READY, PAUSED or PLAYING state"));
    } else if (param->flags & GST_PARAM_MUTABLE_PAUSED) {
      g_print (", %s", _("changeable only in NULL, READY or PAUSED state"));
    } else if (param->flags & GST_PARAM_MUTABLE_READY) {
      g_print (", %s", _("changeable only in NULL or READY state"));
    }
    if (param->flags & ~KNOWN_PARAM_FLAGS) {
      g_print ("%s0x%0x", (first_flag) ? "" : ", ",
          param->flags & ~KNOWN_PARAM_FLAGS);
    }
    n_print ("\n");

    switch (G_VALUE_TYPE (&value)) {
      case G_TYPE_STRING:
      {
        const char *string_val = g_value_get_string (&value);

        n_print ("%-23.23s String. ", "");

        if (string_val == NULL)
          g_print ("Default: null");
        else
          g_print ("Default: \"%s\"", string_val);
        break;
      }
      case G_TYPE_BOOLEAN:
      {
        gboolean bool_val = g_value_get_boolean (&value);

        n_print ("%-23.23s Boolean. ", "");

        g_print ("Default: %s", bool_val ? "true" : "false");
        break;
      }
      case G_TYPE_ULONG:
      {
        GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);

        n_print ("%-23.23s Unsigned Long. ", "");
        g_print ("Range: %lu - %lu Default: %lu ",
            pulong->minimum, pulong->maximum, g_value_get_ulong (&value));

        GST_ERROR ("%s: property '%s' of type ulong: consider changing to "
            "uint/uint64", GST_OBJECT_NAME (element),
            g_param_spec_get_name (param));
        break;
      }
      case G_TYPE_LONG:
      {
        GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);

        n_print ("%-23.23s Long. ", "");
        g_print ("Range: %ld - %ld Default: %ld ",
            plong->minimum, plong->maximum, g_value_get_long (&value));

        GST_ERROR ("%s: property '%s' of type long: consider changing to "
            "int/int64", GST_OBJECT_NAME (element),
            g_param_spec_get_name (param));
        break;
      }
      case G_TYPE_UINT:
      {
        GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);

        n_print ("%-23.23s Unsigned Integer. ", "");
        g_print ("Range: %u - %u Default: %u ",
            puint->minimum, puint->maximum, g_value_get_uint (&value));
        break;
      }
      case G_TYPE_INT:
      {
        GParamSpecInt *pint = G_PARAM_SPEC_INT (param);

        n_print ("%-23.23s Integer. ", "");
        g_print ("Range: %d - %d Default: %d ",
            pint->minimum, pint->maximum, g_value_get_int (&value));
        break;
      }
      case G_TYPE_UINT64:
      {
        GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);

        n_print ("%-23.23s Unsigned Integer64. ", "");
        g_print ("Range: %" G_GUINT64_FORMAT " - %" G_GUINT64_FORMAT
            " Default: %" G_GUINT64_FORMAT " ",
            puint64->minimum, puint64->maximum, g_value_get_uint64 (&value));
        break;
      }
      case G_TYPE_INT64:
      {
        GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);

        n_print ("%-23.23s Integer64. ", "");
        g_print ("Range: %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT
            " Default: %" G_GINT64_FORMAT " ",
            pint64->minimum, pint64->maximum, g_value_get_int64 (&value));
        break;
      }
      case G_TYPE_FLOAT:
      {
        GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);

        n_print ("%-23.23s Float. ", "");
        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
            pfloat->minimum, pfloat->maximum, g_value_get_float (&value));
        break;
      }
      case G_TYPE_DOUBLE:
      {
        GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);

        n_print ("%-23.23s Double. ", "");
        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
            pdouble->minimum, pdouble->maximum, g_value_get_double (&value));
        break;
      }
      case G_TYPE_CHAR:
      case G_TYPE_UCHAR:
        GST_ERROR ("%s: property '%s' of type char: consider changing to "
            "int/string", GST_OBJECT_NAME (element),
            g_param_spec_get_name (param));
        /* fall through */
      default:
        if (param->value_type == GST_TYPE_CAPS) {
          const GstCaps *caps = gst_value_get_caps (&value);

          if (!caps)
            n_print ("%-23.23s Caps (NULL)", "");
          else {
            print_caps (caps, "                           ");
          }
        } else if (G_IS_PARAM_SPEC_ENUM (param)) {
          GEnumValue *values;
          guint j = 0;
          gint enum_value;
          const gchar *value_nick = "";

          values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
          enum_value = g_value_get_enum (&value);

          while (values[j].value_name) {
            if (values[j].value == enum_value)
              value_nick = values[j].value_nick;
            j++;
          }

          n_print ("%-23.23s Enum \"%s\" Default: %d, \"%s\"", "",
              g_type_name (G_VALUE_TYPE (&value)), enum_value, value_nick);

          j = 0;
          while (values[j].value_name) {
            g_print ("\n");
            if (_name)
              g_print ("%s", _name);
            g_print ("%-23.23s    (%d): %-16s - %s", "",
                values[j].value, values[j].value_nick, values[j].value_name);
            j++;
          }
          /* g_type_class_unref (ec); */
        } else if (G_IS_PARAM_SPEC_FLAGS (param)) {
          GParamSpecFlags *pflags = G_PARAM_SPEC_FLAGS (param);
          GFlagsValue *vals;
          gchar *cur;

          vals = pflags->flags_class->values;

          cur = flags_to_string (vals, g_value_get_flags (&value));

          n_print ("%-23.23s Flags \"%s\" Default: 0x%08x, \"%s\"", "",
              g_type_name (G_VALUE_TYPE (&value)),
              g_value_get_flags (&value), cur);

          while (vals[0].value_name) {
            g_print ("\n");
            if (_name)
              g_print ("%s", _name);
            g_print ("%-23.23s    (0x%08x): %-16s - %s", "",
                vals[0].value, vals[0].value_nick, vals[0].value_name);
            ++vals;
          }

          g_free (cur);
        } else if (G_IS_PARAM_SPEC_OBJECT (param)) {
          n_print ("%-23.23s Object of type \"%s\"", "",
              g_type_name (param->value_type));
        } else if (G_IS_PARAM_SPEC_BOXED (param)) {
          n_print ("%-23.23s Boxed pointer of type \"%s\"", "",
              g_type_name (param->value_type));
          if (param->value_type == GST_TYPE_STRUCTURE) {
            const GstStructure *s = gst_value_get_structure (&value);
            if (s)
              gst_structure_foreach (s, print_field,
                  (gpointer) "                           ");
          }
        } else if (G_IS_PARAM_SPEC_POINTER (param)) {
          if (param->value_type != G_TYPE_POINTER) {
            n_print ("%-23.23s Pointer of type \"%s\".", "",
                g_type_name (param->value_type));
          } else {
            n_print ("%-23.23s Pointer.", "");
          }
        } else if (param->value_type == G_TYPE_VALUE_ARRAY) {
          GParamSpecValueArray *pvarray = G_PARAM_SPEC_VALUE_ARRAY (param);

          if (pvarray->element_spec) {
            n_print ("%-23.23s Array of GValues of type \"%s\"", "",
                g_type_name (pvarray->element_spec->value_type));
          } else {
            n_print ("%-23.23s Array of GValues", "");
          }
        } else if (GST_IS_PARAM_SPEC_FRACTION (param)) {
          GstParamSpecFraction *pfraction = GST_PARAM_SPEC_FRACTION (param);

          n_print ("%-23.23s Fraction. ", "");

          g_print ("Range: %d/%d - %d/%d Default: %d/%d ",
              pfraction->min_num, pfraction->min_den,
              pfraction->max_num, pfraction->max_den,
              gst_value_get_fraction_numerator (&value),
              gst_value_get_fraction_denominator (&value));
        } else {
          n_print ("%-23.23s Unknown type %ld \"%s\"", "",
              (glong) param->value_type, g_type_name (param->value_type));
        }
        break;
    }
    if (!readable)
      g_print (" Write only\n");
    else
      g_print ("\n");

    g_value_reset (&value);
  }
  if (num_properties == 0)
    n_print ("  none\n");

  g_free (property_specs);
}
static void
terminal_profile_gsettings_changeset_add (TerminalProfile *profile,
        GSettings *changeset,
        GParamSpec *pspec)
{
	TerminalProfilePrivate *priv = profile->priv;
	char *key;
	const GValue *value;

	/* FIXME: do this? */
#if 0
	if (priv->locked[pspec->param_id])
		return;

	if (!g_settings_is_writable (priv->settings, gsettings_key, NULL))
		return;
#endif

	key = g_param_spec_get_qdata (pspec, gsettings_key_quark);
	if (!key)
		return;

	value = g_value_array_get_nth (priv->properties, pspec->param_id);

	_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
	                       "Adding pspec %s with value %s to the GSettings changeset\n",
	                       pspec->name, g_strdup_value_contents (value));

	if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
		g_settings_set_boolean (changeset, key, g_value_get_boolean (value));
	else if (G_IS_PARAM_SPEC_STRING (pspec))
	{
		const char *str;

		str = g_value_get_string (value);
		g_settings_set_string (changeset, key, str ? str : "");
	}
	else if (G_IS_PARAM_SPEC_ENUM (pspec))
	{
		const GEnumValue *eval;

		eval = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, g_value_get_enum (value));

		g_settings_set_enum (changeset, key, eval->value);
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_COLOR)
	{
		GdkColor *color;
		char str[16];

		color = g_value_get_boxed (value);
		if (!color)
			goto cleanup;

		g_snprintf (str, sizeof (str),
		            "#%04X%04X%04X",
		            color->red,
		            color->green,
		            color->blue);

		g_settings_set_string (changeset, key, str);
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == PANGO_TYPE_FONT_DESCRIPTION)
	{
		PangoFontDescription *font_desc;
		char *font;

		font_desc = g_value_get_boxed (value);
		if (!font_desc)
			goto cleanup;

		font = pango_font_description_to_string (font_desc);
		g_settings_set_string (changeset, key, font);
		g_free (font);
	}
	else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
		g_settings_set_double (changeset, key, g_value_get_double (value));
	else if (G_IS_PARAM_SPEC_INT (pspec))
		g_settings_set_int (changeset, key, g_value_get_int (value));
	else if (G_IS_PARAM_SPEC_VALUE_ARRAY (pspec) &&
	         G_PARAM_SPEC_VALUE_TYPE (G_PARAM_SPEC_VALUE_ARRAY (pspec)->element_spec) == GDK_TYPE_COLOR)
	{
		GValueArray *array;
		GString *string;
		guint n_colors, i;

		/* We need to do this ourselves, because the gtk_color_selection_palette_to_string
		 * does not carry all the bytes, and xterm's palette is messed up...
		 */

		array = g_value_get_boxed (value);
		if (!array)
			goto cleanup;

		n_colors = array->n_values;
		string = g_string_sized_new (n_colors * (1 /* # */ + 3 * 4) + n_colors /* : separators and terminating \0 */);
		for (i = 0; i < n_colors; ++i)
		{
			GdkColor *color;

			if (i > 0)
				g_string_append_c (string, ':');

			color = g_value_get_boxed (g_value_array_get_nth (array, i));
			if (!color)
				continue;

			g_string_append_printf (string,
			                        "#%04X%04X%04X",
			                        color->red,
			                        color->green,
			                        color->blue);
		}

		g_settings_set_string (changeset, key, string->str);
		g_string_free (string, TRUE);
	}
	else
		g_printerr ("Unhandled value type %s of pspec %s\n", g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), pspec->name);

cleanup:
	return;
}
static void
terminal_profile_gsettings_notify_cb (GSettings *settings,
                                      gchar *key,
                                      gpointer     user_data)
{
	TerminalProfile *profile = TERMINAL_PROFILE (user_data);
	TerminalProfilePrivate *priv = profile->priv;
	TerminalProfileClass *klass;
	GVariant *settings_value;
	GParamSpec *pspec;
	GValue value = { 0, };
	gboolean equal;
	gboolean force_set = FALSE;

	if (!key) return;

	_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
	                       "GSettings notification for key %s [%s]\n",
	                       key,
	                       g_settings_is_writable (settings, key) ? "writable" : "LOCKED");

	klass = TERMINAL_PROFILE_GET_CLASS (profile);
	pspec = g_hash_table_lookup (klass->gsettings_keys, key);
	if (!pspec)
		return; /* ignore unknown keys, for future extensibility */

	priv->locked[pspec->param_id] = !g_settings_is_writable (settings, key);

	settings_value = g_settings_get_value (settings, key);
	if (!settings_value)
		return;

	g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));

	if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_BOOLEAN))
			goto out;

		g_value_set_boolean (&value, g_variant_get_boolean (settings_value));
	}
	else if (G_IS_PARAM_SPEC_STRING (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		g_value_set_string (&value, g_variant_get_string (settings_value, NULL));
	}
	else if (G_IS_PARAM_SPEC_ENUM (pspec))
	{

		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		g_value_set_enum (&value, g_settings_get_enum (settings, key));
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == GDK_TYPE_COLOR)
	{
		GdkColor color;

		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		if (!gdk_color_parse (g_variant_get_string (settings_value, NULL), &color))
			goto out;

		g_value_set_boxed (&value, &color);
	}
	else if (G_PARAM_SPEC_VALUE_TYPE (pspec) == PANGO_TYPE_FONT_DESCRIPTION)
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		g_value_take_boxed (&value, pango_font_description_from_string (g_variant_get_string (settings_value, NULL)));
	}
	else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_DOUBLE))
			goto out;

		g_value_set_double (&value, g_variant_get_double (settings_value));
	}
	else if (G_IS_PARAM_SPEC_INT (pspec))
	{
		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_INT16) &&
		    !g_variant_is_of_type (settings_value, G_VARIANT_TYPE_INT32) &&
		    !g_variant_is_of_type (settings_value, G_VARIANT_TYPE_INT64))
			goto out;

		g_value_set_int (&value, g_settings_get_int(settings, key));
	}
	else if (G_IS_PARAM_SPEC_VALUE_ARRAY (pspec) &&
	         G_PARAM_SPEC_VALUE_TYPE (G_PARAM_SPEC_VALUE_ARRAY (pspec)->element_spec) == GDK_TYPE_COLOR)
	{
		char **color_strings;
		GdkColor *colors;
		int n_colors, i;

		if (!g_variant_is_of_type (settings_value, G_VARIANT_TYPE_STRING))
			goto out;

		color_strings = g_strsplit (g_variant_get_string (settings_value, NULL), ":", -1);
		if (!color_strings)
			goto out;

		n_colors = g_strv_length (color_strings);
		colors = g_new0 (GdkColor, n_colors);
		for (i = 0; i < n_colors; ++i)
		{
			if (!gdk_color_parse (color_strings[i], &colors[i]))
				continue; /* ignore errors */
		}
		g_strfreev (color_strings);

		/* We continue even with a palette size != TERMINAL_PALETTE_SIZE,
		 * so we can change the palette size in future versions without
		 * causing too many issues.
		 */
		set_value_from_palette (&value, colors, n_colors);
		g_free (colors);
	}
	else
	{
		g_printerr ("Unhandled value type %s of pspec %s\n", g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), pspec->name);
		goto out;
	}

	if (g_param_value_validate (pspec, &value))
	{
		_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
		                       "Invalid value in GSettings for key %s was changed to comply with pspec %s\n",
		                       key, pspec->name);

		force_set = TRUE;
	}

	/* Only set the property if the value is different than our current value,
	 * so we don't go into an infinite loop.
	 */
	equal = values_equal (pspec, &value, g_value_array_get_nth (priv->properties, pspec->param_id));
#ifdef MATE_ENABLE_DEBUG
	_TERMINAL_DEBUG_IF (TERMINAL_DEBUG_PROFILE)
	{
		if (!equal)
			_terminal_debug_print (TERMINAL_DEBUG_PROFILE,
			                       "Setting property %s to a different value\n"
			                       "  now: %s\n"
			                       "  new: %s\n",
			                       pspec->name,
			                       g_strdup_value_contents (g_value_array_get_nth (priv->properties, pspec->param_id)),
			                       g_strdup_value_contents (&value));
	}
#endif

	if (!equal || force_set)
	{
		priv->gsettings_notification_pspec = pspec;
		g_object_set_property (G_OBJECT (profile), pspec->name, &value);
		priv->gsettings_notification_pspec = NULL;
	}

out:
	/* FIXME: if we arrive here through goto in the error cases,
	 * should we maybe reset the property to its default value?
	 */

	g_value_unset (&value);
	g_variant_unref (settings_value);
}
Beispiel #11
0
static void
print_element_properties_info (GstElement * element)
{
  GParamSpec **property_specs;
  guint num_properties, i;
  gboolean readable;
  gboolean first_flag;

  property_specs = g_object_class_list_properties
      (G_OBJECT_GET_CLASS (element), &num_properties);
  n_print ("\n");
  n_print ("Element Properties:\n");

  for (i = 0; i < num_properties; i++) {
    GValue value = { 0, };
    GParamSpec *param = property_specs[i];

    readable = FALSE;

    g_value_init (&value, param->value_type);

    n_print ("  %-20s: %s\n", g_param_spec_get_name (param),
        g_param_spec_get_blurb (param));

    first_flag = TRUE;
    n_print ("%-23.23s flags: ", "");
    if (param->flags & G_PARAM_READABLE) {
      g_object_get_property (G_OBJECT (element), param->name, &value);
      readable = TRUE;
      if (!first_flag)
        g_print (", ");
      else
        first_flag = FALSE;
      g_print (_("readable"));
    }
    if (param->flags & G_PARAM_WRITABLE) {
      if (!first_flag)
        g_print (", ");
      else
        first_flag = FALSE;
      g_print (_("writable"));
    }
    if (param->flags & GST_PARAM_CONTROLLABLE) {
      if (!first_flag)
        g_print (", ");
      else
        first_flag = FALSE;
      g_print (_("controllable"));
    }
    n_print ("\n");

    switch (G_VALUE_TYPE (&value)) {
      case G_TYPE_STRING:
      {
        GParamSpecString *pstring = G_PARAM_SPEC_STRING (param);

        n_print ("%-23.23s String. ", "");

        if (pstring->default_value == NULL)
          g_print ("Default: null ");
        else
          g_print ("Default: \"%s\" ", pstring->default_value);

        if (readable) {
          const char *string_val = g_value_get_string (&value);

          if (string_val == NULL)
            g_print ("Current: null");
          else
            g_print ("Current: \"%s\"", string_val);
        }
        break;
      }
      case G_TYPE_BOOLEAN:
      {
        GParamSpecBoolean *pboolean = G_PARAM_SPEC_BOOLEAN (param);

        n_print ("%-23.23s Boolean. ", "");
        g_print ("Default: %s ", (pboolean->default_value ? "true" : "false"));
        if (readable)
          g_print ("Current: %s",
              (g_value_get_boolean (&value) ? "true" : "false"));
        break;
      }
      case G_TYPE_ULONG:
      {
        GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);

        n_print ("%-23.23s Unsigned Long. ", "");
        g_print ("Range: %lu - %lu Default: %lu ",
            pulong->minimum, pulong->maximum, pulong->default_value);
        if (readable)
          g_print ("Current: %lu", g_value_get_ulong (&value));
        break;
      }
      case G_TYPE_LONG:
      {
        GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);

        n_print ("%-23.23s Long. ", "");
        g_print ("Range: %ld - %ld Default: %ld ",
            plong->minimum, plong->maximum, plong->default_value);
        if (readable)
          g_print ("Current: %ld", g_value_get_long (&value));
        break;
      }
      case G_TYPE_UINT:
      {
        GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);

        n_print ("%-23.23s Unsigned Integer. ", "");
        g_print ("Range: %u - %u Default: %u ",
            puint->minimum, puint->maximum, puint->default_value);
        if (readable)
          g_print ("Current: %u", g_value_get_uint (&value));
        break;
      }
      case G_TYPE_INT:
      {
        GParamSpecInt *pint = G_PARAM_SPEC_INT (param);

        n_print ("%-23.23s Integer. ", "");
        g_print ("Range: %d - %d Default: %d ",
            pint->minimum, pint->maximum, pint->default_value);
        if (readable)
          g_print ("Current: %d", g_value_get_int (&value));
        break;
      }
      case G_TYPE_UINT64:
      {
        GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);

        n_print ("%-23.23s Unsigned Integer64. ", "");
        g_print ("Range: %" G_GUINT64_FORMAT " - %" G_GUINT64_FORMAT
            " Default: %" G_GUINT64_FORMAT " ",
            puint64->minimum, puint64->maximum, puint64->default_value);
        if (readable)
          g_print ("Current: %" G_GUINT64_FORMAT, g_value_get_uint64 (&value));
        break;
      }
      case G_TYPE_INT64:
      {
        GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);

        n_print ("%-23.23s Integer64. ", "");
        g_print ("Range: %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT
            " Default: %" G_GINT64_FORMAT " ",
            pint64->minimum, pint64->maximum, pint64->default_value);
        if (readable)
          g_print ("Current: %" G_GINT64_FORMAT, g_value_get_int64 (&value));
        break;
      }
      case G_TYPE_FLOAT:
      {
        GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);

        n_print ("%-23.23s Float. ", "");
        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
            pfloat->minimum, pfloat->maximum, pfloat->default_value);
        if (readable)
          g_print ("Current: %15.7g", g_value_get_float (&value));
        break;
      }
      case G_TYPE_DOUBLE:
      {
        GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);

        n_print ("%-23.23s Double. ", "");
        g_print ("Range: %15.7g - %15.7g Default: %15.7g ",
            pdouble->minimum, pdouble->maximum, pdouble->default_value);
        if (readable)
          g_print ("Current: %15.7g", g_value_get_double (&value));
        break;
      }
      default:
        if (param->value_type == GST_TYPE_CAPS) {
          const GstCaps *caps = gst_value_get_caps (&value);

          if (!caps)
            n_print ("%-23.23s Caps (NULL)", "");
          else {
            print_caps (caps, "                           ");
          }
        } else if (G_IS_PARAM_SPEC_ENUM (param)) {
          GParamSpecEnum *penum = G_PARAM_SPEC_ENUM (param);
          GEnumValue *values;
          guint j = 0;
          gint enum_value;
          const gchar *def_val_nick = "", *cur_val_nick = "";

          values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
          enum_value = g_value_get_enum (&value);

          while (values[j].value_name) {
            if (values[j].value == enum_value)
              cur_val_nick = values[j].value_nick;
            if (values[j].value == penum->default_value)
              def_val_nick = values[j].value_nick;
            j++;
          }

          n_print
              ("%-23.23s Enum \"%s\" Default: %d, \"%s\" Current: %d, \"%s\"",
              "", g_type_name (G_VALUE_TYPE (&value)), penum->default_value,
              def_val_nick, enum_value, cur_val_nick);

          j = 0;
          while (values[j].value_name) {
            g_print ("\n");
            if (_name)
              g_print ("%s", _name);
            g_print ("%-23.23s    (%d): %-16s - %s", "",
                values[j].value, values[j].value_nick, values[j].value_name);
            j++;
          }
          /* g_type_class_unref (ec); */
        } else if (G_IS_PARAM_SPEC_FLAGS (param)) {
          GParamSpecFlags *pflags = G_PARAM_SPEC_FLAGS (param);
          GFlagsValue *values;
          guint j = 0;
          gint flags_value;
          GString *cur_flags = NULL, *def_flags = NULL;

          values = G_FLAGS_CLASS (g_type_class_ref (param->value_type))->values;
          flags_value = g_value_get_flags (&value);

          while (values[j].value_name) {
            if (values[j].value & flags_value) {
              if (cur_flags) {
                g_string_append_printf (cur_flags, " | %s",
                    values[j].value_nick);
              } else {
                cur_flags = g_string_new (values[j].value_nick);
              }
            }
            if (values[j].value & pflags->default_value) {
              if (def_flags) {
                g_string_append_printf (def_flags, " | %s",
                    values[j].value_nick);
              } else {
                def_flags = g_string_new (values[j].value_nick);
              }
            }
            j++;
          }

          n_print
              ("%-23.23s Flags \"%s\" Default: 0x%08x, \"%s\" Current: 0x%08x, \"%s\"",
              "", g_type_name (G_VALUE_TYPE (&value)), pflags->default_value,
              (def_flags ? def_flags->str : "(none)"), flags_value,
              (cur_flags ? cur_flags->str : "(none)"));

          j = 0;
          while (values[j].value_name) {
            g_print ("\n");
            if (_name)
              g_print ("%s", _name);
            g_print ("%-23.23s    (0x%08x): %-16s - %s", "",
                values[j].value, values[j].value_nick, values[j].value_name);
            j++;
          }

          if (cur_flags)
            g_string_free (cur_flags, TRUE);
          if (def_flags)
            g_string_free (def_flags, TRUE);
        } else if (G_IS_PARAM_SPEC_OBJECT (param)) {
          n_print ("%-23.23s Object of type \"%s\"", "",
              g_type_name (param->value_type));
        } else if (G_IS_PARAM_SPEC_BOXED (param)) {
          n_print ("%-23.23s Boxed pointer of type \"%s\"", "",
              g_type_name (param->value_type));
        } else if (G_IS_PARAM_SPEC_POINTER (param)) {
          if (param->value_type != G_TYPE_POINTER) {
            n_print ("%-23.23s Pointer of type \"%s\".", "",
                g_type_name (param->value_type));
          } else {
            n_print ("%-23.23s Pointer.", "");
          }
        } else if (param->value_type == G_TYPE_VALUE_ARRAY) {
          GParamSpecValueArray *pvarray = G_PARAM_SPEC_VALUE_ARRAY (param);

          if (pvarray->element_spec) {
            n_print ("%-23.23s Array of GValues of type \"%s\"", "",
                g_type_name (pvarray->element_spec->value_type));
          } else {
            n_print ("%-23.23s Array of GValues", "");
          }
        } else if (GST_IS_PARAM_SPEC_FRACTION (param)) {
          GstParamSpecFraction *pfraction = GST_PARAM_SPEC_FRACTION (param);

          n_print ("%-23.23s Fraction. ", "");

          g_print ("Range: %d/%d - %d/%d Default: %d/%d ",
              pfraction->min_num, pfraction->min_den,
              pfraction->max_num, pfraction->max_den,
              pfraction->def_num, pfraction->def_den);
          if (readable)
            g_print ("Current: %d/%d",
                gst_value_get_fraction_numerator (&value),
                gst_value_get_fraction_denominator (&value));

        } else if (GST_IS_PARAM_SPEC_MINI_OBJECT (param)) {
          n_print ("%-23.23s MiniObject of type \"%s\"", "",
              g_type_name (param->value_type));
        } else {
          n_print ("%-23.23s Unknown type %ld \"%s\"", "", param->value_type,
              g_type_name (param->value_type));
        }
        break;
    }
    if (!readable)
      g_print (" Write only\n");
    else
      g_print ("\n");

    g_value_reset (&value);
  }
  if (num_properties == 0)
    n_print ("  none\n");

  g_free (property_specs);
}