diff options
author | Benjamin Otte <otte@redhat.com> | 2016-10-06 21:46:27 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2016-10-16 18:17:21 +0200 |
commit | 05763e4875d11b0f10617dad78bc211e9cf32e95 (patch) | |
tree | 513d811176d906e882008d42bd1e7ad5f0d8042c /gtk | |
parent | 361d322bfb3a3896d447c6b1fe0bfefa5dc599fd (diff) | |
download | gtk+-05763e4875d11b0f10617dad78bc211e9cf32e95.tar.gz |
settings: Pull in the RC parsing code
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtksettings.c | 272 |
1 files changed, 269 insertions, 3 deletions
diff --git a/gtk/gtksettings.c b/gtk/gtksettings.c index 4596752601..82333772e8 100644 --- a/gtk/gtksettings.c +++ b/gtk/gtksettings.c @@ -29,6 +29,7 @@ #include "gtkwidget.h" #include "gtkprivate.h" #include "gtkcssproviderprivate.h" +#include "gtkhslaprivate.h" #include "gtkstyleproviderprivate.h" #include "gtktypebuiltins.h" #include "gtkversion.h" @@ -56,8 +57,6 @@ #include "win32/gdkwin32.h" #endif -#include "deprecated/gtkrc.h" - #ifdef GDK_WINDOWING_QUARTZ #define PRINT_PREVIEW_COMMAND "open -a /Applications/Preview.app %f" #else @@ -2512,8 +2511,275 @@ gtk_settings_set_double_property (GtkSettings *settings, g_value_unset (&svalue.value); } +static const GScannerConfig gtk_rc_scanner_config = +{ + ( + " \t\r\n" + ) /* cset_skip_characters */, + ( + "_" + G_CSET_a_2_z + G_CSET_A_2_Z + ) /* cset_identifier_first */, + ( + G_CSET_DIGITS + "-_" + G_CSET_a_2_z + G_CSET_A_2_Z + ) /* cset_identifier_nth */, + ( "#\n" ) /* cpair_comment_single */, + + TRUE /* case_sensitive */, + + TRUE /* skip_comment_multi */, + TRUE /* skip_comment_single */, + TRUE /* scan_comment_multi */, + TRUE /* scan_identifier */, + FALSE /* scan_identifier_1char */, + FALSE /* scan_identifier_NULL */, + TRUE /* scan_symbols */, + TRUE /* scan_binary */, + TRUE /* scan_octal */, + TRUE /* scan_float */, + TRUE /* scan_hex */, + TRUE /* scan_hex_dollar */, + TRUE /* scan_string_sq */, + TRUE /* scan_string_dq */, + TRUE /* numbers_2_int */, + FALSE /* int_2_float */, + FALSE /* identifier_2_string */, + TRUE /* char_2_token */, + TRUE /* symbol_2_token */, + FALSE /* scope_0_fallback */, +}; + +static GScanner* +gtk_rc_scanner_new (void) +{ + return g_scanner_new (>k_rc_scanner_config); +} + G_GNUC_BEGIN_IGNORE_DEPRECATIONS +static void +color_shade (const GdkColor *color, + GdkColor *color_return, + gdouble factor) +{ + GdkRGBA rgba; + GtkHSLA hsla; + + rgba.red = color->red / 65535.; + rgba.green = color->green / 65535.; + rgba.blue = color->blue / 65535.; + rgba.alpha = 1.0; + + _gtk_hsla_init_from_rgba (&hsla, &rgba); + _gtk_hsla_shade (&hsla, &hsla, factor); + _gdk_rgba_init_from_hsla (&rgba, &hsla); + + color_return->red = 65535. * rgba.red; + color_return->green = 65535. * rgba.green; + color_return->blue = 65535. * rgba.blue; +} + +/* + * gtk_parse_color: + * @scanner: a #GScanner + * @color: (out): a pointer to a #GdkColor in which to store + * the result + * + * Parses a color in the format expected + * in a RC file. If @style is not %NULL, it will be consulted to resolve + * references to symbolic colors. + * + * Returns: %G_TOKEN_NONE if parsing succeeded, otherwise the token + * that was expected but not found + */ +static guint +gtk_parse_color (GScanner *scanner, + GdkColor *color) +{ + guint token; + + g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR); + + /* we don't need to set our own scope here, because + * we don't need own symbols + */ + + token = g_scanner_get_next_token (scanner); + switch (token) + { + gint token_int; + GdkColor c1, c2; + gboolean negate; + gdouble l; + + case G_TOKEN_LEFT_CURLY: + token = g_scanner_get_next_token (scanner); + if (token == G_TOKEN_INT) + token_int = scanner->value.v_int; + else if (token == G_TOKEN_FLOAT) + token_int = scanner->value.v_float * 65535.0; + else + return G_TOKEN_FLOAT; + color->red = CLAMP (token_int, 0, 65535); + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_COMMA) + return G_TOKEN_COMMA; + + token = g_scanner_get_next_token (scanner); + if (token == G_TOKEN_INT) + token_int = scanner->value.v_int; + else if (token == G_TOKEN_FLOAT) + token_int = scanner->value.v_float * 65535.0; + else + return G_TOKEN_FLOAT; + color->green = CLAMP (token_int, 0, 65535); + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_COMMA) + return G_TOKEN_COMMA; + + token = g_scanner_get_next_token (scanner); + if (token == G_TOKEN_INT) + token_int = scanner->value.v_int; + else if (token == G_TOKEN_FLOAT) + token_int = scanner->value.v_float * 65535.0; + else + return G_TOKEN_FLOAT; + color->blue = CLAMP (token_int, 0, 65535); + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_RIGHT_CURLY) + return G_TOKEN_RIGHT_CURLY; + return G_TOKEN_NONE; + + case G_TOKEN_STRING: + if (!gdk_color_parse (scanner->value.v_string, color)) + { + g_scanner_warn (scanner, "Invalid color constant '%s'", + scanner->value.v_string); + return G_TOKEN_STRING; + } + return G_TOKEN_NONE; + + case G_TOKEN_IDENTIFIER: + if (strcmp (scanner->value.v_identifier, "mix") == 0) + { + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_LEFT_PAREN) + return G_TOKEN_LEFT_PAREN; + + negate = FALSE; + if (g_scanner_peek_next_token (scanner) == '-') + { + g_scanner_get_next_token (scanner); /* eat sign */ + negate = TRUE; + } + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_FLOAT) + return G_TOKEN_FLOAT; + + l = negate ? -scanner->value.v_float : scanner->value.v_float; + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_COMMA) + return G_TOKEN_COMMA; + + token = gtk_parse_color (scanner, &c1); + if (token != G_TOKEN_NONE) + return token; + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_COMMA) + return G_TOKEN_COMMA; + + token = gtk_parse_color (scanner, &c2); + if (token != G_TOKEN_NONE) + return token; + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_RIGHT_PAREN) + return G_TOKEN_RIGHT_PAREN; + + color->red = l * c1.red + (1.0 - l) * c2.red; + color->green = l * c1.green + (1.0 - l) * c2.green; + color->blue = l * c1.blue + (1.0 - l) * c2.blue; + + return G_TOKEN_NONE; + } + else if (strcmp (scanner->value.v_identifier, "shade") == 0) + { + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_LEFT_PAREN) + return G_TOKEN_LEFT_PAREN; + + negate = FALSE; + if (g_scanner_peek_next_token (scanner) == '-') + { + g_scanner_get_next_token (scanner); /* eat sign */ + negate = TRUE; + } + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_FLOAT) + return G_TOKEN_FLOAT; + + l = negate ? -scanner->value.v_float : scanner->value.v_float; + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_COMMA) + return G_TOKEN_COMMA; + + token = gtk_parse_color (scanner, &c1); + if (token != G_TOKEN_NONE) + return token; + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_RIGHT_PAREN) + return G_TOKEN_RIGHT_PAREN; + + color_shade (&c1, color, l); + + return G_TOKEN_NONE; + } + else if (strcmp (scanner->value.v_identifier, "lighter") == 0 || + strcmp (scanner->value.v_identifier, "darker") == 0) + { + if (scanner->value.v_identifier[0] == 'l') + l = 1.3; + else + l = 0.7; + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_LEFT_PAREN) + return G_TOKEN_LEFT_PAREN; + + token = gtk_parse_color (scanner, &c1); + if (token != G_TOKEN_NONE) + return token; + + token = g_scanner_get_next_token (scanner); + if (token != G_TOKEN_RIGHT_PAREN) + return G_TOKEN_RIGHT_PAREN; + + color_shade (&c1, color, l); + + return G_TOKEN_NONE; + } + else + return G_TOKEN_IDENTIFIER; + + default: + return G_TOKEN_STRING; + } +} + + /** * gtk_rc_property_parse_color: * @pspec: a #GParamSpec @@ -2544,7 +2810,7 @@ gtk_rc_property_parse_color (const GParamSpec *pspec, scanner = gtk_rc_scanner_new (); g_scanner_input_text (scanner, gstring->str, gstring->len); - if (gtk_rc_parse_color (scanner, &color) == G_TOKEN_NONE && + if (gtk_parse_color (scanner, &color) == G_TOKEN_NONE && g_scanner_get_next_token (scanner) == G_TOKEN_EOF) { g_value_set_boxed (property_value, &color); |