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