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