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