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