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