summaryrefslogtreecommitdiff
path: root/gtk/gtkcssvalue.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2012-03-08 16:20:03 +0100
committerAlexander Larsson <alexl@redhat.com>2012-03-08 16:39:49 +0100
commit1ceed037b24c78b48a5319f465e4c489eb373413 (patch)
treea22e506b9d737b3a67817d5c7eb06aa2b375530d /gtk/gtkcssvalue.c
parent616cc5b96dc6d04ec0dcb43fe1024dc5473bfc9b (diff)
downloadgtk+-1ceed037b24c78b48a5319f465e4c489eb373413.tar.gz
Don't use GValue in GtkCssValue
We now have complete coverage in the GtkCssValue API for type handling, so drop the GValue from internal storage and just create new ones when needed.
Diffstat (limited to 'gtk/gtkcssvalue.c')
-rw-r--r--gtk/gtkcssvalue.c254
1 files changed, 163 insertions, 91 deletions
diff --git a/gtk/gtkcssvalue.c b/gtk/gtkcssvalue.c
index a3ea6d2dcc..367818116e 100644
--- a/gtk/gtkcssvalue.c
+++ b/gtk/gtkcssvalue.c
@@ -28,19 +28,25 @@
struct _GtkCssValue
{
volatile gint ref_count;
- GValue g_value;
+ GType type;
+ union {
+ gpointer ptr;
+ gint gint;
+ double dbl;
+ } u;
};
G_DEFINE_BOXED_TYPE (GtkCssValue, _gtk_css_value, _gtk_css_value_ref, _gtk_css_value_unref)
static GtkCssValue *
-_gtk_css_value_new (void)
+_gtk_css_value_new (GType type)
{
GtkCssValue *value;
value = g_slice_new0 (GtkCssValue);
value->ref_count = 1;
+ value->type = type;
return value;
}
@@ -62,9 +68,24 @@ _gtk_css_value_new_from_gvalue (const GValue *g_value)
value = _gtk_css_value_new_from_number (g_value_get_boxed (g_value));
else
{
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, type);
- g_value_copy (g_value, &value->g_value);
+ value = _gtk_css_value_new (type);
+
+ if (g_type_is_a (type, G_TYPE_OBJECT))
+ value->u.ptr = g_value_dup_object (g_value);
+ else if (g_type_is_a (type, G_TYPE_BOXED))
+ value->u.ptr = g_value_dup_boxed (g_value);
+ else if (g_type_is_a (type, G_TYPE_INT))
+ value->u.gint = g_value_get_int (g_value);
+ else if (g_type_is_a (type, G_TYPE_BOOLEAN))
+ value->u.gint = g_value_get_boolean (g_value);
+ else if (g_type_is_a (type, G_TYPE_ENUM))
+ value->u.gint = g_value_get_enum (g_value);
+ else if (g_type_is_a (type, G_TYPE_STRING))
+ value->u.ptr = g_value_dup_string (g_value);
+ else if (g_type_is_a (type, G_TYPE_DOUBLE))
+ value->u.dbl = g_value_get_double (g_value);
+ else
+ g_assert_not_reached ();
}
return value;
@@ -93,8 +114,24 @@ _gtk_css_value_new_take_gvalue (GValue *g_value)
}
else
{
- value = _gtk_css_value_new ();
- value->g_value = *g_value;
+ value = _gtk_css_value_new (type);
+
+ if (g_type_is_a (type, G_TYPE_OBJECT))
+ value->u.ptr = g_value_get_object (g_value);
+ else if (g_type_is_a (type, G_TYPE_BOXED))
+ value->u.ptr = g_value_get_boxed (g_value);
+ else if (g_type_is_a (type, G_TYPE_INT))
+ value->u.gint = g_value_get_int (g_value);
+ else if (g_type_is_a (type, G_TYPE_BOOLEAN))
+ value->u.gint = g_value_get_boolean (g_value);
+ else if (g_type_is_a (type, G_TYPE_ENUM))
+ value->u.gint = g_value_get_enum (g_value);
+ else if (g_type_is_a (type, G_TYPE_STRING))
+ value->u.ptr = g_value_dup_string (g_value);
+ else if (g_type_is_a (type, G_TYPE_DOUBLE))
+ value->u.dbl = g_value_get_double (g_value);
+ else
+ g_assert_not_reached ();
}
return value;
@@ -110,17 +147,15 @@ _gtk_css_value_new_from_int (gint val)
{
if (singletons[val] == NULL)
{
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, G_TYPE_INT);
- g_value_set_int (&value->g_value, val);
+ value = _gtk_css_value_new (G_TYPE_INT);
+ value->u.gint = val;
singletons[val] = value;
}
return _gtk_css_value_ref (singletons[val]);
}
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, G_TYPE_INT);
- g_value_set_int (&value->g_value, val);
+ value = _gtk_css_value_new (G_TYPE_INT);
+ value->u.gint = val;
return value;
}
@@ -130,9 +165,8 @@ _gtk_css_value_new_take_string (char *string)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, G_TYPE_STRING);
- g_value_take_string (&value->g_value, string);
+ value = _gtk_css_value_new (G_TYPE_STRING);
+ value->u.ptr = string;
return value;
}
@@ -142,21 +176,28 @@ _gtk_css_value_new_from_string (const char *string)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, G_TYPE_STRING);
- g_value_set_string (&value->g_value, string);
+ value = _gtk_css_value_new (G_TYPE_STRING);
+ value->u.ptr = g_strdup (string);
return value;
}
+static gpointer
+g_boxed_copy0 (GType boxed_type,
+ gconstpointer src_boxed)
+{
+ if (src_boxed == NULL)
+ return NULL;
+ return g_boxed_copy (boxed_type, src_boxed);
+}
+
GtkCssValue *
_gtk_css_value_new_from_border (const GtkBorder *border)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_BORDER);
- g_value_set_boxed (&value->g_value, border);
+ value = _gtk_css_value_new (GTK_TYPE_BORDER);
+ value->u.ptr = g_boxed_copy0 (GTK_TYPE_BORDER, border);
return value;
}
@@ -166,9 +207,8 @@ _gtk_css_value_new_take_pattern (cairo_pattern_t *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, CAIRO_GOBJECT_TYPE_PATTERN);
- g_value_take_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (CAIRO_GOBJECT_TYPE_PATTERN);
+ value->u.ptr = v;
return value;
}
@@ -178,9 +218,8 @@ _gtk_css_value_new_from_pattern (const cairo_pattern_t *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, CAIRO_GOBJECT_TYPE_PATTERN);
- g_value_set_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (CAIRO_GOBJECT_TYPE_PATTERN);
+ value->u.ptr = g_boxed_copy0 (CAIRO_GOBJECT_TYPE_PATTERN, v);
return value;
}
@@ -190,9 +229,8 @@ _gtk_css_value_new_take_shadow (GtkShadow *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_SHADOW);
- g_value_take_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GTK_TYPE_SHADOW);
+ value->u.ptr = v;
return value;
}
@@ -202,9 +240,8 @@ _gtk_css_value_new_take_font_description (PangoFontDescription *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, PANGO_TYPE_FONT_DESCRIPTION);
- g_value_take_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (PANGO_TYPE_FONT_DESCRIPTION);
+ value->u.ptr = v;
return value;
}
@@ -214,9 +251,8 @@ _gtk_css_value_new_take_image (GtkCssImage *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_CSS_IMAGE);
- g_value_take_object (&value->g_value, v);
+ value = _gtk_css_value_new (GTK_TYPE_CSS_IMAGE);
+ value->u.ptr = v;
return value;
}
@@ -233,9 +269,8 @@ _gtk_css_value_new_from_number (const GtkCssNumber *v)
{
if (zero_singleton == NULL)
{
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_CSS_NUMBER);
- g_value_set_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GTK_TYPE_CSS_NUMBER);
+ value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_NUMBER, v);
zero_singleton = value;
}
return _gtk_css_value_ref (zero_singleton);
@@ -251,18 +286,16 @@ _gtk_css_value_new_from_number (const GtkCssNumber *v)
int i = round (v->value);
if (px_singletons[i] == NULL)
{
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_CSS_NUMBER);
- g_value_set_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GTK_TYPE_CSS_NUMBER);
+ value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_NUMBER, v);
px_singletons[i] = value;
}
return _gtk_css_value_ref (px_singletons[i]);
}
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_CSS_NUMBER);
- g_value_set_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GTK_TYPE_CSS_NUMBER);
+ value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_NUMBER, v);
return value;
}
@@ -272,9 +305,8 @@ _gtk_css_value_new_from_rgba (const GdkRGBA *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GDK_TYPE_RGBA);
- g_value_set_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GDK_TYPE_RGBA);
+ value->u.ptr = g_boxed_copy0 (GDK_TYPE_RGBA, v);
return value;
}
@@ -284,9 +316,8 @@ _gtk_css_value_new_from_color (const GdkColor *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GDK_TYPE_COLOR);
- g_value_set_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GDK_TYPE_COLOR);
+ value->u.ptr = g_boxed_copy0 (GDK_TYPE_COLOR, v);
return value;
}
@@ -296,9 +327,8 @@ _gtk_css_value_new_from_background_size (const GtkCssBackgroundSize *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_CSS_BACKGROUND_SIZE);
- g_value_set_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GTK_TYPE_CSS_BACKGROUND_SIZE);
+ value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_BACKGROUND_SIZE, v);
return value;
}
@@ -308,9 +338,8 @@ _gtk_css_value_new_take_symbolic_color (GtkSymbolicColor *v)
{
GtkCssValue *value;
- value = _gtk_css_value_new ();
- g_value_init (&value->g_value, GTK_TYPE_SYMBOLIC_COLOR);
- g_value_take_boxed (&value->g_value, v);
+ value = _gtk_css_value_new (GTK_TYPE_SYMBOLIC_COLOR);
+ value->u.ptr = v;
return value;
}
@@ -328,26 +357,62 @@ _gtk_css_value_ref (GtkCssValue *value)
void
_gtk_css_value_unref (GtkCssValue *value)
{
+ GType type;
+
if (value == NULL)
return;
if (!g_atomic_int_dec_and_test (&value->ref_count))
return;
- g_value_unset (&value->g_value);
+ type = value->type;
+
+ if (g_type_is_a (type, G_TYPE_OBJECT) && value->u.ptr != NULL)
+ g_object_unref (value->u.ptr);
+ else if (g_type_is_a (type, G_TYPE_BOXED) && value->u.ptr != NULL)
+ g_boxed_free (type, value->u.ptr);
+ else if (g_type_is_a (type, G_TYPE_STRING))
+ g_free (value->u.ptr);
+
g_slice_free (GtkCssValue, value);
}
GType
_gtk_css_value_get_content_type (GtkCssValue *value)
{
- return G_VALUE_TYPE (&value->g_value);
+ return value->type;
}
gboolean
_gtk_css_value_holds (GtkCssValue *value, GType type)
{
- return G_VALUE_HOLDS (&value->g_value, type);
+ return g_type_is_a (value->type, type);
+}
+
+static void
+fill_gvalue (GtkCssValue *value,
+ GValue *g_value)
+{
+ GType type;
+
+ type = value->type;
+
+ if (g_type_is_a (type, G_TYPE_OBJECT))
+ g_value_set_object (g_value, value->u.ptr);
+ else if (g_type_is_a (type, G_TYPE_BOXED))
+ g_value_set_boxed (g_value, value->u.ptr);
+ else if (g_type_is_a (type, G_TYPE_INT))
+ g_value_set_int (g_value, value->u.gint);
+ else if (g_type_is_a (type, G_TYPE_BOOLEAN))
+ g_value_set_boolean (g_value, value->u.gint);
+ else if (g_type_is_a (type, G_TYPE_ENUM))
+ g_value_set_enum (g_value, value->u.gint);
+ else if (g_type_is_a (type, G_TYPE_STRING))
+ g_value_set_string (g_value, value->u.ptr);
+ else if (g_type_is_a (type, G_TYPE_DOUBLE))
+ g_value_set_double (g_value, value->u.dbl);
+ else
+ g_assert_not_reached ();
}
void
@@ -356,8 +421,8 @@ _gtk_css_value_init_gvalue (GtkCssValue *value,
{
if (value != NULL)
{
- g_value_init (g_value, G_VALUE_TYPE (&value->g_value));
- g_value_copy (&value->g_value, g_value);
+ g_value_init (g_value, value->type);
+ fill_gvalue (value, g_value);
}
}
@@ -365,13 +430,18 @@ void
_gtk_css_value_to_gvalue (GtkCssValue *value,
GValue *g_value)
{
- if (G_VALUE_TYPE (&value->g_value) == G_VALUE_TYPE (g_value))
- g_value_copy (&value->g_value, g_value);
- else if (g_value_type_transformable (G_VALUE_TYPE (&value->g_value), G_VALUE_TYPE (g_value)))
- g_value_transform (&value->g_value, g_value);
+ if (value->type == G_VALUE_TYPE (g_value))
+ fill_gvalue (value, g_value);
+ else if (g_value_type_transformable (value->type, G_VALUE_TYPE (g_value)))
+ {
+ GValue v = G_VALUE_INIT;
+ _gtk_css_value_init_gvalue (value, &v);
+ g_value_transform (&v, g_value);
+ g_value_unset (&v);
+ }
else
g_warning ("can't convert css value of type `%s' as value of type `%s'",
- G_VALUE_TYPE_NAME (&value->g_value),
+ g_type_name (value->type),
G_VALUE_TYPE_NAME (g_value));
}
@@ -385,159 +455,161 @@ GtkCssSpecialValue
_gtk_css_value_get_special_kind (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_SPECIAL_VALUE), 0);
- return g_value_get_enum (&value->g_value);
+ return value->u.gint;
}
GtkCssNumber *
_gtk_css_value_get_number (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_NUMBER), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
GtkSymbolicColor *
_gtk_css_value_get_symbolic_color (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_SYMBOLIC_COLOR), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
int
_gtk_css_value_get_int (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_INT), 0);
- return g_value_get_int (&value->g_value);
+ return value->u.gint;
}
double
_gtk_css_value_get_double (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_DOUBLE), 0);
- return g_value_get_double (&value->g_value);
+ return value->u.dbl;
}
const char *
_gtk_css_value_get_string (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_STRING), 0);
- return g_value_get_string (&value->g_value);
+ return value->u.ptr;
}
gpointer
_gtk_css_value_dup_object (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_OBJECT), NULL);
- return g_value_dup_object (&value->g_value);
+ if (value->u.ptr)
+ return g_object_ref (value->u.ptr);
+ return NULL;
}
gpointer
_gtk_css_value_get_object (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_OBJECT), NULL);
- return g_value_get_object (&value->g_value);
+ return value->u.ptr;
}
gpointer
_gtk_css_value_get_boxed (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_BOXED), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
const char **
_gtk_css_value_get_strv (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, G_TYPE_STRV), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
GtkCssImage *
_gtk_css_value_get_image (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_IMAGE), NULL);
- return g_value_get_object (&value->g_value);
+ return value->u.ptr;
}
GtkBorderStyle
_gtk_css_value_get_border_style (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_BORDER_STYLE), 0);
- return g_value_get_enum (&value->g_value);
+ return value->u.gint;
}
GtkCssBackgroundSize *
_gtk_css_value_get_background_size (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BACKGROUND_SIZE), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
GtkCssBorderImageRepeat *
_gtk_css_value_get_border_image_repeat (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
GtkCssBorderCornerRadius *
_gtk_css_value_get_border_corner_radius (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BORDER_CORNER_RADIUS), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
PangoFontDescription *
_gtk_css_value_get_font_description (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_FONT_DESCRIPTION), 0);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
PangoStyle
_gtk_css_value_get_pango_style (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_STYLE), 0);
- return g_value_get_enum (&value->g_value);
+ return value->u.gint;
}
PangoVariant
_gtk_css_value_get_pango_variant (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_VARIANT), 0);
- return g_value_get_enum (&value->g_value);
+ return value->u.gint;
}
PangoWeight
_gtk_css_value_get_pango_weight (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, PANGO_TYPE_WEIGHT), 0);
- return g_value_get_enum (&value->g_value);
+ return value->u.gint;
}
GdkRGBA *
_gtk_css_value_get_rgba (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GDK_TYPE_RGBA), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
cairo_pattern_t *
_gtk_css_value_get_pattern (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, CAIRO_GOBJECT_TYPE_PATTERN), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
GtkGradient *
_gtk_css_value_get_gradient (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_GRADIENT), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}
GtkShadow *
_gtk_css_value_get_shadow (GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_SHADOW), NULL);
- return g_value_get_boxed (&value->g_value);
+ return value->u.ptr;
}