]> Pileus Git - ~andy/gtk/blob - gtk/gtkcssstylepropertyimpl.c
css: Make the 'currentColor' keyword a symbolic color
[~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, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21
22 #include "gtkstylepropertyprivate.h"
23
24 #include <gobject/gvaluecollector.h>
25 #include <gdk-pixbuf/gdk-pixbuf.h>
26 #include <cairo-gobject.h>
27
28 #include "gtkcssparserprivate.h"
29 #include "gtkcssstylefuncsprivate.h"
30 #include "gtkcssstylepropertyprivate.h"
31 #include "gtkcsstypesprivate.h"
32 #include "gtkintl.h"
33 #include "gtkprivatetypebuiltins.h"
34 #include "gtkstylepropertiesprivate.h"
35
36 /* the actual parsers we have */
37 #include "gtkanimationdescription.h"
38 #include "gtkbindings.h"
39 #include "gtkcssimageprivate.h"
40 #include "gtkgradient.h"
41 #include "gtkshadowprivate.h"
42 #include "gtksymboliccolorprivate.h"
43 #include "gtkthemingengine.h"
44 #include "gtktypebuiltins.h"
45 #include "gtkwin32themeprivate.h"
46
47 /*** REGISTRATION ***/
48
49 static void
50 color_compute (GtkCssStyleProperty    *property,
51                GValue                 *computed,
52                GtkStyleContext        *context,
53                const GValue           *specified)
54 {
55   g_value_init (computed, GDK_TYPE_RGBA);
56
57   /* for when resolvage fails */
58 restart:
59
60   if (G_VALUE_HOLDS (specified, GTK_TYPE_SYMBOLIC_COLOR))
61     {
62       GtkSymbolicColor *symbolic = g_value_get_boxed (specified);
63       GdkRGBA rgba;
64
65       if (symbolic == _gtk_symbolic_color_get_current_color ())
66         {
67           /* The computed value of the ‘currentColor’ keyword is the computed
68            * value of the ‘color’ property. If the ‘currentColor’ keyword is
69            * set on the ‘color’ property itself, it is treated as ‘color: inherit’. 
70            */
71           if (g_str_equal (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (property)), "color"))
72             {
73               GtkStyleContext *parent = gtk_style_context_get_parent (context);
74
75               if (parent)
76                 g_value_copy (_gtk_style_context_peek_property (parent, "color"), computed);
77               else
78                 _gtk_css_style_compute_value (computed,
79                                               context,
80                                               _gtk_css_style_property_get_initial_value (property));
81             }
82           else
83             {
84               g_value_copy (_gtk_style_context_peek_property (context, "color"), computed);
85             }
86         }
87       else if (_gtk_style_context_resolve_color (context,
88                                                  symbolic,
89                                                  &rgba))
90         {
91           g_value_set_boxed (computed, &rgba);
92         }
93       else
94         {
95           specified = _gtk_css_style_property_get_initial_value (property);
96           goto restart;
97         }
98
99     }
100   else
101     g_value_copy (specified, computed);
102 }
103
104 static void
105 _gtk_style_property_register (const char *                   name,
106                               GType                          value_type,
107                               GtkStylePropertyFlags          flags,
108                               GtkCssStylePropertyParseFunc   parse_value,
109                               GtkCssStylePropertyPrintFunc   print_value,
110                               GtkCssStylePropertyComputeFunc compute_value,
111                               const GValue *                 initial_value)
112 {
113   GtkCssStyleProperty *node;
114
115   node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY,
116                        "inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE,
117                        "initial-value", initial_value,
118                        "name", name,
119                        "value-type", value_type,
120                        NULL);
121   
122   if (parse_value)
123     node->parse_value = parse_value;
124   if (print_value)
125     node->print_value = print_value;
126   if (compute_value)
127     node->compute_value = compute_value;
128 }
129
130 static void
131 gtk_style_property_register (const char *                   name,
132                              GType                          value_type,
133                              GtkStylePropertyFlags          flags,
134                              GtkCssStylePropertyParseFunc   parse_value,
135                              GtkCssStylePropertyPrintFunc   print_value,
136                              GtkCssStylePropertyComputeFunc compute_value,
137                              ...)
138 {
139   GValue initial_value = G_VALUE_INIT;
140   char *error = NULL;
141   va_list args;
142
143   va_start (args, compute_value);
144   G_VALUE_COLLECT_INIT (&initial_value, value_type,
145                         args, 0, &error);
146   if (error)
147     {
148       g_error ("property `%s' initial value is broken: %s", name, error);
149       g_value_unset (&initial_value);
150       return;
151     }
152
153   va_end (args);
154
155   _gtk_style_property_register (name,
156                                 value_type,
157                                 flags,
158                                 parse_value,
159                                 print_value,
160                                 compute_value,
161                                 &initial_value);
162
163   g_value_unset (&initial_value);
164 }
165
166 /*** HELPERS ***/
167
168 static void
169 string_append_double (GString *string,
170                       double   d)
171 {
172   char buf[G_ASCII_DTOSTR_BUF_SIZE];
173
174   g_ascii_dtostr (buf, sizeof (buf), d);
175   g_string_append (string, buf);
176 }
177
178 static void
179 string_append_string (GString    *str,
180                       const char *string)
181 {
182   gsize len;
183
184   g_string_append_c (str, '"');
185
186   do {
187     len = strcspn (string, "\"\n\r\f");
188     g_string_append (str, string);
189     string += len;
190     switch (*string)
191       {
192       case '\0':
193         break;
194       case '\n':
195         g_string_append (str, "\\A ");
196         break;
197       case '\r':
198         g_string_append (str, "\\D ");
199         break;
200       case '\f':
201         g_string_append (str, "\\C ");
202         break;
203       case '\"':
204         g_string_append (str, "\\\"");
205         break;
206       default:
207         g_assert_not_reached ();
208         break;
209       }
210   } while (*string);
211
212   g_string_append_c (str, '"');
213 }
214
215 /*** IMPLEMENTATIONS ***/
216
217 static gboolean
218 font_family_parse (GtkCssStyleProperty *property,
219                    GValue              *value,
220                    GtkCssParser        *parser,
221                    GFile               *base)
222 {
223   GPtrArray *names;
224   char *name;
225
226   /* We don't special case generic families. Pango should do
227    * that for us */
228
229   names = g_ptr_array_new ();
230
231   do {
232     name = _gtk_css_parser_try_ident (parser, TRUE);
233     if (name)
234       {
235         GString *string = g_string_new (name);
236         g_free (name);
237         while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
238           {
239             g_string_append_c (string, ' ');
240             g_string_append (string, name);
241             g_free (name);
242           }
243         name = g_string_free (string, FALSE);
244       }
245     else 
246       {
247         name = _gtk_css_parser_read_string (parser);
248         if (name == NULL)
249           {
250             g_ptr_array_free (names, TRUE);
251             return FALSE;
252           }
253       }
254
255     g_ptr_array_add (names, name);
256   } while (_gtk_css_parser_try (parser, ",", TRUE));
257
258   /* NULL-terminate array */
259   g_ptr_array_add (names, NULL);
260   g_value_set_boxed (value, g_ptr_array_free (names, FALSE));
261   return TRUE;
262 }
263
264 static void
265 font_family_value_print (GtkCssStyleProperty *property,
266                          const GValue        *value,
267                          GString             *string)
268 {
269   const char **names = g_value_get_boxed (value);
270
271   if (names == NULL || *names == NULL)
272     {
273       g_string_append (string, "none");
274       return;
275     }
276
277   string_append_string (string, *names);
278   names++;
279   while (*names)
280     {
281       g_string_append (string, ", ");
282       string_append_string (string, *names);
283       names++;
284     }
285 }
286
287 static gboolean 
288 bindings_value_parse (GtkCssStyleProperty *property,
289                       GValue              *value,
290                       GtkCssParser        *parser,
291                       GFile               *base)
292 {
293   GPtrArray *array;
294   GtkBindingSet *binding_set;
295   char *name;
296
297   array = g_ptr_array_new ();
298
299   do {
300       name = _gtk_css_parser_try_ident (parser, TRUE);
301       if (name == NULL)
302         {
303           _gtk_css_parser_error (parser, "Not a valid binding name");
304           g_ptr_array_free (array, TRUE);
305           return FALSE;
306         }
307
308       binding_set = gtk_binding_set_find (name);
309
310       if (!binding_set)
311         {
312           _gtk_css_parser_error (parser, "No binding set named '%s'", name);
313           g_free (name);
314           continue;
315         }
316
317       g_ptr_array_add (array, binding_set);
318       g_free (name);
319     }
320   while (_gtk_css_parser_try (parser, ",", TRUE));
321
322   g_value_take_boxed (value, array);
323
324   return TRUE;
325 }
326
327 static void
328 bindings_value_print (GtkCssStyleProperty *property,
329                       const GValue        *value,
330                       GString             *string)
331 {
332   GPtrArray *array;
333   guint i;
334
335   array = g_value_get_boxed (value);
336
337   for (i = 0; i < array->len; i++)
338     {
339       GtkBindingSet *binding_set = g_ptr_array_index (array, i);
340
341       if (i > 0)
342         g_string_append (string, ", ");
343       g_string_append (string, binding_set->set_name);
344     }
345 }
346
347 static gboolean 
348 border_corner_radius_value_parse (GtkCssStyleProperty *property,
349                                   GValue              *value,
350                                   GtkCssParser        *parser,
351                                   GFile               *base)
352 {
353   GtkCssBorderCornerRadius corner;
354
355   if (!_gtk_css_parser_try_double (parser, &corner.horizontal))
356     {
357       _gtk_css_parser_error (parser, "Expected a number");
358       return FALSE;
359     }
360   else if (corner.horizontal < 0)
361     goto negative;
362
363   if (!_gtk_css_parser_try_double (parser, &corner.vertical))
364     corner.vertical = corner.horizontal;
365   else if (corner.vertical < 0)
366     goto negative;
367
368   g_value_set_boxed (value, &corner);
369   return TRUE;
370
371 negative:
372   _gtk_css_parser_error (parser, "Border radius values cannot be negative");
373   return FALSE;
374 }
375
376 static void
377 border_corner_radius_value_print (GtkCssStyleProperty *property,
378                                   const GValue        *value,
379                                   GString             *string)
380 {
381   GtkCssBorderCornerRadius *corner;
382
383   corner = g_value_get_boxed (value);
384
385   if (corner == NULL)
386     {
387       g_string_append (string, "none");
388       return;
389     }
390
391   string_append_double (string, corner->horizontal);
392   if (corner->horizontal != corner->vertical)
393     {
394       g_string_append_c (string, ' ');
395       string_append_double (string, corner->vertical);
396     }
397 }
398
399 static gboolean 
400 css_image_value_parse (GtkCssStyleProperty *property,
401                        GValue              *value,
402                        GtkCssParser        *parser,
403                        GFile               *base)
404 {
405   GtkCssImage *image;
406
407   if (_gtk_css_parser_try (parser, "none", TRUE))
408     image = NULL;
409   else
410     {
411       image = _gtk_css_image_new_parse (parser, base);
412       if (image == NULL)
413         return FALSE;
414     }
415
416   g_value_unset (value);
417   g_value_init (value, GTK_TYPE_CSS_IMAGE);
418   g_value_take_object (value, image);
419   return TRUE;
420 }
421
422 static void
423 css_image_value_print (GtkCssStyleProperty *property,
424                        const GValue        *value,
425                        GString             *string)
426 {
427   GtkCssImage *image = g_value_get_object (value);
428
429   if (image)
430     _gtk_css_image_print (image, string);
431   else
432     g_string_append (string, "none");
433 }
434
435 static void
436 css_image_value_compute (GtkCssStyleProperty    *property,
437                          GValue                 *computed,
438                          GtkStyleContext        *context,
439                          const GValue           *specified)
440 {
441   GtkCssImage *image = g_value_get_object (specified);
442
443   if (image)
444     image = _gtk_css_image_compute (image, context);
445
446   g_value_init (computed, GTK_TYPE_CSS_IMAGE);
447   g_value_take_object (computed, image);
448 }
449
450 static void
451 compute_border_width (GtkCssStyleProperty    *property,
452                       GValue                 *computed,
453                       GtkStyleContext        *context,
454                       const GValue           *specified)
455 {
456   GtkCssStyleProperty *style;
457   GtkBorderStyle border_style;
458   
459   /* The -1 is magic that is only true because we register the style
460    * properties directly after the width properties.
461    */
462   style = _gtk_css_style_property_lookup_by_id (_gtk_css_style_property_get_id (property) - 1);
463   border_style = g_value_get_enum (_gtk_style_context_peek_property (context, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (style))));
464
465   g_value_init (computed, G_TYPE_INT);
466   if (border_style == GTK_BORDER_STYLE_NONE ||
467       border_style == GTK_BORDER_STYLE_HIDDEN)
468     g_value_set_int (computed, 0);
469   else
470     g_value_copy (specified, computed);
471 }
472
473 static gboolean
474 background_repeat_value_parse (GtkCssStyleProperty *property,
475                                GValue              *value,
476                                GtkCssParser        *parser,
477                                GFile               *base)
478 {
479   int repeat, vertical;
480
481   if (!_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &repeat))
482     {
483       _gtk_css_parser_error (parser, "Not a valid value");
484       return FALSE;
485     }
486
487   if (repeat <= GTK_CSS_BACKGROUND_REPEAT_MASK)
488     {
489       if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &vertical))
490         {
491           if (vertical >= GTK_CSS_BACKGROUND_REPEAT_MASK)
492             {
493               _gtk_css_parser_error (parser, "Not a valid 2nd value");
494               return FALSE;
495             }
496           else
497             repeat |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
498         }
499       else
500         repeat |= repeat << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
501     }
502
503   g_value_set_enum (value, repeat);
504   return TRUE;
505 }
506
507 static void
508 background_repeat_value_print (GtkCssStyleProperty *property,
509                                const GValue        *value,
510                                GString             *string)
511 {
512   GEnumClass *enum_class;
513   GEnumValue *enum_value;
514   GtkCssBackgroundRepeat repeat;
515
516   repeat = g_value_get_enum (value);
517   enum_class = g_type_class_ref (GTK_TYPE_CSS_BACKGROUND_REPEAT);
518   enum_value = g_enum_get_value (enum_class, repeat);
519
520   /* only triggers for 'repeat-x' and 'repeat-y' */
521   if (enum_value)
522     g_string_append (string, enum_value->value_nick);
523   else
524     {
525       enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_HORIZONTAL (repeat));
526       g_string_append (string, enum_value->value_nick);
527
528       if (GTK_CSS_BACKGROUND_HORIZONTAL (repeat) != GTK_CSS_BACKGROUND_VERTICAL (repeat))
529         {
530           enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_VERTICAL (repeat));
531           g_string_append (string, " ");
532           g_string_append (string, enum_value->value_nick);
533         }
534     }
535
536   g_type_class_unref (enum_class);
537 }
538
539 /*** REGISTRATION ***/
540
541 #define rgba_init(rgba, r, g, b, a) G_STMT_START{ \
542   (rgba)->red = (r); \
543   (rgba)->green = (g); \
544   (rgba)->blue = (b); \
545   (rgba)->alpha = (a); \
546 }G_STMT_END
547 void
548 _gtk_css_style_property_init_properties (void)
549 {
550   GValue value = { 0, };
551   char *default_font_family[] = { "Sans", NULL };
552   GdkRGBA rgba;
553   GtkCssBorderCornerRadius no_corner_radius = { 0, };
554   GtkBorder border_of_ones = { 1, 1, 1, 1 };
555   GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
556
557   /* Initialize "color" and "font-size" first,
558    * so that when computing values later they are
559    * done first. That way, 'currentColor' and font
560    * sizes in em can be looked up properly */
561   rgba_init (&rgba, 1, 1, 1, 1);
562   gtk_style_property_register            ("color",
563                                           GDK_TYPE_RGBA,
564                                           GTK_STYLE_PROPERTY_INHERIT,
565                                           NULL,
566                                           NULL,
567                                           color_compute,
568                                           &rgba);
569   gtk_style_property_register            ("font-size",
570                                           G_TYPE_DOUBLE,
571                                           GTK_STYLE_PROPERTY_INHERIT,
572                                           NULL,
573                                           NULL,
574                                           NULL,
575                                           10.0);
576
577   /* properties that aren't referenced when computing values
578    * start here */
579   rgba_init (&rgba, 0, 0, 0, 0);
580   gtk_style_property_register            ("background-color",
581                                           GDK_TYPE_RGBA,
582                                           0,
583                                           NULL,
584                                           NULL,
585                                           color_compute,
586                                           &rgba);
587
588   gtk_style_property_register            ("font-family",
589                                           G_TYPE_STRV,
590                                           GTK_STYLE_PROPERTY_INHERIT,
591                                           font_family_parse,
592                                           font_family_value_print,
593                                           NULL,
594                                           default_font_family);
595   gtk_style_property_register            ("font-style",
596                                           PANGO_TYPE_STYLE,
597                                           GTK_STYLE_PROPERTY_INHERIT,
598                                           NULL,
599                                           NULL,
600                                           NULL,
601                                           PANGO_STYLE_NORMAL);
602   gtk_style_property_register            ("font-variant",
603                                           PANGO_TYPE_VARIANT,
604                                           GTK_STYLE_PROPERTY_INHERIT,
605                                           NULL,
606                                           NULL,
607                                           NULL,
608                                           PANGO_VARIANT_NORMAL);
609   /* xxx: need to parse this properly, ie parse the numbers */
610   gtk_style_property_register            ("font-weight",
611                                           PANGO_TYPE_WEIGHT,
612                                           GTK_STYLE_PROPERTY_INHERIT,
613                                           NULL,
614                                           NULL,
615                                           NULL,
616                                           PANGO_WEIGHT_NORMAL);
617
618   gtk_style_property_register            ("text-shadow",
619                                           GTK_TYPE_SHADOW,
620                                           GTK_STYLE_PROPERTY_INHERIT,
621                                           NULL,
622                                           NULL,
623                                           NULL,
624                                           NULL);
625
626   gtk_style_property_register            ("icon-shadow",
627                                           GTK_TYPE_SHADOW,
628                                           GTK_STYLE_PROPERTY_INHERIT,
629                                           NULL,
630                                           NULL,
631                                           NULL,
632                                           NULL);
633
634   gtk_style_property_register            ("box-shadow",
635                                           GTK_TYPE_SHADOW,
636                                           0,
637                                           NULL,
638                                           NULL,
639                                           NULL,
640                                           NULL);
641
642   gtk_style_property_register            ("margin-top",
643                                           G_TYPE_INT,
644                                           0,
645                                           NULL,
646                                           NULL,
647                                           NULL,
648                                           0);
649   gtk_style_property_register            ("margin-left",
650                                           G_TYPE_INT,
651                                           0,
652                                           NULL,
653                                           NULL,
654                                           NULL,
655                                           0);
656   gtk_style_property_register            ("margin-bottom",
657                                           G_TYPE_INT,
658                                           0,
659                                           NULL,
660                                           NULL,
661                                           NULL,
662                                           0);
663   gtk_style_property_register            ("margin-right",
664                                           G_TYPE_INT,
665                                           0,
666                                           NULL,
667                                           NULL,
668                                           NULL,
669                                           0);
670   gtk_style_property_register            ("padding-top",
671                                           G_TYPE_INT,
672                                           0,
673                                           NULL,
674                                           NULL,
675                                           NULL,
676                                           0);
677   gtk_style_property_register            ("padding-left",
678                                           G_TYPE_INT,
679                                           0,
680                                           NULL,
681                                           NULL,
682                                           NULL,
683                                           0);
684   gtk_style_property_register            ("padding-bottom",
685                                           G_TYPE_INT,
686                                           0,
687                                           NULL,
688                                           NULL,
689                                           NULL,
690                                           0);
691   gtk_style_property_register            ("padding-right",
692                                           G_TYPE_INT,
693                                           0,
694                                           NULL,
695                                           NULL,
696                                           NULL,
697                                           0);
698   /* IMPORTANT: compute_border_width() requires that the border-width
699    * properties be immeditaly followed by the border-style properties
700    */
701   gtk_style_property_register            ("border-top-style",
702                                           GTK_TYPE_BORDER_STYLE,
703                                           0,
704                                           NULL,
705                                           NULL,
706                                           NULL,
707                                           GTK_BORDER_STYLE_NONE);
708   gtk_style_property_register            ("border-top-width",
709                                           G_TYPE_INT,
710                                           0,
711                                           NULL,
712                                           NULL,
713                                           compute_border_width,
714                                           0);
715   gtk_style_property_register            ("border-left-style",
716                                           GTK_TYPE_BORDER_STYLE,
717                                           0,
718                                           NULL,
719                                           NULL,
720                                           NULL,
721                                           GTK_BORDER_STYLE_NONE);
722   gtk_style_property_register            ("border-left-width",
723                                           G_TYPE_INT,
724                                           0,
725                                           NULL,
726                                           NULL,
727                                           compute_border_width,
728                                           0);
729   gtk_style_property_register            ("border-bottom-style",
730                                           GTK_TYPE_BORDER_STYLE,
731                                           0,
732                                           NULL,
733                                           NULL,
734                                           NULL,
735                                           GTK_BORDER_STYLE_NONE);
736   gtk_style_property_register            ("border-bottom-width",
737                                           G_TYPE_INT,
738                                           0,
739                                           NULL,
740                                           NULL,
741                                           compute_border_width,
742                                           0);
743   gtk_style_property_register            ("border-right-style",
744                                           GTK_TYPE_BORDER_STYLE,
745                                           0,
746                                           NULL,
747                                           NULL,
748                                           NULL,
749                                           GTK_BORDER_STYLE_NONE);
750   gtk_style_property_register            ("border-right-width",
751                                           G_TYPE_INT,
752                                           0,
753                                           NULL,
754                                           NULL,
755                                           compute_border_width,
756                                           0);
757
758   gtk_style_property_register            ("border-top-left-radius",
759                                           GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
760                                           0,
761                                           border_corner_radius_value_parse,
762                                           border_corner_radius_value_print,
763                                           NULL,
764                                           &no_corner_radius);
765   gtk_style_property_register            ("border-top-right-radius",
766                                           GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
767                                           0,
768                                           border_corner_radius_value_parse,
769                                           border_corner_radius_value_print,
770                                           NULL,
771                                           &no_corner_radius);
772   gtk_style_property_register            ("border-bottom-right-radius",
773                                           GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
774                                           0,
775                                           border_corner_radius_value_parse,
776                                           border_corner_radius_value_print,
777                                           NULL,
778                                           &no_corner_radius);
779   gtk_style_property_register            ("border-bottom-left-radius",
780                                           GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
781                                           0,
782                                           border_corner_radius_value_parse,
783                                           border_corner_radius_value_print,
784                                           NULL,
785                                           &no_corner_radius);
786
787   gtk_style_property_register            ("outline-style",
788                                           GTK_TYPE_BORDER_STYLE,
789                                           0,
790                                           NULL,
791                                           NULL,
792                                           NULL,
793                                           GTK_BORDER_STYLE_NONE);
794   gtk_style_property_register            ("outline-width",
795                                           G_TYPE_INT,
796                                           0,
797                                           NULL,
798                                           NULL,
799                                           compute_border_width,
800                                           0);
801   gtk_style_property_register            ("outline-offset",
802                                           G_TYPE_INT,
803                                           0,
804                                           NULL,
805                                           NULL,
806                                           NULL,
807                                           0);
808
809   gtk_style_property_register            ("background-clip",
810                                           GTK_TYPE_CSS_AREA,
811                                           0,
812                                           NULL,
813                                           NULL,
814                                           NULL,
815                                           GTK_CSS_AREA_BORDER_BOX);
816                                         
817   gtk_style_property_register            ("background-origin",
818                                           GTK_TYPE_CSS_AREA,
819                                           0,
820                                           NULL,
821                                           NULL,
822                                           NULL,
823                                           GTK_CSS_AREA_PADDING_BOX);
824
825   g_value_init (&value, GTK_TYPE_SYMBOLIC_COLOR);
826   g_value_set_boxed (&value, _gtk_symbolic_color_get_current_color ());
827   _gtk_style_property_register           ("border-top-color",
828                                           GDK_TYPE_RGBA,
829                                           0,
830                                           NULL,
831                                           NULL,
832                                           color_compute,
833                                           &value);
834   _gtk_style_property_register           ("border-right-color",
835                                           GDK_TYPE_RGBA,
836                                           0,
837                                           NULL,
838                                           NULL,
839                                           color_compute,
840                                           &value);
841   _gtk_style_property_register           ("border-bottom-color",
842                                           GDK_TYPE_RGBA,
843                                           0,
844                                           NULL,
845                                           NULL,
846                                           color_compute,
847                                           &value);
848   _gtk_style_property_register           ("border-left-color",
849                                           GDK_TYPE_RGBA,
850                                           0,
851                                           NULL,
852                                           NULL,
853                                           color_compute,
854                                           &value);
855   _gtk_style_property_register           ("outline-color",
856                                           GDK_TYPE_RGBA,
857                                           0,
858                                           NULL,
859                                           NULL,
860                                           color_compute,
861                                           &value);
862   g_value_unset (&value);
863
864   gtk_style_property_register            ("background-repeat",
865                                           GTK_TYPE_CSS_BACKGROUND_REPEAT,
866                                           0,
867                                           background_repeat_value_parse,
868                                           background_repeat_value_print,
869                                           NULL,
870                                           GTK_CSS_BACKGROUND_REPEAT | (GTK_CSS_BACKGROUND_REPEAT << GTK_CSS_BACKGROUND_REPEAT_SHIFT));
871   g_value_init (&value, GTK_TYPE_CSS_IMAGE);
872   _gtk_style_property_register           ("background-image",
873                                           CAIRO_GOBJECT_TYPE_PATTERN,
874                                           0,
875                                           css_image_value_parse,
876                                           css_image_value_print,
877                                           css_image_value_compute,
878                                           &value);
879
880   _gtk_style_property_register           ("border-image-source",
881                                           CAIRO_GOBJECT_TYPE_PATTERN,
882                                           0,
883                                           css_image_value_parse,
884                                           css_image_value_print,
885                                           css_image_value_compute,
886                                           &value);
887   g_value_unset (&value);
888   gtk_style_property_register            ("border-image-repeat",
889                                           GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
890                                           0,
891                                           NULL,
892                                           NULL,
893                                           NULL,
894                                           &border_image_repeat);
895
896   /* XXX: The initial vaue is wrong, it should be 100% */
897   gtk_style_property_register            ("border-image-slice",
898                                           GTK_TYPE_BORDER,
899                                           0,
900                                           NULL,
901                                           NULL,
902                                           NULL,
903                                           &border_of_ones);
904   gtk_style_property_register            ("border-image-width",
905                                           GTK_TYPE_BORDER,
906                                           0,
907                                           NULL,
908                                           NULL,
909                                           NULL,
910                                           NULL);
911   gtk_style_property_register            ("engine",
912                                           GTK_TYPE_THEMING_ENGINE,
913                                           0,
914                                           NULL,
915                                           NULL,
916                                           NULL,
917                                           gtk_theming_engine_load (NULL));
918   gtk_style_property_register            ("transition",
919                                           GTK_TYPE_ANIMATION_DESCRIPTION,
920                                           0,
921                                           NULL,
922                                           NULL,
923                                           NULL,
924                                           NULL);
925
926   /* Private property holding the binding sets */
927   gtk_style_property_register            ("gtk-key-bindings",
928                                           G_TYPE_PTR_ARRAY,
929                                           0,
930                                           bindings_value_parse,
931                                           bindings_value_print,
932                                           NULL,
933                                           NULL);
934 }
935