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