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 */
23
24 #include "clearlooks_style.h"
25 #include "clearlooks_rc_style.h"
26
27 static void clearlooks_rc_style_init (ClearlooksRcStyle *style);
28 static void clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass);
29 static GtkStyle *clearlooks_rc_style_create_style (GtkRcStyle *rc_style);
30 static guint clearlooks_rc_style_parse (GtkRcStyle *rc_style,
31 GtkSettings *settings,
32 GScanner *scanner);
33 static void clearlooks_rc_style_merge (GtkRcStyle *dest,
34 GtkRcStyle *src);
35
36
37 static GtkRcStyleClass *parent_class;
38
39 GType clearlooks_type_rc_style = 0;
40
41 enum
42 {
43 TOKEN_SPOTCOLOR = G_TOKEN_LAST + 1,
44 TOKEN_CONTRAST,
45 TOKEN_SUNKENMENU,
46 TOKEN_PROGRESSBARSTYLE,
47 TOKEN_MENUBARSTYLE,
48 TOKEN_MENUITEMSTYLE,
49 TOKEN_LISTVIEWITEMSTYLE
50 };
51
52 static struct
53 {
54 const gchar *name;
55 guint token;
56 }
57 theme_symbols[] =
58 {
59 { "spotcolor", TOKEN_SPOTCOLOR },
60 { "contrast", TOKEN_CONTRAST },
61 { "sunkenmenubar", TOKEN_SUNKENMENU },
62 { "progressbarstyle", TOKEN_PROGRESSBARSTYLE },
63 { "menubarstyle", TOKEN_MENUBARSTYLE },
64 { "menuitemstyle", TOKEN_MENUITEMSTYLE },
65 { "listviewitemstyle", TOKEN_LISTVIEWITEMSTYLE }
66 };
67
68
69 void
clearlooks_rc_style_register_type(GTypeModule * module)70 clearlooks_rc_style_register_type (GTypeModule *module)
71 {
72 static const GTypeInfo object_info =
73 {
74 sizeof (ClearlooksRcStyleClass),
75 (GBaseInitFunc) NULL,
76 (GBaseFinalizeFunc) NULL,
77 (GClassInitFunc) clearlooks_rc_style_class_init,
78 NULL, /* class_finalize */
79 NULL, /* class_data */
80 sizeof (ClearlooksRcStyle),
81 0, /* n_preallocs */
82 (GInstanceInitFunc) clearlooks_rc_style_init,
83 NULL
84 };
85
86 clearlooks_type_rc_style = g_type_module_register_type (module,
87 GTK_TYPE_RC_STYLE,
88 "ClearlooksRcStyle",
89 &object_info, 0);
90 }
91
92 static void
clearlooks_rc_style_init(ClearlooksRcStyle * clearlooks_rc)93 clearlooks_rc_style_init (ClearlooksRcStyle *clearlooks_rc)
94 {
95 clearlooks_rc->has_spot_color = FALSE;
96 clearlooks_rc->contrast = 1.0;
97 clearlooks_rc->sunkenmenubar = 1;
98 clearlooks_rc->progressbarstyle = 0;
99 clearlooks_rc->menubarstyle = 0;
100 clearlooks_rc->menuitemstyle = 1;
101 clearlooks_rc->listviewitemstyle = 1;
102 }
103
104 static void
clearlooks_rc_style_class_init(ClearlooksRcStyleClass * klass)105 clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass)
106 {
107 GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass);
108
109 parent_class = g_type_class_peek_parent (klass);
110
111 rc_style_class->parse = clearlooks_rc_style_parse;
112 rc_style_class->create_style = clearlooks_rc_style_create_style;
113 rc_style_class->merge = clearlooks_rc_style_merge;
114 }
115
116 static guint
theme_parse_color(GtkSettings * settings,GScanner * scanner,GdkColor * color)117 theme_parse_color(GtkSettings *settings,
118 GScanner *scanner,
119 GdkColor *color)
120 {
121 guint token;
122
123 /* Skip 'blah_color' */
124 token = g_scanner_get_next_token(scanner);
125
126 token = g_scanner_get_next_token(scanner);
127 if (token != G_TOKEN_EQUAL_SIGN)
128 return G_TOKEN_EQUAL_SIGN;
129
130 return gtk_rc_parse_color (scanner, color);
131 }
132
133 static guint
theme_parse_contrast(GtkSettings * settings,GScanner * scanner,double * contrast)134 theme_parse_contrast(GtkSettings *settings,
135 GScanner *scanner,
136 double *contrast)
137 {
138 guint token;
139
140 /* Skip 'contrast' */
141 token = g_scanner_get_next_token(scanner);
142
143 token = g_scanner_get_next_token(scanner);
144 if (token != G_TOKEN_EQUAL_SIGN)
145 return G_TOKEN_EQUAL_SIGN;
146
147 token = g_scanner_get_next_token(scanner);
148 if (token != G_TOKEN_FLOAT)
149 return G_TOKEN_FLOAT;
150
151 *contrast = scanner->value.v_float;
152
153 return G_TOKEN_NONE;
154 }
155
156 static guint
theme_parse_sunkenmenubar(GtkSettings * settings,GScanner * scanner,guint8 * sunken)157 theme_parse_sunkenmenubar(GtkSettings *settings,
158 GScanner *scanner,
159 guint8 *sunken)
160 {
161 guint token;
162
163 /* Skip 'sunkenmenubar' */
164 token = g_scanner_get_next_token(scanner);
165
166 token = g_scanner_get_next_token(scanner);
167 if (token != G_TOKEN_EQUAL_SIGN)
168 return G_TOKEN_EQUAL_SIGN;
169
170 token = g_scanner_get_next_token(scanner);
171 if (token != G_TOKEN_INT)
172 return G_TOKEN_INT;
173
174 *sunken = scanner->value.v_int;
175
176 return G_TOKEN_NONE;
177 }
178
179 static guint
theme_parse_progressbarstyle(GtkSettings * settings,GScanner * scanner,guint8 * progressbarstyle)180 theme_parse_progressbarstyle(GtkSettings *settings,
181 GScanner *scanner,
182 guint8 *progressbarstyle)
183 {
184 guint token;
185
186 /* Skip 'sunkenmenubar' */
187 token = g_scanner_get_next_token(scanner);
188
189 token = g_scanner_get_next_token(scanner);
190 if (token != G_TOKEN_EQUAL_SIGN)
191 return G_TOKEN_EQUAL_SIGN;
192
193 token = g_scanner_get_next_token(scanner);
194 if (token != G_TOKEN_INT)
195 return G_TOKEN_INT;
196
197 *progressbarstyle = scanner->value.v_int;
198
199 return G_TOKEN_NONE;
200 }
201
202 static guint
theme_parse_menubarstyle(GtkSettings * settings,GScanner * scanner,guint8 * menubarstyle)203 theme_parse_menubarstyle(GtkSettings *settings,
204 GScanner *scanner,
205 guint8 *menubarstyle)
206 {
207 guint token;
208
209 /* Skip 'menubarstyle' */
210 token = g_scanner_get_next_token(scanner);
211
212 token = g_scanner_get_next_token(scanner);
213 if (token != G_TOKEN_EQUAL_SIGN)
214 return G_TOKEN_EQUAL_SIGN;
215
216 token = g_scanner_get_next_token(scanner);
217 if (token != G_TOKEN_INT)
218 return G_TOKEN_INT;
219
220 *menubarstyle = scanner->value.v_int;
221
222 return G_TOKEN_NONE;
223 }
224
225 static guint
theme_parse_menuitemstyle(GtkSettings * settings,GScanner * scanner,guint8 * menuitemstyle)226 theme_parse_menuitemstyle(GtkSettings *settings,
227 GScanner *scanner,
228 guint8 *menuitemstyle)
229 {
230 guint token;
231
232 /* Skip 'sunkenmenubar' */
233 token = g_scanner_get_next_token(scanner);
234
235 token = g_scanner_get_next_token(scanner);
236 if (token != G_TOKEN_EQUAL_SIGN)
237 return G_TOKEN_EQUAL_SIGN;
238
239 token = g_scanner_get_next_token(scanner);
240 if (token != G_TOKEN_INT)
241 return G_TOKEN_INT;
242
243 *menuitemstyle = scanner->value.v_int;
244
245 return G_TOKEN_NONE;
246 }
247
248 static guint
theme_parse_listviewitemstyle(GtkSettings * settings,GScanner * scanner,guint8 * listviewitemstyle)249 theme_parse_listviewitemstyle(GtkSettings *settings,
250 GScanner *scanner,
251 guint8 *listviewitemstyle)
252 {
253 guint token;
254
255 token = g_scanner_get_next_token(scanner);
256
257 token = g_scanner_get_next_token(scanner);
258
259 if (token != G_TOKEN_EQUAL_SIGN)
260 return G_TOKEN_EQUAL_SIGN;
261
262 token = g_scanner_get_next_token(scanner);
263 if (token != G_TOKEN_INT)
264 return G_TOKEN_INT;
265
266 *listviewitemstyle = scanner->value.v_int;
267
268 return G_TOKEN_NONE;
269 }
270
271 static guint
clearlooks_rc_style_parse(GtkRcStyle * rc_style,GtkSettings * settings,GScanner * scanner)272 clearlooks_rc_style_parse (GtkRcStyle *rc_style,
273 GtkSettings *settings,
274 GScanner *scanner)
275
276 {
277 static GQuark scope_id = 0;
278 ClearlooksRcStyle *clearlooks_style = CLEARLOOKS_RC_STYLE (rc_style);
279
280 guint old_scope;
281 guint token;
282 guint i;
283
284 /* Set up a new scope in this scanner. */
285
286 if (!scope_id)
287 scope_id = g_quark_from_string("clearlooks_theme_engine");
288
289 /* If we bail out due to errors, we *don't* reset the scope, so the
290 * error messaging code can make sense of our tokens.
291 */
292 old_scope = g_scanner_set_scope(scanner, scope_id);
293
294 /* Now check if we already added our symbols to this scope
295 * (in some previous call to clearlooks_rc_style_parse for the
296 * same scanner.
297 */
298
299 if (!g_scanner_lookup_symbol(scanner, theme_symbols[0].name))
300 {
301 g_scanner_freeze_symbol_table(scanner);
302 for (i = 0; i < G_N_ELEMENTS (theme_symbols); i++)
303 g_scanner_scope_add_symbol(scanner, scope_id,
304 theme_symbols[i].name,
305 GINT_TO_POINTER(theme_symbols[i].token));
306 g_scanner_thaw_symbol_table(scanner);
307 }
308
309 /* We're ready to go, now parse the top level */
310
311 token = g_scanner_peek_next_token(scanner);
312 while (token != G_TOKEN_RIGHT_CURLY)
313 {
314 switch (token)
315 {
316 case TOKEN_SPOTCOLOR:
317 token = theme_parse_color(settings, scanner, &clearlooks_style->spot_color);
318 clearlooks_style->has_spot_color = TRUE;
319 break;
320 case TOKEN_CONTRAST:
321 token = theme_parse_contrast(settings, scanner, &clearlooks_style->contrast);
322 break;
323 case TOKEN_SUNKENMENU:
324 token = theme_parse_sunkenmenubar(settings, scanner, &clearlooks_style->sunkenmenubar);
325 break;
326 case TOKEN_PROGRESSBARSTYLE:
327 token = theme_parse_progressbarstyle(settings, scanner, &clearlooks_style->progressbarstyle);
328 break;
329 case TOKEN_MENUBARSTYLE:
330 token = theme_parse_menubarstyle(settings, scanner, &clearlooks_style->menubarstyle);
331 break;
332 case TOKEN_MENUITEMSTYLE:
333 token = theme_parse_menuitemstyle(settings, scanner, &clearlooks_style->menuitemstyle);
334 break;
335 case TOKEN_LISTVIEWITEMSTYLE:
336 token = theme_parse_listviewitemstyle(settings, scanner, &clearlooks_style->listviewitemstyle);
337 break;
338 default:
339 g_scanner_get_next_token(scanner);
340 token = G_TOKEN_RIGHT_CURLY;
341 break;
342 }
343
344 if (token != G_TOKEN_NONE)
345 return token;
346
347 token = g_scanner_peek_next_token(scanner);
348 }
349
350 g_scanner_get_next_token(scanner);
351
352 g_scanner_set_scope(scanner, old_scope);
353
354 return G_TOKEN_NONE;
355 }
356
357 static void
clearlooks_rc_style_merge(GtkRcStyle * dest,GtkRcStyle * src)358 clearlooks_rc_style_merge (GtkRcStyle *dest,
359 GtkRcStyle *src)
360 {
361 ClearlooksRcStyle *dest_w, *src_w;
362
363 parent_class->merge (dest, src);
364
365 if (!CLEARLOOKS_IS_RC_STYLE (src))
366 return;
367
368 src_w = CLEARLOOKS_RC_STYLE (src);
369 dest_w = CLEARLOOKS_RC_STYLE (dest);
370
371 dest_w->contrast = src_w->contrast;
372 dest_w->sunkenmenubar = src_w->sunkenmenubar;
373 dest_w->progressbarstyle = src_w->progressbarstyle;
374 dest_w->menubarstyle = src_w->menubarstyle;
375 dest_w->menuitemstyle = src_w->menuitemstyle;
376 dest_w->listviewitemstyle = src_w->listviewitemstyle;
377
378 if (src_w->has_spot_color)
379 {
380 dest_w->has_spot_color = TRUE;
381 dest_w->spot_color = src_w->spot_color;
382 }
383 }
384
385
386 /* Create an empty style suitable to this RC style
387 */
388 static GtkStyle *
clearlooks_rc_style_create_style(GtkRcStyle * rc_style)389 clearlooks_rc_style_create_style (GtkRcStyle *rc_style)
390 {
391 return GTK_STYLE (g_object_new (CLEARLOOKS_TYPE_STYLE, NULL));
392 }
393