]> Pileus Git - ~andy/gtk/blob - gtk/gtkcssstylepropertyimpl.c
530a85ec3c8cc8a7e7391c4d3f8ffb658391858c
[~andy/gtk] / gtk / gtkcssstylepropertyimpl.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include "gtkstylepropertyprivate.h"
21
22 #include <gobject/gvaluecollector.h>
23 #include <gdk-pixbuf/gdk-pixbuf.h>
24 #include <cairo-gobject.h>
25 #include <math.h>
26
27 #include "gtkcssparserprivate.h"
28 #include "gtkcssstylefuncsprivate.h"
29 #include "gtkcssstylepropertyprivate.h"
30 #include "gtkcsstypesprivate.h"
31 #include "gtkintl.h"
32 #include "gtkprivatetypebuiltins.h"
33 #include "gtkstylepropertiesprivate.h"
34
35 /* this is in case round() is not provided by the compiler, 
36  * such as in the case of C89 compilers, like MSVC
37  */
38 #include "fallback-c89.c"
39
40 /* the actual parsers we have */
41 #include "gtkanimationdescription.h"
42 #include "gtkbindings.h"
43 #include "gtkcssarrayvalueprivate.h"
44 #include "gtkcssbgsizevalueprivate.h"
45 #include "gtkcssbordervalueprivate.h"
46 #include "gtkcsscornervalueprivate.h"
47 #include "gtkcsseasevalueprivate.h"
48 #include "gtkcssenginevalueprivate.h"
49 #include "gtkcssimagegradientprivate.h"
50 #include "gtkcssimageprivate.h"
51 #include "gtkcssimagevalueprivate.h"
52 #include "gtkcssenumvalueprivate.h"
53 #include "gtkcssnumbervalueprivate.h"
54 #include "gtkcsspositionvalueprivate.h"
55 #include "gtkcssrepeatvalueprivate.h"
56 #include "gtkcssrgbavalueprivate.h"
57 #include "gtkcssshadowsvalueprivate.h"
58 #include "gtkcssstringvalueprivate.h"
59 #include "gtksymboliccolorprivate.h"
60 #include "gtkthemingengine.h"
61 #include "gtktypebuiltins.h"
62 #include "gtkwin32themeprivate.h"
63
64 /*** REGISTRATION ***/
65
66 typedef enum {
67   GTK_STYLE_PROPERTY_INHERIT = (1 << 0),
68   GTK_STYLE_PROPERTY_ANIMATED = (1 << 1)
69 } GtkStylePropertyFlags;
70
71 static void
72 gtk_css_style_property_register (const char *                   name,
73                                  guint                          expected_id,
74                                  GType                          value_type,
75                                  GtkStylePropertyFlags          flags,
76                                  GtkCssStylePropertyParseFunc   parse_value,
77                                  GtkCssStylePropertyPrintFunc   print_value,
78                                  GtkCssStylePropertyComputeFunc compute_value,
79                                  GtkCssStylePropertyQueryFunc   query_value,
80                                  GtkCssStylePropertyAssignFunc  assign_value,
81                                  GtkCssStylePropertyEqualFunc   equal_func,
82                                  GtkCssValue *                  initial_value)
83 {
84   GtkCssStyleProperty *node;
85
86   g_assert (initial_value != NULL);
87   g_assert (parse_value != NULL);
88   g_assert (value_type == G_TYPE_NONE || query_value != NULL);
89   g_assert (value_type == G_TYPE_NONE || assign_value != NULL);
90
91   node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY,
92                        "value-type", value_type,
93                        "animated", (flags & GTK_STYLE_PROPERTY_ANIMATED) ? TRUE : FALSE,
94                        "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE,
95                        "initial-value", initial_value,
96                        "name", name,
97                        NULL);
98   
99   node->parse_value = parse_value;
100   if (print_value)
101     node->print_value = print_value;
102   if (compute_value)
103     node->compute_value = compute_value;
104   node->query_value = query_value;
105   node->assign_value = assign_value;
106   if (equal_func)
107     node->equal_func = equal_func;
108
109   _gtk_css_value_unref (initial_value);
110
111   g_assert (_gtk_css_style_property_get_id (node) == expected_id);
112 }
113
114 /*** IMPLEMENTATIONS ***/
115
116 static void
117 query_simple (GtkCssStyleProperty *property,
118               const GtkCssValue   *css_value,
119               GValue              *value)
120 {
121   _gtk_css_value_init_gvalue (css_value, value);
122 }
123
124 static GtkCssValue *
125 assign_simple (GtkCssStyleProperty *property,
126               const GValue        *value)
127 {
128   return _gtk_css_value_new_from_gvalue (value);
129 }
130
131 static void
132 query_length_as_int (GtkCssStyleProperty *property,
133                      const GtkCssValue   *css_value,
134                      GValue              *value)
135 {
136   g_value_init (value, G_TYPE_INT);
137   g_value_set_int (value, round (_gtk_css_number_value_get (css_value, 100)));
138 }
139
140 static GtkCssValue *
141 assign_length_from_int (GtkCssStyleProperty *property,
142                         const GValue        *value)
143 {
144   return _gtk_css_number_value_new (g_value_get_int (value), GTK_CSS_PX);
145 }
146
147 static void
148 query_length_as_double (GtkCssStyleProperty *property,
149                         const GtkCssValue   *css_value,
150                         GValue              *value)
151 {
152   g_value_init (value, G_TYPE_DOUBLE);
153   g_value_set_double (value, _gtk_css_number_value_get (css_value, 100));
154 }
155
156 static GtkCssValue *
157 assign_length_from_double (GtkCssStyleProperty *property,
158                            const GValue        *value)
159 {
160   return _gtk_css_number_value_new (g_value_get_double (value), GTK_CSS_PX);
161 }
162
163 static void
164 query_border (GtkCssStyleProperty *property,
165               const GtkCssValue   *css_value,
166               GValue              *value)
167 {
168   GtkBorder border;
169
170   g_value_init (value, GTK_TYPE_BORDER);
171   
172   border.top = round (_gtk_css_number_value_get (_gtk_css_border_value_get_top (css_value), 100));
173   border.right = round (_gtk_css_number_value_get (_gtk_css_border_value_get_right (css_value), 100));
174   border.bottom = round (_gtk_css_number_value_get (_gtk_css_border_value_get_bottom (css_value), 100));
175   border.left = round (_gtk_css_number_value_get (_gtk_css_border_value_get_left (css_value), 100));
176
177   g_value_set_boxed (value, &border);
178 }
179
180 static GtkCssValue *
181 assign_border (GtkCssStyleProperty *property,
182                const GValue        *value)
183 {
184   const GtkBorder *border = g_value_get_boxed (value);
185
186   if (border == NULL)
187     return _gtk_css_value_ref (_gtk_css_style_property_get_initial_value (property));
188   else
189     return _gtk_css_border_value_new (_gtk_css_number_value_new (border->top, GTK_CSS_PX),
190                                       _gtk_css_number_value_new (border->right, GTK_CSS_PX),
191                                       _gtk_css_number_value_new (border->bottom, GTK_CSS_PX),
192                                       _gtk_css_number_value_new (border->left, GTK_CSS_PX));
193 }
194
195 static GtkCssValue *
196 color_parse (GtkCssStyleProperty *property,
197              GtkCssParser        *parser,
198              GFile               *base)
199 {
200   GtkSymbolicColor *symbolic;
201
202   if (_gtk_css_parser_try (parser, "currentcolor", TRUE))
203     {
204       symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ());
205     }
206   else
207     {
208       symbolic = _gtk_css_parser_read_symbolic_color (parser);
209       if (symbolic == NULL)
210         return NULL;
211     }
212
213   return _gtk_css_value_new_take_symbolic_color (symbolic);
214 }
215
216 static GtkCssValue *
217 color_compute (GtkCssStyleProperty    *property,
218                GtkStyleContext        *context,
219                GtkCssValue            *specified)
220 {
221   return _gtk_css_rgba_value_compute_from_symbolic (specified,
222                                                     _gtk_css_style_property_get_initial_value (property),
223                                                     context,
224                                                     FALSE);
225 }
226
227 static GtkCssValue *
228 color_property_compute (GtkCssStyleProperty    *property,
229                         GtkStyleContext        *context,
230                         GtkCssValue            *specified)
231 {
232   GtkCssValue *value;
233
234   value = _gtk_css_rgba_value_compute_from_symbolic (specified,
235                                                     _gtk_css_style_property_get_initial_value (property),
236                                                     context,
237                                                     TRUE);
238   _gtk_css_rgba_value_get_rgba (value);
239   return value;
240 }
241
242 static void
243 color_query (GtkCssStyleProperty *property,
244              const GtkCssValue   *css_value,
245              GValue              *value)
246 {
247   g_value_init (value, GDK_TYPE_RGBA);
248   g_value_set_boxed (value, _gtk_css_rgba_value_get_rgba (css_value));
249 }
250
251 static GtkCssValue *
252 color_assign (GtkCssStyleProperty *property,
253               const GValue        *value)
254 {
255   return _gtk_css_rgba_value_new_from_rgba (g_value_get_boxed (value));
256 }
257
258 static GtkCssValue *
259 font_family_parse_one (GtkCssParser *parser)
260 {
261   char *name;
262
263   name = _gtk_css_parser_try_ident (parser, TRUE);
264   if (name)
265     {
266       GString *string = g_string_new (name);
267       g_free (name);
268       while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
269         {
270           g_string_append_c (string, ' ');
271           g_string_append (string, name);
272           g_free (name);
273         }
274       name = g_string_free (string, FALSE);
275     }
276   else 
277     {
278       name = _gtk_css_parser_read_string (parser);
279       if (name == NULL)
280         return NULL;
281     }
282
283   return _gtk_css_string_value_new_take (name);
284 }
285
286 static GtkCssValue *
287 font_family_parse (GtkCssStyleProperty *property,
288                    GtkCssParser        *parser,
289                    GFile               *base)
290 {
291   return _gtk_css_array_value_parse (parser, font_family_parse_one, FALSE);
292 }
293
294 static void
295 font_family_query (GtkCssStyleProperty *property,
296                    const GtkCssValue   *css_value,
297                    GValue              *value)
298 {
299   GPtrArray *array;
300   guint i;
301
302   array = g_ptr_array_new ();
303
304   for (i = 0; i < _gtk_css_array_value_get_n_values (css_value); i++)
305     {
306       g_ptr_array_add (array, g_strdup (_gtk_css_string_value_get (_gtk_css_array_value_get_nth (css_value, i))));
307     }
308
309   /* NULL-terminate */
310   g_ptr_array_add (array, NULL);
311
312   g_value_init (value, G_TYPE_STRV);
313   g_value_set_boxed (value, g_ptr_array_free (array, FALSE));
314 }
315
316 static GtkCssValue *
317 font_family_assign (GtkCssStyleProperty *property,
318                     const GValue        *value)
319 {
320   const char **names = g_value_get_boxed (value);
321   GtkCssValue *result;
322   GPtrArray *array;
323
324   array = g_ptr_array_new ();
325
326   for (names = g_value_get_boxed (value); *names; names++)
327     {
328       g_ptr_array_add (array, _gtk_css_string_value_new (*names));
329     }
330
331   result = _gtk_css_array_value_new_from_array ((GtkCssValue **) array->pdata, array->len);
332   g_ptr_array_free (array, TRUE);
333   return result;
334 }
335
336 static GtkCssValue *
337 parse_pango_style (GtkCssStyleProperty *property,
338                    GtkCssParser        *parser,
339                    GFile               *base)
340 {
341   GtkCssValue *value = _gtk_css_font_style_value_try_parse (parser);
342   
343   if (value == NULL)
344     _gtk_css_parser_error (parser, "unknown value for property");
345
346   return value;
347 }
348
349 static void
350 query_pango_style (GtkCssStyleProperty *property,
351                     const GtkCssValue   *css_value,
352                     GValue              *value)
353 {
354   g_value_init (value, PANGO_TYPE_STYLE);
355   g_value_set_enum (value, _gtk_css_font_style_value_get (css_value));
356 }
357
358 static GtkCssValue *
359 assign_pango_style (GtkCssStyleProperty *property,
360                     const GValue        *value)
361 {
362   return _gtk_css_font_style_value_new (g_value_get_enum (value));
363 }
364
365 static GtkCssValue *
366 parse_pango_weight (GtkCssStyleProperty *property,
367                     GtkCssParser        *parser,
368                     GFile               *base)
369 {
370   GtkCssValue *value = _gtk_css_font_weight_value_try_parse (parser);
371   
372   if (value == NULL)
373     _gtk_css_parser_error (parser, "unknown value for property");
374
375   return value;
376 }
377
378 static void
379 query_pango_weight (GtkCssStyleProperty *property,
380                     const GtkCssValue   *css_value,
381                     GValue              *value)
382 {
383   g_value_init (value, PANGO_TYPE_WEIGHT);
384   g_value_set_enum (value, _gtk_css_font_weight_value_get (css_value));
385 }
386
387 static GtkCssValue *
388 assign_pango_weight (GtkCssStyleProperty *property,
389                      const GValue        *value)
390 {
391   return _gtk_css_font_weight_value_new (g_value_get_enum (value));
392 }
393
394 static GtkCssValue *
395 parse_pango_variant (GtkCssStyleProperty *property,
396                      GtkCssParser        *parser,
397                      GFile               *base)
398 {
399   GtkCssValue *value = _gtk_css_font_variant_value_try_parse (parser);
400   
401   if (value == NULL)
402     _gtk_css_parser_error (parser, "unknown value for property");
403
404   return value;
405 }
406
407 static void
408 query_pango_variant (GtkCssStyleProperty *property,
409                      const GtkCssValue   *css_value,
410                      GValue              *value)
411 {
412   g_value_init (value, PANGO_TYPE_VARIANT);
413   g_value_set_enum (value, _gtk_css_font_variant_value_get (css_value));
414 }
415
416 static GtkCssValue *
417 assign_pango_variant (GtkCssStyleProperty *property,
418                       const GValue        *value)
419 {
420   return _gtk_css_font_variant_value_new (g_value_get_enum (value));
421 }
422
423 static GtkCssValue *
424 parse_border_style (GtkCssStyleProperty *property,
425                     GtkCssParser        *parser,
426                     GFile               *base)
427 {
428   GtkCssValue *value = _gtk_css_border_style_value_try_parse (parser);
429   
430   if (value == NULL)
431     _gtk_css_parser_error (parser, "unknown value for property");
432
433   return value;
434 }
435
436 static void
437 query_border_style (GtkCssStyleProperty *property,
438                     const GtkCssValue   *css_value,
439                     GValue              *value)
440 {
441   g_value_init (value, GTK_TYPE_BORDER_STYLE);
442   g_value_set_enum (value, _gtk_css_border_style_value_get (css_value));
443 }
444
445 static GtkCssValue *
446 assign_border_style (GtkCssStyleProperty *property,
447                      const GValue        *value)
448 {
449   return _gtk_css_border_style_value_new (g_value_get_enum (value));
450 }
451
452 static GtkCssValue *
453 parse_css_area (GtkCssStyleProperty *property,
454                 GtkCssParser        *parser,
455                 GFile               *base)
456 {
457   GtkCssValue *value = _gtk_css_area_value_try_parse (parser);
458   
459   if (value == NULL)
460     _gtk_css_parser_error (parser, "unknown value for property");
461
462   return value;
463 }
464
465 static GtkCssValue *
466 bindings_value_parse_one (GtkCssParser *parser)
467 {
468   char *name;
469
470   name = _gtk_css_parser_try_ident (parser, TRUE);
471   if (name == NULL)
472     {
473       _gtk_css_parser_error (parser, "Not a valid binding name");
474       return NULL;
475     }
476
477
478   if (!gtk_binding_set_find (name))
479     {
480       _gtk_css_parser_error (parser, "No binding set named '%s'", name);
481       g_free (name);
482       return NULL;
483     }
484
485   return _gtk_css_string_value_new_take (name);
486 }
487
488 static GtkCssValue *
489 bindings_value_parse (GtkCssStyleProperty *property,
490                       GtkCssParser        *parser,
491                       GFile               *base)
492 {
493   return _gtk_css_array_value_parse (parser, bindings_value_parse_one, TRUE);
494 }
495
496 static void
497 bindings_value_query (GtkCssStyleProperty *property,
498                       const GtkCssValue   *css_value,
499                       GValue              *value)
500 {
501   GPtrArray *array;
502   guint i;
503
504   g_value_init (value, G_TYPE_PTR_ARRAY);
505
506   if (_gtk_css_array_value_get_n_values (css_value) == 0)
507     return;
508
509   array = g_ptr_array_new ();
510
511   for (i = 0; i < _gtk_css_array_value_get_n_values (css_value); i++)
512     {
513       GtkBindingSet *binding_set = gtk_binding_set_find (_gtk_css_string_value_get (_gtk_css_array_value_get_nth (css_value, i)));
514
515       g_ptr_array_add (array, binding_set);
516     }
517
518   g_value_take_boxed (value, array);
519 }
520
521 static GtkCssValue *
522 bindings_value_assign (GtkCssStyleProperty *property,
523                        const GValue        *value)
524 {
525   GPtrArray *binding_sets = g_value_get_boxed (value);
526   GtkCssValue **values, *result;
527   guint i;
528
529   if (binding_sets == NULL || binding_sets->len == 0)
530     return _gtk_css_array_value_new (NULL);
531
532   values = g_new (GtkCssValue *, binding_sets->len);
533
534   for (i = 0; i < binding_sets->len; i++)
535     {
536       GtkBindingSet *binding_set = g_ptr_array_index (binding_sets, i);
537       values[i] = _gtk_css_string_value_new (binding_set->set_name);
538     }
539
540   result = _gtk_css_array_value_new_from_array (values, binding_sets->len);
541   g_free (values);
542   return result;
543 }
544
545 static GtkCssValue *
546 shadow_value_parse (GtkCssStyleProperty *property,
547                     GtkCssParser        *parser,
548                     GFile               *base)
549 {
550   return _gtk_css_shadows_value_parse (parser);
551 }
552
553 static GtkCssValue *
554 shadow_value_compute (GtkCssStyleProperty *property,
555                       GtkStyleContext     *context,
556                       GtkCssValue         *specified)
557 {
558   return _gtk_css_shadows_value_compute (specified, context);
559 }
560
561 static GtkCssValue *
562 border_corner_radius_value_parse (GtkCssStyleProperty *property,
563                                   GtkCssParser        *parser,
564                                   GFile               *base)
565 {
566   return _gtk_css_corner_value_parse (parser);
567 }
568
569 static GtkCssValue *
570 border_corner_radius_value_compute (GtkCssStyleProperty *property,
571                                     GtkStyleContext     *context,
572                                     GtkCssValue         *specified)
573 {
574   return _gtk_css_corner_value_compute (specified, context);
575 }
576
577 static GtkCssValue *
578 css_image_value_parse (GtkCssStyleProperty *property,
579                        GtkCssParser        *parser,
580                        GFile               *base)
581 {
582   GtkCssImage *image;
583
584   if (_gtk_css_parser_try (parser, "none", TRUE))
585     image = NULL;
586   else
587     {
588       image = _gtk_css_image_new_parse (parser, base);
589       if (image == NULL)
590         return FALSE;
591     }
592
593   return _gtk_css_image_value_new (image);
594 }
595
596 static GtkCssValue *
597 css_image_value_compute (GtkCssStyleProperty    *property,
598                          GtkStyleContext        *context,
599                          GtkCssValue            *specified)
600 {
601   GtkCssImage *image, *computed;
602   
603   image = _gtk_css_image_value_get_image (specified);
604
605   if (image == NULL)
606     return _gtk_css_value_ref (specified);
607
608   computed = _gtk_css_image_compute (image, context);
609
610   if (computed == image)
611     {
612       g_object_unref (computed);
613       return _gtk_css_value_ref (specified);
614     }
615
616   return _gtk_css_image_value_new (computed);
617 }
618
619 static void
620 css_image_value_query (GtkCssStyleProperty *property,
621                        const GtkCssValue   *css_value,
622                        GValue              *value)
623 {
624   GtkCssImage *image = _gtk_css_image_value_get_image (css_value);
625   cairo_pattern_t *pattern;
626   cairo_surface_t *surface;
627   cairo_matrix_t matrix;
628   
629   g_value_init (value, CAIRO_GOBJECT_TYPE_PATTERN);
630
631   if (GTK_IS_CSS_IMAGE_GRADIENT (image))
632     g_value_set_boxed (value, GTK_CSS_IMAGE_GRADIENT (image)->pattern);
633   else if (image != NULL)
634     {
635       double width, height;
636
637       /* the 100, 100 is rather random */
638       _gtk_css_image_get_concrete_size (image, 0, 0, 100, 100, &width, &height);
639       surface = _gtk_css_image_get_surface (image, NULL, width, height);
640       pattern = cairo_pattern_create_for_surface (surface);
641       cairo_matrix_init_scale (&matrix, width, height);
642       cairo_pattern_set_matrix (pattern, &matrix);
643       cairo_surface_destroy (surface);
644       g_value_take_boxed (value, pattern);
645     }
646 }
647
648 static GtkCssValue *
649 css_image_value_assign (GtkCssStyleProperty *property,
650                         const GValue        *value)
651 {
652   g_warning ("FIXME: assigning images is not implemented");
653   return _gtk_css_image_value_new (NULL);
654 }
655
656 static GtkCssValue *
657 font_size_parse (GtkCssStyleProperty *property,
658                  GtkCssParser        *parser,
659                  GFile               *base)
660 {
661   gdouble d;
662
663   if (!_gtk_css_parser_try_double (parser, &d))
664     {
665       _gtk_css_parser_error (parser, "Expected a number");
666       return NULL;
667     }
668
669   return _gtk_css_number_value_new (d, GTK_CSS_PX);
670 }
671
672 static GtkCssValue *
673 font_size_compute (GtkCssStyleProperty *property,
674                    GtkStyleContext     *context,
675                    GtkCssValue         *specified)
676 {
677   return _gtk_css_number_value_compute (specified, context);
678 }
679
680 static GtkCssValue *
681 outline_parse (GtkCssStyleProperty *property,
682                GtkCssParser        *parser,
683                GFile               *base)
684 {
685   return _gtk_css_number_value_parse (parser,
686                                       GTK_CSS_NUMBER_AS_PIXELS
687                                       | GTK_CSS_PARSE_LENGTH);
688 }
689
690 static GtkCssValue *
691 outline_compute (GtkCssStyleProperty *property,
692                  GtkStyleContext     *context,
693                  GtkCssValue         *specified)
694 {
695   return _gtk_css_number_value_compute (specified, context);
696 }
697
698 static GtkCssValue *
699 border_image_repeat_parse (GtkCssStyleProperty *property,
700                            GtkCssParser        *parser,
701                            GFile               *base)
702 {
703   GtkCssValue *value = _gtk_css_border_repeat_value_try_parse (parser);
704
705   if (value == NULL)
706     {
707       _gtk_css_parser_error (parser, "Not a valid value");
708       return NULL;
709     }
710
711   return value;
712 }
713
714 static GtkCssValue *
715 border_image_slice_parse (GtkCssStyleProperty *property,
716                           GtkCssParser        *parser,
717                           GFile               *base)
718 {
719   return _gtk_css_border_value_parse (parser,
720                                       GTK_CSS_PARSE_PERCENT
721                                       | GTK_CSS_PARSE_NUMBER
722                                       | GTK_CSS_POSITIVE_ONLY,
723                                       FALSE,
724                                       TRUE);
725 }
726
727 static GtkCssValue *
728 border_image_width_parse (GtkCssStyleProperty *property,
729                           GtkCssParser        *parser,
730                           GFile               *base)
731 {
732   GValue value = G_VALUE_INIT;
733   GtkCssValue *result;
734
735   g_value_init (&value, GTK_TYPE_BORDER);
736   if (!_gtk_css_style_parse_value (&value, parser, base))
737     {
738       g_value_unset (&value);
739       return NULL;
740     }
741
742   result = _gtk_css_value_new_from_gvalue (&value);
743   g_value_unset (&value);
744
745   return result;
746 }
747
748 static GtkCssValue *
749 compute_border (GtkCssStyleProperty *property,
750                 GtkStyleContext     *context,
751                 GtkCssValue         *specified)
752 {
753   return _gtk_css_border_value_compute (specified, context);
754 }
755
756 static GtkCssValue *
757 transition_property_parse_one (GtkCssParser *parser)
758 {
759   GtkCssValue *value;
760
761   value = _gtk_css_ident_value_try_parse (parser);
762
763   if (value == NULL)
764     {
765       _gtk_css_parser_error (parser, "Expected an identifier");
766       return NULL;
767     }
768
769   return value;
770 }
771
772 static GtkCssValue *
773 transition_property_parse (GtkCssStyleProperty *property,
774                            GtkCssParser        *parser,
775                            GFile               *base)
776 {
777   return _gtk_css_array_value_parse (parser, transition_property_parse_one, FALSE);
778 }
779
780 static GtkCssValue *
781 transition_time_parse_one (GtkCssParser *parser)
782 {
783   return _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_TIME);
784 }
785
786 static GtkCssValue *
787 transition_time_parse (GtkCssStyleProperty *property,
788                        GtkCssParser        *parser,
789                        GFile               *base)
790 {
791   return _gtk_css_array_value_parse (parser, transition_time_parse_one, FALSE);
792 }
793
794 static GtkCssValue *
795 transition_timing_function_parse (GtkCssStyleProperty *property,
796                                   GtkCssParser        *parser,
797                                   GFile               *base)
798 {
799   return _gtk_css_array_value_parse (parser, _gtk_css_ease_value_parse, FALSE);
800 }
801
802 static GtkCssValue *
803 engine_parse (GtkCssStyleProperty *property,
804               GtkCssParser        *parser,
805               GFile               *base)
806 {
807   return _gtk_css_engine_value_parse (parser);
808 }
809
810 static void
811 engine_query (GtkCssStyleProperty *property,
812               const GtkCssValue   *css_value,
813               GValue              *value)
814 {
815   g_value_init (value, GTK_TYPE_THEMING_ENGINE);
816   g_value_set_object (value, _gtk_css_engine_value_get_engine (css_value));
817 }
818
819 static GtkCssValue *
820 engine_assign (GtkCssStyleProperty *property,
821                const GValue        *value)
822 {
823   return _gtk_css_engine_value_new (g_value_get_object (value));
824 }
825
826 static GtkCssValue *
827 transition_parse (GtkCssStyleProperty *property,
828                   GtkCssParser        *parser,
829                   GFile               *base)
830 {
831   GValue value = G_VALUE_INIT;
832   GtkCssValue *result;
833
834   g_value_init (&value, GTK_TYPE_ANIMATION_DESCRIPTION);
835   if (!_gtk_css_style_parse_value (&value, parser, base))
836     {
837       g_value_unset (&value);
838       return NULL;
839     }
840
841   result = _gtk_css_value_new_from_gvalue (&value);
842   g_value_unset (&value);
843
844   return result;
845 }
846
847 static GtkCssValue *
848 parse_margin (GtkCssStyleProperty *property,
849               GtkCssParser        *parser,
850               GFile               *base)
851 {
852   return _gtk_css_number_value_parse (parser,
853                                       GTK_CSS_NUMBER_AS_PIXELS
854                                       | GTK_CSS_PARSE_LENGTH);
855 }
856
857 static GtkCssValue *
858 compute_margin (GtkCssStyleProperty *property,
859                 GtkStyleContext     *context,
860                 GtkCssValue         *specified)
861 {
862   return _gtk_css_number_value_compute (specified, context);
863 }
864
865 static GtkCssValue *
866 parse_padding (GtkCssStyleProperty *property,
867                GtkCssParser        *parser,
868                GFile               *base)
869 {
870   return _gtk_css_number_value_parse (parser,
871                                       GTK_CSS_POSITIVE_ONLY
872                                       | GTK_CSS_NUMBER_AS_PIXELS
873                                       | GTK_CSS_PARSE_LENGTH);
874 }
875
876 static GtkCssValue *
877 compute_padding (GtkCssStyleProperty *property,
878                  GtkStyleContext     *context,
879                  GtkCssValue         *specified)
880 {
881   return _gtk_css_number_value_compute (specified, context);
882 }
883
884 static GtkCssValue *
885 parse_border_width (GtkCssStyleProperty *property,
886                     GtkCssParser        *parser,
887                     GFile               *base)
888 {
889   return _gtk_css_number_value_parse (parser,
890                                       GTK_CSS_POSITIVE_ONLY
891                                       | GTK_CSS_NUMBER_AS_PIXELS
892                                       | GTK_CSS_PARSE_LENGTH);
893 }
894
895 static GtkCssValue *
896 compute_border_width (GtkCssStyleProperty    *property,
897                       GtkStyleContext        *context,
898                       GtkCssValue            *specified)
899 {
900   GtkBorderStyle border_style;
901   
902   /* The -1 is magic that is only true because we register the style
903    * properties directly after the width properties.
904    */
905   border_style = _gtk_css_border_style_value_get (_gtk_style_context_peek_property (context, _gtk_css_style_property_get_id (property) - 1));
906
907   if (border_style == GTK_BORDER_STYLE_NONE ||
908       border_style == GTK_BORDER_STYLE_HIDDEN)
909     return _gtk_css_number_value_new (0, GTK_CSS_PX);
910   else
911     return _gtk_css_number_value_compute (specified, context);
912 }
913
914 static GtkCssValue *
915 background_repeat_value_parse (GtkCssStyleProperty *property,
916                                GtkCssParser        *parser,
917                                GFile               *base)
918 {
919   GtkCssValue *value = _gtk_css_background_repeat_value_try_parse (parser);
920
921   if (value == NULL)
922     {
923       _gtk_css_parser_error (parser, "Not a valid value");
924       return NULL;
925     }
926
927   return value;
928 }
929
930 static GtkCssValue *
931 background_size_parse (GtkCssStyleProperty *property,
932                        GtkCssParser        *parser,
933                        GFile               *base)
934 {
935   return _gtk_css_bg_size_value_parse (parser);
936 }
937
938 static GtkCssValue *
939 background_size_compute (GtkCssStyleProperty    *property,
940                          GtkStyleContext        *context,
941                          GtkCssValue            *specified)
942 {
943   return _gtk_css_bg_size_value_compute (specified, context);
944 }
945
946 static GtkCssValue *
947 background_position_parse (GtkCssStyleProperty *property,
948                            GtkCssParser        *parser,
949                            GFile               *base)
950 {
951   return _gtk_css_position_value_parse (parser);
952 }
953
954 static GtkCssValue *
955 background_position_compute (GtkCssStyleProperty    *property,
956                              GtkStyleContext        *context,
957                              GtkCssValue            *specified)
958 {
959   return _gtk_css_position_value_compute (specified, context);
960 }
961
962 /*** REGISTRATION ***/
963
964 static GtkSymbolicColor *
965 gtk_symbolic_color_new_rgba (double red,
966                              double green,
967                              double blue,
968                              double alpha)
969 {
970   GdkRGBA rgba = { red, green, blue, alpha };
971
972   return gtk_symbolic_color_new_literal (&rgba);
973 }
974
975 void
976 _gtk_css_style_property_init_properties (void)
977 {
978   /* Initialize "color" and "font-size" first,
979    * so that when computing values later they are
980    * done first. That way, 'currentColor' and font
981    * sizes in em can be looked up properly */
982   gtk_css_style_property_register        ("color",
983                                           GTK_CSS_PROPERTY_COLOR,
984                                           GDK_TYPE_RGBA,
985                                           GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
986                                           color_parse,
987                                           NULL,
988                                           color_property_compute,
989                                           color_query,
990                                           color_assign,
991                                           NULL,
992                                           _gtk_css_value_new_take_symbolic_color (
993                                             gtk_symbolic_color_new_rgba (1, 1, 1, 1)));
994   gtk_css_style_property_register        ("font-size",
995                                           GTK_CSS_PROPERTY_FONT_SIZE,
996                                           G_TYPE_DOUBLE,
997                                           GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
998                                           font_size_parse,
999                                           NULL,
1000                                           font_size_compute,
1001                                           query_length_as_double,
1002                                           assign_length_from_double,
1003                                           NULL,
1004                                           /* XXX: This should be 'normal' */
1005                                           _gtk_css_number_value_new (10.0, GTK_CSS_PX));
1006
1007   /* properties that aren't referenced when computing values
1008    * start here */
1009   gtk_css_style_property_register        ("background-color",
1010                                           GTK_CSS_PROPERTY_BACKGROUND_COLOR,
1011                                           GDK_TYPE_RGBA,
1012                                           GTK_STYLE_PROPERTY_ANIMATED,
1013                                           color_parse,
1014                                           NULL,
1015                                           color_compute,
1016                                           color_query,
1017                                           color_assign,
1018                                           NULL,
1019                                           _gtk_css_value_new_take_symbolic_color (
1020                                             gtk_symbolic_color_new_rgba (0, 0, 0, 0)));
1021
1022   gtk_css_style_property_register        ("font-family",
1023                                           GTK_CSS_PROPERTY_FONT_FAMILY,
1024                                           G_TYPE_STRV,
1025                                           GTK_STYLE_PROPERTY_INHERIT,
1026                                           font_family_parse,
1027                                           NULL,
1028                                           NULL,
1029                                           font_family_query,
1030                                           font_family_assign,
1031                                           NULL,
1032                                           _gtk_css_array_value_new (_gtk_css_string_value_new ("Sans")));
1033   gtk_css_style_property_register        ("font-style",
1034                                           GTK_CSS_PROPERTY_FONT_STYLE,
1035                                           PANGO_TYPE_STYLE,
1036                                           GTK_STYLE_PROPERTY_INHERIT,
1037                                           parse_pango_style,
1038                                           NULL,
1039                                           NULL,
1040                                           query_pango_style,
1041                                           assign_pango_style,
1042                                           NULL,
1043                                           _gtk_css_font_style_value_new (PANGO_STYLE_NORMAL));
1044   gtk_css_style_property_register        ("font-variant",
1045                                           GTK_CSS_PROPERTY_FONT_VARIANT,
1046                                           PANGO_TYPE_VARIANT,
1047                                           GTK_STYLE_PROPERTY_INHERIT,
1048                                           parse_pango_variant,
1049                                           NULL,
1050                                           NULL,
1051                                           query_pango_variant,
1052                                           assign_pango_variant,
1053                                           NULL,
1054                                           _gtk_css_font_variant_value_new (PANGO_VARIANT_NORMAL));
1055   gtk_css_style_property_register        ("font-weight",
1056                                           GTK_CSS_PROPERTY_FONT_WEIGHT,
1057                                           PANGO_TYPE_WEIGHT,
1058                                           GTK_STYLE_PROPERTY_INHERIT,
1059                                           parse_pango_weight,
1060                                           NULL,
1061                                           NULL,
1062                                           query_pango_weight,
1063                                           assign_pango_weight,
1064                                           NULL,
1065                                           _gtk_css_font_weight_value_new (PANGO_WEIGHT_NORMAL));
1066
1067   gtk_css_style_property_register        ("text-shadow",
1068                                           GTK_CSS_PROPERTY_TEXT_SHADOW,
1069                                           G_TYPE_NONE,
1070                                           GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1071                                           shadow_value_parse,
1072                                           NULL,
1073                                           shadow_value_compute,
1074                                           NULL,
1075                                           NULL,
1076                                           NULL,
1077                                           _gtk_css_shadows_value_new_none ());
1078
1079   gtk_css_style_property_register        ("icon-shadow",
1080                                           GTK_CSS_PROPERTY_ICON_SHADOW,
1081                                           G_TYPE_NONE,
1082                                           GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
1083                                           shadow_value_parse,
1084                                           NULL,
1085                                           shadow_value_compute,
1086                                           NULL,
1087                                           NULL,
1088                                           NULL,
1089                                           _gtk_css_shadows_value_new_none ());
1090
1091   gtk_css_style_property_register        ("box-shadow",
1092                                           GTK_CSS_PROPERTY_BOX_SHADOW,
1093                                           G_TYPE_NONE,
1094                                           GTK_STYLE_PROPERTY_ANIMATED,
1095                                           shadow_value_parse,
1096                                           NULL,
1097                                           shadow_value_compute,
1098                                           NULL,
1099                                           NULL,
1100                                           NULL,
1101                                           _gtk_css_shadows_value_new_none ());
1102
1103   gtk_css_style_property_register        ("margin-top",
1104                                           GTK_CSS_PROPERTY_MARGIN_TOP,
1105                                           G_TYPE_INT,
1106                                           GTK_STYLE_PROPERTY_ANIMATED,
1107                                           parse_margin,
1108                                           NULL,
1109                                           compute_margin,
1110                                           query_length_as_int,
1111                                           assign_length_from_int,
1112                                           NULL,
1113                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1114   gtk_css_style_property_register        ("margin-left",
1115                                           GTK_CSS_PROPERTY_MARGIN_LEFT,
1116                                           G_TYPE_INT,
1117                                           GTK_STYLE_PROPERTY_ANIMATED,
1118                                           parse_margin,
1119                                           NULL,
1120                                           compute_margin,
1121                                           query_length_as_int,
1122                                           assign_length_from_int,
1123                                           NULL,
1124                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1125   gtk_css_style_property_register        ("margin-bottom",
1126                                           GTK_CSS_PROPERTY_MARGIN_BOTTOM,
1127                                           G_TYPE_INT,
1128                                           GTK_STYLE_PROPERTY_ANIMATED,
1129                                           parse_margin,
1130                                           NULL,
1131                                           compute_margin,
1132                                           query_length_as_int,
1133                                           assign_length_from_int,
1134                                           NULL,
1135                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1136   gtk_css_style_property_register        ("margin-right",
1137                                           GTK_CSS_PROPERTY_MARGIN_RIGHT,
1138                                           G_TYPE_INT,
1139                                           GTK_STYLE_PROPERTY_ANIMATED,
1140                                           parse_margin,
1141                                           NULL,
1142                                           compute_margin,
1143                                           query_length_as_int,
1144                                           assign_length_from_int,
1145                                           NULL,
1146                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1147   gtk_css_style_property_register        ("padding-top",
1148                                           GTK_CSS_PROPERTY_PADDING_TOP,
1149                                           G_TYPE_INT,
1150                                           GTK_STYLE_PROPERTY_ANIMATED,
1151                                           parse_padding,
1152                                           NULL,
1153                                           compute_padding,
1154                                           query_length_as_int,
1155                                           assign_length_from_int,
1156                                           NULL,
1157                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1158   gtk_css_style_property_register        ("padding-left",
1159                                           GTK_CSS_PROPERTY_PADDING_LEFT,
1160                                           G_TYPE_INT,
1161                                           GTK_STYLE_PROPERTY_ANIMATED,
1162                                           parse_padding,
1163                                           NULL,
1164                                           compute_padding,
1165                                           query_length_as_int,
1166                                           assign_length_from_int,
1167                                           NULL,
1168                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1169   gtk_css_style_property_register        ("padding-bottom",
1170                                           GTK_CSS_PROPERTY_PADDING_BOTTOM,
1171                                           G_TYPE_INT,
1172                                           GTK_STYLE_PROPERTY_ANIMATED,
1173                                           parse_padding,
1174                                           NULL,
1175                                           compute_padding,
1176                                           query_length_as_int,
1177                                           assign_length_from_int,
1178                                           NULL,
1179                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1180   gtk_css_style_property_register        ("padding-right",
1181                                           GTK_CSS_PROPERTY_PADDING_RIGHT,
1182                                           G_TYPE_INT,
1183                                           GTK_STYLE_PROPERTY_ANIMATED,
1184                                           parse_padding,
1185                                           NULL,
1186                                           compute_padding,
1187                                           query_length_as_int,
1188                                           assign_length_from_int,
1189                                           NULL,
1190                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1191   /* IMPORTANT: compute_border_width() requires that the border-width
1192    * properties be immeditaly followed by the border-style properties
1193    */
1194   gtk_css_style_property_register        ("border-top-style",
1195                                           GTK_CSS_PROPERTY_BORDER_TOP_STYLE,
1196                                           GTK_TYPE_BORDER_STYLE,
1197                                           0,
1198                                           parse_border_style,
1199                                           NULL,
1200                                           NULL,
1201                                           query_border_style,
1202                                           assign_border_style,
1203                                           NULL,
1204                                           _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1205   gtk_css_style_property_register        ("border-top-width",
1206                                           GTK_CSS_PROPERTY_BORDER_TOP_WIDTH,
1207                                           G_TYPE_INT,
1208                                           GTK_STYLE_PROPERTY_ANIMATED,
1209                                           parse_border_width,
1210                                           NULL,
1211                                           compute_border_width,
1212                                           query_length_as_int,
1213                                           assign_length_from_int,
1214                                           NULL,
1215                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1216   gtk_css_style_property_register        ("border-left-style",
1217                                           GTK_CSS_PROPERTY_BORDER_LEFT_STYLE,
1218                                           GTK_TYPE_BORDER_STYLE,
1219                                           0,
1220                                           parse_border_style,
1221                                           NULL,
1222                                           NULL,
1223                                           query_border_style,
1224                                           assign_border_style,
1225                                           NULL,
1226                                           _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1227   gtk_css_style_property_register        ("border-left-width",
1228                                           GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH,
1229                                           G_TYPE_INT,
1230                                           GTK_STYLE_PROPERTY_ANIMATED,
1231                                           parse_border_width,
1232                                           NULL,
1233                                           compute_border_width,
1234                                           query_length_as_int,
1235                                           assign_length_from_int,
1236                                           NULL,
1237                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1238   gtk_css_style_property_register        ("border-bottom-style",
1239                                           GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE,
1240                                           GTK_TYPE_BORDER_STYLE,
1241                                           0,
1242                                           parse_border_style,
1243                                           NULL,
1244                                           NULL,
1245                                           query_border_style,
1246                                           assign_border_style,
1247                                           NULL,
1248                                           _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1249   gtk_css_style_property_register        ("border-bottom-width",
1250                                           GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
1251                                           G_TYPE_INT,
1252                                           GTK_STYLE_PROPERTY_ANIMATED,
1253                                           parse_border_width,
1254                                           NULL,
1255                                           compute_border_width,
1256                                           query_length_as_int,
1257                                           assign_length_from_int,
1258                                           NULL,
1259                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1260   gtk_css_style_property_register        ("border-right-style",
1261                                           GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE,
1262                                           GTK_TYPE_BORDER_STYLE,
1263                                           0,
1264                                           parse_border_style,
1265                                           NULL,
1266                                           NULL,
1267                                           query_border_style,
1268                                           assign_border_style,
1269                                           NULL,
1270                                           _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1271   gtk_css_style_property_register        ("border-right-width",
1272                                           GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH,
1273                                           G_TYPE_INT,
1274                                           GTK_STYLE_PROPERTY_ANIMATED,
1275                                           parse_border_width,
1276                                           NULL,
1277                                           compute_border_width,
1278                                           query_length_as_int,
1279                                           assign_length_from_int,
1280                                           NULL,
1281                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1282
1283   gtk_css_style_property_register        ("border-top-left-radius",
1284                                           GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS,
1285                                           G_TYPE_NONE,
1286                                           GTK_STYLE_PROPERTY_ANIMATED,
1287                                           border_corner_radius_value_parse,
1288                                           NULL,
1289                                           border_corner_radius_value_compute,
1290                                           NULL,
1291                                           NULL,
1292                                           NULL,
1293                                           _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1294                                                                      _gtk_css_number_value_new (0, GTK_CSS_PX)));
1295   gtk_css_style_property_register        ("border-top-right-radius",
1296                                           GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS,
1297                                           G_TYPE_NONE,
1298                                           GTK_STYLE_PROPERTY_ANIMATED,
1299                                           border_corner_radius_value_parse,
1300                                           NULL,
1301                                           border_corner_radius_value_compute,
1302                                           NULL,
1303                                           NULL,
1304                                           NULL,
1305                                           _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1306                                                                      _gtk_css_number_value_new (0, GTK_CSS_PX)));
1307   gtk_css_style_property_register        ("border-bottom-right-radius",
1308                                           GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS,
1309                                           G_TYPE_NONE,
1310                                           GTK_STYLE_PROPERTY_ANIMATED,
1311                                           border_corner_radius_value_parse,
1312                                           NULL,
1313                                           border_corner_radius_value_compute,
1314                                           NULL,
1315                                           NULL,
1316                                           NULL,
1317                                           _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1318                                                                      _gtk_css_number_value_new (0, GTK_CSS_PX)));
1319   gtk_css_style_property_register        ("border-bottom-left-radius",
1320                                           GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS,
1321                                           G_TYPE_NONE,
1322                                           GTK_STYLE_PROPERTY_ANIMATED,
1323                                           border_corner_radius_value_parse,
1324                                           NULL,
1325                                           border_corner_radius_value_compute,
1326                                           NULL,
1327                                           NULL,
1328                                           NULL,
1329                                           _gtk_css_corner_value_new (_gtk_css_number_value_new (0, GTK_CSS_PX),
1330                                                                      _gtk_css_number_value_new (0, GTK_CSS_PX)));
1331
1332   gtk_css_style_property_register        ("outline-style",
1333                                           GTK_CSS_PROPERTY_OUTLINE_STYLE,
1334                                           GTK_TYPE_BORDER_STYLE,
1335                                           0,
1336                                           parse_border_style,
1337                                           NULL,
1338                                           NULL,
1339                                           query_border_style,
1340                                           assign_border_style,
1341                                           NULL,
1342                                           _gtk_css_border_style_value_new (GTK_BORDER_STYLE_NONE));
1343   gtk_css_style_property_register        ("outline-width",
1344                                           GTK_CSS_PROPERTY_OUTLINE_WIDTH,
1345                                           G_TYPE_INT,
1346                                           GTK_STYLE_PROPERTY_ANIMATED,
1347                                           parse_border_width,
1348                                           NULL,
1349                                           compute_border_width,
1350                                           query_length_as_int,
1351                                           assign_length_from_int,
1352                                           NULL,
1353                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1354   gtk_css_style_property_register        ("outline-offset",
1355                                           GTK_CSS_PROPERTY_OUTLINE_OFFSET,
1356                                           G_TYPE_INT,
1357                                           0,
1358                                           outline_parse,
1359                                           NULL,
1360                                           outline_compute,
1361                                           query_length_as_int,
1362                                           assign_length_from_int,
1363                                           NULL,
1364                                           _gtk_css_number_value_new (0.0, GTK_CSS_PX));
1365
1366   gtk_css_style_property_register        ("background-clip",
1367                                           GTK_CSS_PROPERTY_BACKGROUND_CLIP,
1368                                           G_TYPE_NONE,
1369                                           0,
1370                                           parse_css_area,
1371                                           NULL,
1372                                           NULL,
1373                                           NULL,
1374                                           NULL,
1375                                           NULL,
1376                                           _gtk_css_area_value_new (GTK_CSS_AREA_BORDER_BOX));
1377   gtk_css_style_property_register        ("background-origin",
1378                                           GTK_CSS_PROPERTY_BACKGROUND_ORIGIN,
1379                                           G_TYPE_NONE,
1380                                           0,
1381                                           parse_css_area,
1382                                           NULL,
1383                                           NULL,
1384                                           NULL,
1385                                           NULL,
1386                                           NULL,
1387                                           _gtk_css_area_value_new (GTK_CSS_AREA_PADDING_BOX));
1388   gtk_css_style_property_register        ("background-size",
1389                                           GTK_CSS_PROPERTY_BACKGROUND_SIZE,
1390                                           G_TYPE_NONE,
1391                                           0,
1392                                           background_size_parse,
1393                                           NULL,
1394                                           background_size_compute,
1395                                           NULL,
1396                                           NULL,
1397                                           NULL,
1398                                           _gtk_css_bg_size_value_new (NULL, NULL));
1399   gtk_css_style_property_register        ("background-position",
1400                                           GTK_CSS_PROPERTY_BACKGROUND_POSITION,
1401                                           G_TYPE_NONE,
1402                                           GTK_STYLE_PROPERTY_ANIMATED,
1403                                           background_position_parse,
1404                                           NULL,
1405                                           background_position_compute,
1406                                           NULL,
1407                                           NULL,
1408                                           NULL,
1409                                           _gtk_css_position_value_new (_gtk_css_number_value_new (0, GTK_CSS_PERCENT),
1410                                                                        _gtk_css_number_value_new (0, GTK_CSS_PERCENT)));
1411
1412   gtk_css_style_property_register        ("border-top-color",
1413                                           GTK_CSS_PROPERTY_BORDER_TOP_COLOR,
1414                                           GDK_TYPE_RGBA,
1415                                           GTK_STYLE_PROPERTY_ANIMATED,
1416                                           color_parse,
1417                                           NULL,
1418                                           color_compute,
1419                                           color_query,
1420                                           color_assign,
1421                                           NULL,
1422                                           _gtk_css_value_new_take_symbolic_color (
1423                                             gtk_symbolic_color_ref (
1424                                               _gtk_symbolic_color_get_current_color ())));
1425   gtk_css_style_property_register        ("border-right-color",
1426                                           GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR,
1427                                           GDK_TYPE_RGBA,
1428                                           GTK_STYLE_PROPERTY_ANIMATED,
1429                                           color_parse,
1430                                           NULL,
1431                                           color_compute,
1432                                           color_query,
1433                                           color_assign,
1434                                           NULL,
1435                                           _gtk_css_value_new_take_symbolic_color (
1436                                             gtk_symbolic_color_ref (
1437                                               _gtk_symbolic_color_get_current_color ())));
1438   gtk_css_style_property_register        ("border-bottom-color",
1439                                           GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR,
1440                                           GDK_TYPE_RGBA,
1441                                           GTK_STYLE_PROPERTY_ANIMATED,
1442                                           color_parse,
1443                                           NULL,
1444                                           color_compute,
1445                                           color_query,
1446                                           color_assign,
1447                                           NULL,
1448                                           _gtk_css_value_new_take_symbolic_color (
1449                                             gtk_symbolic_color_ref (
1450                                               _gtk_symbolic_color_get_current_color ())));
1451   gtk_css_style_property_register        ("border-left-color",
1452                                           GTK_CSS_PROPERTY_BORDER_LEFT_COLOR,
1453                                           GDK_TYPE_RGBA,
1454                                           GTK_STYLE_PROPERTY_ANIMATED,
1455                                           color_parse,
1456                                           NULL,
1457                                           color_compute,
1458                                           color_query,
1459                                           color_assign,
1460                                           NULL,
1461                                           _gtk_css_value_new_take_symbolic_color (
1462                                             gtk_symbolic_color_ref (
1463                                               _gtk_symbolic_color_get_current_color ())));
1464   gtk_css_style_property_register        ("outline-color",
1465                                           GTK_CSS_PROPERTY_OUTLINE_COLOR,
1466                                           GDK_TYPE_RGBA,
1467                                           GTK_STYLE_PROPERTY_ANIMATED,
1468                                           color_parse,
1469                                           NULL,
1470                                           color_compute,
1471                                           color_query,
1472                                           color_assign,
1473                                           NULL,
1474                                           _gtk_css_value_new_take_symbolic_color (
1475                                             gtk_symbolic_color_ref (
1476                                               _gtk_symbolic_color_get_current_color ())));
1477
1478   gtk_css_style_property_register        ("background-repeat",
1479                                           GTK_CSS_PROPERTY_BACKGROUND_REPEAT,
1480                                           G_TYPE_NONE,
1481                                           0,
1482                                           background_repeat_value_parse,
1483                                           NULL,
1484                                           NULL,
1485                                           NULL,
1486                                           NULL,
1487                                           NULL,
1488                                           _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT,
1489                                                                                 GTK_CSS_REPEAT_STYLE_REPEAT));
1490   gtk_css_style_property_register        ("background-image",
1491                                           GTK_CSS_PROPERTY_BACKGROUND_IMAGE,
1492                                           CAIRO_GOBJECT_TYPE_PATTERN,
1493                                           GTK_STYLE_PROPERTY_ANIMATED,
1494                                           css_image_value_parse,
1495                                           NULL,
1496                                           css_image_value_compute,
1497                                           css_image_value_query,
1498                                           css_image_value_assign,
1499                                           NULL,
1500                                           _gtk_css_image_value_new (NULL));
1501
1502   gtk_css_style_property_register        ("border-image-source",
1503                                           GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE,
1504                                           CAIRO_GOBJECT_TYPE_PATTERN,
1505                                           GTK_STYLE_PROPERTY_ANIMATED,
1506                                           css_image_value_parse,
1507                                           NULL,
1508                                           css_image_value_compute,
1509                                           css_image_value_query,
1510                                           css_image_value_assign,
1511                                           NULL,
1512                                           _gtk_css_image_value_new (NULL));
1513   gtk_css_style_property_register        ("border-image-repeat",
1514                                           GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT,
1515                                           G_TYPE_NONE,
1516                                           0,
1517                                           border_image_repeat_parse,
1518                                           NULL,
1519                                           NULL,
1520                                           NULL,
1521                                           NULL,
1522                                           NULL,
1523                                           _gtk_css_border_repeat_value_new (GTK_CSS_REPEAT_STYLE_STRETCH,
1524                                                                             GTK_CSS_REPEAT_STYLE_STRETCH));
1525
1526   gtk_css_style_property_register        ("border-image-slice",
1527                                           GTK_CSS_PROPERTY_BORDER_IMAGE_SLICE,
1528                                           GTK_TYPE_BORDER,
1529                                           0,
1530                                           border_image_slice_parse,
1531                                           NULL,
1532                                           compute_border,
1533                                           query_border,
1534                                           assign_border,
1535                                           NULL,
1536                                           _gtk_css_border_value_new (_gtk_css_number_value_new (100, GTK_CSS_PERCENT),
1537                                                                      _gtk_css_number_value_new (100, GTK_CSS_PERCENT),
1538                                                                      _gtk_css_number_value_new (100, GTK_CSS_PERCENT),
1539                                                                      _gtk_css_number_value_new (100, GTK_CSS_PERCENT)));
1540   gtk_css_style_property_register        ("border-image-width",
1541                                           GTK_CSS_PROPERTY_BORDER_IMAGE_WIDTH,
1542                                           GTK_TYPE_BORDER,
1543                                           0,
1544                                           border_image_width_parse,
1545                                           NULL,
1546                                           NULL,
1547                                           query_simple,
1548                                           assign_simple,
1549                                           NULL,
1550                                           _gtk_css_value_new_from_boxed (GTK_TYPE_BORDER, NULL));
1551
1552   gtk_css_style_property_register        ("transition-property",
1553                                           GTK_CSS_PROPERTY_TRANSITION_PROPERTY,
1554                                           G_TYPE_NONE,
1555                                           0,
1556                                           transition_property_parse,
1557                                           NULL,
1558                                           NULL,
1559                                           NULL,
1560                                           NULL,
1561                                           NULL,
1562                                           _gtk_css_array_value_new (_gtk_css_ident_value_new ("all")));
1563   gtk_css_style_property_register        ("transition-duration",
1564                                           GTK_CSS_PROPERTY_TRANSITION_DURATION,
1565                                           G_TYPE_NONE,
1566                                           0,
1567                                           transition_time_parse,
1568                                           NULL,
1569                                           NULL,
1570                                           NULL,
1571                                           NULL,
1572                                           NULL,
1573                                           _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S)));
1574   gtk_css_style_property_register        ("transition-timing-function",
1575                                           GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION,
1576                                           G_TYPE_NONE,
1577                                           0,
1578                                           transition_timing_function_parse,
1579                                           NULL,
1580                                           NULL,
1581                                           NULL,
1582                                           NULL,
1583                                           NULL,
1584                                           _gtk_css_array_value_new (
1585                                             _gtk_css_ease_value_new_cubic_bezier (0.25, 0.1, 0.25, 1.0)));
1586   gtk_css_style_property_register        ("transition-delay",
1587                                           GTK_CSS_PROPERTY_TRANSITION_DELAY,
1588                                           G_TYPE_NONE,
1589                                           0,
1590                                           transition_time_parse,
1591                                           NULL,
1592                                           NULL,
1593                                           NULL,
1594                                           NULL,
1595                                           NULL,
1596                                           _gtk_css_array_value_new (_gtk_css_number_value_new (0, GTK_CSS_S)));
1597
1598   gtk_css_style_property_register        ("engine",
1599                                           GTK_CSS_PROPERTY_ENGINE,
1600                                           GTK_TYPE_THEMING_ENGINE,
1601                                           0,
1602                                           engine_parse,
1603                                           NULL,
1604                                           NULL,
1605                                           engine_query,
1606                                           engine_assign,
1607                                           NULL,
1608                                           _gtk_css_engine_value_new (gtk_theming_engine_load (NULL)));
1609   gtk_css_style_property_register        ("transition",
1610                                           GTK_CSS_PROPERTY_TRANSITION,
1611                                           GTK_TYPE_ANIMATION_DESCRIPTION,
1612                                           0,
1613                                           transition_parse,
1614                                           NULL,
1615                                           NULL,
1616                                           query_simple,
1617                                           assign_simple,
1618                                           NULL,
1619                                           _gtk_css_value_new_from_boxed (GTK_TYPE_ANIMATION_DESCRIPTION, NULL));
1620
1621   /* Private property holding the binding sets */
1622   gtk_css_style_property_register        ("gtk-key-bindings",
1623                                           GTK_CSS_PROPERTY_GTK_KEY_BINDINGS,
1624                                           G_TYPE_PTR_ARRAY,
1625                                           0,
1626                                           bindings_value_parse,
1627                                           NULL,
1628                                           NULL,
1629                                           bindings_value_query,
1630                                           bindings_value_assign,
1631                                           NULL,
1632                                           _gtk_css_array_value_new (NULL));
1633 }
1634