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