+typedef enum {
+ GTK_STYLE_PROPERTY_INHERIT = (1 << 0),
+ GTK_STYLE_PROPERTY_ANIMATED = (1 << 1),
+ GTK_STYLE_PROPERTY_NO_RESIZE = (1 << 2),
+ GTK_STYLE_PROPERTY_AFFECTS_FONT = (1 << 3)
+} GtkStylePropertyFlags;
+
+static void
+gtk_css_style_property_register (const char * name,
+ guint expected_id,
+ GType value_type,
+ GtkStylePropertyFlags flags,
+ GtkCssStylePropertyParseFunc parse_value,
+ GtkCssStylePropertyQueryFunc query_value,
+ GtkCssStylePropertyAssignFunc assign_value,
+ GtkCssValue * initial_value)
+{
+ GtkCssStyleProperty *node;
+
+ g_assert (initial_value != NULL);
+ g_assert (parse_value != NULL);
+ g_assert (value_type == G_TYPE_NONE || query_value != NULL);
+ g_assert (value_type == G_TYPE_NONE || assign_value != NULL);
+
+ node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY,
+ "value-type", value_type,
+ "affects-size", (flags & GTK_STYLE_PROPERTY_NO_RESIZE) ? FALSE : TRUE,
+ "affects-font", (flags & GTK_STYLE_PROPERTY_AFFECTS_FONT) ? TRUE : FALSE,
+ "animated", (flags & GTK_STYLE_PROPERTY_ANIMATED) ? TRUE : FALSE,
+ "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE,
+ "initial-value", initial_value,
+ "name", name,
+ NULL);
+
+ node->parse_value = parse_value;
+ node->query_value = query_value;
+ node->assign_value = assign_value;
+
+ _gtk_css_value_unref (initial_value);
+
+ g_assert (_gtk_css_style_property_get_id (node) == expected_id);
+}
+
+/*** IMPLEMENTATIONS ***/
+
+static void
+query_length_as_int (GtkCssStyleProperty *property,
+ const GtkCssValue *css_value,
+ GValue *value)
+{
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, round (_gtk_css_number_value_get (css_value, 100)));
+}
+
+static GtkCssValue *
+assign_length_from_int (GtkCssStyleProperty *property,
+ const GValue *value)
+{
+ return _gtk_css_number_value_new (g_value_get_int (value), GTK_CSS_PX);
+}
+
+static void
+query_length_as_double (GtkCssStyleProperty *property,
+ const GtkCssValue *css_value,
+ GValue *value)
+{
+ g_value_init (value, G_TYPE_DOUBLE);
+ g_value_set_double (value, _gtk_css_number_value_get (css_value, 100));
+}
+
+static GtkCssValue *
+assign_length_from_double (GtkCssStyleProperty *property,
+ const GValue *value)
+{
+ return _gtk_css_number_value_new (g_value_get_double (value), GTK_CSS_PX);
+}
+
+static void
+query_border (GtkCssStyleProperty *property,
+ const GtkCssValue *css_value,
+ GValue *value)
+{
+ GtkBorder border;
+
+ g_value_init (value, GTK_TYPE_BORDER);
+
+ border.top = round (_gtk_css_number_value_get (_gtk_css_border_value_get_top (css_value), 100));
+ border.right = round (_gtk_css_number_value_get (_gtk_css_border_value_get_right (css_value), 100));
+ border.bottom = round (_gtk_css_number_value_get (_gtk_css_border_value_get_bottom (css_value), 100));
+ border.left = round (_gtk_css_number_value_get (_gtk_css_border_value_get_left (css_value), 100));
+
+ g_value_set_boxed (value, &border);
+}
+
+static GtkCssValue *
+assign_border (GtkCssStyleProperty *property,
+ const GValue *value)
+{
+ const GtkBorder *border = g_value_get_boxed (value);
+
+ if (border == NULL)
+ return _gtk_css_initial_value_new ();
+ else
+ return _gtk_css_border_value_new (_gtk_css_number_value_new (border->top, GTK_CSS_PX),
+ _gtk_css_number_value_new (border->right, GTK_CSS_PX),
+ _gtk_css_number_value_new (border->bottom, GTK_CSS_PX),
+ _gtk_css_number_value_new (border->left, GTK_CSS_PX));
+}
+
+static GtkCssValue *
+color_parse (GtkCssStyleProperty *property,
+ GtkCssParser *parser)
+{
+ return _gtk_css_color_value_parse (parser);
+}
+