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