diff options
-rw-r--r-- | src/theme-parser.c | 226 | ||||
-rw-r--r-- | src/theme-viewer.c | 16 | ||||
-rw-r--r-- | src/theme.c | 568 | ||||
-rw-r--r-- | src/theme.h | 212 |
4 files changed, 558 insertions, 464 deletions
diff --git a/src/theme-parser.c b/src/theme-parser.c index 1c57950e..0d9c1491 100644 --- a/src/theme-parser.c +++ b/src/theme-parser.c @@ -1641,8 +1641,10 @@ parse_geometry_element (GMarkupParseContext *context, } } +#if 0 static gboolean -check_expression (const char *expr, +check_expression (PosToken *tokens, + int n_tokens, gboolean has_object, MetaTheme *theme, GMarkupParseContext *context, @@ -1681,7 +1683,7 @@ check_expression (const char *expr, env.mini_icon_height = 0; env.theme = theme; - if (!meta_parse_position_expression (expr, + if (!meta_parse_position_expression (tokens, n_tokens, &env, &x, &y, error)) @@ -1692,16 +1694,7 @@ check_expression (const char *expr, return TRUE; } - -static char* -optimize_expression (MetaTheme *theme, - const char *expr) -{ - /* We aren't expecting an error here, since we already - * did check_expression - */ - return meta_theme_replace_constants (theme, expr, NULL); -} +#endif static void parse_draw_op_element (GMarkupParseContext *context, @@ -1775,6 +1768,7 @@ parse_draw_op_element (GMarkupParseContext *context, return; } +#if 0 if (!check_expression (x1, FALSE, info->theme, context, error)) return; @@ -1786,7 +1780,8 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (y2, FALSE, info->theme, context, error)) return; - +#endif + dash_on_val = 0; if (dash_on_length && !parse_positive_integer (dash_on_length, &dash_on_val, context, info->theme, error)) @@ -1815,10 +1810,12 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_LINE); op->data.line.color_spec = color_spec; - op->data.line.x1 = optimize_expression (info->theme, x1); - op->data.line.y1 = optimize_expression (info->theme, y1); - op->data.line.x2 = optimize_expression (info->theme, x2); - op->data.line.y2 = optimize_expression (info->theme, y2); + + op->data.line.x1 = meta_draw_spec_new (info->theme, x1, NULL); + op->data.line.y1 = meta_draw_spec_new (info->theme, y1, NULL); + op->data.line.x2 = meta_draw_spec_new (info->theme, x2, NULL); + op->data.line.y2 = meta_draw_spec_new (info->theme, y2, NULL); + op->data.line.width = width_val; op->data.line.dash_on_length = dash_on_val; op->data.line.dash_off_length = dash_off_val; @@ -1885,6 +1882,7 @@ parse_draw_op_element (GMarkupParseContext *context, return; } +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -1896,6 +1894,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; +#endif filled_val = FALSE; if (filled && !parse_boolean (filled, &filled_val, context, error)) @@ -1914,10 +1913,12 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_RECTANGLE); op->data.rectangle.color_spec = color_spec; - op->data.rectangle.x = optimize_expression (info->theme, x); - op->data.rectangle.y = optimize_expression (info->theme, y); - op->data.rectangle.width = optimize_expression (info->theme, width); - op->data.rectangle.height = optimize_expression (info->theme, height); + op->data.rectangle.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.rectangle.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.rectangle.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.rectangle.height = meta_draw_spec_new (info->theme, + height, NULL); + op->data.rectangle.filled = filled_val; g_assert (info->op_list); @@ -2025,7 +2026,7 @@ parse_draw_op_element (GMarkupParseContext *context, } } - +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2037,6 +2038,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; +#endif if (start_angle == NULL) { @@ -2081,10 +2083,12 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_ARC); op->data.arc.color_spec = color_spec; - op->data.arc.x = optimize_expression (info->theme, x); - op->data.arc.y = optimize_expression (info->theme, y); - op->data.arc.width = optimize_expression (info->theme, width); - op->data.arc.height = optimize_expression (info->theme, height); + + op->data.arc.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.arc.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.arc.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.arc.height = meta_draw_spec_new (info->theme, height, NULL); + op->data.arc.filled = filled_val; op->data.arc.start_angle = start_angle_val; op->data.arc.extent_angle = extent_angle_val; @@ -2138,6 +2142,7 @@ parse_draw_op_element (GMarkupParseContext *context, return; } +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2149,13 +2154,13 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; - +#endif op = meta_draw_op_new (META_DRAW_CLIP); - op->data.clip.x = optimize_expression (info->theme, x); - op->data.clip.y = optimize_expression (info->theme, y); - op->data.clip.width = optimize_expression (info->theme, width); - op->data.clip.height = optimize_expression (info->theme, height); + op->data.clip.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.clip.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.clip.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.clip.height = meta_draw_spec_new (info->theme, height, NULL); g_assert (info->op_list); @@ -2225,7 +2230,7 @@ parse_draw_op_element (GMarkupParseContext *context, _("No \"alpha\" attribute on element <%s>"), element_name); return; } - +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2237,7 +2242,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; - +#endif alpha_spec = NULL; if (!parse_alpha (alpha, &alpha_spec, context, error)) return; @@ -2259,10 +2264,11 @@ parse_draw_op_element (GMarkupParseContext *context, op->data.tint.color_spec = color_spec; op->data.tint.alpha_spec = alpha_spec; - op->data.tint.x = optimize_expression (info->theme, x); - op->data.tint.y = optimize_expression (info->theme, y); - op->data.tint.width = optimize_expression (info->theme, width); - op->data.tint.height = optimize_expression (info->theme, height); + + op->data.tint.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.tint.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.tint.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.tint.height = meta_draw_spec_new (info->theme, height, NULL); g_assert (info->op_list); @@ -2325,6 +2331,7 @@ parse_draw_op_element (GMarkupParseContext *context, return; } +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2336,7 +2343,8 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; - +#endif + type_val = meta_gradient_type_from_string (type); if (type_val == META_GRADIENT_LAST) { @@ -2353,10 +2361,12 @@ parse_draw_op_element (GMarkupParseContext *context, g_assert (info->op == NULL); info->op = meta_draw_op_new (META_DRAW_GRADIENT); - info->op->data.gradient.x = optimize_expression (info->theme, x); - info->op->data.gradient.y = optimize_expression (info->theme, y); - info->op->data.gradient.width = optimize_expression (info->theme, width); - info->op->data.gradient.height = optimize_expression (info->theme, height); + info->op->data.gradient.x = meta_draw_spec_new (info->theme, x, NULL); + info->op->data.gradient.y = meta_draw_spec_new (info->theme, y, NULL); + info->op->data.gradient.width = meta_draw_spec_new (info->theme, + width, NULL); + info->op->data.gradient.height = meta_draw_spec_new (info->theme, + height, NULL); info->op->data.gradient.gradient_spec = meta_gradient_spec_new (type_val); @@ -2429,7 +2439,7 @@ parse_draw_op_element (GMarkupParseContext *context, _("No \"filename\" attribute on element <%s>"), element_name); return; } - +#if 0 if (!check_expression (x, TRUE, info->theme, context, error)) return; @@ -2441,7 +2451,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, TRUE, info->theme, context, error)) return; - +#endif fill_type_val = META_IMAGE_FILL_SCALE; if (fill_type) { @@ -2493,10 +2503,12 @@ parse_draw_op_element (GMarkupParseContext *context, op->data.image.pixbuf = pixbuf; op->data.image.colorize_spec = colorize_spec; - op->data.image.x = optimize_expression (info->theme, x); - op->data.image.y = optimize_expression (info->theme, y); - op->data.image.width = optimize_expression (info->theme, width); - op->data.image.height = optimize_expression (info->theme, height); + + op->data.image.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.image.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.image.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.image.height = meta_draw_spec_new (info->theme, height, NULL); + op->data.image.alpha_spec = alpha_spec; op->data.image.fill_type = fill_type_val; @@ -2642,7 +2654,7 @@ parse_draw_op_element (GMarkupParseContext *context, _("No \"height\" attribute on element <%s>"), element_name); return; } - +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2654,7 +2666,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; - +#endif filled_val = TRUE; if (filled && !parse_boolean (filled, &filled_val, context, error)) return; @@ -2691,10 +2703,12 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_GTK_ARROW); - op->data.gtk_arrow.x = optimize_expression (info->theme, x); - op->data.gtk_arrow.y = optimize_expression (info->theme, y); - op->data.gtk_arrow.width = optimize_expression (info->theme, width); - op->data.gtk_arrow.height = optimize_expression (info->theme, height); + op->data.gtk_arrow.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.gtk_arrow.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.gtk_arrow.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.gtk_arrow.height = meta_draw_spec_new (info->theme, + height, NULL); + op->data.gtk_arrow.filled = filled_val; op->data.gtk_arrow.state = state_val; op->data.gtk_arrow.shadow = shadow_val; @@ -2768,7 +2782,7 @@ parse_draw_op_element (GMarkupParseContext *context, _("No \"height\" attribute on element <%s>"), element_name); return; } - +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2780,7 +2794,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; - +#endif state_val = meta_gtk_state_from_string (state); if (((int) state_val) == -1) { @@ -2803,10 +2817,11 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_GTK_BOX); - op->data.gtk_box.x = optimize_expression (info->theme, x); - op->data.gtk_box.y = optimize_expression (info->theme, y); - op->data.gtk_box.width = optimize_expression (info->theme, width); - op->data.gtk_box.height = optimize_expression (info->theme, height); + op->data.gtk_box.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.gtk_box.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.gtk_box.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.gtk_box.height = meta_draw_spec_new (info->theme, height, NULL); + op->data.gtk_box.state = state_val; op->data.gtk_box.shadow = shadow_val; @@ -2860,6 +2875,7 @@ parse_draw_op_element (GMarkupParseContext *context, return; } +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2868,6 +2884,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (y2, FALSE, info->theme, context, error)) return; +#endif state_val = meta_gtk_state_from_string (state); if (((int) state_val) == -1) @@ -2881,9 +2898,10 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_GTK_VLINE); - op->data.gtk_vline.x = optimize_expression (info->theme, x); - op->data.gtk_vline.y1 = optimize_expression (info->theme, y1); - op->data.gtk_vline.y2 = optimize_expression (info->theme, y2); + op->data.gtk_vline.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.gtk_vline.y1 = meta_draw_spec_new (info->theme, y1, NULL); + op->data.gtk_vline.y2 = meta_draw_spec_new (info->theme, y2, NULL); + op->data.gtk_vline.state = state_val; g_assert (info->op_list); @@ -2940,7 +2958,7 @@ parse_draw_op_element (GMarkupParseContext *context, _("No \"height\" attribute on element <%s>"), element_name); return; } - +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; @@ -2952,7 +2970,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (height, FALSE, info->theme, context, error)) return; - +#endif fill_type_val = META_IMAGE_FILL_SCALE; if (fill_type) { @@ -2972,11 +2990,12 @@ parse_draw_op_element (GMarkupParseContext *context, return; op = meta_draw_op_new (META_DRAW_ICON); + + op->data.icon.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.icon.y = meta_draw_spec_new (info->theme, y, NULL); + op->data.icon.width = meta_draw_spec_new (info->theme, width, NULL); + op->data.icon.height = meta_draw_spec_new (info->theme, height, NULL); - op->data.icon.x = optimize_expression (info->theme, x); - op->data.icon.y = optimize_expression (info->theme, y); - op->data.icon.width = optimize_expression (info->theme, width); - op->data.icon.height = optimize_expression (info->theme, height); op->data.icon.alpha_spec = alpha_spec; op->data.icon.fill_type = fill_type_val; @@ -3022,12 +3041,14 @@ parse_draw_op_element (GMarkupParseContext *context, return; } +#if 0 if (!check_expression (x, FALSE, info->theme, context, error)) return; if (!check_expression (y, FALSE, info->theme, context, error)) return; - +#endif + /* Check last so we don't have to free it when other * stuff fails */ @@ -3041,8 +3062,9 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_TITLE); op->data.title.color_spec = color_spec; - op->data.title.x = optimize_expression (info->theme, x); - op->data.title.y = optimize_expression (info->theme, y); + + op->data.title.x = meta_draw_spec_new (info->theme, x, NULL); + op->data.title.y = meta_draw_spec_new (info->theme, y, NULL); g_assert (info->op_list); @@ -3078,7 +3100,7 @@ parse_draw_op_element (GMarkupParseContext *context, /* x/y/width/height default to 0,0,width,height - should * probably do this for all the draw ops */ - +#if 0 if (x && !check_expression (x, FALSE, info->theme, context, error)) return; @@ -3090,6 +3112,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (height && !check_expression (height, FALSE, info->theme, context, error)) return; +#endif op_list = meta_theme_lookup_draw_op_list (info->theme, name); @@ -3118,15 +3141,16 @@ parse_draw_op_element (GMarkupParseContext *context, meta_draw_op_list_ref (op_list); op->data.op_list.op_list = op_list; - op->data.op_list.x = x ? optimize_expression (info->theme, x) : - g_strdup ("0"); - op->data.op_list.y = y ? optimize_expression (info->theme, y) : - g_strdup ("0"); - op->data.op_list.width = width ? optimize_expression (info->theme, width) : - g_strdup ("width"); - op->data.op_list.height = height ? optimize_expression (info->theme, height) : - g_strdup ("height"); - + + op->data.op_list.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL); + op->data.op_list.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL); + op->data.op_list.width = meta_draw_spec_new (info->theme, + width ? width : "width", + NULL); + op->data.op_list.height = meta_draw_spec_new (info->theme, + height ? height : "height", + NULL); + meta_draw_op_list_append (info->op_list, op); push_state (info, STATE_INCLUDE); @@ -3179,6 +3203,7 @@ parse_draw_op_element (GMarkupParseContext *context, } /* These default to 0 */ +#if 0 if (tile_xoffset && !check_expression (tile_xoffset, FALSE, info->theme, context, error)) return; @@ -3188,7 +3213,6 @@ parse_draw_op_element (GMarkupParseContext *context, /* x/y/width/height default to 0,0,width,height - should * probably do this for all the draw ops */ - if (x && !check_expression (x, FALSE, info->theme, context, error)) return; @@ -3206,7 +3230,7 @@ parse_draw_op_element (GMarkupParseContext *context, if (!check_expression (tile_height, FALSE, info->theme, context, error)) return; - +#endif op_list = meta_theme_lookup_draw_op_list (info->theme, name); if (op_list == NULL) @@ -3233,23 +3257,25 @@ parse_draw_op_element (GMarkupParseContext *context, op = meta_draw_op_new (META_DRAW_TILE); meta_draw_op_list_ref (op_list); + + op->data.tile.x = meta_draw_spec_new (info->theme, x ? x : "0", NULL); + op->data.tile.y = meta_draw_spec_new (info->theme, y ? y : "0", NULL); + op->data.tile.width = meta_draw_spec_new (info->theme, + width ? width : "width", + NULL); + op->data.tile.height = meta_draw_spec_new (info->theme, + height ? height : "height", + NULL); + op->data.tile.tile_xoffset = meta_draw_spec_new (info->theme, + tile_xoffset ? tile_xoffset : "0", + NULL); + op->data.tile.tile_yoffset = meta_draw_spec_new (info->theme, + tile_yoffset ? tile_yoffset : "0", + NULL); + op->data.tile.tile_width = meta_draw_spec_new (info->theme, tile_width, NULL); + op->data.tile.tile_height = meta_draw_spec_new (info->theme, tile_height, NULL); + op->data.tile.op_list = op_list; - op->data.tile.x = x ? optimize_expression (info->theme, x) : - g_strdup ("0"); - op->data.tile.y = y ? optimize_expression (info->theme, y) : - g_strdup ("0"); - op->data.tile.width = width ? optimize_expression (info->theme, width) : - g_strdup ("width"); - op->data.tile.height = height ? optimize_expression (info->theme, height) : - g_strdup ("height"); - op->data.tile.tile_xoffset = tile_xoffset ? - optimize_expression (info->theme, tile_xoffset) : - g_strdup ("0"); - op->data.tile.tile_yoffset = tile_yoffset ? - optimize_expression (info->theme, tile_yoffset) : - g_strdup ("0"); - op->data.tile.tile_width = optimize_expression (info->theme, tile_width); - op->data.tile.tile_height = optimize_expression (info->theme, tile_height); meta_draw_op_list_append (info->op_list, op); diff --git a/src/theme-viewer.c b/src/theme-viewer.c index d4a1106b..4b97de66 100644 --- a/src/theme-viewer.c +++ b/src/theme-viewer.c @@ -1175,6 +1175,7 @@ static const PositionExpressionTest position_expression_tests[] = { static void run_position_expression_tests (void) { +#if 0 int i; MetaPositionExprEnv env; @@ -1184,6 +1185,8 @@ run_position_expression_tests (void) GError *err; gboolean retval; const PositionExpressionTest *test; + PosToken *tokens; + int n_tokens; int x, y; test = &position_expression_tests[i]; @@ -1210,10 +1213,13 @@ run_position_expression_tests (void) env.mini_icon_height = 16; env.theme = NULL; - retval = meta_parse_position_expression (test->expr, - &env, - &x, &y, - &err); + if (err == NULL) + { + retval = meta_parse_position_expression (tokens, n_tokens, + &env, + &x, &y, + &err); + } if (retval && err) g_error (_("position expression test returned TRUE but set error")); @@ -1243,8 +1249,10 @@ run_position_expression_tests (void) if (err) g_error_free (err); + meta_pos_tokens_free (tokens, n_tokens); ++i; } +#endif } #if 0 diff --git a/src/theme.c b/src/theme.c index 92ff558f..5cd22f8a 100644 --- a/src/theme.c +++ b/src/theme.c @@ -60,6 +60,8 @@ static void hls_to_rgb (gdouble *h, gdouble *l, gdouble *s); +static MetaTheme *meta_current_theme = NULL; + static GdkPixbuf * colorize_pixbuf (GdkPixbuf *orig, GdkColor *new_color) @@ -1167,6 +1169,7 @@ meta_color_spec_new_from_string (const char *str, spec->data.blend.alpha = alpha; spec->data.blend.background = bg; spec->data.blend.foreground = fg; + spec->data.blend.color_set = FALSE; } else if (str[0] == 's' && str[1] == 'h' && str[2] == 'a' && str[3] == 'd' && str[4] == 'e' && str[5] == '/') @@ -1225,6 +1228,7 @@ meta_color_spec_new_from_string (const char *str, spec = meta_color_spec_new (META_COLOR_SPEC_SHADE); spec->data.shade.factor = factor; spec->data.shade.base = base; + spec->data.shade.color_set = FALSE; } else { @@ -1312,49 +1316,38 @@ meta_color_spec_render (MetaColorSpec *spec, { GdkColor bg, fg; - meta_color_spec_render (spec->data.blend.background, widget, &bg); - meta_color_spec_render (spec->data.blend.foreground, widget, &fg); + if (spec->data.blend.color_set == FALSE) + { + meta_color_spec_render (spec->data.blend.background, widget, &bg); + meta_color_spec_render (spec->data.blend.foreground, widget, &fg); - color_composite (&bg, &fg, spec->data.blend.alpha, color); + color_composite (&bg, &fg, spec->data.blend.alpha, + &spec->data.blend.color); + spec->data.blend.color_set = TRUE; + } + + *color = spec->data.blend.color; } break; case META_COLOR_SPEC_SHADE: { - GdkColor base; - - meta_color_spec_render (spec->data.shade.base, widget, &base); - - gtk_style_shade (&base, &base, spec->data.shade.factor); + if (spec->data.shade.color_set == FALSE) + { + meta_color_spec_render (spec->data.shade.base, widget, + &spec->data.shade.color); + + gtk_style_shade (&spec->data.shade.color, + &spec->data.shade.color, spec->data.shade.factor); + spec->data.shade.color_set = TRUE; + } - *color = base; + *color = spec->data.shade.color; } break; } } -typedef enum -{ - POS_TOKEN_INT, - POS_TOKEN_DOUBLE, - POS_TOKEN_OPERATOR, - POS_TOKEN_VARIABLE, - POS_TOKEN_OPEN_PAREN, - POS_TOKEN_CLOSE_PAREN -} PosTokenType; - -typedef enum -{ - POS_OP_NONE, - POS_OP_ADD, - POS_OP_SUBTRACT, - POS_OP_MULTIPLY, - POS_OP_DIVIDE, - POS_OP_MOD, - POS_OP_MAX, - POS_OP_MIN -} PosOperatorType; - static const char* op_name (PosOperatorType type) { @@ -1429,33 +1422,6 @@ op_from_string (const char *p, return POS_OP_NONE; } -typedef struct -{ - PosTokenType type; - - union - { - struct { - int val; - } i; - - struct { - double val; - } d; - - struct { - PosOperatorType op; - } o; - - struct { - char *name; - } v; - - } d; - -} PosToken; - - static void free_tokens (PosToken *tokens, int n_tokens) @@ -1550,6 +1516,46 @@ parse_number (const char *p, #define IS_VARIABLE_CHAR(c) (g_ascii_isalpha ((c)) || (c) == '_') +#if 0 +static void +debug_print_tokens (PosToken *tokens, + int n_tokens) +{ + int i; + + for (i = 0; i < n_tokens; i++) + { + PosToken *t = &tokens[i]; + + g_print (" "); + + switch (t->type) + { + case POS_TOKEN_INT: + g_print ("\"%d\"", t->d.i.val); + break; + case POS_TOKEN_DOUBLE: + g_print ("\"%g\"", t->d.d.val); + break; + case POS_TOKEN_OPEN_PAREN: + g_print ("\"(\""); + break; + case POS_TOKEN_CLOSE_PAREN: + g_print ("\")\""); + break; + case POS_TOKEN_VARIABLE: + g_print ("\"%s\"", t->d.v.name); + break; + case POS_TOKEN_OPERATOR: + g_print ("\"%s\"", op_name (t->d.o.op)); + break; + } + } + + g_print ("\n"); +} +#endif + static gboolean pos_tokenize (const char *expr, PosToken **tokens_p, @@ -1675,46 +1681,6 @@ pos_tokenize (const char *expr, return FALSE; } -#if 0 -static void -debug_print_tokens (PosToken *tokens, - int n_tokens) -{ - int i; - - for (i = 0; i < n_tokens; i++) - { - PosToken *t = &tokens[i]; - - g_print (" "); - - switch (t->type) - { - case POS_TOKEN_INT: - g_print ("\"%d\"", t->d.i.val); - break; - case POS_TOKEN_DOUBLE: - g_print ("\"%g\"", t->d.d.val); - break; - case POS_TOKEN_OPEN_PAREN: - g_print ("\"(\""); - break; - case POS_TOKEN_CLOSE_PAREN: - g_print ("\")\""); - break; - case POS_TOKEN_VARIABLE: - g_print ("\"%s\"", t->d.v.name); - break; - case POS_TOKEN_OPERATOR: - g_print ("\"%s\"", op_name (t->d.o.op)); - break; - } - } - - g_print ("\n"); -} -#endif - typedef enum { POS_EXPR_INT, @@ -2030,7 +1996,6 @@ pos_eval_helper (PosToken *tokens, #if 0 g_print ("Pos eval helper on %d tokens:\n", n_tokens); - debug_print_tokens (tokens, n_tokens); #endif /* Our first goal is to get a list of PosExpr, essentially @@ -2087,35 +2052,35 @@ pos_eval_helper (PosToken *tokens, * in a hash, maybe keep width/height out * for optimization purposes */ - if (strcmp (t->d.v.name, "width") == 0) + if (t->d.v.name_quark == env->theme->quark_width) exprs[n_exprs].d.int_val = env->rect.width; - else if (strcmp (t->d.v.name, "height") == 0) + else if (t->d.v.name_quark == env->theme->quark_height) exprs[n_exprs].d.int_val = env->rect.height; else if (env->object_width >= 0 && - strcmp (t->d.v.name, "object_width") == 0) + t->d.v.name_quark == env->theme->quark_object_width) exprs[n_exprs].d.int_val = env->object_width; else if (env->object_height >= 0 && - strcmp (t->d.v.name, "object_height") == 0) + t->d.v.name_quark == env->theme->quark_object_height) exprs[n_exprs].d.int_val = env->object_height; - else if (strcmp (t->d.v.name, "left_width") == 0) + else if (t->d.v.name_quark == env->theme->quark_left_width) exprs[n_exprs].d.int_val = env->left_width; - else if (strcmp (t->d.v.name, "right_width") == 0) + else if (t->d.v.name_quark == env->theme->quark_right_width) exprs[n_exprs].d.int_val = env->right_width; - else if (strcmp (t->d.v.name, "top_height") == 0) + else if (t->d.v.name_quark == env->theme->quark_top_height) exprs[n_exprs].d.int_val = env->top_height; - else if (strcmp (t->d.v.name, "bottom_height") == 0) + else if (t->d.v.name_quark == env->theme->quark_bottom_height) exprs[n_exprs].d.int_val = env->bottom_height; - else if (strcmp (t->d.v.name, "mini_icon_width") == 0) + else if (t->d.v.name_quark == env->theme->quark_mini_icon_width) exprs[n_exprs].d.int_val = env->mini_icon_width; - else if (strcmp (t->d.v.name, "mini_icon_height") == 0) + else if (t->d.v.name_quark == env->theme->quark_mini_icon_height) exprs[n_exprs].d.int_val = env->mini_icon_height; - else if (strcmp (t->d.v.name, "icon_width") == 0) + else if (t->d.v.name_quark == env->theme->quark_icon_width) exprs[n_exprs].d.int_val = env->icon_width; - else if (strcmp (t->d.v.name, "icon_height") == 0) + else if (t->d.v.name_quark == env->theme->quark_icon_height) exprs[n_exprs].d.int_val = env->icon_height; - else if (strcmp (t->d.v.name, "title_width") == 0) + else if (t->d.v.name_quark == env->theme->quark_title_width) exprs[n_exprs].d.int_val = env->title_width; - else if (strcmp (t->d.v.name, "title_height") == 0) + else if (t->d.v.name_quark == env->theme->quark_title_height) exprs[n_exprs].d.int_val = env->title_height; /* In practice we only hit this code on initial theme * parse; after that we always optimize constants away @@ -2232,8 +2197,7 @@ pos_eval_helper (PosToken *tokens, * so very not worth fooling with bison, yet so very painful by hand. */ static gboolean -pos_eval (PosToken *tokens, - int n_tokens, +pos_eval (MetaDrawSpec *spec, const MetaPositionExprEnv *env, int *val_p, GError **err) @@ -2242,7 +2206,7 @@ pos_eval (PosToken *tokens, *val_p = 0; - if (pos_eval_helper (tokens, n_tokens, env, &expr, err)) + if (pos_eval_helper (spec->tokens, spec->n_tokens, env, &expr, err)) { switch (expr.type) { @@ -2269,7 +2233,7 @@ pos_eval (PosToken *tokens, */ gboolean -meta_parse_position_expression (const char *expr, +meta_parse_position_expression (MetaDrawSpec *spec, const MetaPositionExprEnv *env, int *x_return, int *y_return, @@ -2281,73 +2245,55 @@ meta_parse_position_expression (const char *expr, * optionally "object_width" and object_height". Negative numbers * aren't allowed. */ - PosToken *tokens; - int n_tokens; int val; - if (!pos_tokenize (expr, &tokens, &n_tokens, err)) + if (spec->constant) + val = spec->value; + else { - g_assert (err == NULL || *err != NULL); - return FALSE; + if (pos_eval (spec, env, &spec->value, err) == FALSE) + { + g_assert (err == NULL || *err != NULL); + return FALSE; + } + + val = spec->value; } -#if 0 - g_print ("Tokenized \"%s\" to --->\n", expr); - debug_print_tokens (tokens, n_tokens); -#endif + if (x_return) + *x_return = env->rect.x + val; + if (y_return) + *y_return = env->rect.y + val; - if (pos_eval (tokens, n_tokens, env, &val, err)) - { - if (x_return) - *x_return = env->rect.x + val; - if (y_return) - *y_return = env->rect.y + val; - free_tokens (tokens, n_tokens); - return TRUE; - } - else - { - g_assert (err == NULL || *err != NULL); - free_tokens (tokens, n_tokens); - return FALSE; - } + return TRUE; } gboolean -meta_parse_size_expression (const char *expr, +meta_parse_size_expression (MetaDrawSpec *spec, const MetaPositionExprEnv *env, int *val_return, GError **err) { - PosToken *tokens; - int n_tokens; int val; - if (!pos_tokenize (expr, &tokens, &n_tokens, err)) + if (spec->constant) + val = spec->value; + else { - g_assert (err == NULL || *err != NULL); - return FALSE; + if (pos_eval (spec, env, &spec->value, err) == FALSE) + { + g_assert (err == NULL || *err != NULL); + return FALSE; + } + + val = spec->value; } -#if 0 - g_print ("Tokenized \"%s\" to --->\n", expr); - debug_print_tokens (tokens, n_tokens); -#endif + if (val_return) + *val_return = MAX (val, 1); /* require that sizes be at least 1x1 */ - if (pos_eval (tokens, n_tokens, env, &val, err)) - { - if (val_return) - *val_return = MAX (val, 1); /* require that sizes be at least 1x1 */ - free_tokens (tokens, n_tokens); - return TRUE; - } - else - { - g_assert (err == NULL || *err != NULL); - free_tokens (tokens, n_tokens); - return FALSE; - } + return TRUE; } /* To do this we tokenize, replace variable tokens @@ -2356,85 +2302,51 @@ meta_parse_size_expression (const char *expr, * lookups to eval them. Obviously it's a tradeoff that * slows down theme load times. */ -char* +gboolean meta_theme_replace_constants (MetaTheme *theme, - const char *expr, + PosToken *tokens, + int n_tokens, GError **err) { - PosToken *tokens; - int n_tokens; int i; - GString *str; - char buf[G_ASCII_DTOSTR_BUF_SIZE]; double dval; int ival; + gboolean is_constant = TRUE; - if (!pos_tokenize (expr, &tokens, &n_tokens, err)) - { - g_assert (err == NULL || *err != NULL); - return NULL; - } - -#if 0 - g_print ("Tokenized \"%s\" to --->\n", expr); - debug_print_tokens (tokens, n_tokens); -#endif - - str = g_string_new (NULL); - + /* Loop through tokenized string looking for variables to replace */ for (i = 0; i < n_tokens; i++) { PosToken *t = &tokens[i]; - /* spaces so we don't accidentally merge variables - * or anything like that - */ - if (i > 0) - g_string_append_c (str, ' '); - - switch (t->type) + if (t->type == POS_TOKEN_VARIABLE) { - case POS_TOKEN_INT: - g_string_append_printf (str, "%d", t->d.i.val); - break; - case POS_TOKEN_DOUBLE: - g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, - "%g", t->d.d.val); - g_string_append (str, buf); - break; - case POS_TOKEN_OPEN_PAREN: - g_string_append_c (str, '('); - break; - case POS_TOKEN_CLOSE_PAREN: - g_string_append_c (str, ')'); - break; - case POS_TOKEN_VARIABLE: if (meta_theme_lookup_int_constant (theme, t->d.v.name, &ival)) - g_string_append_printf (str, "%d", ival); + { + t->type = POS_TOKEN_INT; + t->d.i.val = ival; + } else if (meta_theme_lookup_float_constant (theme, t->d.v.name, &dval)) { - g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, - "%g", dval); - g_string_append (str, buf); + t->type = POS_TOKEN_DOUBLE; + t->d.d.val = dval; } - else + else { - g_string_append (str, t->d.v.name); + /* If we've found a variable that cannot be replaced then the + expression is not a constant expression and we want to + replace it with a GQuark */ + + t->d.v.name_quark = g_quark_from_string (t->d.v.name); + is_constant = FALSE; } - break; - case POS_TOKEN_OPERATOR: - g_string_append (str, op_name (t->d.o.op)); - break; } } - - free_tokens (tokens, n_tokens); - return g_string_free (str, FALSE); + return is_constant; } static int -parse_x_position_unchecked (const char *expr, +parse_x_position_unchecked (MetaDrawSpec *spec, const MetaPositionExprEnv *env) { int retval; @@ -2442,21 +2354,19 @@ parse_x_position_unchecked (const char *expr, retval = 0; error = NULL; - if (!meta_parse_position_expression (expr, env, - &retval, NULL, - &error)) + if (!meta_parse_position_expression (spec, env, &retval, NULL, &error)) { - meta_warning (_("Theme contained an expression \"%s\" that resulted in an error: %s\n"), - expr, error->message); - + meta_warning (_("Theme contained an expression that resulted in an error: %s\n"), + error->message); + g_error_free (error); } - + return retval; } static int -parse_y_position_unchecked (const char *expr, +parse_y_position_unchecked (MetaDrawSpec *spec, const MetaPositionExprEnv *env) { int retval; @@ -2464,12 +2374,10 @@ parse_y_position_unchecked (const char *expr, retval = 0; error = NULL; - if (!meta_parse_position_expression (expr, env, - NULL, &retval, - &error)) + if (!meta_parse_position_expression (spec, env, NULL, &retval, &error)) { - meta_warning (_("Theme contained an expression \"%s\" that resulted in an error: %s\n"), - expr, error->message); + meta_warning (_("Theme contained an expression that resulted in an error: %s\n"), + error->message); g_error_free (error); } @@ -2478,7 +2386,7 @@ parse_y_position_unchecked (const char *expr, } static int -parse_size_unchecked (const char *expr, +parse_size_unchecked (MetaDrawSpec *spec, MetaPositionExprEnv *env) { int retval; @@ -2486,11 +2394,10 @@ parse_size_unchecked (const char *expr, retval = 0; error = NULL; - if (!meta_parse_size_expression (expr, env, - &retval, &error)) + if (!meta_parse_size_expression (spec, env, &retval, &error)) { - meta_warning (_("Theme contained an expression \"%s\" that resulted in an error: %s\n"), - expr, error->message); + meta_warning (_("Theme contained an expression that resulted in an error: %s\n"), + error->message); g_error_free (error); } @@ -2498,6 +2405,42 @@ parse_size_unchecked (const char *expr, return retval; } +void +meta_draw_spec_free (MetaDrawSpec *spec) +{ + free_tokens (spec->tokens, spec->n_tokens); + g_slice_free (MetaDrawSpec, spec); +} + +MetaDrawSpec * +meta_draw_spec_new (MetaTheme *theme, + const char *expr, + GError **error) +{ + MetaDrawSpec *spec; + + spec = g_slice_new0 (MetaDrawSpec); + + pos_tokenize (expr, &spec->tokens, &spec->n_tokens, NULL); + + spec->constant = meta_theme_replace_constants (theme, spec->tokens, + spec->n_tokens, NULL); + if (spec->constant) + { + gboolean result; + + g_print ("%s is constant\n", expr); + result = pos_eval (spec, NULL, &spec->value, error); + if (result == FALSE) + { + meta_draw_spec_free (spec); + return NULL; + } + } + + return spec; +} + MetaDrawOp* meta_draw_op_new (MetaDrawType type) { @@ -2581,130 +2524,145 @@ meta_draw_op_free (MetaDrawOp *op) case META_DRAW_LINE: if (op->data.line.color_spec) meta_color_spec_free (op->data.line.color_spec); - g_free (op->data.line.x1); - g_free (op->data.line.y1); - g_free (op->data.line.x2); - g_free (op->data.line.y2); + + meta_draw_spec_free (op->data.line.x1); + meta_draw_spec_free (op->data.line.y1); + meta_draw_spec_free (op->data.line.x2); + meta_draw_spec_free (op->data.line.y2); break; case META_DRAW_RECTANGLE: if (op->data.rectangle.color_spec) g_free (op->data.rectangle.color_spec); - g_free (op->data.rectangle.x); - g_free (op->data.rectangle.y); - g_free (op->data.rectangle.width); - g_free (op->data.rectangle.height); + + meta_draw_spec_free (op->data.rectangle.x); + meta_draw_spec_free (op->data.rectangle.y); + meta_draw_spec_free (op->data.rectangle.width); + meta_draw_spec_free (op->data.rectangle.height); break; case META_DRAW_ARC: if (op->data.arc.color_spec) g_free (op->data.arc.color_spec); - g_free (op->data.arc.x); - g_free (op->data.arc.y); - g_free (op->data.arc.width); - g_free (op->data.arc.height); + + meta_draw_spec_free (op->data.arc.x); + meta_draw_spec_free (op->data.arc.y); + meta_draw_spec_free (op->data.arc.width); + meta_draw_spec_free (op->data.arc.height); break; case META_DRAW_CLIP: - g_free (op->data.clip.x); - g_free (op->data.clip.y); - g_free (op->data.clip.width); - g_free (op->data.clip.height); + meta_draw_spec_free (op->data.clip.x); + meta_draw_spec_free (op->data.clip.y); + meta_draw_spec_free (op->data.clip.width); + meta_draw_spec_free (op->data.clip.height); break; case META_DRAW_TINT: if (op->data.tint.color_spec) meta_color_spec_free (op->data.tint.color_spec); + if (op->data.tint.alpha_spec) meta_alpha_gradient_spec_free (op->data.tint.alpha_spec); - g_free (op->data.tint.x); - g_free (op->data.tint.y); - g_free (op->data.tint.width); - g_free (op->data.tint.height); + + meta_draw_spec_free (op->data.tint.x); + meta_draw_spec_free (op->data.tint.y); + meta_draw_spec_free (op->data.tint.width); + meta_draw_spec_free (op->data.tint.height); break; case META_DRAW_GRADIENT: if (op->data.gradient.gradient_spec) meta_gradient_spec_free (op->data.gradient.gradient_spec); + if (op->data.gradient.alpha_spec) meta_alpha_gradient_spec_free (op->data.gradient.alpha_spec); - g_free (op->data.gradient.x); - g_free (op->data.gradient.y); - g_free (op->data.gradient.width); - g_free (op->data.gradient.height); + + meta_draw_spec_free (op->data.gradient.x); + meta_draw_spec_free (op->data.gradient.y); + meta_draw_spec_free (op->data.gradient.width); + meta_draw_spec_free (op->data.gradient.height); break; case META_DRAW_IMAGE: if (op->data.image.alpha_spec) meta_alpha_gradient_spec_free (op->data.image.alpha_spec); + if (op->data.image.pixbuf) g_object_unref (G_OBJECT (op->data.image.pixbuf)); + if (op->data.image.colorize_spec) meta_color_spec_free (op->data.image.colorize_spec); + if (op->data.image.colorize_cache_pixbuf) g_object_unref (G_OBJECT (op->data.image.colorize_cache_pixbuf)); - g_free (op->data.image.x); - g_free (op->data.image.y); - g_free (op->data.image.width); - g_free (op->data.image.height); + + meta_draw_spec_free (op->data.image.x); + meta_draw_spec_free (op->data.image.y); + meta_draw_spec_free (op->data.image.width); + meta_draw_spec_free (op->data.image.height); break; case META_DRAW_GTK_ARROW: - g_free (op->data.gtk_arrow.x); - g_free (op->data.gtk_arrow.y); - g_free (op->data.gtk_arrow.width); - g_free (op->data.gtk_arrow.height); + meta_draw_spec_free (op->data.gtk_arrow.x); + meta_draw_spec_free (op->data.gtk_arrow.y); + meta_draw_spec_free (op->data.gtk_arrow.width); + meta_draw_spec_free (op->data.gtk_arrow.height); break; case META_DRAW_GTK_BOX: - g_free (op->data.gtk_box.x); - g_free (op->data.gtk_box.y); - g_free (op->data.gtk_box.width); - g_free (op->data.gtk_box.height); + meta_draw_spec_free (op->data.gtk_box.x); + meta_draw_spec_free (op->data.gtk_box.y); + meta_draw_spec_free (op->data.gtk_box.width); + meta_draw_spec_free (op->data.gtk_box.height); break; case META_DRAW_GTK_VLINE: - g_free (op->data.gtk_vline.x); - g_free (op->data.gtk_vline.y1); - g_free (op->data.gtk_vline.y2); + meta_draw_spec_free (op->data.gtk_vline.x); + meta_draw_spec_free (op->data.gtk_vline.y1); + meta_draw_spec_free (op->data.gtk_vline.y2); break; case META_DRAW_ICON: if (op->data.icon.alpha_spec) meta_alpha_gradient_spec_free (op->data.icon.alpha_spec); - g_free (op->data.icon.x); - g_free (op->data.icon.y); - g_free (op->data.icon.width); - g_free (op->data.icon.height); + + meta_draw_spec_free (op->data.icon.x); + meta_draw_spec_free (op->data.icon.y); + meta_draw_spec_free (op->data.icon.width); + meta_draw_spec_free (op->data.icon.height); break; case META_DRAW_TITLE: if (op->data.title.color_spec) meta_color_spec_free (op->data.title.color_spec); - g_free (op->data.title.x); - g_free (op->data.title.y); + + meta_draw_spec_free (op->data.title.x); + meta_draw_spec_free (op->data.title.y); break; case META_DRAW_OP_LIST: if (op->data.op_list.op_list) meta_draw_op_list_unref (op->data.op_list.op_list); - g_free (op->data.op_list.x); - g_free (op->data.op_list.y); - g_free (op->data.op_list.width); - g_free (op->data.op_list.height); + + meta_draw_spec_free (op->data.op_list.x); + meta_draw_spec_free (op->data.op_list.y); + meta_draw_spec_free (op->data.op_list.width); + meta_draw_spec_free (op->data.op_list.height); break; case META_DRAW_TILE: if (op->data.tile.op_list) meta_draw_op_list_unref (op->data.tile.op_list); - g_free (op->data.tile.x); - g_free (op->data.tile.y); - g_free (op->data.tile.width); - g_free (op->data.tile.height); - g_free (op->data.tile.tile_xoffset); - g_free (op->data.tile.tile_yoffset); - g_free (op->data.tile.tile_width); - g_free (op->data.tile.tile_height); + + meta_draw_spec_free (op->data.tile.x); + meta_draw_spec_free (op->data.tile.y); + meta_draw_spec_free (op->data.tile.width); + meta_draw_spec_free (op->data.tile.height); + meta_draw_spec_free (op->data.tile.tile_xoffset); + meta_draw_spec_free (op->data.tile.tile_yoffset); + meta_draw_spec_free (op->data.tile.tile_width); + meta_draw_spec_free (op->data.tile.tile_height); break; } @@ -3258,7 +3216,7 @@ fill_env (MetaPositionExprEnv *env, env->title_width = info->title_layout_width; env->title_height = info->title_layout_height; - env->theme = NULL; /* not required, constants have been optimized out */ + env->theme = meta_current_theme; } static void @@ -3293,7 +3251,7 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, } x1 = parse_x_position_unchecked (op->data.line.x1, env); - y1 = parse_y_position_unchecked (op->data.line.y1, env); + y1 = parse_y_position_unchecked (op->data.line.y1, env); x2 = parse_x_position_unchecked (op->data.line.x2, env); y2 = parse_y_position_unchecked (op->data.line.y2, env); @@ -4463,8 +4421,6 @@ meta_frame_style_set_validate (MetaFrameStyleSet *style_set, return TRUE; } -static MetaTheme *meta_current_theme = NULL; - MetaTheme* meta_theme_get_current (void) { @@ -4542,6 +4498,22 @@ meta_theme_new (void) g_free, (GDestroyNotify) meta_frame_style_set_unref); + /* Create our variable quarks so we can look up variables without + having to strcmp for the names */ + theme->quark_width = g_quark_from_static_string ("width"); + theme->quark_height = g_quark_from_static_string ("height"); + theme->quark_object_width = g_quark_from_static_string ("object_width"); + theme->quark_object_height = g_quark_from_static_string ("object_height"); + theme->quark_left_width = g_quark_from_static_string ("left_width"); + theme->quark_right_width = g_quark_from_static_string ("right_width"); + theme->quark_top_height = g_quark_from_static_string ("top_height"); + theme->quark_bottom_height = g_quark_from_static_string ("bottom_height"); + theme->quark_mini_icon_width = g_quark_from_static_string ("mini_icon_width"); + theme->quark_mini_icon_height = g_quark_from_static_string ("mini_icon_height"); + theme->quark_icon_width = g_quark_from_static_string ("icon_width"); + theme->quark_icon_height = g_quark_from_static_string ("icon_height"); + theme->quark_title_width = g_quark_from_static_string ("title_width"); + theme->quark_title_height = g_quark_from_static_string ("title_height"); return theme; } diff --git a/src/theme.h b/src/theme.h index 005842ec..58a16c42 100644 --- a/src/theme.h +++ b/src/theme.h @@ -214,10 +214,16 @@ struct _MetaColorSpec MetaColorSpec *foreground; MetaColorSpec *background; double alpha; + + gboolean color_set; + GdkColor color; } blend; struct { MetaColorSpec *base; double factor; + + gboolean color_set; + GdkColor color; } shade; } data; }; @@ -275,6 +281,64 @@ typedef enum META_DRAW_TILE } MetaDrawType; +typedef enum +{ + POS_TOKEN_INT, + POS_TOKEN_DOUBLE, + POS_TOKEN_OPERATOR, + POS_TOKEN_VARIABLE, + POS_TOKEN_OPEN_PAREN, + POS_TOKEN_CLOSE_PAREN +} PosTokenType; + +typedef enum +{ + POS_OP_NONE, + POS_OP_ADD, + POS_OP_SUBTRACT, + POS_OP_MULTIPLY, + POS_OP_DIVIDE, + POS_OP_MOD, + POS_OP_MAX, + POS_OP_MIN +} PosOperatorType; + +typedef struct +{ + PosTokenType type; + + union + { + struct { + int val; + } i; + + struct { + double val; + } d; + + struct { + PosOperatorType op; + } o; + + struct { + char *name; + GQuark name_quark; + } v; + + } d; +} PosToken; + +typedef struct _MetaDrawSpec +{ + int value; + + PosToken *tokens; + int n_tokens; + + gboolean constant : 1; /* Does the expression contain any variables? */ +} MetaDrawSpec; + struct _MetaDrawOp { MetaDrawType type; @@ -287,65 +351,66 @@ struct _MetaDrawOp int dash_on_length; int dash_off_length; int width; - char *x1; - char *y1; - char *x2; - char *y2; + MetaDrawSpec *x1; + MetaDrawSpec *y1; + MetaDrawSpec *x2; + MetaDrawSpec *y2; } line; struct { MetaColorSpec *color_spec; gboolean filled; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; } rectangle; struct { MetaColorSpec *color_spec; gboolean filled; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; double start_angle; double extent_angle; } arc; struct { - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; } clip; struct { MetaColorSpec *color_spec; MetaAlphaGradientSpec *alpha_spec; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; } tint; struct { MetaGradientSpec *gradient_spec; MetaAlphaGradientSpec *alpha_spec; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; } gradient; struct { MetaColorSpec *colorize_spec; MetaAlphaGradientSpec *alpha_spec; GdkPixbuf *pixbuf; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; + guint32 colorize_cache_pixel; GdkPixbuf *colorize_cache_pixbuf; MetaImageFillType fill_type; @@ -358,61 +423,62 @@ struct _MetaDrawOp GtkShadowType shadow; GtkArrowType arrow; gboolean filled; - char *x; - char *y; - char *width; - char *height; + + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; } gtk_arrow; struct { GtkStateType state; GtkShadowType shadow; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; } gtk_box; struct { GtkStateType state; - char *x; - char *y1; - char *y2; + MetaDrawSpec *x; + MetaDrawSpec *y1; + MetaDrawSpec *y2; } gtk_vline; struct { MetaAlphaGradientSpec *alpha_spec; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; MetaImageFillType fill_type; } icon; struct { MetaColorSpec *color_spec; - char *x; - char *y; + MetaDrawSpec *x; + MetaDrawSpec *y; } title; struct { MetaDrawOpList *op_list; - char *x; - char *y; - char *width; - char *height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; } op_list; struct { MetaDrawOpList *op_list; - char *x; - char *y; - char *width; - char *height; - char *tile_xoffset; - char *tile_yoffset; - char *tile_width; - char *tile_height; + MetaDrawSpec *x; + MetaDrawSpec *y; + MetaDrawSpec *width; + MetaDrawSpec *height; + MetaDrawSpec *tile_xoffset; + MetaDrawSpec *tile_yoffset; + MetaDrawSpec *tile_width; + MetaDrawSpec *tile_height; } tile; } data; @@ -597,6 +663,21 @@ struct _MetaTheme MetaFrameStyleSet *style_sets_by_type[META_FRAME_TYPE_LAST]; GdkPixbuf *fallback_icon, *fallback_mini_icon; + + GQuark quark_width; + GQuark quark_height; + GQuark quark_object_width; + GQuark quark_object_height; + GQuark quark_left_width; + GQuark quark_right_width; + GQuark quark_top_height; + GQuark quark_bottom_height; + GQuark quark_mini_icon_width; + GQuark quark_mini_icon_height; + GQuark quark_icon_width; + GQuark quark_icon_height; + GQuark quark_title_width; + GQuark quark_title_height; }; struct _MetaPositionExprEnv @@ -643,16 +724,21 @@ void meta_frame_layout_calc_geometry (const MetaFrameLayout *layout gboolean meta_frame_layout_validate (const MetaFrameLayout *layout, GError **error); -gboolean meta_parse_position_expression (const char *expr, +gboolean meta_parse_position_expression (MetaDrawSpec *spec, const MetaPositionExprEnv *env, int *x_return, int *y_return, GError **err); -gboolean meta_parse_size_expression (const char *expr, +gboolean meta_parse_size_expression (MetaDrawSpec *spec, const MetaPositionExprEnv *env, int *val_return, GError **err); +MetaDrawSpec* meta_draw_spec_new (MetaTheme *theme, + const char *expr, + GError **error); +void meta_draw_spec_free (MetaDrawSpec *spec); + MetaColorSpec* meta_color_spec_new (MetaColorSpecType type); MetaColorSpec* meta_color_spec_new_from_string (const char *str, GError **err); @@ -833,9 +919,10 @@ gboolean meta_theme_lookup_color_constant (MetaTheme *theme, const char *name, char **value); -char* meta_theme_replace_constants (MetaTheme *theme, - const char *expr, - GError **err); +gboolean meta_theme_replace_constants (MetaTheme *theme, + PosToken *tokens, + int n_tokens, + GError **err); /* random stuff */ @@ -877,6 +964,7 @@ const char* meta_image_fill_type_to_string (MetaImageFillType f guint meta_theme_earliest_version_with_button (MetaButtonType type); + #define META_THEME_ALLOWS(theme, feature) (theme->format_version >= feature) /* What version of the theme file format were various features introduced in? */ |