1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1 |
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
2 |
||
3 |
/* Metacity theme parsing */
|
|
4 |
||
5 |
/*
|
|
6 |
* Copyright (C) 2001 Havoc Pennington
|
|
7 |
*
|
|
8 |
* This program is free software; you can redistribute it and/or
|
|
9 |
* modify it under the terms of the GNU General Public License as
|
|
10 |
* published by the Free Software Foundation; either version 2 of the
|
|
11 |
* License, or (at your option) any later version.
|
|
12 |
*
|
|
13 |
* This program is distributed in the hope that it will be useful, but
|
|
14 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
16 |
* General Public License for more details.
|
|
17 |
*
|
|
18 |
* You should have received a copy of the GNU General Public License
|
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
19 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
20 |
*/
|
21 |
||
22 |
#include <config.h> |
|
23 |
#include "theme-parser.h" |
|
24 |
#include "util.h" |
|
25 |
#include <string.h> |
|
26 |
#include <stdlib.h> |
|
27 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
28 |
/* We were intending to put the version number
|
29 |
* in the subdirectory name, but we ended up
|
|
30 |
* using the filename instead. The "-1" survives
|
|
31 |
* as a fossil.
|
|
32 |
*/
|
|
33 |
#define THEME_SUBDIR "metacity-1"
|
|
34 |
||
35 |
/* Highest version of the theme format to
|
|
36 |
* look out for.
|
|
37 |
*/
|
|
38 |
#define THEME_MAJOR_VERSION 3
|
|
39 |
#define THEME_MINOR_VERSION 5
|
|
40 |
#define THEME_VERSION (1000 * THEME_MAJOR_VERSION + THEME_MINOR_VERSION)
|
|
41 |
||
42 |
#define METACITY_THEME_FILENAME_FORMAT "metacity-theme-%d.xml"
|
|
43 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
44 |
typedef enum |
45 |
{
|
|
46 |
STATE_START, |
|
47 |
STATE_THEME, |
|
48 |
/* info section */
|
|
49 |
STATE_INFO, |
|
50 |
STATE_NAME, |
|
51 |
STATE_AUTHOR, |
|
52 |
STATE_COPYRIGHT, |
|
53 |
STATE_DATE, |
|
54 |
STATE_DESCRIPTION, |
|
55 |
/* constants */
|
|
56 |
STATE_CONSTANT, |
|
57 |
/* geometry */
|
|
58 |
STATE_FRAME_GEOMETRY, |
|
59 |
STATE_DISTANCE, |
|
60 |
STATE_BORDER, |
|
61 |
STATE_ASPECT_RATIO, |
|
62 |
/* draw ops */
|
|
63 |
STATE_DRAW_OPS, |
|
64 |
STATE_LINE, |
|
65 |
STATE_RECTANGLE, |
|
66 |
STATE_ARC, |
|
67 |
STATE_CLIP, |
|
68 |
STATE_TINT, |
|
69 |
STATE_GRADIENT, |
|
70 |
STATE_IMAGE, |
|
71 |
STATE_GTK_ARROW, |
|
72 |
STATE_GTK_BOX, |
|
73 |
STATE_GTK_VLINE, |
|
74 |
STATE_ICON, |
|
75 |
STATE_TITLE, |
|
76 |
STATE_INCLUDE, /* include another draw op list */ |
|
77 |
STATE_TILE, /* tile another draw op list */ |
|
78 |
/* sub-parts of gradient */
|
|
79 |
STATE_COLOR, |
|
80 |
/* frame style */
|
|
81 |
STATE_FRAME_STYLE, |
|
82 |
STATE_PIECE, |
|
83 |
STATE_BUTTON, |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
84 |
STATE_SHADOW, |
85 |
STATE_PADDING, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
86 |
/* style set */
|
87 |
STATE_FRAME_STYLE_SET, |
|
88 |
STATE_FRAME, |
|
89 |
/* assigning style sets to windows */
|
|
90 |
STATE_WINDOW, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
91 |
/* things we don't use any more but we can still parse: */
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
92 |
STATE_MENU_ICON, |
93 |
STATE_FALLBACK
|
|
94 |
} ParseState; |
|
95 |
||
96 |
typedef struct |
|
97 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
98 |
/* This two lists contain stacks of state and required version
|
99 |
* (cast to pointers.) There is one list item for each currently
|
|
100 |
* open element. */
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
101 |
GSList *states; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
102 |
GSList *required_versions; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
103 |
|
104 |
const char *theme_name; /* name of theme (directory it's in) */ |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
105 |
const char *theme_file; /* theme filename */ |
106 |
const char *theme_dir; /* dir the theme is inside */ |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
107 |
MetaTheme *theme; /* theme being parsed */ |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
108 |
guint format_version; /* version of format of theme file */ |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
109 |
char *name; /* name of named thing being parsed */ |
110 |
MetaFrameLayout *layout; /* layout being parsed if any */ |
|
111 |
MetaDrawOpList *op_list; /* op list being parsed if any */ |
|
112 |
MetaDrawOp *op; /* op being parsed if any */ |
|
113 |
MetaFrameStyle *style; /* frame style being parsed if any */ |
|
114 |
MetaFrameStyleSet *style_set; /* frame style set being parsed if any */ |
|
115 |
MetaFramePiece piece; /* position of piece being parsed */ |
|
116 |
MetaButtonType button_type; /* type of button/menuitem being parsed */ |
|
117 |
MetaButtonState button_state; /* state of button being parsed */ |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
118 |
int skip_level; /* depth of elements that we're ignoring */ |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
119 |
} ParseInfo; |
120 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
121 |
typedef enum { |
122 |
THEME_PARSE_ERROR_TOO_OLD, |
|
123 |
THEME_PARSE_ERROR_TOO_FAILED
|
|
124 |
} ThemeParseError; |
|
125 |
||
126 |
static GQuark |
|
127 |
theme_parse_error_quark (void) |
|
128 |
{
|
|
129 |
return g_quark_from_static_string ("theme-parse-error-quark"); |
|
130 |
}
|
|
131 |
||
132 |
#define THEME_PARSE_ERROR (theme_parse_error_quark ())
|
|
133 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
134 |
static void set_error (GError **err, |
135 |
GMarkupParseContext *context, |
|
136 |
int error_domain, |
|
137 |
int error_code, |
|
138 |
const char *format, |
|
139 |
...) G_GNUC_PRINTF (5, 6); |
|
140 |
||
141 |
static void add_context_to_error (GError **err, |
|
142 |
GMarkupParseContext *context); |
|
143 |
||
144 |
static void parse_info_init (ParseInfo *info); |
|
145 |
static void parse_info_free (ParseInfo *info); |
|
146 |
||
147 |
static void push_state (ParseInfo *info, |
|
148 |
ParseState state); |
|
149 |
static void pop_state (ParseInfo *info); |
|
150 |
static ParseState peek_state (ParseInfo *info); |
|
151 |
||
152 |
||
153 |
static void parse_toplevel_element (GMarkupParseContext *context, |
|
154 |
const gchar *element_name, |
|
155 |
const gchar **attribute_names, |
|
156 |
const gchar **attribute_values, |
|
157 |
ParseInfo *info, |
|
158 |
GError **error); |
|
159 |
static void parse_info_element (GMarkupParseContext *context, |
|
160 |
const gchar *element_name, |
|
161 |
const gchar **attribute_names, |
|
162 |
const gchar **attribute_values, |
|
163 |
ParseInfo *info, |
|
164 |
GError **error); |
|
165 |
static void parse_geometry_element (GMarkupParseContext *context, |
|
166 |
const gchar *element_name, |
|
167 |
const gchar **attribute_names, |
|
168 |
const gchar **attribute_values, |
|
169 |
ParseInfo *info, |
|
170 |
GError **error); |
|
171 |
static void parse_draw_op_element (GMarkupParseContext *context, |
|
172 |
const gchar *element_name, |
|
173 |
const gchar **attribute_names, |
|
174 |
const gchar **attribute_values, |
|
175 |
ParseInfo *info, |
|
176 |
GError **error); |
|
177 |
static void parse_gradient_element (GMarkupParseContext *context, |
|
178 |
const gchar *element_name, |
|
179 |
const gchar **attribute_names, |
|
180 |
const gchar **attribute_values, |
|
181 |
ParseInfo *info, |
|
182 |
GError **error); |
|
183 |
static void parse_style_element (GMarkupParseContext *context, |
|
184 |
const gchar *element_name, |
|
185 |
const gchar **attribute_names, |
|
186 |
const gchar **attribute_values, |
|
187 |
ParseInfo *info, |
|
188 |
GError **error); |
|
189 |
static void parse_style_set_element (GMarkupParseContext *context, |
|
190 |
const gchar *element_name, |
|
191 |
const gchar **attribute_names, |
|
192 |
const gchar **attribute_values, |
|
193 |
ParseInfo *info, |
|
194 |
GError **error); |
|
195 |
||
196 |
static void parse_piece_element (GMarkupParseContext *context, |
|
197 |
const gchar *element_name, |
|
198 |
const gchar **attribute_names, |
|
199 |
const gchar **attribute_values, |
|
200 |
ParseInfo *info, |
|
201 |
GError **error); |
|
202 |
||
203 |
static void parse_button_element (GMarkupParseContext *context, |
|
204 |
const gchar *element_name, |
|
205 |
const gchar **attribute_names, |
|
206 |
const gchar **attribute_values, |
|
207 |
ParseInfo *info, |
|
208 |
GError **error); |
|
209 |
||
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
210 |
static void parse_shadow_element (GMarkupParseContext *context, |
211 |
const gchar *element_name, |
|
212 |
const gchar **attribute_names, |
|
213 |
const gchar **attribute_values, |
|
214 |
ParseInfo *info, |
|
215 |
GError **error); |
|
216 |
||
217 |
static void parse_padding_element (GMarkupParseContext *context, |
|
218 |
const gchar *element_name, |
|
219 |
const gchar **attribute_names, |
|
220 |
const gchar **attribute_values, |
|
221 |
ParseInfo *info, |
|
222 |
GError **error); |
|
223 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
224 |
static void parse_menu_icon_element (GMarkupParseContext *context, |
225 |
const gchar *element_name, |
|
226 |
const gchar **attribute_names, |
|
227 |
const gchar **attribute_values, |
|
228 |
ParseInfo *info, |
|
229 |
GError **error); |
|
230 |
||
231 |
static void start_element_handler (GMarkupParseContext *context, |
|
232 |
const gchar *element_name, |
|
233 |
const gchar **attribute_names, |
|
234 |
const gchar **attribute_values, |
|
235 |
gpointer user_data, |
|
236 |
GError **error); |
|
237 |
static void end_element_handler (GMarkupParseContext *context, |
|
238 |
const gchar *element_name, |
|
239 |
gpointer user_data, |
|
240 |
GError **error); |
|
241 |
static void text_handler (GMarkupParseContext *context, |
|
242 |
const gchar *text, |
|
243 |
gsize text_len, |
|
244 |
gpointer user_data, |
|
245 |
GError **error); |
|
246 |
||
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
247 |
/* Translators: This means that an attribute which should have been found
|
248 |
* on an XML element was not in fact found.
|
|
249 |
*/
|
|
250 |
#define ATTRIBUTE_NOT_FOUND _("No \"%s\" attribute on element <%s>")
|
|
251 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
252 |
static GMarkupParser metacity_theme_parser = { |
253 |
start_element_handler, |
|
254 |
end_element_handler, |
|
255 |
text_handler, |
|
256 |
NULL, |
|
257 |
NULL
|
|
258 |
};
|
|
259 |
||
260 |
static void |
|
261 |
set_error (GError **err, |
|
262 |
GMarkupParseContext *context, |
|
263 |
int error_domain, |
|
264 |
int error_code, |
|
265 |
const char *format, |
|
266 |
...)
|
|
267 |
{
|
|
268 |
int line, ch; |
|
269 |
va_list args; |
|
270 |
char *str; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
271 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
272 |
g_markup_parse_context_get_position (context, &line, &ch); |
273 |
||
274 |
va_start (args, format); |
|
275 |
str = g_strdup_vprintf (format, args); |
|
276 |
va_end (args); |
|
277 |
||
278 |
g_set_error (err, error_domain, error_code, |
|
279 |
_("Line %d character %d: %s"), |
|
280 |
line, ch, str); |
|
281 |
||
282 |
g_free (str); |
|
283 |
}
|
|
284 |
||
285 |
static void |
|
286 |
add_context_to_error (GError **err, |
|
287 |
GMarkupParseContext *context) |
|
288 |
{
|
|
289 |
int line, ch; |
|
290 |
char *str; |
|
291 |
||
292 |
if (err == NULL || *err == NULL) |
|
293 |
return; |
|
294 |
||
295 |
g_markup_parse_context_get_position (context, &line, &ch); |
|
296 |
||
297 |
str = g_strdup_printf (_("Line %d character %d: %s"), |
|
298 |
line, ch, (*err)->message); |
|
299 |
g_free ((*err)->message); |
|
300 |
(*err)->message = str; |
|
301 |
}
|
|
302 |
||
303 |
static void |
|
304 |
parse_info_init (ParseInfo *info) |
|
305 |
{
|
|
306 |
info->theme_file = NULL; |
|
307 |
info->states = g_slist_prepend (NULL, GINT_TO_POINTER (STATE_START)); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
308 |
info->required_versions = NULL; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
309 |
info->theme = NULL; |
310 |
info->name = NULL; |
|
311 |
info->layout = NULL; |
|
312 |
info->op_list = NULL; |
|
313 |
info->op = NULL; |
|
314 |
info->style = NULL; |
|
315 |
info->style_set = NULL; |
|
316 |
info->piece = META_FRAME_PIECE_LAST; |
|
317 |
info->button_type = META_BUTTON_TYPE_LAST; |
|
318 |
info->button_state = META_BUTTON_STATE_LAST; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
319 |
info->skip_level = 0; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
320 |
}
|
321 |
||
322 |
static void |
|
323 |
parse_info_free (ParseInfo *info) |
|
324 |
{
|
|
325 |
g_slist_free (info->states); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
326 |
g_slist_free (info->required_versions); |
327 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
328 |
if (info->theme) |
329 |
meta_theme_free (info->theme); |
|
330 |
||
331 |
if (info->layout) |
|
332 |
meta_frame_layout_unref (info->layout); |
|
333 |
||
334 |
if (info->op_list) |
|
335 |
meta_draw_op_list_unref (info->op_list); |
|
336 |
||
337 |
if (info->op) |
|
338 |
meta_draw_op_free (info->op); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
339 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
340 |
if (info->style) |
341 |
meta_frame_style_unref (info->style); |
|
342 |
||
343 |
if (info->style_set) |
|
344 |
meta_frame_style_set_unref (info->style_set); |
|
345 |
}
|
|
346 |
||
347 |
static void |
|
348 |
push_state (ParseInfo *info, |
|
349 |
ParseState state) |
|
350 |
{
|
|
351 |
info->states = g_slist_prepend (info->states, GINT_TO_POINTER (state)); |
|
352 |
}
|
|
353 |
||
354 |
static void |
|
355 |
pop_state (ParseInfo *info) |
|
356 |
{
|
|
357 |
g_return_if_fail (info->states != NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
358 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
359 |
info->states = g_slist_remove (info->states, info->states->data); |
360 |
}
|
|
361 |
||
362 |
static ParseState |
|
363 |
peek_state (ParseInfo *info) |
|
364 |
{
|
|
365 |
g_return_val_if_fail (info->states != NULL, STATE_START); |
|
366 |
||
367 |
return GPOINTER_TO_INT (info->states->data); |
|
368 |
}
|
|
369 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
370 |
static void |
371 |
push_required_version (ParseInfo *info, |
|
372 |
int version) |
|
373 |
{
|
|
374 |
info->required_versions = g_slist_prepend (info->required_versions, |
|
375 |
GINT_TO_POINTER (version)); |
|
376 |
}
|
|
377 |
||
378 |
static void |
|
379 |
pop_required_version (ParseInfo *info) |
|
380 |
{
|
|
381 |
g_return_if_fail (info->required_versions != NULL); |
|
382 |
||
383 |
info->required_versions = g_slist_delete_link (info->required_versions, info->required_versions); |
|
384 |
}
|
|
385 |
||
386 |
static int |
|
387 |
peek_required_version (ParseInfo *info) |
|
388 |
{
|
|
389 |
if (info->required_versions) |
|
390 |
return GPOINTER_TO_INT (info->required_versions->data); |
|
391 |
else
|
|
392 |
return info->format_version; |
|
393 |
}
|
|
394 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
395 |
#define ELEMENT_IS(name) (strcmp (element_name, (name)) == 0)
|
396 |
||
397 |
typedef struct |
|
398 |
{
|
|
399 |
const char *name; |
|
400 |
const char **retloc; |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
401 |
gboolean required; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
402 |
} LocateAttr; |
403 |
||
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
404 |
/* Attribute names can have a leading '!' to indicate that they are
|
405 |
* required.
|
|
406 |
*/
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
407 |
static gboolean |
408 |
locate_attributes (GMarkupParseContext *context, |
|
409 |
const char *element_name, |
|
410 |
const char **attribute_names, |
|
411 |
const char **attribute_values, |
|
412 |
GError **error, |
|
413 |
const char *first_attribute_name, |
|
414 |
const char **first_attribute_retloc, |
|
415 |
...)
|
|
416 |
{
|
|
417 |
va_list args; |
|
418 |
const char *name; |
|
419 |
const char **retloc; |
|
420 |
int n_attrs; |
|
421 |
#define MAX_ATTRS 24
|
|
422 |
LocateAttr attrs[MAX_ATTRS]; |
|
423 |
gboolean retval; |
|
424 |
int i; |
|
425 |
||
426 |
g_return_val_if_fail (first_attribute_name != NULL, FALSE); |
|
427 |
g_return_val_if_fail (first_attribute_retloc != NULL, FALSE); |
|
428 |
||
429 |
retval = TRUE; |
|
430 |
||
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
431 |
/* FIXME: duplicated code; refactor loop */
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
432 |
n_attrs = 1; |
433 |
attrs[0].name = first_attribute_name; |
|
434 |
attrs[0].retloc = first_attribute_retloc; |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
435 |
attrs[0].required = attrs[0].name[0]=='!'; |
436 |
if (attrs[0].required) |
|
437 |
attrs[0].name++; /* skip past it */ |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
438 |
*first_attribute_retloc = NULL; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
439 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
440 |
va_start (args, first_attribute_retloc); |
441 |
||
442 |
name = va_arg (args, const char*); |
|
443 |
retloc = va_arg (args, const char**); |
|
444 |
||
445 |
while (name != NULL) |
|
446 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
447 |
if (retloc == NULL) |
448 |
{
|
|
449 |
retval = FALSE; |
|
450 |
goto out; |
|
451 |
}
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
452 |
|
453 |
g_assert (n_attrs < MAX_ATTRS); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
454 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
455 |
attrs[n_attrs].name = name; |
456 |
attrs[n_attrs].retloc = retloc; |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
457 |
attrs[n_attrs].required = attrs[n_attrs].name[0]=='!'; |
458 |
if (attrs[n_attrs].required) |
|
459 |
attrs[n_attrs].name++; /* skip past it */ |
|
460 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
461 |
n_attrs += 1; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
462 |
*retloc = NULL; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
463 |
|
464 |
name = va_arg (args, const char*); |
|
465 |
retloc = va_arg (args, const char**); |
|
466 |
}
|
|
467 |
||
468 |
va_end (args); |
|
469 |
||
470 |
i = 0; |
|
471 |
while (attribute_names[i]) |
|
472 |
{
|
|
473 |
int j; |
|
474 |
gboolean found; |
|
475 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
476 |
/* Can be present anywhere */
|
477 |
if (strcmp (attribute_names[i], "version") == 0) |
|
478 |
{
|
|
479 |
++i; |
|
480 |
continue; |
|
481 |
}
|
|
482 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
483 |
found = FALSE; |
484 |
j = 0; |
|
485 |
while (j < n_attrs) |
|
486 |
{
|
|
487 |
if (strcmp (attrs[j].name, attribute_names[i]) == 0) |
|
488 |
{
|
|
489 |
retloc = attrs[j].retloc; |
|
490 |
||
491 |
if (*retloc != NULL) |
|
492 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
493 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
494 |
set_error (error, context, |
495 |
G_MARKUP_ERROR, |
|
496 |
G_MARKUP_ERROR_PARSE, |
|
497 |
_("Attribute \"%s\" repeated twice on the same <%s> element"), |
|
498 |
attrs[j].name, element_name); |
|
499 |
retval = FALSE; |
|
500 |
goto out; |
|
501 |
}
|
|
502 |
||
503 |
*retloc = attribute_values[i]; |
|
504 |
found = TRUE; |
|
505 |
}
|
|
506 |
||
507 |
++j; |
|
508 |
}
|
|
509 |
||
510 |
if (!found) |
|
511 |
{
|
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
512 |
j = 0; |
513 |
while (j < n_attrs) |
|
514 |
{
|
|
515 |
g_warning ("It could have been %s.\n", attrs[j++].name); |
|
516 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
517 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
518 |
set_error (error, context, |
519 |
G_MARKUP_ERROR, |
|
520 |
G_MARKUP_ERROR_PARSE, |
|
521 |
_("Attribute \"%s\" is invalid on <%s> element in this context"), |
|
522 |
attribute_names[i], element_name); |
|
523 |
retval = FALSE; |
|
524 |
goto out; |
|
525 |
}
|
|
526 |
||
527 |
++i; |
|
528 |
}
|
|
529 |
||
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
530 |
/* Did we catch them all? */
|
531 |
i = 0; |
|
532 |
while (i < n_attrs) |
|
533 |
{
|
|
534 |
if (attrs[i].required && *(attrs[i].retloc)==NULL) |
|
535 |
{
|
|
536 |
set_error (error, context, |
|
537 |
G_MARKUP_ERROR, |
|
538 |
G_MARKUP_ERROR_PARSE, |
|
539 |
ATTRIBUTE_NOT_FOUND, |
|
540 |
attrs[i].name, element_name); |
|
541 |
retval = FALSE; |
|
542 |
goto out; |
|
543 |
}
|
|
544 |
||
545 |
++i; |
|
546 |
}
|
|
547 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
548 |
out: |
549 |
return retval; |
|
550 |
}
|
|
551 |
||
552 |
static gboolean |
|
553 |
check_no_attributes (GMarkupParseContext *context, |
|
554 |
const char *element_name, |
|
555 |
const char **attribute_names, |
|
556 |
const char **attribute_values, |
|
557 |
GError **error) |
|
558 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
559 |
int i = 0; |
560 |
||
561 |
/* Can be present anywhere */
|
|
562 |
if (attribute_names[0] && strcmp (attribute_names[i], "version") == 0) |
|
563 |
i++; |
|
564 |
||
565 |
if (attribute_names[i] != NULL) |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
566 |
{
|
567 |
set_error (error, context, |
|
568 |
G_MARKUP_ERROR, |
|
569 |
G_MARKUP_ERROR_PARSE, |
|
570 |
_("Attribute \"%s\" is invalid on <%s> element in this context"), |
|
571 |
attribute_names[0], element_name); |
|
572 |
return FALSE; |
|
573 |
}
|
|
574 |
||
575 |
return TRUE; |
|
576 |
}
|
|
577 |
||
578 |
#define MAX_REASONABLE 4096
|
|
579 |
static gboolean |
|
580 |
parse_positive_integer (const char *str, |
|
581 |
int *val, |
|
582 |
GMarkupParseContext *context, |
|
583 |
MetaTheme *theme, |
|
584 |
GError **error) |
|
585 |
{
|
|
586 |
char *end; |
|
587 |
long l; |
|
588 |
int j; |
|
589 |
||
590 |
*val = 0; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
591 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
592 |
end = NULL; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
593 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
594 |
/* Is str a constant? */
|
595 |
||
596 |
if (META_THEME_ALLOWS (theme, META_THEME_UBIQUITOUS_CONSTANTS) && |
|
597 |
meta_theme_lookup_int_constant (theme, str, &j)) |
|
598 |
{
|
|
599 |
/* Yes. */
|
|
600 |
l = j; |
|
601 |
}
|
|
602 |
else
|
|
603 |
{
|
|
604 |
/* No. Let's try parsing it instead. */
|
|
605 |
||
606 |
l = strtol (str, &end, 10); |
|
607 |
||
608 |
if (end == NULL || end == str) |
|
609 |
{
|
|
610 |
set_error (error, context, G_MARKUP_ERROR, |
|
611 |
G_MARKUP_ERROR_PARSE, |
|
612 |
_("Could not parse \"%s\" as an integer"), |
|
613 |
str); |
|
614 |
return FALSE; |
|
615 |
}
|
|
616 |
||
617 |
if (*end != '\0') |
|
618 |
{
|
|
619 |
set_error (error, context, G_MARKUP_ERROR, |
|
620 |
G_MARKUP_ERROR_PARSE, |
|
621 |
_("Did not understand trailing characters \"%s\" in string \"%s\""), |
|
622 |
end, str); |
|
623 |
return FALSE; |
|
624 |
}
|
|
625 |
}
|
|
626 |
||
627 |
if (l < 0) |
|
628 |
{
|
|
629 |
set_error (error, context, G_MARKUP_ERROR, |
|
630 |
G_MARKUP_ERROR_PARSE, |
|
631 |
_("Integer %ld must be positive"), l); |
|
632 |
return FALSE; |
|
633 |
}
|
|
634 |
||
635 |
if (l > MAX_REASONABLE) |
|
636 |
{
|
|
637 |
set_error (error, context, G_MARKUP_ERROR, |
|
638 |
G_MARKUP_ERROR_PARSE, |
|
639 |
_("Integer %ld is too large, current max is %d"), |
|
640 |
l, MAX_REASONABLE); |
|
641 |
return FALSE; |
|
642 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
643 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
644 |
*val = (int) l; |
645 |
||
646 |
return TRUE; |
|
647 |
}
|
|
648 |
||
649 |
static gboolean |
|
650 |
parse_double (const char *str, |
|
651 |
double *val, |
|
652 |
GMarkupParseContext *context, |
|
653 |
GError **error) |
|
654 |
{
|
|
655 |
char *end; |
|
656 |
||
657 |
*val = 0; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
658 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
659 |
end = NULL; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
660 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
661 |
*val = g_ascii_strtod (str, &end); |
662 |
||
663 |
if (end == NULL || end == str) |
|
664 |
{
|
|
665 |
set_error (error, context, G_MARKUP_ERROR, |
|
666 |
G_MARKUP_ERROR_PARSE, |
|
667 |
_("Could not parse \"%s\" as a floating point number"), |
|
668 |
str); |
|
669 |
return FALSE; |
|
670 |
}
|
|
671 |
||
672 |
if (*end != '\0') |
|
673 |
{
|
|
674 |
set_error (error, context, G_MARKUP_ERROR, |
|
675 |
G_MARKUP_ERROR_PARSE, |
|
676 |
_("Did not understand trailing characters \"%s\" in string \"%s\""), |
|
677 |
end, str); |
|
678 |
return FALSE; |
|
679 |
}
|
|
680 |
||
681 |
return TRUE; |
|
682 |
}
|
|
683 |
||
684 |
static gboolean |
|
685 |
parse_boolean (const char *str, |
|
686 |
gboolean *val, |
|
687 |
GMarkupParseContext *context, |
|
688 |
GError **error) |
|
689 |
{
|
|
690 |
if (strcmp ("true", str) == 0) |
|
691 |
*val = TRUE; |
|
692 |
else if (strcmp ("false", str) == 0) |
|
693 |
*val = FALSE; |
|
694 |
else
|
|
695 |
{
|
|
696 |
set_error (error, context, G_MARKUP_ERROR, |
|
697 |
G_MARKUP_ERROR_PARSE, |
|
698 |
_("Boolean values must be \"true\" or \"false\" not \"%s\""), |
|
699 |
str); |
|
700 |
return FALSE; |
|
701 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
702 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
703 |
return TRUE; |
704 |
}
|
|
705 |
||
706 |
static gboolean |
|
707 |
parse_rounding (const char *str, |
|
708 |
guint *val, |
|
709 |
GMarkupParseContext *context, |
|
710 |
MetaTheme *theme, |
|
711 |
GError **error) |
|
712 |
{
|
|
713 |
if (strcmp ("true", str) == 0) |
|
714 |
*val = 5; /* historical "true" value */ |
|
715 |
else if (strcmp ("false", str) == 0) |
|
716 |
*val = 0; |
|
717 |
else
|
|
718 |
{
|
|
719 |
int tmp; |
|
720 |
gboolean result; |
|
721 |
if (!META_THEME_ALLOWS (theme, META_THEME_VARIED_ROUND_CORNERS)) |
|
722 |
{
|
|
723 |
/* Not known in this version, so bail. */
|
|
724 |
set_error (error, context, G_MARKUP_ERROR, |
|
725 |
G_MARKUP_ERROR_PARSE, |
|
726 |
_("Boolean values must be \"true\" or \"false\" not \"%s\""), |
|
727 |
str); |
|
728 |
return FALSE; |
|
729 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
730 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
731 |
result = parse_positive_integer (str, &tmp, context, theme, error); |
732 |
||
733 |
*val = tmp; |
|
734 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
735 |
return result; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
736 |
}
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
737 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
738 |
return TRUE; |
739 |
}
|
|
740 |
||
741 |
static gboolean |
|
742 |
parse_angle (const char *str, |
|
743 |
double *val, |
|
744 |
GMarkupParseContext *context, |
|
745 |
GError **error) |
|
746 |
{
|
|
747 |
if (!parse_double (str, val, context, error)) |
|
748 |
return FALSE; |
|
749 |
||
750 |
if (*val < (0.0 - 1e6) || *val > (360.0 + 1e6)) |
|
751 |
{
|
|
752 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
753 |
_("Angle must be between 0.0 and 360.0, was %g\n"), |
|
754 |
*val); |
|
755 |
return FALSE; |
|
756 |
}
|
|
757 |
||
758 |
return TRUE; |
|
759 |
}
|
|
760 |
||
761 |
static gboolean |
|
762 |
parse_alpha (const char *str, |
|
763 |
MetaAlphaGradientSpec **spec_ret, |
|
764 |
GMarkupParseContext *context, |
|
765 |
GError **error) |
|
766 |
{
|
|
767 |
char **split; |
|
768 |
int i; |
|
769 |
int n_alphas; |
|
770 |
MetaAlphaGradientSpec *spec; |
|
771 |
||
772 |
*spec_ret = NULL; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
773 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
774 |
split = g_strsplit (str, ":", -1); |
775 |
||
776 |
i = 0; |
|
777 |
while (split[i]) |
|
778 |
++i; |
|
779 |
||
780 |
if (i == 0) |
|
781 |
{
|
|
782 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
783 |
_("Could not parse \"%s\" as a floating point number"), |
|
784 |
str); |
|
785 |
||
786 |
g_strfreev (split); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
787 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
788 |
return FALSE; |
789 |
}
|
|
790 |
||
791 |
n_alphas = i; |
|
792 |
||
793 |
/* FIXME allow specifying horizontal/vertical/diagonal in theme format,
|
|
794 |
* once we implement vertical/diagonal in gradient.c
|
|
795 |
*/
|
|
796 |
spec = meta_alpha_gradient_spec_new (META_GRADIENT_HORIZONTAL, |
|
797 |
n_alphas); |
|
798 |
||
799 |
i = 0; |
|
800 |
while (i < n_alphas) |
|
801 |
{
|
|
802 |
double v; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
803 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
804 |
if (!parse_double (split[i], &v, context, error)) |
805 |
{
|
|
806 |
/* clear up, but don't set error: it was set by parse_double */
|
|
807 |
g_strfreev (split); |
|
808 |
meta_alpha_gradient_spec_free (spec); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
809 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
810 |
return FALSE; |
811 |
}
|
|
812 |
||
813 |
if (v < (0.0 - 1e-6) || v > (1.0 + 1e-6)) |
|
814 |
{
|
|
815 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
816 |
_("Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"), |
|
817 |
v); |
|
818 |
||
819 |
g_strfreev (split); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
820 |
meta_alpha_gradient_spec_free (spec); |
821 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
822 |
return FALSE; |
823 |
}
|
|
824 |
||
825 |
spec->alphas[i] = (unsigned char) (v * 255); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
826 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
827 |
++i; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
828 |
}
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
829 |
|
830 |
g_strfreev (split); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
831 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
832 |
*spec_ret = spec; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
833 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
834 |
return TRUE; |
835 |
}
|
|
836 |
||
837 |
static MetaColorSpec* |
|
838 |
parse_color (MetaTheme *theme, |
|
839 |
const char *str, |
|
840 |
GError **err) |
|
841 |
{
|
|
842 |
char* referent; |
|
843 |
||
844 |
if (META_THEME_ALLOWS (theme, META_THEME_COLOR_CONSTANTS) && |
|
845 |
meta_theme_lookup_color_constant (theme, str, &referent)) |
|
846 |
{
|
|
847 |
if (referent) |
|
848 |
return meta_color_spec_new_from_string (referent, err); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
849 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
850 |
/* no need to free referent: it's a pointer into the actual hash table */
|
851 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
852 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
853 |
return meta_color_spec_new_from_string (str, err); |
854 |
}
|
|
855 |
||
856 |
static gboolean |
|
857 |
parse_title_scale (const char *str, |
|
858 |
double *val, |
|
859 |
GMarkupParseContext *context, |
|
860 |
GError **error) |
|
861 |
{
|
|
862 |
double factor; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
863 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
864 |
if (strcmp (str, "xx-small") == 0) |
865 |
factor = PANGO_SCALE_XX_SMALL; |
|
866 |
else if (strcmp (str, "x-small") == 0) |
|
867 |
factor = PANGO_SCALE_X_SMALL; |
|
868 |
else if (strcmp (str, "small") == 0) |
|
869 |
factor = PANGO_SCALE_SMALL; |
|
870 |
else if (strcmp (str, "medium") == 0) |
|
871 |
factor = PANGO_SCALE_MEDIUM; |
|
872 |
else if (strcmp (str, "large") == 0) |
|
873 |
factor = PANGO_SCALE_LARGE; |
|
874 |
else if (strcmp (str, "x-large") == 0) |
|
875 |
factor = PANGO_SCALE_X_LARGE; |
|
876 |
else if (strcmp (str, "xx-large") == 0) |
|
877 |
factor = PANGO_SCALE_XX_LARGE; |
|
878 |
else
|
|
879 |
{
|
|
880 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
881 |
_("Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,large,x-large,xx-large)\n"), |
|
882 |
str); |
|
883 |
return FALSE; |
|
884 |
}
|
|
885 |
||
886 |
*val = factor; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
887 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
888 |
return TRUE; |
889 |
}
|
|
890 |
||
891 |
static void |
|
892 |
parse_toplevel_element (GMarkupParseContext *context, |
|
893 |
const gchar *element_name, |
|
894 |
const gchar **attribute_names, |
|
895 |
const gchar **attribute_values, |
|
896 |
ParseInfo *info, |
|
897 |
GError **error) |
|
898 |
{
|
|
899 |
g_return_if_fail (peek_state (info) == STATE_THEME); |
|
900 |
||
901 |
if (ELEMENT_IS ("info")) |
|
902 |
{
|
|
903 |
if (!check_no_attributes (context, element_name, |
|
904 |
attribute_names, attribute_values, |
|
905 |
error)) |
|
906 |
return; |
|
907 |
||
908 |
push_state (info, STATE_INFO); |
|
909 |
}
|
|
910 |
else if (ELEMENT_IS ("constant")) |
|
911 |
{
|
|
912 |
const char *name; |
|
913 |
const char *value; |
|
914 |
int ival = 0; |
|
915 |
double dval = 0.0; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
916 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
917 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
918 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
919 |
"!name", &name, "!value", &value, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
920 |
NULL)) |
921 |
return; |
|
922 |
||
1.2.62
by Rico Tzschichholz
Import upstream version 2.34.0 |
923 |
/* We don't know how a a constant is going to be used, so we have guess its
|
924 |
* type from its contents:
|
|
925 |
*
|
|
926 |
* - Starts like a number and contains a '.': float constant
|
|
927 |
* - Starts like a number and doesn't contain a '.': int constant
|
|
928 |
* - Starts with anything else: a color constant.
|
|
929 |
* (colors always start with # or a letter)
|
|
930 |
*/
|
|
931 |
if (value[0] == '.' || value[0] == '+' || value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
932 |
{
|
1.2.62
by Rico Tzschichholz
Import upstream version 2.34.0 |
933 |
if (strchr (value, '.')) |
934 |
{
|
|
935 |
if (!parse_double (value, &dval, context, error)) |
|
936 |
return; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
937 |
|
1.2.62
by Rico Tzschichholz
Import upstream version 2.34.0 |
938 |
if (!meta_theme_define_float_constant (info->theme, |
939 |
name, |
|
940 |
dval, |
|
941 |
error)) |
|
942 |
{
|
|
943 |
add_context_to_error (error, context); |
|
944 |
return; |
|
945 |
}
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
946 |
}
|
1.2.62
by Rico Tzschichholz
Import upstream version 2.34.0 |
947 |
else
|
948 |
{
|
|
949 |
if (!parse_positive_integer (value, &ival, context, info->theme, error)) |
|
950 |
return; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
951 |
|
1.2.62
by Rico Tzschichholz
Import upstream version 2.34.0 |
952 |
if (!meta_theme_define_int_constant (info->theme, |
953 |
name, |
|
954 |
ival, |
|
955 |
error)) |
|
956 |
{
|
|
957 |
add_context_to_error (error, context); |
|
958 |
return; |
|
959 |
}
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
960 |
}
|
961 |
}
|
|
962 |
else
|
|
963 |
{
|
|
964 |
if (!meta_theme_define_color_constant (info->theme, |
|
965 |
name, |
|
966 |
value, |
|
967 |
error)) |
|
968 |
{
|
|
969 |
add_context_to_error (error, context); |
|
970 |
return; |
|
971 |
}
|
|
972 |
}
|
|
973 |
||
974 |
push_state (info, STATE_CONSTANT); |
|
975 |
}
|
|
976 |
else if (ELEMENT_IS ("frame_geometry")) |
|
977 |
{
|
|
978 |
const char *name = NULL; |
|
979 |
const char *parent = NULL; |
|
980 |
const char *has_title = NULL; |
|
981 |
const char *title_scale = NULL; |
|
982 |
const char *rounded_top_left = NULL; |
|
983 |
const char *rounded_top_right = NULL; |
|
984 |
const char *rounded_bottom_left = NULL; |
|
985 |
const char *rounded_bottom_right = NULL; |
|
986 |
const char *hide_buttons = NULL; |
|
987 |
gboolean has_title_val; |
|
988 |
guint rounded_top_left_val; |
|
989 |
guint rounded_top_right_val; |
|
990 |
guint rounded_bottom_left_val; |
|
991 |
guint rounded_bottom_right_val; |
|
992 |
gboolean hide_buttons_val; |
|
993 |
double title_scale_val; |
|
994 |
MetaFrameLayout *parent_layout; |
|
995 |
||
996 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
997 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
998 |
"!name", &name, "parent", &parent, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
999 |
"has_title", &has_title, "title_scale", &title_scale, |
1000 |
"rounded_top_left", &rounded_top_left, |
|
1001 |
"rounded_top_right", &rounded_top_right, |
|
1002 |
"rounded_bottom_left", &rounded_bottom_left, |
|
1003 |
"rounded_bottom_right", &rounded_bottom_right, |
|
1004 |
"hide_buttons", &hide_buttons, |
|
1005 |
NULL)) |
|
1006 |
return; |
|
1007 |
||
1008 |
has_title_val = TRUE; |
|
1009 |
if (has_title && !parse_boolean (has_title, &has_title_val, context, error)) |
|
1010 |
return; |
|
1011 |
||
1012 |
hide_buttons_val = FALSE; |
|
1013 |
if (hide_buttons && !parse_boolean (hide_buttons, &hide_buttons_val, context, error)) |
|
1014 |
return; |
|
1015 |
||
1016 |
rounded_top_left_val = 0; |
|
1017 |
rounded_top_right_val = 0; |
|
1018 |
rounded_bottom_left_val = 0; |
|
1019 |
rounded_bottom_right_val = 0; |
|
1020 |
||
1021 |
if (rounded_top_left && !parse_rounding (rounded_top_left, &rounded_top_left_val, context, info->theme, error)) |
|
1022 |
return; |
|
1023 |
if (rounded_top_right && !parse_rounding (rounded_top_right, &rounded_top_right_val, context, info->theme, error)) |
|
1024 |
return; |
|
1025 |
if (rounded_bottom_left && !parse_rounding (rounded_bottom_left, &rounded_bottom_left_val, context, info->theme, error)) |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1026 |
return; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1027 |
if (rounded_bottom_right && !parse_rounding (rounded_bottom_right, &rounded_bottom_right_val, context, info->theme, error)) |
1028 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1029 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1030 |
title_scale_val = 1.0; |
1031 |
if (title_scale && !parse_title_scale (title_scale, &title_scale_val, context, error)) |
|
1032 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1033 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1034 |
if (meta_theme_lookup_layout (info->theme, name)) |
1035 |
{
|
|
1036 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1037 |
_("<%s> name \"%s\" used a second time"), |
|
1038 |
element_name, name); |
|
1039 |
return; |
|
1040 |
}
|
|
1041 |
||
1042 |
parent_layout = NULL; |
|
1043 |
if (parent) |
|
1044 |
{
|
|
1045 |
parent_layout = meta_theme_lookup_layout (info->theme, parent); |
|
1046 |
if (parent_layout == NULL) |
|
1047 |
{
|
|
1048 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1049 |
_("<%s> parent \"%s\" has not been defined"), |
|
1050 |
element_name, parent); |
|
1051 |
return; |
|
1052 |
}
|
|
1053 |
}
|
|
1054 |
||
1055 |
g_assert (info->layout == NULL); |
|
1056 |
||
1057 |
if (parent_layout) |
|
1058 |
info->layout = meta_frame_layout_copy (parent_layout); |
|
1059 |
else
|
|
1060 |
info->layout = meta_frame_layout_new (); |
|
1061 |
||
1062 |
if (has_title) /* only if explicit, otherwise inherit */ |
|
1063 |
info->layout->has_title = has_title_val; |
|
1064 |
||
1065 |
if (META_THEME_ALLOWS (info->theme, META_THEME_HIDDEN_BUTTONS) && hide_buttons_val) |
|
1066 |
info->layout->hide_buttons = hide_buttons_val; |
|
1067 |
||
1068 |
if (title_scale) |
|
1069 |
info->layout->title_scale = title_scale_val; |
|
1070 |
||
1071 |
if (rounded_top_left) |
|
1072 |
info->layout->top_left_corner_rounded_radius = rounded_top_left_val; |
|
1073 |
||
1074 |
if (rounded_top_right) |
|
1075 |
info->layout->top_right_corner_rounded_radius = rounded_top_right_val; |
|
1076 |
||
1077 |
if (rounded_bottom_left) |
|
1078 |
info->layout->bottom_left_corner_rounded_radius = rounded_bottom_left_val; |
|
1079 |
||
1080 |
if (rounded_bottom_right) |
|
1081 |
info->layout->bottom_right_corner_rounded_radius = rounded_bottom_right_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1082 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1083 |
meta_theme_insert_layout (info->theme, name, info->layout); |
1084 |
||
1085 |
push_state (info, STATE_FRAME_GEOMETRY); |
|
1086 |
}
|
|
1087 |
else if (ELEMENT_IS ("draw_ops")) |
|
1088 |
{
|
|
1089 |
const char *name = NULL; |
|
1090 |
||
1091 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
1092 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1093 |
"!name", &name, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1094 |
NULL)) |
1095 |
return; |
|
1096 |
||
1097 |
if (meta_theme_lookup_draw_op_list (info->theme, name)) |
|
1098 |
{
|
|
1099 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1100 |
_("<%s> name \"%s\" used a second time"), |
|
1101 |
element_name, name); |
|
1102 |
return; |
|
1103 |
}
|
|
1104 |
||
1105 |
g_assert (info->op_list == NULL); |
|
1106 |
info->op_list = meta_draw_op_list_new (2); |
|
1107 |
||
1108 |
meta_theme_insert_draw_op_list (info->theme, name, info->op_list); |
|
1109 |
||
1110 |
push_state (info, STATE_DRAW_OPS); |
|
1111 |
}
|
|
1112 |
else if (ELEMENT_IS ("frame_style")) |
|
1113 |
{
|
|
1114 |
const char *name = NULL; |
|
1115 |
const char *parent = NULL; |
|
1116 |
const char *geometry = NULL; |
|
1117 |
const char *background = NULL; |
|
1118 |
const char *alpha = NULL; |
|
1119 |
MetaFrameStyle *parent_style; |
|
1120 |
MetaFrameLayout *layout; |
|
1121 |
||
1122 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
1123 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1124 |
"!name", &name, "parent", &parent, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1125 |
"geometry", &geometry, |
1126 |
"background", &background, |
|
1127 |
"alpha", &alpha, |
|
1128 |
NULL)) |
|
1129 |
return; |
|
1130 |
||
1131 |
if (meta_theme_lookup_style (info->theme, name)) |
|
1132 |
{
|
|
1133 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1134 |
_("<%s> name \"%s\" used a second time"), |
|
1135 |
element_name, name); |
|
1136 |
return; |
|
1137 |
}
|
|
1138 |
||
1139 |
parent_style = NULL; |
|
1140 |
if (parent) |
|
1141 |
{
|
|
1142 |
parent_style = meta_theme_lookup_style (info->theme, parent); |
|
1143 |
if (parent_style == NULL) |
|
1144 |
{
|
|
1145 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1146 |
_("<%s> parent \"%s\" has not been defined"), |
|
1147 |
element_name, parent); |
|
1148 |
return; |
|
1149 |
}
|
|
1150 |
}
|
|
1151 |
||
1152 |
layout = NULL; |
|
1153 |
if (geometry) |
|
1154 |
{
|
|
1155 |
layout = meta_theme_lookup_layout (info->theme, geometry); |
|
1156 |
if (layout == NULL) |
|
1157 |
{
|
|
1158 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1159 |
_("<%s> geometry \"%s\" has not been defined"), |
|
1160 |
element_name, geometry); |
|
1161 |
return; |
|
1162 |
}
|
|
1163 |
}
|
|
1164 |
else if (parent_style) |
|
1165 |
{
|
|
1166 |
layout = parent_style->layout; |
|
1167 |
}
|
|
1168 |
||
1169 |
if (layout == NULL) |
|
1170 |
{
|
|
1171 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1172 |
_("<%s> must specify either a geometry or a parent that has a geometry"), |
|
1173 |
element_name); |
|
1174 |
return; |
|
1175 |
}
|
|
1176 |
||
1177 |
g_assert (info->style == NULL); |
|
1178 |
||
1179 |
info->style = meta_frame_style_new (parent_style); |
|
1180 |
g_assert (info->style->layout == NULL); |
|
1181 |
meta_frame_layout_ref (layout); |
|
1182 |
info->style->layout = layout; |
|
1183 |
||
1184 |
if (background != NULL && META_THEME_ALLOWS (info->theme, META_THEME_FRAME_BACKGROUNDS)) |
|
1185 |
{
|
|
1186 |
info->style->window_background_color = meta_color_spec_new_from_string (background, error); |
|
1187 |
if (!info->style->window_background_color) |
|
1188 |
return; |
|
1189 |
||
1190 |
if (alpha != NULL) |
|
1191 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1192 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1193 |
gboolean success; |
1194 |
MetaAlphaGradientSpec *alpha_vector; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1195 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1196 |
g_clear_error (error); |
1197 |
/* fortunately, we already have a routine to parse alpha values,
|
|
1198 |
* though it produces a vector of them, which is a superset of
|
|
1199 |
* what we want.
|
|
1200 |
*/
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1201 |
success = parse_alpha (alpha, &alpha_vector, context, error); |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1202 |
if (!success) |
1203 |
return; |
|
1204 |
||
1205 |
/* alpha_vector->alphas must contain at least one element */
|
|
1206 |
info->style->window_background_alpha = alpha_vector->alphas[0]; |
|
1207 |
||
1208 |
meta_alpha_gradient_spec_free (alpha_vector); |
|
1209 |
}
|
|
1210 |
}
|
|
1211 |
else if (alpha != NULL) |
|
1212 |
{
|
|
1213 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1214 |
_("You must specify a background for an alpha value to be meaningful")); |
|
1215 |
return; |
|
1216 |
}
|
|
1217 |
||
1218 |
meta_theme_insert_style (info->theme, name, info->style); |
|
1219 |
||
1220 |
push_state (info, STATE_FRAME_STYLE); |
|
1221 |
}
|
|
1222 |
else if (ELEMENT_IS ("frame_style_set")) |
|
1223 |
{
|
|
1224 |
const char *name = NULL; |
|
1225 |
const char *parent = NULL; |
|
1226 |
MetaFrameStyleSet *parent_set; |
|
1227 |
||
1228 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
1229 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1230 |
"!name", &name, "parent", &parent, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1231 |
NULL)) |
1232 |
return; |
|
1233 |
||
1234 |
if (meta_theme_lookup_style_set (info->theme, name)) |
|
1235 |
{
|
|
1236 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1237 |
_("<%s> name \"%s\" used a second time"), |
|
1238 |
element_name, name); |
|
1239 |
return; |
|
1240 |
}
|
|
1241 |
||
1242 |
parent_set = NULL; |
|
1243 |
if (parent) |
|
1244 |
{
|
|
1245 |
parent_set = meta_theme_lookup_style_set (info->theme, parent); |
|
1246 |
if (parent_set == NULL) |
|
1247 |
{
|
|
1248 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1249 |
_("<%s> parent \"%s\" has not been defined"), |
|
1250 |
element_name, parent); |
|
1251 |
return; |
|
1252 |
}
|
|
1253 |
}
|
|
1254 |
||
1255 |
g_assert (info->style_set == NULL); |
|
1256 |
||
1257 |
info->style_set = meta_frame_style_set_new (parent_set); |
|
1258 |
||
1259 |
meta_theme_insert_style_set (info->theme, name, info->style_set); |
|
1260 |
||
1261 |
push_state (info, STATE_FRAME_STYLE_SET); |
|
1262 |
}
|
|
1263 |
else if (ELEMENT_IS ("window")) |
|
1264 |
{
|
|
1265 |
const char *type_name = NULL; |
|
1266 |
const char *style_set_name = NULL; |
|
1267 |
MetaFrameStyleSet *style_set; |
|
1268 |
MetaFrameType type; |
|
1269 |
||
1270 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
1271 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1272 |
"!type", &type_name, "!style_set", &style_set_name, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1273 |
NULL)) |
1274 |
return; |
|
1275 |
||
1276 |
type = meta_frame_type_from_string (type_name); |
|
1277 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1278 |
if (type == META_FRAME_TYPE_LAST || |
1279 |
(type == META_FRAME_TYPE_ATTACHED && peek_required_version (info) < 3002)) |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1280 |
{
|
1281 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1282 |
_("Unknown type \"%s\" on <%s> element"), |
|
1283 |
type_name, element_name); |
|
1284 |
return; |
|
1285 |
}
|
|
1286 |
||
1287 |
style_set = meta_theme_lookup_style_set (info->theme, |
|
1288 |
style_set_name); |
|
1289 |
||
1290 |
if (style_set == NULL) |
|
1291 |
{
|
|
1292 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1293 |
_("Unknown style_set \"%s\" on <%s> element"), |
|
1294 |
style_set_name, element_name); |
|
1295 |
return; |
|
1296 |
}
|
|
1297 |
||
1298 |
if (info->theme->style_sets_by_type[type] != NULL) |
|
1299 |
{
|
|
1300 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1301 |
_("Window type \"%s\" has already been assigned a style set"), |
|
1302 |
type_name); |
|
1303 |
return; |
|
1304 |
}
|
|
1305 |
||
1306 |
meta_frame_style_set_ref (style_set); |
|
1307 |
info->theme->style_sets_by_type[type] = style_set; |
|
1308 |
||
1309 |
push_state (info, STATE_WINDOW); |
|
1310 |
}
|
|
1311 |
else if (ELEMENT_IS ("menu_icon")) |
|
1312 |
{
|
|
1313 |
/* Not supported any more, but we have to parse it if they include it,
|
|
1314 |
* for backwards compatibility.
|
|
1315 |
*/
|
|
1316 |
g_assert (info->op_list == NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1317 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1318 |
push_state (info, STATE_MENU_ICON); |
1319 |
}
|
|
1320 |
else if (ELEMENT_IS ("fallback")) |
|
1321 |
{
|
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1322 |
/* Not supported any more, but we have to parse it if they include it,
|
1323 |
* for backwards compatibility.
|
|
1324 |
*/
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1325 |
push_state (info, STATE_FALLBACK); |
1326 |
}
|
|
1327 |
else
|
|
1328 |
{
|
|
1329 |
set_error (error, context, |
|
1330 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1331 |
_("Element <%s> is not allowed below <%s>"), |
|
1332 |
element_name, "metacity_theme"); |
|
1333 |
}
|
|
1334 |
}
|
|
1335 |
||
1336 |
static void |
|
1337 |
parse_info_element (GMarkupParseContext *context, |
|
1338 |
const gchar *element_name, |
|
1339 |
const gchar **attribute_names, |
|
1340 |
const gchar **attribute_values, |
|
1341 |
ParseInfo *info, |
|
1342 |
GError **error) |
|
1343 |
{
|
|
1344 |
g_return_if_fail (peek_state (info) == STATE_INFO); |
|
1345 |
||
1346 |
if (ELEMENT_IS ("name")) |
|
1347 |
{
|
|
1348 |
if (!check_no_attributes (context, element_name, |
|
1349 |
attribute_names, attribute_values, |
|
1350 |
error)) |
|
1351 |
return; |
|
1352 |
||
1353 |
push_state (info, STATE_NAME); |
|
1354 |
}
|
|
1355 |
else if (ELEMENT_IS ("author")) |
|
1356 |
{
|
|
1357 |
if (!check_no_attributes (context, element_name, |
|
1358 |
attribute_names, attribute_values, |
|
1359 |
error)) |
|
1360 |
return; |
|
1361 |
||
1362 |
push_state (info, STATE_AUTHOR); |
|
1363 |
}
|
|
1364 |
else if (ELEMENT_IS ("copyright")) |
|
1365 |
{
|
|
1366 |
if (!check_no_attributes (context, element_name, |
|
1367 |
attribute_names, attribute_values, |
|
1368 |
error)) |
|
1369 |
return; |
|
1370 |
||
1371 |
push_state (info, STATE_COPYRIGHT); |
|
1372 |
}
|
|
1373 |
else if (ELEMENT_IS ("description")) |
|
1374 |
{
|
|
1375 |
if (!check_no_attributes (context, element_name, |
|
1376 |
attribute_names, attribute_values, |
|
1377 |
error)) |
|
1378 |
return; |
|
1379 |
||
1380 |
push_state (info, STATE_DESCRIPTION); |
|
1381 |
}
|
|
1382 |
else if (ELEMENT_IS ("date")) |
|
1383 |
{
|
|
1384 |
if (!check_no_attributes (context, element_name, |
|
1385 |
attribute_names, attribute_values, |
|
1386 |
error)) |
|
1387 |
return; |
|
1388 |
||
1389 |
push_state (info, STATE_DATE); |
|
1390 |
}
|
|
1391 |
else
|
|
1392 |
{
|
|
1393 |
set_error (error, context, |
|
1394 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1395 |
_("Element <%s> is not allowed below <%s>"), |
|
1396 |
element_name, "info"); |
|
1397 |
}
|
|
1398 |
}
|
|
1399 |
||
1400 |
static void |
|
1401 |
parse_distance (GMarkupParseContext *context, |
|
1402 |
const gchar *element_name, |
|
1403 |
const gchar **attribute_names, |
|
1404 |
const gchar **attribute_values, |
|
1405 |
ParseInfo *info, |
|
1406 |
GError **error) |
|
1407 |
{
|
|
1408 |
const char *name; |
|
1409 |
const char *value; |
|
1410 |
int val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1411 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1412 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
1413 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1414 |
"!name", &name, "!value", &value, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1415 |
NULL)) |
1416 |
return; |
|
1417 |
||
1418 |
val = 0; |
|
1419 |
if (!parse_positive_integer (value, &val, context, info->theme, error)) |
|
1420 |
return; |
|
1421 |
||
1422 |
g_assert (val >= 0); /* yeah, "non-negative" not "positive" get over it */ |
|
1423 |
g_assert (info->layout); |
|
1424 |
||
1425 |
if (strcmp (name, "left_width") == 0) |
|
1426 |
info->layout->left_width = val; |
|
1427 |
else if (strcmp (name, "right_width") == 0) |
|
1428 |
info->layout->right_width = val; |
|
1429 |
else if (strcmp (name, "bottom_height") == 0) |
|
1430 |
info->layout->bottom_height = val; |
|
1431 |
else if (strcmp (name, "title_vertical_pad") == 0) |
|
1432 |
info->layout->title_vertical_pad = val; |
|
1433 |
else if (strcmp (name, "right_titlebar_edge") == 0) |
|
1434 |
info->layout->right_titlebar_edge = val; |
|
1435 |
else if (strcmp (name, "left_titlebar_edge") == 0) |
|
1436 |
info->layout->left_titlebar_edge = val; |
|
1437 |
else if (strcmp (name, "button_width") == 0) |
|
1438 |
{
|
|
1439 |
info->layout->button_width = val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1440 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1441 |
if (!(info->layout->button_sizing == META_BUTTON_SIZING_LAST || |
1442 |
info->layout->button_sizing == META_BUTTON_SIZING_FIXED)) |
|
1443 |
{
|
|
1444 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1.2.48
by Pedro Fragoso
Import upstream version 2.25.8 |
1445 |
_("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons")); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1446 |
return; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1447 |
}
|
1448 |
||
1449 |
info->layout->button_sizing = META_BUTTON_SIZING_FIXED; |
|
1450 |
}
|
|
1451 |
else if (strcmp (name, "button_height") == 0) |
|
1452 |
{
|
|
1453 |
info->layout->button_height = val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1454 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1455 |
if (!(info->layout->button_sizing == META_BUTTON_SIZING_LAST || |
1456 |
info->layout->button_sizing == META_BUTTON_SIZING_FIXED)) |
|
1457 |
{
|
|
1458 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1.2.48
by Pedro Fragoso
Import upstream version 2.25.8 |
1459 |
_("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons")); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1460 |
return; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1461 |
}
|
1462 |
||
1463 |
info->layout->button_sizing = META_BUTTON_SIZING_FIXED; |
|
1464 |
}
|
|
1465 |
else
|
|
1466 |
{
|
|
1467 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1468 |
_("Distance \"%s\" is unknown"), name); |
|
1469 |
return; |
|
1470 |
}
|
|
1471 |
}
|
|
1472 |
||
1473 |
static void |
|
1474 |
parse_aspect_ratio (GMarkupParseContext *context, |
|
1475 |
const gchar *element_name, |
|
1476 |
const gchar **attribute_names, |
|
1477 |
const gchar **attribute_values, |
|
1478 |
ParseInfo *info, |
|
1479 |
GError **error) |
|
1480 |
{
|
|
1481 |
const char *name; |
|
1482 |
const char *value; |
|
1483 |
double val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1484 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1485 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
1486 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1487 |
"!name", &name, "!value", &value, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1488 |
NULL)) |
1489 |
return; |
|
1490 |
||
1491 |
val = 0; |
|
1492 |
if (!parse_double (value, &val, context, error)) |
|
1493 |
return; |
|
1494 |
||
1495 |
g_assert (info->layout); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1496 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1497 |
if (strcmp (name, "button") == 0) |
1498 |
{
|
|
1499 |
info->layout->button_aspect = val; |
|
1500 |
||
1501 |
if (info->layout->button_sizing != META_BUTTON_SIZING_LAST) |
|
1502 |
{
|
|
1503 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1.2.48
by Pedro Fragoso
Import upstream version 2.25.8 |
1504 |
_("Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" for buttons")); |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1505 |
return; |
1506 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1507 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1508 |
info->layout->button_sizing = META_BUTTON_SIZING_ASPECT; |
1509 |
}
|
|
1510 |
else
|
|
1511 |
{
|
|
1512 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1513 |
_("Aspect ratio \"%s\" is unknown"), name); |
|
1514 |
return; |
|
1515 |
}
|
|
1516 |
}
|
|
1517 |
||
1518 |
static void |
|
1519 |
parse_border (GMarkupParseContext *context, |
|
1520 |
const gchar *element_name, |
|
1521 |
const gchar **attribute_names, |
|
1522 |
const gchar **attribute_values, |
|
1523 |
ParseInfo *info, |
|
1524 |
GError **error) |
|
1525 |
{
|
|
1526 |
const char *name; |
|
1527 |
const char *top; |
|
1528 |
const char *bottom; |
|
1529 |
const char *left; |
|
1530 |
const char *right; |
|
1531 |
int top_val; |
|
1532 |
int bottom_val; |
|
1533 |
int left_val; |
|
1534 |
int right_val; |
|
1535 |
GtkBorder *border; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1536 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1537 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
1538 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1539 |
"!name", &name, |
1540 |
"!top", &top, |
|
1541 |
"!bottom", &bottom, |
|
1542 |
"!left", &left, |
|
1543 |
"!right", &right, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1544 |
NULL)) |
1545 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1546 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1547 |
top_val = 0; |
1548 |
if (!parse_positive_integer (top, &top_val, context, info->theme, error)) |
|
1549 |
return; |
|
1550 |
||
1551 |
bottom_val = 0; |
|
1552 |
if (!parse_positive_integer (bottom, &bottom_val, context, info->theme, error)) |
|
1553 |
return; |
|
1554 |
||
1555 |
left_val = 0; |
|
1556 |
if (!parse_positive_integer (left, &left_val, context, info->theme, error)) |
|
1557 |
return; |
|
1558 |
||
1559 |
right_val = 0; |
|
1560 |
if (!parse_positive_integer (right, &right_val, context, info->theme, error)) |
|
1561 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1562 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1563 |
g_assert (info->layout); |
1564 |
||
1565 |
border = NULL; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1566 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1567 |
if (strcmp (name, "title_border") == 0) |
1568 |
border = &info->layout->title_border; |
|
1569 |
else if (strcmp (name, "button_border") == 0) |
|
1570 |
border = &info->layout->button_border; |
|
1571 |
||
1572 |
if (border == NULL) |
|
1573 |
{
|
|
1574 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1575 |
_("Border \"%s\" is unknown"), name); |
|
1576 |
return; |
|
1577 |
}
|
|
1578 |
||
1579 |
border->top = top_val; |
|
1580 |
border->bottom = bottom_val; |
|
1581 |
border->left = left_val; |
|
1582 |
border->right = right_val; |
|
1583 |
}
|
|
1584 |
||
1585 |
static void |
|
1586 |
parse_geometry_element (GMarkupParseContext *context, |
|
1587 |
const gchar *element_name, |
|
1588 |
const gchar **attribute_names, |
|
1589 |
const gchar **attribute_values, |
|
1590 |
ParseInfo *info, |
|
1591 |
GError **error) |
|
1592 |
{
|
|
1593 |
g_return_if_fail (peek_state (info) == STATE_FRAME_GEOMETRY); |
|
1594 |
||
1595 |
if (ELEMENT_IS ("distance")) |
|
1596 |
{
|
|
1597 |
parse_distance (context, element_name, |
|
1598 |
attribute_names, attribute_values, |
|
1599 |
info, error); |
|
1600 |
push_state (info, STATE_DISTANCE); |
|
1601 |
}
|
|
1602 |
else if (ELEMENT_IS ("border")) |
|
1603 |
{
|
|
1604 |
parse_border (context, element_name, |
|
1605 |
attribute_names, attribute_values, |
|
1606 |
info, error); |
|
1607 |
push_state (info, STATE_BORDER); |
|
1608 |
}
|
|
1609 |
else if (ELEMENT_IS ("aspect_ratio")) |
|
1610 |
{
|
|
1611 |
parse_aspect_ratio (context, element_name, |
|
1612 |
attribute_names, attribute_values, |
|
1613 |
info, error); |
|
1614 |
||
1615 |
push_state (info, STATE_ASPECT_RATIO); |
|
1616 |
}
|
|
1617 |
else
|
|
1618 |
{
|
|
1619 |
set_error (error, context, |
|
1620 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1621 |
_("Element <%s> is not allowed below <%s>"), |
|
1622 |
element_name, "frame_geometry"); |
|
1623 |
}
|
|
1624 |
}
|
|
1625 |
||
1626 |
#if 0
|
|
1627 |
static gboolean
|
|
1628 |
check_expression (PosToken *tokens,
|
|
1629 |
int n_tokens,
|
|
1630 |
gboolean has_object,
|
|
1631 |
MetaTheme *theme,
|
|
1632 |
GMarkupParseContext *context,
|
|
1633 |
GError **error)
|
|
1634 |
{
|
|
1635 |
MetaPositionExprEnv env;
|
|
1636 |
int x, y;
|
|
1637 |
||
1638 |
/* We set it all to 0 to try and catch divide-by-zero screwups.
|
|
1639 |
* it's possible we should instead guarantee that widths and heights
|
|
1640 |
* are at least 1.
|
|
1641 |
*/
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1642 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1643 |
env.rect = meta_rect (0, 0, 0, 0);
|
1644 |
if (has_object)
|
|
1645 |
{
|
|
1646 |
env.object_width = 0;
|
|
1647 |
env.object_height = 0;
|
|
1648 |
}
|
|
1649 |
else
|
|
1650 |
{
|
|
1651 |
env.object_width = -1;
|
|
1652 |
env.object_height = -1;
|
|
1653 |
}
|
|
1654 |
||
1655 |
env.left_width = 0;
|
|
1656 |
env.right_width = 0;
|
|
1657 |
env.top_height = 0;
|
|
1658 |
env.bottom_height = 0;
|
|
1659 |
env.title_width = 0;
|
|
1660 |
env.title_height = 0;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1661 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1662 |
env.icon_width = 0;
|
1663 |
env.icon_height = 0;
|
|
1664 |
env.mini_icon_width = 0;
|
|
1665 |
env.mini_icon_height = 0;
|
|
1666 |
env.theme = theme;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1667 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1668 |
if (!meta_parse_position_expression (tokens, n_tokens,
|
1669 |
&env,
|
|
1670 |
&x, &y,
|
|
1671 |
error))
|
|
1672 |
{
|
|
1673 |
add_context_to_error (error, context);
|
|
1674 |
return FALSE;
|
|
1675 |
}
|
|
1676 |
||
1677 |
return TRUE;
|
|
1678 |
}
|
|
1679 |
#endif
|
|
1680 |
||
1681 |
static void |
|
1682 |
parse_draw_op_element (GMarkupParseContext *context, |
|
1683 |
const gchar *element_name, |
|
1684 |
const gchar **attribute_names, |
|
1685 |
const gchar **attribute_values, |
|
1686 |
ParseInfo *info, |
|
1687 |
GError **error) |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1688 |
{
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1689 |
g_return_if_fail (peek_state (info) == STATE_DRAW_OPS); |
1690 |
||
1691 |
if (ELEMENT_IS ("line")) |
|
1692 |
{
|
|
1693 |
MetaDrawOp *op; |
|
1694 |
const char *color; |
|
1695 |
const char *x1; |
|
1696 |
const char *y1; |
|
1697 |
const char *x2; |
|
1698 |
const char *y2; |
|
1699 |
const char *dash_on_length; |
|
1700 |
const char *dash_off_length; |
|
1701 |
const char *width; |
|
1702 |
MetaColorSpec *color_spec; |
|
1703 |
int dash_on_val; |
|
1704 |
int dash_off_val; |
|
1705 |
int width_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1706 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1707 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
1708 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1709 |
"!color", &color, |
1710 |
"!x1", &x1, "!y1", &y1, |
|
1711 |
"!x2", &x2, "!y2", &y2, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1712 |
"dash_on_length", &dash_on_length, |
1713 |
"dash_off_length", &dash_off_length, |
|
1714 |
"width", &width, |
|
1715 |
NULL)) |
|
1716 |
return; |
|
1717 |
||
1718 |
#if 0
|
|
1719 |
if (!check_expression (x1, FALSE, info->theme, context, error))
|
|
1720 |
return;
|
|
1721 |
||
1722 |
if (!check_expression (y1, FALSE, info->theme, context, error))
|
|
1723 |
return;
|
|
1724 |
||
1725 |
if (!check_expression (x2, FALSE, info->theme, context, error))
|
|
1726 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1727 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1728 |
if (!check_expression (y2, FALSE, info->theme, context, error))
|
1729 |
return;
|
|
1730 |
#endif
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1731 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1732 |
dash_on_val = 0; |
1733 |
if (dash_on_length && |
|
1734 |
!parse_positive_integer (dash_on_length, &dash_on_val, context, info->theme, error)) |
|
1735 |
return; |
|
1736 |
||
1737 |
dash_off_val = 0; |
|
1738 |
if (dash_off_length && |
|
1739 |
!parse_positive_integer (dash_off_length, &dash_off_val, context, info->theme, error)) |
|
1740 |
return; |
|
1741 |
||
1742 |
width_val = 0; |
|
1743 |
if (width && |
|
1744 |
!parse_positive_integer (width, &width_val, context, info->theme, error)) |
|
1745 |
return; |
|
1746 |
||
1747 |
/* Check last so we don't have to free it when other
|
|
1748 |
* stuff fails
|
|
1749 |
*/
|
|
1750 |
color_spec = parse_color (info->theme, color, error); |
|
1751 |
if (color_spec == NULL) |
|
1752 |
{
|
|
1753 |
add_context_to_error (error, context); |
|
1754 |
return; |
|
1755 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1756 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1757 |
op = meta_draw_op_new (META_DRAW_LINE); |
1758 |
||
1759 |
op->data.line.color_spec = color_spec; |
|
1760 |
||
1761 |
op->data.line.x1 = meta_draw_spec_new (info->theme, x1, NULL); |
|
1762 |
op->data.line.y1 = meta_draw_spec_new (info->theme, y1, NULL); |
|
1.2.54
by Robert Ancell
Import upstream version 2.27.0 |
1763 |
|
1764 |
if (strcmp(x1, x2)==0) |
|
1765 |
op->data.line.x2 = NULL; |
|
1766 |
else
|
|
1767 |
op->data.line.x2 = meta_draw_spec_new (info->theme, x2, NULL); |
|
1768 |
||
1769 |
if (strcmp(y1, y2)==0) |
|
1770 |
op->data.line.y2 = NULL; |
|
1771 |
else
|
|
1772 |
op->data.line.y2 = meta_draw_spec_new (info->theme, y2, NULL); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1773 |
|
1774 |
op->data.line.width = width_val; |
|
1775 |
op->data.line.dash_on_length = dash_on_val; |
|
1776 |
op->data.line.dash_off_length = dash_off_val; |
|
1777 |
||
1778 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1779 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1780 |
meta_draw_op_list_append (info->op_list, op); |
1781 |
||
1782 |
push_state (info, STATE_LINE); |
|
1783 |
}
|
|
1784 |
else if (ELEMENT_IS ("rectangle")) |
|
1785 |
{
|
|
1786 |
MetaDrawOp *op; |
|
1787 |
const char *color; |
|
1788 |
const char *x; |
|
1789 |
const char *y; |
|
1790 |
const char *width; |
|
1791 |
const char *height; |
|
1792 |
const char *filled; |
|
1793 |
gboolean filled_val; |
|
1794 |
MetaColorSpec *color_spec; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1795 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1796 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
1797 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1798 |
"!color", &color, |
1799 |
"!x", &x, "!y", &y, |
|
1800 |
"!width", &width, "!height", &height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1801 |
"filled", &filled, |
1802 |
NULL)) |
|
1803 |
return; |
|
1804 |
||
1805 |
#if 0
|
|
1806 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
1807 |
return;
|
|
1808 |
||
1809 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
1810 |
return;
|
|
1811 |
||
1812 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
1813 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1814 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1815 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
1816 |
return;
|
|
1817 |
#endif
|
|
1818 |
||
1819 |
filled_val = FALSE; |
|
1820 |
if (filled && !parse_boolean (filled, &filled_val, context, error)) |
|
1821 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1822 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1823 |
/* Check last so we don't have to free it when other
|
1824 |
* stuff fails
|
|
1825 |
*/
|
|
1826 |
color_spec = parse_color (info->theme, color, error); |
|
1827 |
if (color_spec == NULL) |
|
1828 |
{
|
|
1829 |
add_context_to_error (error, context); |
|
1830 |
return; |
|
1831 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1832 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1833 |
op = meta_draw_op_new (META_DRAW_RECTANGLE); |
1834 |
||
1835 |
op->data.rectangle.color_spec = color_spec; |
|
1836 |
op->data.rectangle.x = meta_draw_spec_new (info->theme, x, NULL); |
|
1837 |
op->data.rectangle.y = meta_draw_spec_new (info->theme, y, NULL); |
|
1838 |
op->data.rectangle.width = meta_draw_spec_new (info->theme, width, NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1839 |
op->data.rectangle.height = meta_draw_spec_new (info->theme, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1840 |
height, NULL); |
1841 |
||
1842 |
op->data.rectangle.filled = filled_val; |
|
1843 |
||
1844 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1845 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1846 |
meta_draw_op_list_append (info->op_list, op); |
1847 |
||
1848 |
push_state (info, STATE_RECTANGLE); |
|
1849 |
}
|
|
1850 |
else if (ELEMENT_IS ("arc")) |
|
1851 |
{
|
|
1852 |
MetaDrawOp *op; |
|
1853 |
const char *color; |
|
1854 |
const char *x; |
|
1855 |
const char *y; |
|
1856 |
const char *width; |
|
1857 |
const char *height; |
|
1858 |
const char *filled; |
|
1859 |
const char *start_angle; |
|
1860 |
const char *extent_angle; |
|
1861 |
const char *from; |
|
1862 |
const char *to; |
|
1863 |
gboolean filled_val; |
|
1864 |
double start_angle_val; |
|
1865 |
double extent_angle_val; |
|
1866 |
MetaColorSpec *color_spec; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1867 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1868 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
1869 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1870 |
"!color", &color, |
1871 |
"!x", &x, "!y", &y, |
|
1872 |
"!width", &width, "!height", &height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1873 |
"filled", &filled, |
1874 |
"start_angle", &start_angle, |
|
1875 |
"extent_angle", &extent_angle, |
|
1876 |
"from", &from, |
|
1877 |
"to", &to, |
|
1878 |
NULL)) |
|
1879 |
return; |
|
1880 |
||
1881 |
if (META_THEME_ALLOWS (info->theme, META_THEME_DEGREES_IN_ARCS) ) |
|
1882 |
{
|
|
1883 |
if (start_angle == NULL && from == NULL) |
|
1884 |
{
|
|
1885 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1886 |
_("No \"start_angle\" or \"from\" attribute on element <%s>"), element_name); |
|
1887 |
return; |
|
1888 |
}
|
|
1889 |
||
1890 |
if (extent_angle == NULL && to == NULL) |
|
1891 |
{
|
|
1892 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1893 |
_("No \"extent_angle\" or \"to\" attribute on element <%s>"), element_name); |
|
1894 |
return; |
|
1895 |
}
|
|
1896 |
}
|
|
1897 |
else
|
|
1898 |
{
|
|
1899 |
if (start_angle == NULL) |
|
1900 |
{
|
|
1901 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1902 |
ATTRIBUTE_NOT_FOUND, "start_angle", element_name); |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1903 |
return; |
1904 |
}
|
|
1905 |
||
1906 |
if (extent_angle == NULL) |
|
1907 |
{
|
|
1908 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1909 |
ATTRIBUTE_NOT_FOUND, "extent_angle", element_name); |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1910 |
return; |
1911 |
}
|
|
1912 |
}
|
|
1913 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1914 |
#if 0
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1915 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
1916 |
return;
|
|
1917 |
||
1918 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
1919 |
return;
|
|
1920 |
||
1921 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
1922 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1923 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1924 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
1925 |
return;
|
|
1926 |
#endif
|
|
1927 |
||
1928 |
if (start_angle == NULL) |
|
1929 |
{
|
|
1930 |
if (!parse_angle (from, &start_angle_val, context, error)) |
|
1931 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1932 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1933 |
start_angle_val = (180-start_angle_val)/360.0; |
1934 |
}
|
|
1935 |
else
|
|
1936 |
{
|
|
1937 |
if (!parse_angle (start_angle, &start_angle_val, context, error)) |
|
1938 |
return; |
|
1939 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1940 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1941 |
if (extent_angle == NULL) |
1942 |
{
|
|
1943 |
if (!parse_angle (to, &extent_angle_val, context, error)) |
|
1944 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1945 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1946 |
extent_angle_val = ((180-extent_angle_val)/360.0) - start_angle_val; |
1947 |
}
|
|
1948 |
else
|
|
1949 |
{
|
|
1950 |
if (!parse_angle (extent_angle, &extent_angle_val, context, error)) |
|
1951 |
return; |
|
1952 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1953 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1954 |
filled_val = FALSE; |
1955 |
if (filled && !parse_boolean (filled, &filled_val, context, error)) |
|
1956 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1957 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1958 |
/* Check last so we don't have to free it when other
|
1959 |
* stuff fails
|
|
1960 |
*/
|
|
1961 |
color_spec = parse_color (info->theme, color, error); |
|
1962 |
if (color_spec == NULL) |
|
1963 |
{
|
|
1964 |
add_context_to_error (error, context); |
|
1965 |
return; |
|
1966 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1967 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1968 |
op = meta_draw_op_new (META_DRAW_ARC); |
1969 |
||
1970 |
op->data.arc.color_spec = color_spec; |
|
1971 |
||
1972 |
op->data.arc.x = meta_draw_spec_new (info->theme, x, NULL); |
|
1973 |
op->data.arc.y = meta_draw_spec_new (info->theme, y, NULL); |
|
1974 |
op->data.arc.width = meta_draw_spec_new (info->theme, width, NULL); |
|
1975 |
op->data.arc.height = meta_draw_spec_new (info->theme, height, NULL); |
|
1976 |
||
1977 |
op->data.arc.filled = filled_val; |
|
1978 |
op->data.arc.start_angle = start_angle_val; |
|
1979 |
op->data.arc.extent_angle = extent_angle_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1980 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1981 |
g_assert (info->op_list); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1982 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1983 |
meta_draw_op_list_append (info->op_list, op); |
1984 |
||
1985 |
push_state (info, STATE_ARC); |
|
1986 |
}
|
|
1987 |
else if (ELEMENT_IS ("clip")) |
|
1988 |
{
|
|
1989 |
MetaDrawOp *op; |
|
1990 |
const char *x; |
|
1991 |
const char *y; |
|
1992 |
const char *width; |
|
1993 |
const char *height; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
1994 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1995 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
1996 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
1997 |
"!x", &x, "!y", &y, |
1998 |
"!width", &width, "!height", &height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
1999 |
NULL)) |
2000 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2001 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2002 |
#if 0
|
2003 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
2004 |
return;
|
|
2005 |
||
2006 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
2007 |
return;
|
|
2008 |
||
2009 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
2010 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2011 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2012 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
2013 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2014 |
#endif
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2015 |
op = meta_draw_op_new (META_DRAW_CLIP); |
2016 |
||
2017 |
op->data.clip.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2018 |
op->data.clip.y = meta_draw_spec_new (info->theme, y, NULL); |
|
2019 |
op->data.clip.width = meta_draw_spec_new (info->theme, width, NULL); |
|
2020 |
op->data.clip.height = meta_draw_spec_new (info->theme, height, NULL); |
|
2021 |
||
2022 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2023 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2024 |
meta_draw_op_list_append (info->op_list, op); |
2025 |
||
2026 |
push_state (info, STATE_CLIP); |
|
2027 |
}
|
|
2028 |
else if (ELEMENT_IS ("tint")) |
|
2029 |
{
|
|
2030 |
MetaDrawOp *op; |
|
2031 |
const char *color; |
|
2032 |
const char *x; |
|
2033 |
const char *y; |
|
2034 |
const char *width; |
|
2035 |
const char *height; |
|
2036 |
const char *alpha; |
|
2037 |
MetaAlphaGradientSpec *alpha_spec; |
|
2038 |
MetaColorSpec *color_spec; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2039 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2040 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2041 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2042 |
"!color", &color, |
2043 |
"!x", &x, "!y", &y, |
|
2044 |
"!width", &width, "!height", &height, |
|
2045 |
"!alpha", &alpha, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2046 |
NULL)) |
2047 |
return; |
|
2048 |
||
2049 |
#if 0
|
|
2050 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
2051 |
return;
|
|
2052 |
||
2053 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
2054 |
return;
|
|
2055 |
||
2056 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
2057 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2058 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2059 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
2060 |
return;
|
|
2061 |
#endif
|
|
2062 |
alpha_spec = NULL; |
|
2063 |
if (!parse_alpha (alpha, &alpha_spec, context, error)) |
|
2064 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2065 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2066 |
/* Check last so we don't have to free it when other
|
2067 |
* stuff fails
|
|
2068 |
*/
|
|
2069 |
color_spec = parse_color (info->theme, color, error); |
|
2070 |
if (color_spec == NULL) |
|
2071 |
{
|
|
2072 |
if (alpha_spec) |
|
2073 |
meta_alpha_gradient_spec_free (alpha_spec); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2074 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2075 |
add_context_to_error (error, context); |
2076 |
return; |
|
2077 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2078 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2079 |
op = meta_draw_op_new (META_DRAW_TINT); |
2080 |
||
2081 |
op->data.tint.color_spec = color_spec; |
|
2082 |
op->data.tint.alpha_spec = alpha_spec; |
|
2083 |
||
2084 |
op->data.tint.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2085 |
op->data.tint.y = meta_draw_spec_new (info->theme, y, NULL); |
|
2086 |
op->data.tint.width = meta_draw_spec_new (info->theme, width, NULL); |
|
2087 |
op->data.tint.height = meta_draw_spec_new (info->theme, height, NULL); |
|
2088 |
||
2089 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2090 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2091 |
meta_draw_op_list_append (info->op_list, op); |
2092 |
||
2093 |
push_state (info, STATE_TINT); |
|
2094 |
}
|
|
2095 |
else if (ELEMENT_IS ("gradient")) |
|
2096 |
{
|
|
2097 |
const char *x; |
|
2098 |
const char *y; |
|
2099 |
const char *width; |
|
2100 |
const char *height; |
|
2101 |
const char *type; |
|
2102 |
const char *alpha; |
|
2103 |
MetaAlphaGradientSpec *alpha_spec; |
|
2104 |
MetaGradientType type_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2105 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2106 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2107 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2108 |
"!type", &type, |
2109 |
"!x", &x, "!y", &y, |
|
2110 |
"!width", &width, "!height", &height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2111 |
"alpha", &alpha, |
2112 |
NULL)) |
|
2113 |
return; |
|
2114 |
||
2115 |
#if 0
|
|
2116 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
2117 |
return;
|
|
2118 |
||
2119 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
2120 |
return;
|
|
2121 |
||
2122 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
2123 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2124 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2125 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
2126 |
return;
|
|
2127 |
#endif
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2128 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2129 |
type_val = meta_gradient_type_from_string (type); |
2130 |
if (type_val == META_GRADIENT_LAST) |
|
2131 |
{
|
|
2132 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2133 |
_("Did not understand value \"%s\" for type of gradient"), |
|
2134 |
type); |
|
2135 |
return; |
|
2136 |
}
|
|
2137 |
||
2138 |
alpha_spec = NULL; |
|
2139 |
if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) |
|
2140 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2141 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2142 |
g_assert (info->op == NULL); |
2143 |
info->op = meta_draw_op_new (META_DRAW_GRADIENT); |
|
2144 |
||
2145 |
info->op->data.gradient.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2146 |
info->op->data.gradient.y = meta_draw_spec_new (info->theme, y, NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2147 |
info->op->data.gradient.width = meta_draw_spec_new (info->theme, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2148 |
width, NULL); |
2149 |
info->op->data.gradient.height = meta_draw_spec_new (info->theme, |
|
2150 |
height, NULL); |
|
2151 |
||
2152 |
info->op->data.gradient.gradient_spec = meta_gradient_spec_new (type_val); |
|
2153 |
||
2154 |
info->op->data.gradient.alpha_spec = alpha_spec; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2155 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2156 |
push_state (info, STATE_GRADIENT); |
2157 |
||
2158 |
/* op gets appended on close tag */
|
|
2159 |
}
|
|
2160 |
else if (ELEMENT_IS ("image")) |
|
2161 |
{
|
|
2162 |
MetaDrawOp *op; |
|
2163 |
const char *filename; |
|
2164 |
const char *x; |
|
2165 |
const char *y; |
|
2166 |
const char *width; |
|
2167 |
const char *height; |
|
2168 |
const char *alpha; |
|
2169 |
const char *colorize; |
|
2170 |
const char *fill_type; |
|
2171 |
MetaAlphaGradientSpec *alpha_spec; |
|
2172 |
GdkPixbuf *pixbuf; |
|
2173 |
MetaColorSpec *colorize_spec = NULL; |
|
2174 |
MetaImageFillType fill_type_val; |
|
2175 |
int h, w, c; |
|
2176 |
int pixbuf_width, pixbuf_height, pixbuf_n_channels, pixbuf_rowstride; |
|
2177 |
guchar *pixbuf_pixels; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2178 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2179 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2180 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2181 |
"!x", &x, "!y", &y, |
2182 |
"!width", &width, "!height", &height, |
|
2183 |
"alpha", &alpha, "!filename", &filename, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2184 |
"colorize", &colorize, |
2185 |
"fill_type", &fill_type, |
|
2186 |
NULL)) |
|
2187 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2188 |
|
2189 |
#if 0
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2190 |
if (!check_expression (x, TRUE, info->theme, context, error))
|
2191 |
return;
|
|
2192 |
||
2193 |
if (!check_expression (y, TRUE, info->theme, context, error))
|
|
2194 |
return;
|
|
2195 |
||
2196 |
if (!check_expression (width, TRUE, info->theme, context, error))
|
|
2197 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2198 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2199 |
if (!check_expression (height, TRUE, info->theme, context, error))
|
2200 |
return;
|
|
2201 |
#endif
|
|
2202 |
fill_type_val = META_IMAGE_FILL_SCALE; |
|
2203 |
if (fill_type) |
|
2204 |
{
|
|
2205 |
fill_type_val = meta_image_fill_type_from_string (fill_type); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2206 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2207 |
if (((int) fill_type_val) == -1) |
2208 |
{
|
|
2209 |
set_error (error, context, G_MARKUP_ERROR, |
|
2210 |
G_MARKUP_ERROR_PARSE, |
|
2211 |
_("Did not understand fill type \"%s\" for <%s> element"), |
|
2212 |
fill_type, element_name); |
|
2213 |
}
|
|
2214 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2215 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2216 |
/* Check last so we don't have to free it when other
|
2217 |
* stuff fails.
|
|
2218 |
*
|
|
2219 |
* If it's a theme image, ask for it at 64px, which is
|
|
2220 |
* the largest possible. We scale it anyway.
|
|
2221 |
*/
|
|
2222 |
pixbuf = meta_theme_load_image (info->theme, filename, 64, error); |
|
2223 |
||
2224 |
if (pixbuf == NULL) |
|
2225 |
{
|
|
2226 |
add_context_to_error (error, context); |
|
2227 |
return; |
|
2228 |
}
|
|
2229 |
||
2230 |
if (colorize) |
|
2231 |
{
|
|
2232 |
colorize_spec = parse_color (info->theme, colorize, error); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2233 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2234 |
if (colorize_spec == NULL) |
2235 |
{
|
|
2236 |
add_context_to_error (error, context); |
|
2237 |
g_object_unref (G_OBJECT (pixbuf)); |
|
2238 |
return; |
|
2239 |
}
|
|
2240 |
}
|
|
2241 |
||
2242 |
alpha_spec = NULL; |
|
2243 |
if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) |
|
2244 |
{
|
|
2245 |
g_object_unref (G_OBJECT (pixbuf)); |
|
2246 |
return; |
|
2247 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2248 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2249 |
op = meta_draw_op_new (META_DRAW_IMAGE); |
2250 |
||
2251 |
op->data.image.pixbuf = pixbuf; |
|
2252 |
op->data.image.colorize_spec = colorize_spec; |
|
2253 |
||
2254 |
op->data.image.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2255 |
op->data.image.y = meta_draw_spec_new (info->theme, y, NULL); |
|
2256 |
op->data.image.width = meta_draw_spec_new (info->theme, width, NULL); |
|
2257 |
op->data.image.height = meta_draw_spec_new (info->theme, height, NULL); |
|
2258 |
||
2259 |
op->data.image.alpha_spec = alpha_spec; |
|
2260 |
op->data.image.fill_type = fill_type_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2261 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2262 |
/* Check for vertical & horizontal stripes */
|
2263 |
pixbuf_n_channels = gdk_pixbuf_get_n_channels(pixbuf); |
|
2264 |
pixbuf_width = gdk_pixbuf_get_width(pixbuf); |
|
2265 |
pixbuf_height = gdk_pixbuf_get_height(pixbuf); |
|
2266 |
pixbuf_rowstride = gdk_pixbuf_get_rowstride(pixbuf); |
|
2267 |
pixbuf_pixels = gdk_pixbuf_get_pixels(pixbuf); |
|
2268 |
||
2269 |
/* Check for horizontal stripes */
|
|
2270 |
for (h = 0; h < pixbuf_height; h++) |
|
2271 |
{
|
|
2272 |
for (w = 1; w < pixbuf_width; w++) |
|
2273 |
{
|
|
2274 |
for (c = 0; c < pixbuf_n_channels; c++) |
|
2275 |
{
|
|
2276 |
if (pixbuf_pixels[(h * pixbuf_rowstride) + c] != |
|
2277 |
pixbuf_pixels[(h * pixbuf_rowstride) + w + c]) |
|
2278 |
break; |
|
2279 |
}
|
|
2280 |
if (c < pixbuf_n_channels) |
|
2281 |
break; |
|
2282 |
}
|
|
2283 |
if (w < pixbuf_width) |
|
2284 |
break; |
|
2285 |
}
|
|
2286 |
||
2287 |
if (h >= pixbuf_height) |
|
2288 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2289 |
op->data.image.horizontal_stripes = TRUE; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2290 |
}
|
2291 |
else
|
|
2292 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2293 |
op->data.image.horizontal_stripes = FALSE; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2294 |
}
|
2295 |
||
2296 |
/* Check for vertical stripes */
|
|
2297 |
for (w = 0; w < pixbuf_width; w++) |
|
2298 |
{
|
|
2299 |
for (h = 1; h < pixbuf_height; h++) |
|
2300 |
{
|
|
2301 |
for (c = 0; c < pixbuf_n_channels; c++) |
|
2302 |
{
|
|
2303 |
if (pixbuf_pixels[w + c] != |
|
2304 |
pixbuf_pixels[(h * pixbuf_rowstride) + w + c]) |
|
2305 |
break; |
|
2306 |
}
|
|
2307 |
if (c < pixbuf_n_channels) |
|
2308 |
break; |
|
2309 |
}
|
|
2310 |
if (h < pixbuf_height) |
|
2311 |
break; |
|
2312 |
}
|
|
2313 |
||
2314 |
if (w >= pixbuf_width) |
|
2315 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2316 |
op->data.image.vertical_stripes = TRUE; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2317 |
}
|
2318 |
else
|
|
2319 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2320 |
op->data.image.vertical_stripes = FALSE; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2321 |
}
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2322 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2323 |
g_assert (info->op_list); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2324 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2325 |
meta_draw_op_list_append (info->op_list, op); |
2326 |
||
2327 |
push_state (info, STATE_IMAGE); |
|
2328 |
}
|
|
2329 |
else if (ELEMENT_IS ("gtk_arrow")) |
|
2330 |
{
|
|
2331 |
MetaDrawOp *op; |
|
2332 |
const char *state; |
|
2333 |
const char *shadow; |
|
2334 |
const char *arrow; |
|
2335 |
const char *x; |
|
2336 |
const char *y; |
|
2337 |
const char *width; |
|
2338 |
const char *height; |
|
2339 |
const char *filled; |
|
2340 |
gboolean filled_val; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
2341 |
GtkStateFlags state_val; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2342 |
GtkShadowType shadow_val; |
2343 |
GtkArrowType arrow_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2344 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2345 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2346 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2347 |
"!state", &state, |
2348 |
"!shadow", &shadow, |
|
2349 |
"!arrow", &arrow, |
|
2350 |
"!x", &x, "!y", &y, |
|
2351 |
"!width", &width, "!height", &height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2352 |
"filled", &filled, |
2353 |
NULL)) |
|
2354 |
return; |
|
2355 |
||
2356 |
#if 0
|
|
2357 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
2358 |
return;
|
|
2359 |
||
2360 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
2361 |
return;
|
|
2362 |
||
2363 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
2364 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2365 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2366 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
2367 |
return;
|
|
2368 |
#endif
|
|
2369 |
filled_val = TRUE; |
|
2370 |
if (filled && !parse_boolean (filled, &filled_val, context, error)) |
|
2371 |
return; |
|
2372 |
||
2373 |
state_val = meta_gtk_state_from_string (state); |
|
2374 |
if (((int) state_val) == -1) |
|
2375 |
{
|
|
2376 |
set_error (error, context, G_MARKUP_ERROR, |
|
2377 |
G_MARKUP_ERROR_PARSE, |
|
2378 |
_("Did not understand state \"%s\" for <%s> element"), |
|
2379 |
state, element_name); |
|
2380 |
return; |
|
2381 |
}
|
|
2382 |
||
2383 |
shadow_val = meta_gtk_shadow_from_string (shadow); |
|
2384 |
if (((int) shadow_val) == -1) |
|
2385 |
{
|
|
2386 |
set_error (error, context, G_MARKUP_ERROR, |
|
2387 |
G_MARKUP_ERROR_PARSE, |
|
2388 |
_("Did not understand shadow \"%s\" for <%s> element"), |
|
2389 |
shadow, element_name); |
|
2390 |
return; |
|
2391 |
}
|
|
2392 |
||
2393 |
arrow_val = meta_gtk_arrow_from_string (arrow); |
|
2394 |
if (((int) arrow_val) == -1) |
|
2395 |
{
|
|
2396 |
set_error (error, context, G_MARKUP_ERROR, |
|
2397 |
G_MARKUP_ERROR_PARSE, |
|
2398 |
_("Did not understand arrow \"%s\" for <%s> element"), |
|
2399 |
arrow, element_name); |
|
2400 |
return; |
|
2401 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2402 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2403 |
op = meta_draw_op_new (META_DRAW_GTK_ARROW); |
2404 |
||
2405 |
op->data.gtk_arrow.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2406 |
op->data.gtk_arrow.y = meta_draw_spec_new (info->theme, y, NULL); |
|
2407 |
op->data.gtk_arrow.width = meta_draw_spec_new (info->theme, width, NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2408 |
op->data.gtk_arrow.height = meta_draw_spec_new (info->theme, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2409 |
height, NULL); |
2410 |
||
2411 |
op->data.gtk_arrow.filled = filled_val; |
|
2412 |
op->data.gtk_arrow.state = state_val; |
|
2413 |
op->data.gtk_arrow.shadow = shadow_val; |
|
2414 |
op->data.gtk_arrow.arrow = arrow_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2415 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2416 |
g_assert (info->op_list); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2417 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2418 |
meta_draw_op_list_append (info->op_list, op); |
2419 |
||
2420 |
push_state (info, STATE_GTK_ARROW); |
|
2421 |
}
|
|
2422 |
else if (ELEMENT_IS ("gtk_box")) |
|
2423 |
{
|
|
2424 |
MetaDrawOp *op; |
|
2425 |
const char *state; |
|
2426 |
const char *shadow; |
|
2427 |
const char *x; |
|
2428 |
const char *y; |
|
2429 |
const char *width; |
|
2430 |
const char *height; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
2431 |
GtkStateFlags state_val; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2432 |
GtkShadowType shadow_val; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2433 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2434 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2435 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2436 |
"!state", &state, |
2437 |
"!shadow", &shadow, |
|
2438 |
"!x", &x, "!y", &y, |
|
2439 |
"!width", &width, "!height", &height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2440 |
NULL)) |
2441 |
return; |
|
2442 |
||
2443 |
#if 0
|
|
2444 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
2445 |
return;
|
|
2446 |
||
2447 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
2448 |
return;
|
|
2449 |
||
2450 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
2451 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2452 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2453 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
2454 |
return;
|
|
2455 |
#endif
|
|
2456 |
state_val = meta_gtk_state_from_string (state); |
|
2457 |
if (((int) state_val) == -1) |
|
2458 |
{
|
|
2459 |
set_error (error, context, G_MARKUP_ERROR, |
|
2460 |
G_MARKUP_ERROR_PARSE, |
|
2461 |
_("Did not understand state \"%s\" for <%s> element"), |
|
2462 |
state, element_name); |
|
2463 |
return; |
|
2464 |
}
|
|
2465 |
||
2466 |
shadow_val = meta_gtk_shadow_from_string (shadow); |
|
2467 |
if (((int) shadow_val) == -1) |
|
2468 |
{
|
|
2469 |
set_error (error, context, G_MARKUP_ERROR, |
|
2470 |
G_MARKUP_ERROR_PARSE, |
|
2471 |
_("Did not understand shadow \"%s\" for <%s> element"), |
|
2472 |
shadow, element_name); |
|
2473 |
return; |
|
2474 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2475 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2476 |
op = meta_draw_op_new (META_DRAW_GTK_BOX); |
2477 |
||
2478 |
op->data.gtk_box.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2479 |
op->data.gtk_box.y = meta_draw_spec_new (info->theme, y, NULL); |
|
2480 |
op->data.gtk_box.width = meta_draw_spec_new (info->theme, width, NULL); |
|
2481 |
op->data.gtk_box.height = meta_draw_spec_new (info->theme, height, NULL); |
|
2482 |
||
2483 |
op->data.gtk_box.state = state_val; |
|
2484 |
op->data.gtk_box.shadow = shadow_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2485 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2486 |
g_assert (info->op_list); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2487 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2488 |
meta_draw_op_list_append (info->op_list, op); |
2489 |
||
2490 |
push_state (info, STATE_GTK_BOX); |
|
2491 |
}
|
|
2492 |
else if (ELEMENT_IS ("gtk_vline")) |
|
2493 |
{
|
|
2494 |
MetaDrawOp *op; |
|
2495 |
const char *state; |
|
2496 |
const char *x; |
|
2497 |
const char *y1; |
|
2498 |
const char *y2; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
2499 |
GtkStateFlags state_val; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2500 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2501 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2502 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2503 |
"!state", &state, |
2504 |
"!x", &x, "!y1", &y1, "!y2", &y2, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2505 |
NULL)) |
2506 |
return; |
|
2507 |
||
2508 |
#if 0
|
|
2509 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
2510 |
return;
|
|
2511 |
||
2512 |
if (!check_expression (y1, FALSE, info->theme, context, error))
|
|
2513 |
return;
|
|
2514 |
||
2515 |
if (!check_expression (y2, FALSE, info->theme, context, error))
|
|
2516 |
return;
|
|
2517 |
#endif
|
|
2518 |
||
2519 |
state_val = meta_gtk_state_from_string (state); |
|
2520 |
if (((int) state_val) == -1) |
|
2521 |
{
|
|
2522 |
set_error (error, context, G_MARKUP_ERROR, |
|
2523 |
G_MARKUP_ERROR_PARSE, |
|
2524 |
_("Did not understand state \"%s\" for <%s> element"), |
|
2525 |
state, element_name); |
|
2526 |
return; |
|
2527 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2528 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2529 |
op = meta_draw_op_new (META_DRAW_GTK_VLINE); |
2530 |
||
2531 |
op->data.gtk_vline.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2532 |
op->data.gtk_vline.y1 = meta_draw_spec_new (info->theme, y1, NULL); |
|
2533 |
op->data.gtk_vline.y2 = meta_draw_spec_new (info->theme, y2, NULL); |
|
2534 |
||
2535 |
op->data.gtk_vline.state = state_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2536 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2537 |
g_assert (info->op_list); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2538 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2539 |
meta_draw_op_list_append (info->op_list, op); |
2540 |
||
2541 |
push_state (info, STATE_GTK_VLINE); |
|
2542 |
}
|
|
2543 |
else if (ELEMENT_IS ("icon")) |
|
2544 |
{
|
|
2545 |
MetaDrawOp *op; |
|
2546 |
const char *x; |
|
2547 |
const char *y; |
|
2548 |
const char *width; |
|
2549 |
const char *height; |
|
2550 |
const char *alpha; |
|
2551 |
const char *fill_type; |
|
2552 |
MetaAlphaGradientSpec *alpha_spec; |
|
2553 |
MetaImageFillType fill_type_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2554 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2555 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2556 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2557 |
"!x", &x, "!y", &y, |
2558 |
"!width", &width, "!height", &height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2559 |
"alpha", &alpha, |
2560 |
"fill_type", &fill_type, |
|
2561 |
NULL)) |
|
2562 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2563 |
|
2564 |
#if 0
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2565 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
2566 |
return;
|
|
2567 |
||
2568 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
2569 |
return;
|
|
2570 |
||
2571 |
if (!check_expression (width, FALSE, info->theme, context, error))
|
|
2572 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2573 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2574 |
if (!check_expression (height, FALSE, info->theme, context, error))
|
2575 |
return;
|
|
2576 |
#endif
|
|
2577 |
fill_type_val = META_IMAGE_FILL_SCALE; |
|
2578 |
if (fill_type) |
|
2579 |
{
|
|
2580 |
fill_type_val = meta_image_fill_type_from_string (fill_type); |
|
2581 |
||
2582 |
if (((int) fill_type_val) == -1) |
|
2583 |
{
|
|
2584 |
set_error (error, context, G_MARKUP_ERROR, |
|
2585 |
G_MARKUP_ERROR_PARSE, |
|
2586 |
_("Did not understand fill type \"%s\" for <%s> element"), |
|
2587 |
fill_type, element_name); |
|
2588 |
}
|
|
2589 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2590 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2591 |
alpha_spec = NULL; |
2592 |
if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) |
|
2593 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2594 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2595 |
op = meta_draw_op_new (META_DRAW_ICON); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2596 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2597 |
op->data.icon.x = meta_draw_spec_new (info->theme, x, NULL); |
2598 |
op->data.icon.y = meta_draw_spec_new (info->theme, y, NULL); |
|
2599 |
op->data.icon.width = meta_draw_spec_new (info->theme, width, NULL); |
|
2600 |
op->data.icon.height = meta_draw_spec_new (info->theme, height, NULL); |
|
2601 |
||
2602 |
op->data.icon.alpha_spec = alpha_spec; |
|
2603 |
op->data.icon.fill_type = fill_type_val; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2604 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2605 |
g_assert (info->op_list); |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2606 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2607 |
meta_draw_op_list_append (info->op_list, op); |
2608 |
||
2609 |
push_state (info, STATE_ICON); |
|
2610 |
}
|
|
2611 |
else if (ELEMENT_IS ("title")) |
|
2612 |
{
|
|
2613 |
MetaDrawOp *op; |
|
2614 |
const char *color; |
|
2615 |
const char *x; |
|
2616 |
const char *y; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2617 |
const char *ellipsize_width; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2618 |
MetaColorSpec *color_spec; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2619 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2620 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2621 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2622 |
"!color", &color, |
2623 |
"!x", &x, "!y", &y, |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2624 |
"ellipsize_width", &ellipsize_width, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2625 |
NULL)) |
2626 |
return; |
|
2627 |
||
2628 |
#if 0
|
|
2629 |
if (!check_expression (x, FALSE, info->theme, context, error))
|
|
2630 |
return;
|
|
2631 |
||
2632 |
if (!check_expression (y, FALSE, info->theme, context, error))
|
|
2633 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2634 |
|
2635 |
if (!check_expression (ellipsize_width, FALSE, info->theme, context, error))
|
|
2636 |
return;
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2637 |
#endif
|
2638 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2639 |
if (ellipsize_width && peek_required_version (info) < 3001) |
2640 |
{
|
|
2641 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2642 |
ATTRIBUTE_NOT_FOUND, "ellipsize_width", element_name); |
|
2643 |
return; |
|
2644 |
}
|
|
2645 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2646 |
/* Check last so we don't have to free it when other
|
2647 |
* stuff fails
|
|
2648 |
*/
|
|
2649 |
color_spec = parse_color (info->theme, color, error); |
|
2650 |
if (color_spec == NULL) |
|
2651 |
{
|
|
2652 |
add_context_to_error (error, context); |
|
2653 |
return; |
|
2654 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2655 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2656 |
op = meta_draw_op_new (META_DRAW_TITLE); |
2657 |
||
2658 |
op->data.title.color_spec = color_spec; |
|
2659 |
||
2660 |
op->data.title.x = meta_draw_spec_new (info->theme, x, NULL); |
|
2661 |
op->data.title.y = meta_draw_spec_new (info->theme, y, NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2662 |
if (ellipsize_width) |
2663 |
op->data.title.ellipsize_width = meta_draw_spec_new (info->theme, ellipsize_width, NULL); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2664 |
|
2665 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2666 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2667 |
meta_draw_op_list_append (info->op_list, op); |
2668 |
||
2669 |
push_state (info, STATE_TITLE); |
|
2670 |
}
|
|
2671 |
else if (ELEMENT_IS ("include")) |
|
2672 |
{
|
|
2673 |
MetaDrawOp *op; |
|
2674 |
const char *name; |
|
2675 |
const char *x; |
|
2676 |
const char *y; |
|
2677 |
const char *width; |
|
2678 |
const char *height; |
|
2679 |
MetaDrawOpList *op_list; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2680 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2681 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2682 |
error, |
|
2683 |
"x", &x, "y", &y, |
|
2684 |
"width", &width, "height", &height, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2685 |
"!name", &name, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2686 |
NULL)) |
2687 |
return; |
|
2688 |
||
2689 |
/* x/y/width/height default to 0,0,width,height - should
|
|
2690 |
* probably do this for all the draw ops
|
|
2691 |
*/
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2692 |
#if 0
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2693 |
if (x && !check_expression (x, FALSE, info->theme, context, error))
|
2694 |
return;
|
|
2695 |
||
2696 |
if (y && !check_expression (y, FALSE, info->theme, context, error))
|
|
2697 |
return;
|
|
2698 |
||
2699 |
if (width && !check_expression (width, FALSE, info->theme, context, error))
|
|
2700 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2701 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2702 |
if (height && !check_expression (height, FALSE, info->theme, context, error))
|
2703 |
return;
|
|
2704 |
#endif
|
|
2705 |
||
2706 |
op_list = meta_theme_lookup_draw_op_list (info->theme, |
|
2707 |
name); |
|
2708 |
if (op_list == NULL) |
|
2709 |
{
|
|
2710 |
set_error (error, context, G_MARKUP_ERROR, |
|
2711 |
G_MARKUP_ERROR_PARSE, |
|
2712 |
_("No <draw_ops> called \"%s\" has been defined"), |
|
2713 |
name); |
|
2714 |
return; |
|
2715 |
}
|
|
2716 |
||
2717 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2718 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2719 |
if (op_list == info->op_list || |
2720 |
meta_draw_op_list_contains (op_list, info->op_list)) |
|
2721 |
{
|
|
2722 |
set_error (error, context, G_MARKUP_ERROR, |
|
2723 |
G_MARKUP_ERROR_PARSE, |
|
2724 |
_("Including draw_ops \"%s\" here would create a circular reference"), |
|
2725 |
name); |
|
2726 |
return; |
|
2727 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2728 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2729 |
op = meta_draw_op_new (META_DRAW_OP_LIST); |
2730 |
||
2731 |
meta_draw_op_list_ref (op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2732 |
op->data.op_list.op_list = op_list; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2733 |
|
2734 |
op->data.op_list.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL); |
|
2735 |
op->data.op_list.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2736 |
op->data.op_list.width = meta_draw_spec_new (info->theme, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2737 |
width ? width : "width", |
2738 |
NULL); |
|
2739 |
op->data.op_list.height = meta_draw_spec_new (info->theme, |
|
2740 |
height ? height : "height", |
|
2741 |
NULL); |
|
2742 |
||
2743 |
meta_draw_op_list_append (info->op_list, op); |
|
2744 |
||
2745 |
push_state (info, STATE_INCLUDE); |
|
2746 |
}
|
|
2747 |
else if (ELEMENT_IS ("tile")) |
|
2748 |
{
|
|
2749 |
MetaDrawOp *op; |
|
2750 |
const char *name; |
|
2751 |
const char *x; |
|
2752 |
const char *y; |
|
2753 |
const char *width; |
|
2754 |
const char *height; |
|
2755 |
const char *tile_xoffset; |
|
2756 |
const char *tile_yoffset; |
|
2757 |
const char *tile_width; |
|
2758 |
const char *tile_height; |
|
2759 |
MetaDrawOpList *op_list; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2760 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2761 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2762 |
error, |
|
2763 |
"x", &x, "y", &y, |
|
2764 |
"width", &width, "height", &height, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2765 |
"!name", &name, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2766 |
"tile_xoffset", &tile_xoffset, |
2767 |
"tile_yoffset", &tile_yoffset, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2768 |
"!tile_width", &tile_width, |
2769 |
"!tile_height", &tile_height, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2770 |
NULL)) |
2771 |
return; |
|
2772 |
||
2773 |
/* These default to 0 */
|
|
2774 |
#if 0
|
|
2775 |
if (tile_xoffset && !check_expression (tile_xoffset, FALSE, info->theme, context, error))
|
|
2776 |
return;
|
|
2777 |
||
2778 |
if (tile_yoffset && !check_expression (tile_yoffset, FALSE, info->theme, context, error))
|
|
2779 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2780 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2781 |
/* x/y/width/height default to 0,0,width,height - should
|
2782 |
* probably do this for all the draw ops
|
|
2783 |
*/
|
|
2784 |
if (x && !check_expression (x, FALSE, info->theme, context, error))
|
|
2785 |
return;
|
|
2786 |
||
2787 |
if (y && !check_expression (y, FALSE, info->theme, context, error))
|
|
2788 |
return;
|
|
2789 |
||
2790 |
if (width && !check_expression (width, FALSE, info->theme, context, error))
|
|
2791 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2792 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2793 |
if (height && !check_expression (height, FALSE, info->theme, context, error))
|
2794 |
return;
|
|
2795 |
||
2796 |
if (!check_expression (tile_width, FALSE, info->theme, context, error))
|
|
2797 |
return;
|
|
2798 |
||
2799 |
if (!check_expression (tile_height, FALSE, info->theme, context, error))
|
|
2800 |
return;
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2801 |
#endif
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2802 |
op_list = meta_theme_lookup_draw_op_list (info->theme, |
2803 |
name); |
|
2804 |
if (op_list == NULL) |
|
2805 |
{
|
|
2806 |
set_error (error, context, G_MARKUP_ERROR, |
|
2807 |
G_MARKUP_ERROR_PARSE, |
|
2808 |
_("No <draw_ops> called \"%s\" has been defined"), |
|
2809 |
name); |
|
2810 |
return; |
|
2811 |
}
|
|
2812 |
||
2813 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2814 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2815 |
if (op_list == info->op_list || |
2816 |
meta_draw_op_list_contains (op_list, info->op_list)) |
|
2817 |
{
|
|
2818 |
set_error (error, context, G_MARKUP_ERROR, |
|
2819 |
G_MARKUP_ERROR_PARSE, |
|
2820 |
_("Including draw_ops \"%s\" here would create a circular reference"), |
|
2821 |
name); |
|
2822 |
return; |
|
2823 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2824 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2825 |
op = meta_draw_op_new (META_DRAW_TILE); |
2826 |
||
2827 |
meta_draw_op_list_ref (op_list); |
|
2828 |
||
2829 |
op->data.tile.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL); |
|
2830 |
op->data.tile.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL); |
|
2831 |
op->data.tile.width = meta_draw_spec_new (info->theme, |
|
2832 |
width ? width : "width", |
|
2833 |
NULL); |
|
2834 |
op->data.tile.height = meta_draw_spec_new (info->theme, |
|
2835 |
height ? height : "height", |
|
2836 |
NULL); |
|
2837 |
op->data.tile.tile_xoffset = meta_draw_spec_new (info->theme, |
|
2838 |
tile_xoffset ? tile_xoffset : "0", |
|
2839 |
NULL); |
|
2840 |
op->data.tile.tile_yoffset = meta_draw_spec_new (info->theme, |
|
2841 |
tile_yoffset ? tile_yoffset : "0", |
|
2842 |
NULL); |
|
2843 |
op->data.tile.tile_width = meta_draw_spec_new (info->theme, tile_width, NULL); |
|
2844 |
op->data.tile.tile_height = meta_draw_spec_new (info->theme, tile_height, NULL); |
|
2845 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2846 |
op->data.tile.op_list = op_list; |
2847 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2848 |
meta_draw_op_list_append (info->op_list, op); |
2849 |
||
2850 |
push_state (info, STATE_TILE); |
|
2851 |
}
|
|
2852 |
else
|
|
2853 |
{
|
|
2854 |
set_error (error, context, |
|
2855 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2856 |
_("Element <%s> is not allowed below <%s>"), |
|
2857 |
element_name, "draw_ops"); |
|
2858 |
}
|
|
2859 |
}
|
|
2860 |
||
2861 |
static void |
|
2862 |
parse_gradient_element (GMarkupParseContext *context, |
|
2863 |
const gchar *element_name, |
|
2864 |
const gchar **attribute_names, |
|
2865 |
const gchar **attribute_values, |
|
2866 |
ParseInfo *info, |
|
2867 |
GError **error) |
|
2868 |
{
|
|
2869 |
g_return_if_fail (peek_state (info) == STATE_GRADIENT); |
|
2870 |
||
2871 |
if (ELEMENT_IS ("color")) |
|
2872 |
{
|
|
2873 |
const char *value = NULL; |
|
2874 |
MetaColorSpec *color_spec; |
|
2875 |
||
2876 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
2877 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2878 |
"!value", &value, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2879 |
NULL)) |
2880 |
return; |
|
2881 |
||
2882 |
color_spec = parse_color (info->theme, value, error); |
|
2883 |
if (color_spec == NULL) |
|
2884 |
{
|
|
2885 |
add_context_to_error (error, context); |
|
2886 |
return; |
|
2887 |
}
|
|
2888 |
||
2889 |
g_assert (info->op); |
|
2890 |
g_assert (info->op->type == META_DRAW_GRADIENT); |
|
2891 |
g_assert (info->op->data.gradient.gradient_spec != NULL); |
|
2892 |
info->op->data.gradient.gradient_spec->color_specs = |
|
2893 |
g_slist_append (info->op->data.gradient.gradient_spec->color_specs, |
|
2894 |
color_spec); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2895 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2896 |
push_state (info, STATE_COLOR); |
2897 |
}
|
|
2898 |
else
|
|
2899 |
{
|
|
2900 |
set_error (error, context, |
|
2901 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2902 |
_("Element <%s> is not allowed below <%s>"), |
|
2903 |
element_name, "gradient"); |
|
2904 |
}
|
|
2905 |
}
|
|
2906 |
||
2907 |
static void |
|
2908 |
parse_style_element (GMarkupParseContext *context, |
|
2909 |
const gchar *element_name, |
|
2910 |
const gchar **attribute_names, |
|
2911 |
const gchar **attribute_values, |
|
2912 |
ParseInfo *info, |
|
2913 |
GError **error) |
|
2914 |
{
|
|
2915 |
g_return_if_fail (peek_state (info) == STATE_FRAME_STYLE); |
|
2916 |
||
2917 |
g_assert (info->style); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2918 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2919 |
if (ELEMENT_IS ("piece")) |
2920 |
{
|
|
2921 |
const char *position = NULL; |
|
2922 |
const char *draw_ops = NULL; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2923 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2924 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2925 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2926 |
"!position", &position, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2927 |
"draw_ops", &draw_ops, |
2928 |
NULL)) |
|
2929 |
return; |
|
2930 |
||
2931 |
info->piece = meta_frame_piece_from_string (position); |
|
2932 |
if (info->piece == META_FRAME_PIECE_LAST) |
|
2933 |
{
|
|
2934 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2935 |
_("Unknown position \"%s\" for frame piece"), |
|
2936 |
position); |
|
2937 |
return; |
|
2938 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2939 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2940 |
if (info->style->pieces[info->piece] != NULL) |
2941 |
{
|
|
2942 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2943 |
_("Frame style already has a piece at position %s"), |
|
2944 |
position); |
|
2945 |
return; |
|
2946 |
}
|
|
2947 |
||
2948 |
g_assert (info->op_list == NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2949 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2950 |
if (draw_ops) |
2951 |
{
|
|
2952 |
MetaDrawOpList *op_list; |
|
2953 |
||
2954 |
op_list = meta_theme_lookup_draw_op_list (info->theme, |
|
2955 |
draw_ops); |
|
2956 |
||
2957 |
if (op_list == NULL) |
|
2958 |
{
|
|
2959 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2960 |
_("No <draw_ops> with the name \"%s\" has been defined"), |
|
2961 |
draw_ops); |
|
2962 |
return; |
|
2963 |
}
|
|
2964 |
||
2965 |
meta_draw_op_list_ref (op_list); |
|
2966 |
info->op_list = op_list; |
|
2967 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2968 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2969 |
push_state (info, STATE_PIECE); |
2970 |
}
|
|
2971 |
else if (ELEMENT_IS ("button")) |
|
2972 |
{
|
|
2973 |
const char *function = NULL; |
|
2974 |
const char *state = NULL; |
|
2975 |
const char *draw_ops = NULL; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2976 |
gint required_version; |
2977 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2978 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
2979 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
2980 |
"!function", &function, |
2981 |
"!state", &state, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2982 |
"draw_ops", &draw_ops, |
2983 |
NULL)) |
|
2984 |
return; |
|
2985 |
||
2986 |
info->button_type = meta_button_type_from_string (function, info->theme); |
|
2987 |
if (info->button_type == META_BUTTON_TYPE_LAST) |
|
2988 |
{
|
|
2989 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
2990 |
_("Unknown function \"%s\" for button"), |
|
2991 |
function); |
|
2992 |
return; |
|
2993 |
}
|
|
2994 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2995 |
required_version = peek_required_version (info); |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2996 |
if (meta_theme_earliest_version_with_button (info->button_type) > |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
2997 |
(guint)required_version) |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
2998 |
{
|
2999 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3000 |
_("Button function \"%s\" does not exist in this version (%d, need %d)"), |
|
3001 |
function, |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3002 |
required_version, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3003 |
meta_theme_earliest_version_with_button (info->button_type) |
3004 |
);
|
|
3005 |
return; |
|
3006 |
}
|
|
3007 |
||
3008 |
info->button_state = meta_button_state_from_string (state); |
|
3009 |
if (info->button_state == META_BUTTON_STATE_LAST) |
|
3010 |
{
|
|
3011 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3012 |
_("Unknown state \"%s\" for button"), |
|
3013 |
state); |
|
3014 |
return; |
|
3015 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3016 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3017 |
if (info->style->buttons[info->button_type][info->button_state] != NULL) |
3018 |
{
|
|
3019 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3020 |
_("Frame style already has a button for function %s state %s"), |
|
3021 |
function, state); |
|
3022 |
return; |
|
3023 |
}
|
|
3024 |
||
3025 |
g_assert (info->op_list == NULL); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3026 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3027 |
if (draw_ops) |
3028 |
{
|
|
3029 |
MetaDrawOpList *op_list; |
|
3030 |
||
3031 |
op_list = meta_theme_lookup_draw_op_list (info->theme, |
|
3032 |
draw_ops); |
|
3033 |
||
3034 |
if (op_list == NULL) |
|
3035 |
{
|
|
3036 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3037 |
_("No <draw_ops> with the name \"%s\" has been defined"), |
|
3038 |
draw_ops); |
|
3039 |
return; |
|
3040 |
}
|
|
3041 |
||
3042 |
meta_draw_op_list_ref (op_list); |
|
3043 |
info->op_list = op_list; |
|
3044 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3045 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3046 |
push_state (info, STATE_BUTTON); |
3047 |
}
|
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
3048 |
else if (ELEMENT_IS ("shadow")) |
3049 |
{
|
|
3050 |
const char *shadow_radius = NULL; |
|
3051 |
const char *shadow_opacity = NULL; |
|
3052 |
const char *shadow_color = NULL; |
|
3053 |
const char *shadow_x_offset = NULL; |
|
3054 |
const char *shadow_y_offset = NULL; |
|
3055 |
double shadow_radius_v, shadow_opacity_v; |
|
3056 |
int shadow_x_offset_v, shadow_y_offset_v; |
|
3057 |
MetaColorSpec *shadow_color_v; |
|
3058 |
||
3059 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
3060 |
error, |
|
3061 |
"radius", &shadow_radius, |
|
3062 |
"opacity", &shadow_opacity, |
|
3063 |
"color", &shadow_color, |
|
3064 |
"x_offset", &shadow_x_offset, |
|
3065 |
"y_offset", &shadow_y_offset, |
|
3066 |
NULL)) |
|
3067 |
return; |
|
3068 |
||
3069 |
parse_double (shadow_radius, &shadow_radius_v, context, error); |
|
3070 |
parse_double (shadow_opacity, &shadow_opacity_v, context, error); |
|
3071 |
parse_positive_integer (shadow_x_offset, &shadow_x_offset_v, context, info->theme, error); |
|
3072 |
parse_positive_integer (shadow_y_offset, &shadow_y_offset_v, context, info->theme, error); |
|
3073 |
shadow_color_v = parse_color (info->theme, shadow_color, error); |
|
3074 |
||
3075 |
if (!info->style->shadow_properties) |
|
3076 |
info->style->shadow_properties = meta_shadow_properties_new (); |
|
3077 |
||
3078 |
info->style->shadow_properties->shadow_radius = shadow_radius_v; |
|
3079 |
info->style->shadow_properties->shadow_opacity = shadow_opacity_v; |
|
3080 |
info->style->shadow_properties->shadow_x_offset = shadow_x_offset_v; |
|
3081 |
info->style->shadow_properties->shadow_y_offset = shadow_y_offset_v; |
|
3082 |
info->style->shadow_properties->shadow_color = shadow_color_v; |
|
3083 |
||
3084 |
push_state (info, STATE_SHADOW); |
|
3085 |
}
|
|
3086 |
else if (ELEMENT_IS ("padding")) |
|
3087 |
{
|
|
3088 |
const char *left = NULL; |
|
3089 |
const char *bottom = NULL; |
|
3090 |
const char *right = NULL; |
|
3091 |
int left_v, right_v, bottom_v; |
|
3092 |
||
3093 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
|
3094 |
error, |
|
3095 |
"left", &left, |
|
3096 |
"right", &right, |
|
3097 |
"bottom", &bottom, |
|
3098 |
NULL)) |
|
3099 |
return; |
|
3100 |
||
3101 |
parse_positive_integer (left, &left_v, context, info->theme, error); |
|
3102 |
parse_positive_integer (right, &right_v, context, info->theme, error); |
|
3103 |
parse_positive_integer (bottom, &bottom_v, context, info->theme, error); |
|
3104 |
||
3105 |
if (!info->style->invisible_grab_area_properties) |
|
3106 |
info->style->invisible_grab_area_properties = meta_invisible_grab_area_properties_new (); |
|
3107 |
||
3108 |
info->style->invisible_grab_area_properties->left = left_v; |
|
3109 |
info->style->invisible_grab_area_properties->right = right_v; |
|
3110 |
info->style->invisible_grab_area_properties->bottom = bottom_v; |
|
3111 |
||
3112 |
push_state (info, STATE_PADDING); |
|
3113 |
}
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3114 |
else
|
3115 |
{
|
|
3116 |
set_error (error, context, |
|
3117 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3118 |
_("Element <%s> is not allowed below <%s>"), |
|
3119 |
element_name, "frame_style"); |
|
3120 |
}
|
|
3121 |
}
|
|
3122 |
||
3123 |
static void |
|
3124 |
parse_style_set_element (GMarkupParseContext *context, |
|
3125 |
const gchar *element_name, |
|
3126 |
const gchar **attribute_names, |
|
3127 |
const gchar **attribute_values, |
|
3128 |
ParseInfo *info, |
|
3129 |
GError **error) |
|
3130 |
{
|
|
3131 |
g_return_if_fail (peek_state (info) == STATE_FRAME_STYLE_SET); |
|
3132 |
||
3133 |
if (ELEMENT_IS ("frame")) |
|
3134 |
{
|
|
3135 |
const char *focus = NULL; |
|
3136 |
const char *state = NULL; |
|
3137 |
const char *resize = NULL; |
|
3138 |
const char *style = NULL; |
|
3139 |
MetaFrameFocus frame_focus; |
|
3140 |
MetaFrameState frame_state; |
|
3141 |
MetaFrameResize frame_resize; |
|
3142 |
MetaFrameStyle *frame_style; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3143 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3144 |
if (!locate_attributes (context, element_name, attribute_names, attribute_values, |
3145 |
error, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
3146 |
"!focus", &focus, |
3147 |
"!state", &state, |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3148 |
"resize", &resize, |
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
3149 |
"!style", &style, |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3150 |
NULL)) |
3151 |
return; |
|
3152 |
||
3153 |
frame_focus = meta_frame_focus_from_string (focus); |
|
3154 |
if (frame_focus == META_FRAME_FOCUS_LAST) |
|
3155 |
{
|
|
3156 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3157 |
_("\"%s\" is not a valid value for focus attribute"), |
|
3158 |
focus); |
|
3159 |
return; |
|
3160 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3161 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3162 |
frame_state = meta_frame_state_from_string (state); |
3163 |
if (frame_state == META_FRAME_STATE_LAST) |
|
3164 |
{
|
|
3165 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3166 |
_("\"%s\" is not a valid value for state attribute"), |
|
3167 |
focus); |
|
3168 |
return; |
|
3169 |
}
|
|
3170 |
||
3171 |
frame_style = meta_theme_lookup_style (info->theme, style); |
|
3172 |
||
3173 |
if (frame_style == NULL) |
|
3174 |
{
|
|
3175 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3176 |
_("A style called \"%s\" has not been defined"), |
|
3177 |
style); |
|
3178 |
return; |
|
3179 |
}
|
|
3180 |
||
3181 |
switch (frame_state) |
|
3182 |
{
|
|
3183 |
case META_FRAME_STATE_NORMAL: |
|
3184 |
if (resize == NULL) |
|
3185 |
{
|
|
3186 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
1.2.47
by Pedro Fragoso
Import upstream version 2.25.5 |
3187 |
ATTRIBUTE_NOT_FOUND, |
3188 |
"resize", element_name); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3189 |
return; |
3190 |
}
|
|
3191 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3192 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3193 |
frame_resize = meta_frame_resize_from_string (resize); |
3194 |
if (frame_resize == META_FRAME_RESIZE_LAST) |
|
3195 |
{
|
|
3196 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3197 |
_("\"%s\" is not a valid value for resize attribute"), |
|
3198 |
focus); |
|
3199 |
return; |
|
3200 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3201 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3202 |
break; |
3203 |
||
3204 |
case META_FRAME_STATE_SHADED: |
|
3205 |
if (META_THEME_ALLOWS (info->theme, META_THEME_UNRESIZABLE_SHADED_STYLES)) |
|
3206 |
{
|
|
3207 |
if (resize == NULL) |
|
3208 |
/* In state="normal" we would complain here. But instead we accept
|
|
3209 |
* not having a resize attribute and default to resize="both", since
|
|
3210 |
* that most closely mimics what we did in v1, and thus people can
|
|
3211 |
* upgrade a theme to v2 without as much hassle.
|
|
3212 |
*/
|
|
3213 |
frame_resize = META_FRAME_RESIZE_BOTH; |
|
3214 |
else
|
|
3215 |
{
|
|
3216 |
frame_resize = meta_frame_resize_from_string (resize); |
|
3217 |
if (frame_resize == META_FRAME_RESIZE_LAST) |
|
3218 |
{
|
|
3219 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3220 |
_("\"%s\" is not a valid value for resize attribute"), |
|
3221 |
focus); |
|
3222 |
return; |
|
3223 |
}
|
|
3224 |
}
|
|
3225 |
}
|
|
3226 |
else /* v1 theme */ |
|
3227 |
{
|
|
3228 |
if (resize != NULL) |
|
3229 |
{
|
|
3230 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3231 |
_("Should not have \"resize\" attribute on <%s> element for maximized/shaded states"), |
|
3232 |
element_name); |
|
3233 |
return; |
|
3234 |
}
|
|
3235 |
||
3236 |
/* resize="both" is equivalent to the old behaviour */
|
|
3237 |
frame_resize = META_FRAME_RESIZE_BOTH; |
|
3238 |
}
|
|
3239 |
break; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3240 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3241 |
default: |
3242 |
if (resize != NULL) |
|
3243 |
{
|
|
3244 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3245 |
_("Should not have \"resize\" attribute on <%s> element for maximized states"), |
|
3246 |
element_name); |
|
3247 |
return; |
|
3248 |
}
|
|
3249 |
||
3250 |
frame_resize = META_FRAME_RESIZE_LAST; |
|
3251 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3252 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3253 |
switch (frame_state) |
3254 |
{
|
|
3255 |
case META_FRAME_STATE_NORMAL: |
|
3256 |
if (info->style_set->normal_styles[frame_resize][frame_focus]) |
|
3257 |
{
|
|
3258 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3259 |
_("Style has already been specified for state %s resize %s focus %s"), |
|
3260 |
state, resize, focus); |
|
3261 |
return; |
|
3262 |
}
|
|
3263 |
meta_frame_style_ref (frame_style); |
|
3264 |
info->style_set->normal_styles[frame_resize][frame_focus] = frame_style; |
|
3265 |
break; |
|
3266 |
case META_FRAME_STATE_MAXIMIZED: |
|
3267 |
if (info->style_set->maximized_styles[frame_focus]) |
|
3268 |
{
|
|
3269 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3270 |
_("Style has already been specified for state %s focus %s"), |
|
3271 |
state, focus); |
|
3272 |
return; |
|
3273 |
}
|
|
3274 |
meta_frame_style_ref (frame_style); |
|
3275 |
info->style_set->maximized_styles[frame_focus] = frame_style; |
|
3276 |
break; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
3277 |
case META_FRAME_STATE_TILED_LEFT: |
3278 |
if (info->style_set->tiled_left_styles[frame_focus]) |
|
3279 |
{
|
|
3280 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3281 |
_("Style has already been specified for state %s focus %s"), |
|
3282 |
state, focus); |
|
3283 |
return; |
|
3284 |
}
|
|
3285 |
meta_frame_style_ref (frame_style); |
|
3286 |
info->style_set->tiled_left_styles[frame_focus] = frame_style; |
|
3287 |
break; |
|
3288 |
case META_FRAME_STATE_TILED_RIGHT: |
|
3289 |
if (info->style_set->tiled_right_styles[frame_focus]) |
|
3290 |
{
|
|
3291 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3292 |
_("Style has already been specified for state %s focus %s"), |
|
3293 |
state, focus); |
|
3294 |
return; |
|
3295 |
}
|
|
3296 |
meta_frame_style_ref (frame_style); |
|
3297 |
info->style_set->tiled_right_styles[frame_focus] = frame_style; |
|
3298 |
break; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3299 |
case META_FRAME_STATE_SHADED: |
3300 |
if (info->style_set->shaded_styles[frame_resize][frame_focus]) |
|
3301 |
{
|
|
3302 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3303 |
_("Style has already been specified for state %s resize %s focus %s"), |
|
3304 |
state, resize, focus); |
|
3305 |
return; |
|
3306 |
}
|
|
3307 |
meta_frame_style_ref (frame_style); |
|
3308 |
info->style_set->shaded_styles[frame_resize][frame_focus] = frame_style; |
|
3309 |
break; |
|
3310 |
case META_FRAME_STATE_MAXIMIZED_AND_SHADED: |
|
3311 |
if (info->style_set->maximized_and_shaded_styles[frame_focus]) |
|
3312 |
{
|
|
3313 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3314 |
_("Style has already been specified for state %s focus %s"), |
|
3315 |
state, focus); |
|
3316 |
return; |
|
3317 |
}
|
|
3318 |
meta_frame_style_ref (frame_style); |
|
3319 |
info->style_set->maximized_and_shaded_styles[frame_focus] = frame_style; |
|
3320 |
break; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
3321 |
case META_FRAME_STATE_TILED_LEFT_AND_SHADED: |
3322 |
if (info->style_set->tiled_left_and_shaded_styles[frame_focus]) |
|
3323 |
{
|
|
3324 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3325 |
_("Style has already been specified for state %s focus %s"), |
|
3326 |
state, focus); |
|
3327 |
return; |
|
3328 |
}
|
|
3329 |
meta_frame_style_ref (frame_style); |
|
3330 |
info->style_set->tiled_left_and_shaded_styles[frame_focus] = frame_style; |
|
3331 |
break; |
|
3332 |
case META_FRAME_STATE_TILED_RIGHT_AND_SHADED: |
|
3333 |
if (info->style_set->tiled_right_and_shaded_styles[frame_focus]) |
|
3334 |
{
|
|
3335 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3336 |
_("Style has already been specified for state %s focus %s"), |
|
3337 |
state, focus); |
|
3338 |
return; |
|
3339 |
}
|
|
3340 |
meta_frame_style_ref (frame_style); |
|
3341 |
info->style_set->tiled_right_and_shaded_styles[frame_focus] = frame_style; |
|
3342 |
break; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3343 |
case META_FRAME_STATE_LAST: |
3344 |
g_assert_not_reached (); |
|
3345 |
break; |
|
3346 |
}
|
|
3347 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3348 |
push_state (info, STATE_FRAME); |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3349 |
}
|
3350 |
else
|
|
3351 |
{
|
|
3352 |
set_error (error, context, |
|
3353 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3354 |
_("Element <%s> is not allowed below <%s>"), |
|
3355 |
element_name, "frame_style_set"); |
|
3356 |
}
|
|
3357 |
}
|
|
3358 |
||
3359 |
static void |
|
3360 |
parse_piece_element (GMarkupParseContext *context, |
|
3361 |
const gchar *element_name, |
|
3362 |
const gchar **attribute_names, |
|
3363 |
const gchar **attribute_values, |
|
3364 |
ParseInfo *info, |
|
3365 |
GError **error) |
|
3366 |
{
|
|
3367 |
g_return_if_fail (peek_state (info) == STATE_PIECE); |
|
3368 |
||
3369 |
if (ELEMENT_IS ("draw_ops")) |
|
3370 |
{
|
|
3371 |
if (info->op_list) |
|
3372 |
{
|
|
3373 |
set_error (error, context, |
|
3374 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3375 |
_("Can't have a two draw_ops for a <piece> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)")); |
|
3376 |
return; |
|
3377 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3378 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3379 |
if (!check_no_attributes (context, element_name, attribute_names, attribute_values, |
3380 |
error)) |
|
3381 |
return; |
|
3382 |
||
3383 |
g_assert (info->op_list == NULL); |
|
3384 |
info->op_list = meta_draw_op_list_new (2); |
|
3385 |
||
3386 |
push_state (info, STATE_DRAW_OPS); |
|
3387 |
}
|
|
3388 |
else
|
|
3389 |
{
|
|
3390 |
set_error (error, context, |
|
3391 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3392 |
_("Element <%s> is not allowed below <%s>"), |
|
3393 |
element_name, "piece"); |
|
3394 |
}
|
|
3395 |
}
|
|
3396 |
||
3397 |
static void |
|
3398 |
parse_button_element (GMarkupParseContext *context, |
|
3399 |
const gchar *element_name, |
|
3400 |
const gchar **attribute_names, |
|
3401 |
const gchar **attribute_values, |
|
3402 |
ParseInfo *info, |
|
3403 |
GError **error) |
|
3404 |
{
|
|
3405 |
g_return_if_fail (peek_state (info) == STATE_BUTTON); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3406 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3407 |
if (ELEMENT_IS ("draw_ops")) |
3408 |
{
|
|
3409 |
if (info->op_list) |
|
3410 |
{
|
|
3411 |
set_error (error, context, |
|
3412 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3413 |
_("Can't have a two draw_ops for a <button> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)")); |
|
3414 |
return; |
|
3415 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3416 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3417 |
if (!check_no_attributes (context, element_name, attribute_names, attribute_values, |
3418 |
error)) |
|
3419 |
return; |
|
3420 |
||
3421 |
g_assert (info->op_list == NULL); |
|
3422 |
info->op_list = meta_draw_op_list_new (2); |
|
3423 |
||
3424 |
push_state (info, STATE_DRAW_OPS); |
|
3425 |
}
|
|
3426 |
else
|
|
3427 |
{
|
|
3428 |
set_error (error, context, |
|
3429 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3430 |
_("Element <%s> is not allowed below <%s>"), |
|
3431 |
element_name, "button"); |
|
3432 |
}
|
|
3433 |
}
|
|
3434 |
||
3435 |
static void |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
3436 |
parse_shadow_element (GMarkupParseContext *context, |
3437 |
const gchar *element_name, |
|
3438 |
const gchar **attribute_names, |
|
3439 |
const gchar **attribute_values, |
|
3440 |
ParseInfo *info, |
|
3441 |
GError **error) |
|
3442 |
{
|
|
3443 |
g_return_if_fail (peek_state (info) == STATE_SHADOW); |
|
3444 |
||
3445 |
set_error (error, context, |
|
3446 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3447 |
_("Element <%s> is not allowed below <%s>"), |
|
3448 |
element_name, "shadow"); |
|
3449 |
}
|
|
3450 |
||
3451 |
static void |
|
3452 |
parse_padding_element (GMarkupParseContext *context, |
|
3453 |
const gchar *element_name, |
|
3454 |
const gchar **attribute_names, |
|
3455 |
const gchar **attribute_values, |
|
3456 |
ParseInfo *info, |
|
3457 |
GError **error) |
|
3458 |
{
|
|
3459 |
g_return_if_fail (peek_state (info) == STATE_PADDING); |
|
3460 |
||
3461 |
set_error (error, context, |
|
3462 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3463 |
_("Element <%s> is not allowed below <%s>"), |
|
3464 |
element_name, "padding"); |
|
3465 |
}
|
|
3466 |
||
3467 |
static void |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3468 |
parse_menu_icon_element (GMarkupParseContext *context, |
3469 |
const gchar *element_name, |
|
3470 |
const gchar **attribute_names, |
|
3471 |
const gchar **attribute_values, |
|
3472 |
ParseInfo *info, |
|
3473 |
GError **error) |
|
3474 |
{
|
|
3475 |
g_return_if_fail (peek_state (info) == STATE_MENU_ICON); |
|
3476 |
||
3477 |
if (ELEMENT_IS ("draw_ops")) |
|
3478 |
{
|
|
3479 |
if (info->op_list) |
|
3480 |
{
|
|
3481 |
set_error (error, context, |
|
3482 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3483 |
_("Can't have a two draw_ops for a <menu_icon> element (theme specified a draw_ops attribute and also a <draw_ops> element, or specified two elements)")); |
|
3484 |
return; |
|
3485 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3486 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3487 |
if (!check_no_attributes (context, element_name, attribute_names, attribute_values, |
3488 |
error)) |
|
3489 |
return; |
|
3490 |
||
3491 |
g_assert (info->op_list == NULL); |
|
3492 |
info->op_list = meta_draw_op_list_new (2); |
|
3493 |
||
3494 |
push_state (info, STATE_DRAW_OPS); |
|
3495 |
}
|
|
3496 |
else
|
|
3497 |
{
|
|
3498 |
set_error (error, context, |
|
3499 |
G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3500 |
_("Element <%s> is not allowed below <%s>"), |
|
3501 |
element_name, "menu_icon"); |
|
3502 |
}
|
|
3503 |
}
|
|
3504 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3505 |
static const char * |
3506 |
find_version (const char **attribute_names, |
|
3507 |
const char **attribute_values) |
|
3508 |
{
|
|
3509 |
int i; |
|
3510 |
||
3511 |
for (i = 0; attribute_names[i]; i++) |
|
3512 |
{
|
|
3513 |
if (strcmp (attribute_names[i], "version") == 0) |
|
3514 |
return attribute_values[i]; |
|
3515 |
}
|
|
3516 |
||
3517 |
return NULL; |
|
3518 |
}
|
|
3519 |
||
3520 |
/* Returns whether the version element was successfully parsed.
|
|
3521 |
* If successfully parsed, then two additional items are returned:
|
|
3522 |
*
|
|
3523 |
* satisfied: whether this version of Mutter meets the version check
|
|
3524 |
* minimum_required: minimum version of theme format required by version check
|
|
3525 |
*/
|
|
3526 |
static gboolean |
|
3527 |
check_version (GMarkupParseContext *context, |
|
3528 |
const char *version_str, |
|
3529 |
gboolean *satisfied, |
|
3530 |
guint *minimum_required, |
|
3531 |
GError **error) |
|
3532 |
{
|
|
3533 |
static GRegex *version_regex; |
|
3534 |
GMatchInfo *info; |
|
3535 |
char *comparison_str, *major_str, *minor_str; |
|
3536 |
guint version; |
|
3537 |
||
3538 |
*minimum_required = 0; |
|
3539 |
||
3540 |
if (!version_regex) |
|
3541 |
version_regex = g_regex_new ("^\\s*([<>]=?)\\s*(\\d+)(\\.\\d+)?\\s*$", 0, 0, NULL); |
|
3542 |
||
3543 |
if (!g_regex_match (version_regex, version_str, 0, &info)) |
|
3544 |
{
|
|
3545 |
g_match_info_free (info); |
|
3546 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3547 |
_("Bad version specification '%s'"), version_str); |
|
3548 |
return FALSE; |
|
3549 |
}
|
|
3550 |
||
3551 |
comparison_str = g_match_info_fetch (info, 1); |
|
3552 |
major_str = g_match_info_fetch (info, 2); |
|
3553 |
minor_str = g_match_info_fetch (info, 3); |
|
3554 |
||
3555 |
version = 1000 * atoi (major_str); |
|
3556 |
/* might get NULL, see: https://bugzilla.gnome.org/review?bug=588217 */
|
|
3557 |
if (minor_str && minor_str[0]) |
|
3558 |
version += atoi (minor_str + 1); |
|
3559 |
||
3560 |
if (comparison_str[0] == '<') |
|
3561 |
{
|
|
3562 |
if (comparison_str[1] == '=') |
|
3563 |
*satisfied = THEME_VERSION <= version; |
|
3564 |
else
|
|
3565 |
*satisfied = THEME_VERSION < version; |
|
3566 |
}
|
|
3567 |
else
|
|
3568 |
{
|
|
3569 |
if (comparison_str[1] == '=') |
|
3570 |
{
|
|
3571 |
*satisfied = THEME_VERSION >= version; |
|
3572 |
*minimum_required = version; |
|
3573 |
}
|
|
3574 |
else
|
|
3575 |
{
|
|
3576 |
*satisfied = THEME_VERSION > version; |
|
3577 |
*minimum_required = version + 1; |
|
3578 |
}
|
|
3579 |
}
|
|
3580 |
||
3581 |
g_free (comparison_str); |
|
3582 |
g_free (major_str); |
|
3583 |
g_free (minor_str); |
|
3584 |
g_match_info_free (info); |
|
3585 |
||
3586 |
return TRUE; |
|
3587 |
}
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3588 |
|
3589 |
static void |
|
3590 |
start_element_handler (GMarkupParseContext *context, |
|
3591 |
const gchar *element_name, |
|
3592 |
const gchar **attribute_names, |
|
3593 |
const gchar **attribute_values, |
|
3594 |
gpointer user_data, |
|
3595 |
GError **error) |
|
3596 |
{
|
|
3597 |
ParseInfo *info = user_data; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3598 |
const char *version; |
3599 |
guint required_version = 0; |
|
3600 |
||
3601 |
if (info->skip_level > 0) |
|
3602 |
{
|
|
3603 |
info->skip_level++; |
|
3604 |
return; |
|
3605 |
}
|
|
3606 |
||
3607 |
required_version = peek_required_version (info); |
|
3608 |
||
3609 |
version = find_version (attribute_names, attribute_values); |
|
3610 |
if (version != NULL) |
|
3611 |
{
|
|
3612 |
gboolean satisfied; |
|
3613 |
guint element_required; |
|
3614 |
||
3615 |
if (required_version < 3000) |
|
3616 |
{
|
|
3617 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3618 |
_("\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-theme-2.xml")); |
|
3619 |
return; |
|
3620 |
}
|
|
3621 |
||
3622 |
if (!check_version (context, version, &satisfied, &element_required, error)) |
|
3623 |
return; |
|
3624 |
||
3625 |
/* Two different ways of handling an unsatisfied version check:
|
|
3626 |
* for the toplevel element of a file, we throw an error back so
|
|
3627 |
* that the controlling code can go ahead and look for an
|
|
3628 |
* alternate metacity-theme-1.xml or metacity-theme-2.xml; for
|
|
3629 |
* other elements we just silently skip the element and children.
|
|
3630 |
*/
|
|
3631 |
if (peek_state (info) == STATE_START) |
|
3632 |
{
|
|
3633 |
if (satisfied) |
|
3634 |
{
|
|
3635 |
if (element_required > info->format_version) |
|
3636 |
info->format_version = element_required; |
|
3637 |
}
|
|
3638 |
else
|
|
3639 |
{
|
|
3640 |
set_error (error, context, THEME_PARSE_ERROR, THEME_PARSE_ERROR_TOO_OLD, |
|
3641 |
_("Theme requires version %s but latest supported theme version is %d.%d"), |
|
3642 |
version, THEME_VERSION, THEME_MINOR_VERSION); |
|
3643 |
return; |
|
3644 |
}
|
|
3645 |
}
|
|
3646 |
else if (!satisfied) |
|
3647 |
{
|
|
3648 |
info->skip_level = 1; |
|
3649 |
return; |
|
3650 |
}
|
|
3651 |
||
3652 |
if (element_required > required_version) |
|
3653 |
required_version = element_required; |
|
3654 |
}
|
|
3655 |
||
3656 |
push_required_version (info, required_version); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3657 |
|
3658 |
switch (peek_state (info)) |
|
3659 |
{
|
|
3660 |
case STATE_START: |
|
3661 |
if (strcmp (element_name, "metacity_theme") == 0) |
|
3662 |
{
|
|
3663 |
info->theme = meta_theme_new (); |
|
3664 |
info->theme->name = g_strdup (info->theme_name); |
|
3665 |
info->theme->filename = g_strdup (info->theme_file); |
|
3666 |
info->theme->dirname = g_strdup (info->theme_dir); |
|
3667 |
info->theme->format_version = info->format_version; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3668 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3669 |
push_state (info, STATE_THEME); |
3670 |
}
|
|
3671 |
else
|
|
3672 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3673 |
_("Outermost element in theme must be <metacity_theme> not <%s>"), |
|
3674 |
element_name); |
|
3675 |
break; |
|
3676 |
||
3677 |
case STATE_THEME: |
|
3678 |
parse_toplevel_element (context, element_name, |
|
3679 |
attribute_names, attribute_values, |
|
3680 |
info, error); |
|
3681 |
break; |
|
3682 |
case STATE_INFO: |
|
3683 |
parse_info_element (context, element_name, |
|
3684 |
attribute_names, attribute_values, |
|
3685 |
info, error); |
|
3686 |
break; |
|
3687 |
case STATE_NAME: |
|
3688 |
case STATE_AUTHOR: |
|
3689 |
case STATE_COPYRIGHT: |
|
3690 |
case STATE_DATE: |
|
3691 |
case STATE_DESCRIPTION: |
|
3692 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3693 |
_("Element <%s> is not allowed inside a name/author/date/description element"), |
|
3694 |
element_name); |
|
3695 |
break; |
|
3696 |
case STATE_CONSTANT: |
|
3697 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3698 |
_("Element <%s> is not allowed inside a <constant> element"), |
|
3699 |
element_name); |
|
3700 |
break; |
|
3701 |
case STATE_FRAME_GEOMETRY: |
|
3702 |
parse_geometry_element (context, element_name, |
|
3703 |
attribute_names, attribute_values, |
|
3704 |
info, error); |
|
3705 |
break; |
|
3706 |
case STATE_DISTANCE: |
|
3707 |
case STATE_BORDER: |
|
3708 |
case STATE_ASPECT_RATIO: |
|
3709 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3710 |
_("Element <%s> is not allowed inside a distance/border/aspect_ratio element"), |
|
3711 |
element_name); |
|
3712 |
break; |
|
3713 |
case STATE_DRAW_OPS: |
|
3714 |
parse_draw_op_element (context, element_name, |
|
3715 |
attribute_names, attribute_values, |
|
3716 |
info, error); |
|
3717 |
break; |
|
3718 |
case STATE_LINE: |
|
3719 |
case STATE_RECTANGLE: |
|
3720 |
case STATE_ARC: |
|
3721 |
case STATE_CLIP: |
|
3722 |
case STATE_TINT: |
|
3723 |
case STATE_IMAGE: |
|
3724 |
case STATE_GTK_ARROW: |
|
3725 |
case STATE_GTK_BOX: |
|
3726 |
case STATE_GTK_VLINE: |
|
3727 |
case STATE_ICON: |
|
3728 |
case STATE_TITLE: |
|
3729 |
case STATE_INCLUDE: |
|
3730 |
case STATE_TILE: |
|
3731 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3732 |
_("Element <%s> is not allowed inside a draw operation element"), |
|
3733 |
element_name); |
|
3734 |
break; |
|
3735 |
case STATE_GRADIENT: |
|
3736 |
parse_gradient_element (context, element_name, |
|
3737 |
attribute_names, attribute_values, |
|
3738 |
info, error); |
|
3739 |
break; |
|
3740 |
case STATE_COLOR: |
|
3741 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3742 |
_("Element <%s> is not allowed inside a <%s> element"), |
|
3743 |
element_name, "color"); |
|
3744 |
break; |
|
3745 |
case STATE_FRAME_STYLE: |
|
3746 |
parse_style_element (context, element_name, |
|
3747 |
attribute_names, attribute_values, |
|
3748 |
info, error); |
|
3749 |
break; |
|
3750 |
case STATE_PIECE: |
|
3751 |
parse_piece_element (context, element_name, |
|
3752 |
attribute_names, attribute_values, |
|
3753 |
info, error); |
|
3754 |
break; |
|
3755 |
case STATE_BUTTON: |
|
3756 |
parse_button_element (context, element_name, |
|
3757 |
attribute_names, attribute_values, |
|
3758 |
info, error); |
|
3759 |
break; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
3760 |
case STATE_SHADOW: |
3761 |
parse_shadow_element (context, element_name, |
|
3762 |
attribute_names, attribute_values, |
|
3763 |
info, error); |
|
3764 |
break; |
|
3765 |
case STATE_PADDING: |
|
3766 |
parse_padding_element (context, element_name, |
|
3767 |
attribute_names, attribute_values, |
|
3768 |
info, error); |
|
3769 |
break; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3770 |
case STATE_MENU_ICON: |
3771 |
parse_menu_icon_element (context, element_name, |
|
3772 |
attribute_names, attribute_values, |
|
3773 |
info, error); |
|
3774 |
break; |
|
3775 |
case STATE_FRAME_STYLE_SET: |
|
3776 |
parse_style_set_element (context, element_name, |
|
3777 |
attribute_names, attribute_values, |
|
3778 |
info, error); |
|
3779 |
break; |
|
3780 |
case STATE_FRAME: |
|
3781 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3782 |
_("Element <%s> is not allowed inside a <%s> element"), |
|
3783 |
element_name, "frame"); |
|
3784 |
break; |
|
3785 |
case STATE_WINDOW: |
|
3786 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3787 |
_("Element <%s> is not allowed inside a <%s> element"), |
|
3788 |
element_name, "window"); |
|
3789 |
break; |
|
3790 |
case STATE_FALLBACK: |
|
3791 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
3792 |
_("Element <%s> is not allowed inside a <%s> element"), |
|
3793 |
element_name, "fallback"); |
|
3794 |
break; |
|
3795 |
}
|
|
3796 |
}
|
|
3797 |
||
3798 |
static void |
|
3799 |
end_element_handler (GMarkupParseContext *context, |
|
3800 |
const gchar *element_name, |
|
3801 |
gpointer user_data, |
|
3802 |
GError **error) |
|
3803 |
{
|
|
3804 |
ParseInfo *info = user_data; |
|
3805 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3806 |
if (info->skip_level > 0) |
3807 |
{
|
|
3808 |
info->skip_level--; |
|
3809 |
return; |
|
3810 |
}
|
|
3811 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3812 |
switch (peek_state (info)) |
3813 |
{
|
|
3814 |
case STATE_START: |
|
3815 |
break; |
|
3816 |
case STATE_THEME: |
|
3817 |
g_assert (info->theme); |
|
3818 |
||
3819 |
if (!meta_theme_validate (info->theme, error)) |
|
3820 |
{
|
|
3821 |
add_context_to_error (error, context); |
|
3822 |
meta_theme_free (info->theme); |
|
3823 |
info->theme = NULL; |
|
3824 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3825 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3826 |
pop_state (info); |
3827 |
g_assert (peek_state (info) == STATE_START); |
|
3828 |
break; |
|
3829 |
case STATE_INFO: |
|
3830 |
pop_state (info); |
|
3831 |
g_assert (peek_state (info) == STATE_THEME); |
|
3832 |
break; |
|
3833 |
case STATE_NAME: |
|
3834 |
pop_state (info); |
|
3835 |
g_assert (peek_state (info) == STATE_INFO); |
|
3836 |
break; |
|
3837 |
case STATE_AUTHOR: |
|
3838 |
pop_state (info); |
|
3839 |
g_assert (peek_state (info) == STATE_INFO); |
|
3840 |
break; |
|
3841 |
case STATE_COPYRIGHT: |
|
3842 |
pop_state (info); |
|
3843 |
g_assert (peek_state (info) == STATE_INFO); |
|
3844 |
break; |
|
3845 |
case STATE_DATE: |
|
3846 |
pop_state (info); |
|
3847 |
g_assert (peek_state (info) == STATE_INFO); |
|
3848 |
break; |
|
3849 |
case STATE_DESCRIPTION: |
|
3850 |
pop_state (info); |
|
3851 |
g_assert (peek_state (info) == STATE_INFO); |
|
3852 |
break; |
|
3853 |
case STATE_CONSTANT: |
|
3854 |
pop_state (info); |
|
3855 |
g_assert (peek_state (info) == STATE_THEME); |
|
3856 |
break; |
|
3857 |
case STATE_FRAME_GEOMETRY: |
|
3858 |
g_assert (info->layout); |
|
3859 |
||
3860 |
if (!meta_frame_layout_validate (info->layout, |
|
3861 |
error)) |
|
3862 |
{
|
|
3863 |
add_context_to_error (error, context); |
|
3864 |
}
|
|
3865 |
||
3866 |
/* layout will already be stored in the theme under
|
|
3867 |
* its name
|
|
3868 |
*/
|
|
3869 |
meta_frame_layout_unref (info->layout); |
|
3870 |
info->layout = NULL; |
|
3871 |
pop_state (info); |
|
3872 |
g_assert (peek_state (info) == STATE_THEME); |
|
3873 |
break; |
|
3874 |
case STATE_DISTANCE: |
|
3875 |
pop_state (info); |
|
3876 |
g_assert (peek_state (info) == STATE_FRAME_GEOMETRY); |
|
3877 |
break; |
|
3878 |
case STATE_BORDER: |
|
3879 |
pop_state (info); |
|
3880 |
g_assert (peek_state (info) == STATE_FRAME_GEOMETRY); |
|
3881 |
break; |
|
3882 |
case STATE_ASPECT_RATIO: |
|
3883 |
pop_state (info); |
|
3884 |
g_assert (peek_state (info) == STATE_FRAME_GEOMETRY); |
|
3885 |
break; |
|
3886 |
case STATE_DRAW_OPS: |
|
3887 |
{
|
|
3888 |
g_assert (info->op_list); |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
3889 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
3890 |
if (!meta_draw_op_list_validate (info->op_list, |
3891 |
error)) |
|
3892 |
{
|
|
3893 |
add_context_to_error (error, context); |
|
3894 |
meta_draw_op_list_unref (info->op_list); |
|
3895 |
info->op_list = NULL; |
|
3896 |
}
|
|
3897 |
||
3898 |
pop_state (info); |
|
3899 |
||
3900 |
switch (peek_state (info)) |
|
3901 |
{
|
|
3902 |
case STATE_BUTTON: |
|
3903 |
case STATE_PIECE: |
|
3904 |
case STATE_MENU_ICON: |
|
3905 |
/* Leave info->op_list to be picked up
|
|
3906 |
* when these elements are closed
|
|
3907 |
*/
|
|
3908 |
g_assert (info->op_list); |
|
3909 |
break; |
|
3910 |
case STATE_THEME: |
|
3911 |
g_assert (info->op_list); |
|
3912 |
meta_draw_op_list_unref (info->op_list); |
|
3913 |
info->op_list = NULL; |
|
3914 |
break; |
|
3915 |
default: |
|
3916 |
/* Op list can't occur in other contexts */
|
|
3917 |
g_assert_not_reached (); |
|
3918 |
break; |
|
3919 |
}
|
|
3920 |
}
|
|
3921 |
break; |
|
3922 |
case STATE_LINE: |
|
3923 |
pop_state (info); |
|
3924 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3925 |
break; |
|
3926 |
case STATE_RECTANGLE: |
|
3927 |
pop_state (info); |
|
3928 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3929 |
break; |
|
3930 |
case STATE_ARC: |
|
3931 |
pop_state (info); |
|
3932 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3933 |
break; |
|
3934 |
case STATE_CLIP: |
|
3935 |
pop_state (info); |
|
3936 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3937 |
break; |
|
3938 |
case STATE_TINT: |
|
3939 |
pop_state (info); |
|
3940 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3941 |
break; |
|
3942 |
case STATE_GRADIENT: |
|
3943 |
g_assert (info->op); |
|
3944 |
g_assert (info->op->type == META_DRAW_GRADIENT); |
|
3945 |
if (!meta_gradient_spec_validate (info->op->data.gradient.gradient_spec, |
|
3946 |
error)) |
|
3947 |
{
|
|
3948 |
add_context_to_error (error, context); |
|
3949 |
meta_draw_op_free (info->op); |
|
3950 |
info->op = NULL; |
|
3951 |
}
|
|
3952 |
else
|
|
3953 |
{
|
|
3954 |
g_assert (info->op_list); |
|
3955 |
meta_draw_op_list_append (info->op_list, info->op); |
|
3956 |
info->op = NULL; |
|
3957 |
}
|
|
3958 |
pop_state (info); |
|
3959 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3960 |
break; |
|
3961 |
case STATE_IMAGE: |
|
3962 |
pop_state (info); |
|
3963 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3964 |
break; |
|
3965 |
case STATE_GTK_ARROW: |
|
3966 |
pop_state (info); |
|
3967 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3968 |
break; |
|
3969 |
case STATE_GTK_BOX: |
|
3970 |
pop_state (info); |
|
3971 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3972 |
break; |
|
3973 |
case STATE_GTK_VLINE: |
|
3974 |
pop_state (info); |
|
3975 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3976 |
break; |
|
3977 |
case STATE_ICON: |
|
3978 |
pop_state (info); |
|
3979 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3980 |
break; |
|
3981 |
case STATE_TITLE: |
|
3982 |
pop_state (info); |
|
3983 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3984 |
break; |
|
3985 |
case STATE_INCLUDE: |
|
3986 |
pop_state (info); |
|
3987 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3988 |
break; |
|
3989 |
case STATE_TILE: |
|
3990 |
pop_state (info); |
|
3991 |
g_assert (peek_state (info) == STATE_DRAW_OPS); |
|
3992 |
break; |
|
3993 |
case STATE_COLOR: |
|
3994 |
pop_state (info); |
|
3995 |
g_assert (peek_state (info) == STATE_GRADIENT); |
|
3996 |
break; |
|
3997 |
case STATE_FRAME_STYLE: |
|
3998 |
g_assert (info->style); |
|
3999 |
||
4000 |
if (!meta_frame_style_validate (info->style, |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4001 |
peek_required_version (info), |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4002 |
error)) |
4003 |
{
|
|
4004 |
add_context_to_error (error, context); |
|
4005 |
}
|
|
4006 |
||
4007 |
/* Frame style is in the theme hash table and a ref
|
|
4008 |
* is held there
|
|
4009 |
*/
|
|
4010 |
meta_frame_style_unref (info->style); |
|
4011 |
info->style = NULL; |
|
4012 |
pop_state (info); |
|
4013 |
g_assert (peek_state (info) == STATE_THEME); |
|
4014 |
break; |
|
4015 |
case STATE_PIECE: |
|
4016 |
g_assert (info->style); |
|
4017 |
if (info->op_list == NULL) |
|
4018 |
{
|
|
4019 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
4020 |
_("No draw_ops provided for frame piece")); |
|
4021 |
}
|
|
4022 |
else
|
|
4023 |
{
|
|
4024 |
info->style->pieces[info->piece] = info->op_list; |
|
4025 |
info->op_list = NULL; |
|
4026 |
}
|
|
4027 |
pop_state (info); |
|
4028 |
g_assert (peek_state (info) == STATE_FRAME_STYLE); |
|
4029 |
break; |
|
4030 |
case STATE_BUTTON: |
|
4031 |
g_assert (info->style); |
|
4032 |
if (info->op_list == NULL) |
|
4033 |
{
|
|
4034 |
set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, |
|
4035 |
_("No draw_ops provided for button")); |
|
4036 |
}
|
|
4037 |
else
|
|
4038 |
{
|
|
4039 |
info->style->buttons[info->button_type][info->button_state] = |
|
4040 |
info->op_list; |
|
4041 |
info->op_list = NULL; |
|
4042 |
}
|
|
4043 |
pop_state (info); |
|
4044 |
break; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
4045 |
case STATE_SHADOW: |
4046 |
g_assert (info->style); |
|
4047 |
pop_state (info); |
|
4048 |
break; |
|
4049 |
case STATE_PADDING: |
|
4050 |
g_assert (info->style); |
|
4051 |
pop_state (info); |
|
4052 |
break; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4053 |
case STATE_MENU_ICON: |
4054 |
g_assert (info->theme); |
|
4055 |
if (info->op_list != NULL) |
|
4056 |
{
|
|
4057 |
meta_draw_op_list_unref (info->op_list); |
|
4058 |
info->op_list = NULL; |
|
4059 |
}
|
|
4060 |
pop_state (info); |
|
4061 |
g_assert (peek_state (info) == STATE_THEME); |
|
4062 |
break; |
|
4063 |
case STATE_FRAME_STYLE_SET: |
|
4064 |
g_assert (info->style_set); |
|
4065 |
||
4066 |
if (!meta_frame_style_set_validate (info->style_set, |
|
4067 |
error)) |
|
4068 |
{
|
|
4069 |
add_context_to_error (error, context); |
|
4070 |
}
|
|
4071 |
||
4072 |
/* Style set is in the theme hash table and a reference
|
|
4073 |
* is held there.
|
|
4074 |
*/
|
|
4075 |
meta_frame_style_set_unref (info->style_set); |
|
4076 |
info->style_set = NULL; |
|
4077 |
pop_state (info); |
|
4078 |
g_assert (peek_state (info) == STATE_THEME); |
|
4079 |
break; |
|
4080 |
case STATE_FRAME: |
|
4081 |
pop_state (info); |
|
4082 |
g_assert (peek_state (info) == STATE_FRAME_STYLE_SET); |
|
4083 |
break; |
|
4084 |
case STATE_WINDOW: |
|
4085 |
pop_state (info); |
|
4086 |
g_assert (peek_state (info) == STATE_THEME); |
|
4087 |
break; |
|
4088 |
case STATE_FALLBACK: |
|
4089 |
pop_state (info); |
|
4090 |
g_assert (peek_state (info) == STATE_THEME); |
|
4091 |
break; |
|
4092 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4093 |
|
4094 |
pop_required_version (info); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4095 |
}
|
4096 |
||
4097 |
#define NO_TEXT(element_name) set_error (error, context, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, _("No text is allowed inside element <%s>"), element_name)
|
|
4098 |
||
4099 |
static gboolean |
|
4100 |
all_whitespace (const char *text, |
|
4101 |
int text_len) |
|
4102 |
{
|
|
4103 |
const char *p; |
|
4104 |
const char *end; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4105 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4106 |
p = text; |
4107 |
end = text + text_len; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4108 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4109 |
while (p != end) |
4110 |
{
|
|
4111 |
if (!g_ascii_isspace (*p)) |
|
4112 |
return FALSE; |
|
4113 |
||
4114 |
p = g_utf8_next_char (p); |
|
4115 |
}
|
|
4116 |
||
4117 |
return TRUE; |
|
4118 |
}
|
|
4119 |
||
4120 |
static void |
|
4121 |
text_handler (GMarkupParseContext *context, |
|
4122 |
const gchar *text, |
|
4123 |
gsize text_len, |
|
4124 |
gpointer user_data, |
|
4125 |
GError **error) |
|
4126 |
{
|
|
4127 |
ParseInfo *info = user_data; |
|
4128 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4129 |
if (info->skip_level > 0) |
4130 |
return; |
|
4131 |
||
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4132 |
if (all_whitespace (text, text_len)) |
4133 |
return; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4134 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4135 |
/* FIXME http://bugzilla.gnome.org/show_bug.cgi?id=70448 would
|
4136 |
* allow a nice cleanup here.
|
|
4137 |
*/
|
|
4138 |
||
4139 |
switch (peek_state (info)) |
|
4140 |
{
|
|
4141 |
case STATE_START: |
|
4142 |
g_assert_not_reached (); /* gmarkup shouldn't do this */ |
|
4143 |
break; |
|
4144 |
case STATE_THEME: |
|
4145 |
NO_TEXT ("metacity_theme"); |
|
4146 |
break; |
|
4147 |
case STATE_INFO: |
|
4148 |
NO_TEXT ("info"); |
|
4149 |
break; |
|
4150 |
case STATE_NAME: |
|
4151 |
if (info->theme->readable_name != NULL) |
|
4152 |
{
|
|
4153 |
set_error (error, context, G_MARKUP_ERROR, |
|
4154 |
G_MARKUP_ERROR_PARSE, |
|
1.2.54
by Robert Ancell
Import upstream version 2.27.0 |
4155 |
_("<%s> specified twice for this theme"), |
4156 |
"name"); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4157 |
return; |
4158 |
}
|
|
4159 |
||
4160 |
info->theme->readable_name = g_strndup (text, text_len); |
|
4161 |
break; |
|
4162 |
case STATE_AUTHOR: |
|
4163 |
if (info->theme->author != NULL) |
|
4164 |
{
|
|
4165 |
set_error (error, context, G_MARKUP_ERROR, |
|
4166 |
G_MARKUP_ERROR_PARSE, |
|
1.2.54
by Robert Ancell
Import upstream version 2.27.0 |
4167 |
_("<%s> specified twice for this theme"), |
4168 |
"author"); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4169 |
return; |
4170 |
}
|
|
4171 |
||
4172 |
info->theme->author = g_strndup (text, text_len); |
|
4173 |
break; |
|
4174 |
case STATE_COPYRIGHT: |
|
4175 |
if (info->theme->copyright != NULL) |
|
4176 |
{
|
|
4177 |
set_error (error, context, G_MARKUP_ERROR, |
|
4178 |
G_MARKUP_ERROR_PARSE, |
|
1.2.54
by Robert Ancell
Import upstream version 2.27.0 |
4179 |
_("<%s> specified twice for this theme"), |
4180 |
"copyright"); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4181 |
return; |
4182 |
}
|
|
4183 |
||
4184 |
info->theme->copyright = g_strndup (text, text_len); |
|
4185 |
break; |
|
4186 |
case STATE_DATE: |
|
4187 |
if (info->theme->date != NULL) |
|
4188 |
{
|
|
4189 |
set_error (error, context, G_MARKUP_ERROR, |
|
4190 |
G_MARKUP_ERROR_PARSE, |
|
1.2.54
by Robert Ancell
Import upstream version 2.27.0 |
4191 |
_("<%s> specified twice for this theme"), |
4192 |
"date"); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4193 |
return; |
4194 |
}
|
|
4195 |
||
4196 |
info->theme->date = g_strndup (text, text_len); |
|
4197 |
break; |
|
4198 |
case STATE_DESCRIPTION: |
|
4199 |
if (info->theme->description != NULL) |
|
4200 |
{
|
|
4201 |
set_error (error, context, G_MARKUP_ERROR, |
|
4202 |
G_MARKUP_ERROR_PARSE, |
|
1.2.54
by Robert Ancell
Import upstream version 2.27.0 |
4203 |
_("<%s> specified twice for this theme"), |
4204 |
"description"); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4205 |
return; |
4206 |
}
|
|
4207 |
||
4208 |
info->theme->description = g_strndup (text, text_len); |
|
4209 |
break; |
|
4210 |
case STATE_CONSTANT: |
|
4211 |
NO_TEXT ("constant"); |
|
4212 |
break; |
|
4213 |
case STATE_FRAME_GEOMETRY: |
|
4214 |
NO_TEXT ("frame_geometry"); |
|
4215 |
break; |
|
4216 |
case STATE_DISTANCE: |
|
4217 |
NO_TEXT ("distance"); |
|
4218 |
break; |
|
4219 |
case STATE_BORDER: |
|
4220 |
NO_TEXT ("border"); |
|
4221 |
break; |
|
4222 |
case STATE_ASPECT_RATIO: |
|
4223 |
NO_TEXT ("aspect_ratio"); |
|
4224 |
break; |
|
4225 |
case STATE_DRAW_OPS: |
|
4226 |
NO_TEXT ("draw_ops"); |
|
4227 |
break; |
|
4228 |
case STATE_LINE: |
|
4229 |
NO_TEXT ("line"); |
|
4230 |
break; |
|
4231 |
case STATE_RECTANGLE: |
|
4232 |
NO_TEXT ("rectangle"); |
|
4233 |
break; |
|
4234 |
case STATE_ARC: |
|
4235 |
NO_TEXT ("arc"); |
|
4236 |
break; |
|
4237 |
case STATE_CLIP: |
|
4238 |
NO_TEXT ("clip"); |
|
4239 |
break; |
|
4240 |
case STATE_TINT: |
|
4241 |
NO_TEXT ("tint"); |
|
4242 |
break; |
|
4243 |
case STATE_GRADIENT: |
|
4244 |
NO_TEXT ("gradient"); |
|
4245 |
break; |
|
4246 |
case STATE_IMAGE: |
|
4247 |
NO_TEXT ("image"); |
|
4248 |
break; |
|
4249 |
case STATE_GTK_ARROW: |
|
4250 |
NO_TEXT ("gtk_arrow"); |
|
4251 |
break; |
|
4252 |
case STATE_GTK_BOX: |
|
4253 |
NO_TEXT ("gtk_box"); |
|
4254 |
break; |
|
4255 |
case STATE_GTK_VLINE: |
|
4256 |
NO_TEXT ("gtk_vline"); |
|
4257 |
break; |
|
4258 |
case STATE_ICON: |
|
4259 |
NO_TEXT ("icon"); |
|
4260 |
break; |
|
4261 |
case STATE_TITLE: |
|
4262 |
NO_TEXT ("title"); |
|
4263 |
break; |
|
4264 |
case STATE_INCLUDE: |
|
4265 |
NO_TEXT ("include"); |
|
4266 |
break; |
|
4267 |
case STATE_TILE: |
|
4268 |
NO_TEXT ("tile"); |
|
4269 |
break; |
|
4270 |
case STATE_COLOR: |
|
4271 |
NO_TEXT ("color"); |
|
4272 |
break; |
|
4273 |
case STATE_FRAME_STYLE: |
|
4274 |
NO_TEXT ("frame_style"); |
|
4275 |
break; |
|
4276 |
case STATE_PIECE: |
|
4277 |
NO_TEXT ("piece"); |
|
4278 |
break; |
|
4279 |
case STATE_BUTTON: |
|
4280 |
NO_TEXT ("button"); |
|
4281 |
break; |
|
1.2.68
by Dmitry Shachnev
Import upstream version 3.12.0 |
4282 |
case STATE_SHADOW: |
4283 |
NO_TEXT ("shadow"); |
|
4284 |
break; |
|
4285 |
case STATE_PADDING: |
|
4286 |
NO_TEXT ("padding"); |
|
4287 |
break; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4288 |
case STATE_MENU_ICON: |
4289 |
NO_TEXT ("menu_icon"); |
|
4290 |
break; |
|
4291 |
case STATE_FRAME_STYLE_SET: |
|
4292 |
NO_TEXT ("frame_style_set"); |
|
4293 |
break; |
|
4294 |
case STATE_FRAME: |
|
4295 |
NO_TEXT ("frame"); |
|
4296 |
break; |
|
4297 |
case STATE_WINDOW: |
|
4298 |
NO_TEXT ("window"); |
|
4299 |
break; |
|
4300 |
case STATE_FALLBACK: |
|
4301 |
NO_TEXT ("fallback"); |
|
4302 |
break; |
|
4303 |
}
|
|
4304 |
}
|
|
4305 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4306 |
/* If the theme is not-corrupt, keep looking for alternate versions
|
4307 |
* in other locations we might be compatible with
|
|
4308 |
*/
|
|
4309 |
static gboolean |
|
4310 |
theme_error_is_fatal (GError *error) |
|
4311 |
{
|
|
4312 |
return !(error->domain == G_FILE_ERROR || |
|
4313 |
(error->domain == THEME_PARSE_ERROR && |
|
4314 |
error->code == THEME_PARSE_ERROR_TOO_OLD)); |
|
4315 |
}
|
|
4316 |
||
4317 |
static MetaTheme * |
|
4318 |
load_theme (const char *theme_dir, |
|
4319 |
const char *theme_name, |
|
4320 |
guint major_version, |
|
4321 |
GError **error) |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4322 |
{
|
4323 |
GMarkupParseContext *context; |
|
4324 |
ParseInfo info; |
|
4325 |
char *text; |
|
4326 |
gsize length; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4327 |
char *theme_filename; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4328 |
char *theme_file; |
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4329 |
MetaTheme *retval; |
4330 |
||
4331 |
g_return_val_if_fail (error && *error == NULL, NULL); |
|
4332 |
||
4333 |
text = NULL; |
|
4334 |
retval = NULL; |
|
4335 |
context = NULL; |
|
4336 |
||
4337 |
theme_filename = g_strdup_printf (METACITY_THEME_FILENAME_FORMAT, major_version); |
|
4338 |
theme_file = g_build_filename (theme_dir, theme_filename, NULL); |
|
4339 |
||
4340 |
if (!g_file_get_contents (theme_file, &text, &length, error)) |
|
4341 |
goto out; |
|
4342 |
||
4343 |
meta_topic (META_DEBUG_THEMES, "Parsing theme file %s\n", theme_file); |
|
4344 |
||
4345 |
parse_info_init (&info); |
|
4346 |
||
4347 |
info.theme_name = theme_name; |
|
4348 |
info.theme_file = theme_file; |
|
4349 |
info.theme_dir = theme_dir; |
|
4350 |
||
4351 |
info.format_version = 1000 * major_version; |
|
4352 |
||
4353 |
context = g_markup_parse_context_new (&metacity_theme_parser, 0, &info, NULL); |
|
4354 |
||
4355 |
if (!g_markup_parse_context_parse (context, text, length, error)) |
|
4356 |
goto out; |
|
4357 |
||
4358 |
if (!g_markup_parse_context_end_parse (context, error)) |
|
4359 |
goto out; |
|
4360 |
||
4361 |
retval = info.theme; |
|
4362 |
info.theme = NULL; |
|
4363 |
||
4364 |
out: |
|
4365 |
if (*error && !theme_error_is_fatal (*error)) |
|
4366 |
meta_topic (META_DEBUG_THEMES, "Failed to read theme from file %s: %s\n", |
|
4367 |
theme_file, (*error)->message); |
|
4368 |
||
4369 |
g_free (theme_filename); |
|
4370 |
g_free (theme_file); |
|
4371 |
g_free (text); |
|
4372 |
||
4373 |
if (context) |
|
4374 |
{
|
|
4375 |
g_markup_parse_context_free (context); |
|
4376 |
parse_info_free (&info); |
|
4377 |
}
|
|
4378 |
||
4379 |
return retval; |
|
4380 |
}
|
|
4381 |
||
4382 |
static gboolean |
|
4383 |
keep_trying (GError **error) |
|
4384 |
{
|
|
4385 |
if (*error && !theme_error_is_fatal (*error)) |
|
4386 |
{
|
|
4387 |
g_clear_error (error); |
|
4388 |
return TRUE; |
|
4389 |
}
|
|
4390 |
||
4391 |
return FALSE; |
|
4392 |
}
|
|
4393 |
||
4394 |
MetaTheme* |
|
4395 |
meta_theme_load (const char *theme_name, |
|
4396 |
GError **err) |
|
4397 |
{
|
|
4398 |
GError *error = NULL; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4399 |
char *theme_dir; |
4400 |
MetaTheme *retval; |
|
4401 |
const gchar* const* xdg_data_dirs; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4402 |
int major_version; |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4403 |
int i; |
4404 |
||
4405 |
retval = NULL; |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4406 |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4407 |
if (meta_is_debugging ()) |
4408 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4409 |
/* We try all supported major versions from current to oldest */
|
4410 |
for (major_version = THEME_MAJOR_VERSION; (major_version > 0); major_version--) |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4411 |
{
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4412 |
theme_dir = g_build_filename ("./themes", theme_name, NULL); |
4413 |
retval = load_theme (theme_dir, theme_name, major_version, &error); |
|
4414 |
||
4415 |
if (!keep_trying (&error)) |
|
4416 |
goto out; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4417 |
}
|
4418 |
}
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4419 |
|
4420 |
/* We try all supported major versions from current to oldest */
|
|
4421 |
for (major_version = THEME_MAJOR_VERSION; (major_version > 0); major_version--) |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4422 |
{
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4423 |
/* We try first in XDG_USER_DATA_DIR, XDG_DATA_DIRS, then system dir for themes */
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4424 |
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4425 |
/* Try XDG_USER_DATA_DIR first */
|
4426 |
theme_dir = g_build_filename (g_get_user_data_dir(), |
|
4427 |
"themes", |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4428 |
theme_name, |
4429 |
THEME_SUBDIR, |
|
4430 |
NULL); |
|
4431 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4432 |
retval = load_theme (theme_dir, theme_name, major_version, &error); |
4433 |
g_free (theme_dir); |
|
4434 |
if (!keep_trying (&error)) |
|
4435 |
goto out; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4436 |
|
4437 |
/* Try each XDG_DATA_DIRS for theme */
|
|
4438 |
xdg_data_dirs = g_get_system_data_dirs(); |
|
4439 |
for(i = 0; xdg_data_dirs[i] != NULL; i++) |
|
4440 |
{
|
|
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4441 |
theme_dir = g_build_filename (xdg_data_dirs[i], |
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4442 |
"themes", |
4443 |
theme_name, |
|
4444 |
THEME_SUBDIR, |
|
4445 |
NULL); |
|
4446 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4447 |
retval = load_theme (theme_dir, theme_name, major_version, &error); |
4448 |
g_free (theme_dir); |
|
4449 |
if (!keep_trying (&error)) |
|
4450 |
goto out; |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4451 |
}
|
4452 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4453 |
/* Look for themes in METACITY_DATADIR */
|
4454 |
theme_dir = g_build_filename (METACITY_DATADIR, |
|
4455 |
"themes", |
|
4456 |
theme_name, |
|
4457 |
THEME_SUBDIR, |
|
4458 |
NULL); |
|
4459 |
retval = load_theme (theme_dir, theme_name, major_version, &error); |
|
4460 |
g_free (theme_dir); |
|
4461 |
if (!keep_trying (&error)) |
|
4462 |
goto out; |
|
4463 |
}
|
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4464 |
|
4465 |
out: |
|
4466 |
||
1.2.69
by Dmitry Shachnev
Import upstream version 3.14.0 |
4467 |
if (!error && !retval) |
4468 |
g_set_error (&error, META_THEME_ERROR, META_THEME_ERROR_FAILED, |
|
4469 |
_("Failed to find a valid file for theme %s\n"), |
|
4470 |
theme_name); |
|
1.2.37
by Pedro Fragoso
Import upstream version 2.21.8 |
4471 |
|
4472 |
if (error) |
|
4473 |
{
|
|
4474 |
g_propagate_error (err, error); |
|
4475 |
}
|
|
4476 |
||
4477 |
return retval; |
|
4478 |
}
|