Small patch to see if Ben's build problem gets fixed
[ardour.git] / libs / clearlooks-newer / clearlooks_rc_style.c
1 /* Clearlooks theme engine
2  * Copyright (C) 2005 Richard Stellingwerff.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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  * Written by Owen Taylor <otaylor@redhat.com>
20  * and by Alexander Larsson <alexl@redhat.com>
21  * Modified by Richard Stellingwerff <remenic@gmail.com>
22  * Modified by Kulyk Nazar <schamane@myeburg.net>
23  */
24
25 #include "clearlooks_style.h"
26 #include "clearlooks_rc_style.h"
27
28 #include "animation.h"
29
30 static void      clearlooks_rc_style_init         (ClearlooksRcStyle      *style);
31 #ifdef HAVE_ANIMATION
32 static void      clearlooks_rc_style_finalize     (GObject                *object);
33 #endif
34 static void      clearlooks_rc_style_class_init   (ClearlooksRcStyleClass *klass);
35 static GtkStyle *clearlooks_rc_style_create_style (GtkRcStyle             *rc_style);
36 static guint     clearlooks_rc_style_parse        (GtkRcStyle             *rc_style,
37                                                    GtkSettings            *settings,
38                                                    GScanner               *scanner);
39 static void      clearlooks_rc_style_merge        (GtkRcStyle             *dest,
40                                                    GtkRcStyle             *src);
41
42
43 static GtkRcStyleClass *clearlooks_parent_rc_class;
44
45 GType clearlooks_type_rc_style = 0;
46
47 enum
48 {
49         TOKEN_SCROLLBARCOLOR = G_TOKEN_LAST + 1,
50         TOKEN_COLORIZESCROLLBAR,
51         TOKEN_CONTRAST,
52         TOKEN_SUNKENMENU,
53         TOKEN_PROGRESSBARSTYLE,
54         TOKEN_MENUBARSTYLE,
55         TOKEN_TOOLBARSTYLE,
56         TOKEN_MENUITEMSTYLE,
57         TOKEN_LISTVIEWITEMSTYLE,
58         TOKEN_ANIMATION,
59         TOKEN_STYLE,
60         TOKEN_RADIUS,
61
62         TOKEN_CLASSIC,
63         TOKEN_GLOSSY,
64         TOKEN_INVERTED,
65         TOKEN_GUMMY,
66
67         TOKEN_TRUE,
68         TOKEN_FALSE
69 };
70
71 static struct
72 {
73         const gchar        *name;
74         guint               token;
75 }
76 clearlooks_gtk2_rc_symbols[] =
77 {
78         { "scrollbar_color",    TOKEN_SCROLLBARCOLOR  },
79         { "colorize_scrollbar", TOKEN_COLORIZESCROLLBAR },
80         { "contrast",           TOKEN_CONTRAST  },
81         { "sunkenmenubar",      TOKEN_SUNKENMENU },
82         { "progressbarstyle",   TOKEN_PROGRESSBARSTYLE },
83         { "menubarstyle",       TOKEN_MENUBARSTYLE }, 
84         { "toolbarstyle",       TOKEN_TOOLBARSTYLE },
85         { "menuitemstyle",      TOKEN_MENUITEMSTYLE },
86         { "listviewitemstyle",  TOKEN_LISTVIEWITEMSTYLE },
87         { "animation",          TOKEN_ANIMATION },
88         { "style",              TOKEN_STYLE },
89         { "radius",             TOKEN_RADIUS },
90
91         { "CLASSIC",            TOKEN_CLASSIC },
92         { "GLOSSY",             TOKEN_GLOSSY },
93         { "INVERTED",           TOKEN_INVERTED },
94         { "GUMMY",              TOKEN_GUMMY },
95
96         { "TRUE",               TOKEN_TRUE },
97         { "FALSE",              TOKEN_FALSE }
98 };
99
100
101 void
102 clearlooks_rc_style_register_type (GTypeModule *module)
103 {
104         static const GTypeInfo object_info =
105         {
106                 sizeof (ClearlooksRcStyleClass),
107                 (GBaseInitFunc) NULL,
108                 (GBaseFinalizeFunc) NULL,
109                 (GClassInitFunc) clearlooks_rc_style_class_init,
110                 NULL,           /* class_finalize */
111                 NULL,           /* class_data */
112                 sizeof (ClearlooksRcStyle),
113                 0,              /* n_preallocs */
114                 (GInstanceInitFunc) clearlooks_rc_style_init,
115                 NULL
116         };
117
118         clearlooks_type_rc_style = g_type_module_register_type (module,
119                                                      GTK_TYPE_RC_STYLE,
120                                                      "ClearlooksRcStyle",
121                                                      &object_info, 0);
122 }
123
124 static void
125 clearlooks_rc_style_init (ClearlooksRcStyle *clearlooks_rc)
126 {
127         clearlooks_rc->style = CL_STYLE_CLASSIC;
128
129         clearlooks_rc->flags = 0;
130
131         clearlooks_rc->contrast = 1.0;
132         clearlooks_rc->menubarstyle = 0;
133         clearlooks_rc->toolbarstyle = 0;
134         clearlooks_rc->animation = FALSE;
135         clearlooks_rc->colorize_scrollbar = FALSE;
136         clearlooks_rc->radius = 3.0;
137 }
138
139 #ifdef HAVE_ANIMATION
140 static void
141 clearlooks_rc_style_finalize (GObject *object)
142 {
143         /* cleanup all the animation stuff */
144         clearlooks_animation_cleanup ();
145
146         if (G_OBJECT_CLASS (clearlooks_parent_rc_class)->finalize != NULL)
147                 G_OBJECT_CLASS (clearlooks_parent_rc_class)->finalize(object);
148 }
149 #endif
150
151
152 static void
153 clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass)
154 {
155         GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass);
156 #ifdef HAVE_ANIMATION
157         GObjectClass    *g_object_class = G_OBJECT_CLASS (klass);
158 #endif
159
160         clearlooks_parent_rc_class = g_type_class_peek_parent (klass);
161
162         rc_style_class->parse = clearlooks_rc_style_parse;
163         rc_style_class->create_style = clearlooks_rc_style_create_style;
164         rc_style_class->merge = clearlooks_rc_style_merge;
165
166 #ifdef HAVE_ANIMATION
167         g_object_class->finalize = clearlooks_rc_style_finalize;
168 #endif
169 }
170
171 static guint
172 clearlooks_gtk2_rc_parse_boolean (GtkSettings *settings,
173                      GScanner     *scanner,
174                      gboolean *retval)
175 {
176         guint token;
177
178         (void) settings;
179         token = g_scanner_get_next_token(scanner);
180
181         token = g_scanner_get_next_token(scanner);
182         if (token != G_TOKEN_EQUAL_SIGN)
183            return G_TOKEN_EQUAL_SIGN;
184
185         token = g_scanner_get_next_token(scanner);
186         if (token == TOKEN_TRUE)
187            *retval = TRUE;
188         else if (token == TOKEN_FALSE)
189            *retval = FALSE;
190         else
191            return TOKEN_TRUE;
192
193         return G_TOKEN_NONE;
194 }
195
196 static guint
197 clearlooks_gtk2_rc_parse_color(GtkSettings  *settings,
198                   GScanner     *scanner,
199                   GdkColor     *color)
200 {
201         guint token;
202
203         (void) settings;
204
205         /* Skip 'blah_color' */
206         token = g_scanner_get_next_token(scanner);
207
208         token = g_scanner_get_next_token(scanner);
209         if (token != G_TOKEN_EQUAL_SIGN)
210            return G_TOKEN_EQUAL_SIGN;
211
212         return gtk_rc_parse_color (scanner, color);
213 }
214
215 static guint
216 clearlooks_gtk2_rc_parse_double (GtkSettings  *settings,
217                                  GScanner     *scanner,
218                                  gdouble      *val)
219 {
220         guint token;
221
222         (void) settings;
223
224         /* Skip 'blah' */
225         token = g_scanner_get_next_token(scanner);
226
227         token = g_scanner_get_next_token(scanner);
228         if (token != G_TOKEN_EQUAL_SIGN)
229            return G_TOKEN_EQUAL_SIGN;
230
231         token = g_scanner_get_next_token(scanner);
232         if (token != G_TOKEN_FLOAT)
233            return G_TOKEN_FLOAT;
234
235         *val = scanner->value.v_float;
236
237         return G_TOKEN_NONE;
238 }
239
240 static guint
241 clearlooks_gtk2_rc_parse_int (GtkSettings  *settings,
242                          GScanner     *scanner,
243                          guint8       *progressbarstyle)
244 {
245         guint token;
246
247         (void) settings;
248
249         /* Skip 'sunkenmenubar' */
250         token = g_scanner_get_next_token(scanner);
251
252         token = g_scanner_get_next_token(scanner);
253         if (token != G_TOKEN_EQUAL_SIGN)
254            return G_TOKEN_EQUAL_SIGN;
255
256         token = g_scanner_get_next_token(scanner);
257         if (token != G_TOKEN_INT)
258            return G_TOKEN_INT;
259
260         *progressbarstyle = scanner->value.v_int;
261
262         return G_TOKEN_NONE;
263 }
264
265 static guint
266 clearlooks_gtk2_rc_parse_style (GtkSettings      *settings,
267                                 GScanner         *scanner,
268                                 ClearlooksStyles *style)
269 {
270         guint token;
271
272         (void) settings;
273
274         g_assert (CL_NUM_STYLES == CL_STYLE_GUMMY + 1); /* so that people don't forget ;-) */
275
276         /* Skip 'style' */
277         token = g_scanner_get_next_token (scanner);
278
279         token = g_scanner_get_next_token (scanner);
280         if (token != G_TOKEN_EQUAL_SIGN)
281            return G_TOKEN_EQUAL_SIGN;
282
283         token = g_scanner_get_next_token (scanner);
284   
285         switch (token)
286         {
287                 case TOKEN_CLASSIC:
288                    *style = CL_STYLE_CLASSIC;
289                    break;
290                 case TOKEN_GLOSSY:
291                    *style = CL_STYLE_GLOSSY;
292                    break;
293                 case TOKEN_INVERTED:
294                    *style = CL_STYLE_INVERTED;
295                    break;
296                 case TOKEN_GUMMY:
297                    *style = CL_STYLE_GUMMY;
298                    break;
299                 default:
300                    return TOKEN_CLASSIC;
301         }
302
303         return G_TOKEN_NONE;
304 }
305
306 static guint
307 clearlooks_gtk2_rc_parse_dummy (GtkSettings      *settings,
308                                 GScanner         *scanner,
309                                 gchar            *name)
310 {
311         guint token;
312
313         (void) settings;
314
315         /* Skip option */
316         token = g_scanner_get_next_token (scanner);
317
318         /* print a warning. Isn't there a way to get the string from the scanner? */
319         g_scanner_warn (scanner, "Clearlooks configuration option \"%s\" is not supported and will be ignored.", name);
320
321         /* equal sign */
322         token = g_scanner_get_next_token (scanner);
323         if (token != G_TOKEN_EQUAL_SIGN)
324            return G_TOKEN_EQUAL_SIGN;
325
326         /* eat whatever comes next */
327         token = g_scanner_get_next_token (scanner);
328
329         return G_TOKEN_NONE;
330 }
331
332 static guint
333 clearlooks_rc_style_parse (GtkRcStyle *rc_style,
334                            GtkSettings  *settings,
335                            GScanner   *scanner)
336                      
337 {
338         static GQuark scope_id = 0;
339         ClearlooksRcStyle *clearlooks_style = CLEARLOOKS_RC_STYLE (rc_style);
340
341         guint old_scope;
342         guint token;
343         guint i;
344
345         /* Set up a new scope in this scanner. */
346
347         if (!scope_id)
348            scope_id = g_quark_from_string("clearlooks_theme_engine");
349
350         /* If we bail out due to errors, we *don't* reset the scope, so the
351         * error messaging code can make sense of our tokens.
352         */
353         old_scope = g_scanner_set_scope(scanner, scope_id);
354
355         /* Now check if we already added our symbols to this scope
356         * (in some previous call to clearlooks_rc_style_parse for the
357         * same scanner.
358         */
359
360         if (!g_scanner_lookup_symbol(scanner, clearlooks_gtk2_rc_symbols[0].name))
361         {
362                 for (i = 0; i < G_N_ELEMENTS (clearlooks_gtk2_rc_symbols); i++)
363                         g_scanner_scope_add_symbol(scanner, scope_id,
364                                         clearlooks_gtk2_rc_symbols[i].name,
365                                         GINT_TO_POINTER(clearlooks_gtk2_rc_symbols[i].token));
366         }
367
368         /* We're ready to go, now parse the top level */
369
370         token = g_scanner_peek_next_token(scanner);
371         while (token != G_TOKEN_RIGHT_CURLY)
372         {
373                 switch (token)
374                 {
375                         case TOKEN_SCROLLBARCOLOR:
376                                 token = clearlooks_gtk2_rc_parse_color (settings, scanner, &clearlooks_style->scrollbar_color);
377                                 clearlooks_style->flags |= CL_FLAG_SCROLLBAR_COLOR;
378                                 break;
379                         case TOKEN_COLORIZESCROLLBAR:
380                                 token = clearlooks_gtk2_rc_parse_boolean (settings, scanner, &clearlooks_style->colorize_scrollbar);
381                                 clearlooks_style->flags |= CL_FLAG_COLORIZE_SCROLLBAR;
382                                 break;
383                         case TOKEN_CONTRAST:
384                                 token = clearlooks_gtk2_rc_parse_double (settings, scanner, &clearlooks_style->contrast);
385                                 clearlooks_style->flags |= CL_FLAG_CONTRAST;
386                                 break;
387                         case TOKEN_MENUBARSTYLE:
388                                 token = clearlooks_gtk2_rc_parse_int (settings, scanner, &clearlooks_style->menubarstyle);
389                                 clearlooks_style->flags |= CL_FLAG_MENUBARSTYLE;
390                                 break;
391                         case TOKEN_TOOLBARSTYLE:
392                                 token = clearlooks_gtk2_rc_parse_int (settings, scanner, &clearlooks_style->toolbarstyle);
393                                 clearlooks_style->flags |= CL_FLAG_TOOLBARSTYLE;
394                                 break;
395                         case TOKEN_ANIMATION:
396                                 token = clearlooks_gtk2_rc_parse_boolean (settings, scanner, &clearlooks_style->animation);
397                                 clearlooks_style->flags |= CL_FLAG_ANIMATION;
398                                 break;
399                         case TOKEN_STYLE:
400                                 token = clearlooks_gtk2_rc_parse_style (settings, scanner, &clearlooks_style->style);
401                                 clearlooks_style->flags |= CL_FLAG_STYLE;
402                                 break;
403                         case TOKEN_RADIUS:
404                                 token = clearlooks_gtk2_rc_parse_double (settings, scanner, &clearlooks_style->radius);
405                                 clearlooks_style->flags |= CL_FLAG_RADIUS;
406                                 break;
407
408                         /* stuff to ignore */
409                         case TOKEN_SUNKENMENU:
410                                 token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "sunkenmenu");
411                                 break;
412                         case TOKEN_PROGRESSBARSTYLE:
413                                 token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "progressbarstyle");
414                                 break;
415                         case TOKEN_MENUITEMSTYLE:
416                                 token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "menuitemstyle");
417                                 break;
418                         case TOKEN_LISTVIEWITEMSTYLE:
419                                 token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "listviewitemstyle");
420                                 break;
421
422                         default:
423                                 g_scanner_get_next_token(scanner);
424                                 token = G_TOKEN_RIGHT_CURLY;
425                                 break;
426                 }
427
428                 if (token != G_TOKEN_NONE)
429                         return token;
430
431                 token = g_scanner_peek_next_token(scanner);
432         }
433
434         g_scanner_get_next_token(scanner);
435
436         g_scanner_set_scope(scanner, old_scope);
437
438         return G_TOKEN_NONE;
439 }
440
441 static void
442 clearlooks_rc_style_merge (GtkRcStyle *dest,
443                            GtkRcStyle *src)
444 {
445         ClearlooksRcStyle *dest_w, *src_w;
446         ClearlooksRcFlags flags;
447
448         clearlooks_parent_rc_class->merge (dest, src);
449
450         if (!CLEARLOOKS_IS_RC_STYLE (src))
451                 return;
452
453         src_w = CLEARLOOKS_RC_STYLE (src);
454         dest_w = CLEARLOOKS_RC_STYLE (dest);
455
456         flags = (~dest_w->flags) & src_w->flags;
457
458         if (flags & CL_FLAG_STYLE)
459                 dest_w->style = src_w->style;
460         if (flags & CL_FLAG_CONTRAST)
461                 dest_w->contrast = src_w->contrast;
462         if (flags & CL_FLAG_MENUBARSTYLE)
463                 dest_w->menubarstyle = src_w->menubarstyle;
464         if (flags & CL_FLAG_TOOLBARSTYLE)
465                 dest_w->toolbarstyle = src_w->toolbarstyle;
466         if (flags & CL_FLAG_SCROLLBAR_COLOR)
467                 dest_w->scrollbar_color = src_w->scrollbar_color;
468         if (flags & CL_FLAG_COLORIZE_SCROLLBAR)
469                 dest_w->colorize_scrollbar = src_w->colorize_scrollbar;
470         if (flags & CL_FLAG_ANIMATION)
471                 dest_w->animation = src_w->animation;
472         if (flags & CL_FLAG_RADIUS)
473                 dest_w->radius = src_w->radius;
474
475         dest_w->flags |= src_w->flags;
476 }
477
478
479 /* Create an empty style suitable to this RC style
480  */
481 static GtkStyle *
482 clearlooks_rc_style_create_style (GtkRcStyle *rc_style)
483 {
484         (void) rc_style;
485         
486         return GTK_STYLE (g_object_new (CLEARLOOKS_TYPE_STYLE, NULL));
487 }