|
Packit |
5e0819 |
/*
|
|
Packit |
5e0819 |
* Copyright (C) 2001 Havoc Pennington
|
|
Packit |
5e0819 |
* Copyright (C) 2016 Alberts Muktupāvels
|
|
Packit |
5e0819 |
*
|
|
Packit |
5e0819 |
* This program is free software: you can redistribute it and/or modify
|
|
Packit |
5e0819 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
5e0819 |
* the Free Software Foundation, either version 2 of the License, or
|
|
Packit |
5e0819 |
* (at your option) any later version.
|
|
Packit |
5e0819 |
*
|
|
Packit |
5e0819 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
5e0819 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5e0819 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
5e0819 |
* GNU General Public License for more details.
|
|
Packit |
5e0819 |
*
|
|
Packit |
5e0819 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
5e0819 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
5e0819 |
*/
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
#include "config.h"
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
#include <glib/gi18n-lib.h>
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
#include "meta-color.h"
|
|
Packit |
5e0819 |
#include "meta-color-private.h"
|
|
Packit |
5e0819 |
#include "meta-color-spec-private.h"
|
|
Packit |
5e0819 |
#include "meta-theme.h"
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
enum _MetaColorSpecType
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
META_COLOR_SPEC_BASIC,
|
|
Packit |
5e0819 |
META_COLOR_SPEC_GTK,
|
|
Packit |
5e0819 |
META_COLOR_SPEC_GTK_CUSTOM,
|
|
Packit |
5e0819 |
META_COLOR_SPEC_BLEND,
|
|
Packit |
5e0819 |
META_COLOR_SPEC_SHADE
|
|
Packit |
5e0819 |
};
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
enum _MetaGtkColorComponent
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
META_GTK_COLOR_FG,
|
|
Packit |
5e0819 |
META_GTK_COLOR_BG,
|
|
Packit |
5e0819 |
META_GTK_COLOR_LIGHT,
|
|
Packit |
5e0819 |
META_GTK_COLOR_DARK,
|
|
Packit |
5e0819 |
META_GTK_COLOR_MID,
|
|
Packit |
5e0819 |
META_GTK_COLOR_TEXT,
|
|
Packit |
5e0819 |
META_GTK_COLOR_BASE,
|
|
Packit |
5e0819 |
META_GTK_COLOR_TEXT_AA,
|
|
Packit |
5e0819 |
META_GTK_COLOR_LAST
|
|
Packit |
5e0819 |
};
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
struct _MetaColorSpec
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
MetaColorSpecType type;
|
|
Packit |
5e0819 |
union
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
struct {
|
|
Packit |
5e0819 |
GdkRGBA color;
|
|
Packit |
5e0819 |
} basic;
|
|
Packit |
5e0819 |
struct {
|
|
Packit |
5e0819 |
MetaGtkColorComponent component;
|
|
Packit |
5e0819 |
GtkStateFlags state;
|
|
Packit |
5e0819 |
} gtk;
|
|
Packit |
5e0819 |
struct {
|
|
Packit |
5e0819 |
gchar *color_name;
|
|
Packit |
5e0819 |
MetaColorSpec *fallback;
|
|
Packit |
5e0819 |
} gtkcustom;
|
|
Packit |
5e0819 |
struct {
|
|
Packit |
5e0819 |
MetaColorSpec *foreground;
|
|
Packit |
5e0819 |
MetaColorSpec *background;
|
|
Packit |
5e0819 |
gdouble alpha;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
GdkRGBA color;
|
|
Packit |
5e0819 |
} blend;
|
|
Packit |
5e0819 |
struct {
|
|
Packit |
5e0819 |
MetaColorSpec *base;
|
|
Packit |
5e0819 |
gdouble factor;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
GdkRGBA color;
|
|
Packit |
5e0819 |
} shade;
|
|
Packit |
5e0819 |
} data;
|
|
Packit |
5e0819 |
};
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
static void
|
|
Packit |
5e0819 |
set_color_from_style (GdkRGBA *color,
|
|
Packit |
5e0819 |
GtkStyleContext *context,
|
|
Packit |
5e0819 |
GtkStateFlags state,
|
|
Packit |
5e0819 |
MetaGtkColorComponent component)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
GdkRGBA other;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
gtk_style_context_set_state (context, state);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
switch (component)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
case META_GTK_COLOR_BG:
|
|
Packit |
5e0819 |
case META_GTK_COLOR_BASE:
|
|
Packit |
5e0819 |
meta_color_get_background_color (context, state, color);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_GTK_COLOR_FG:
|
|
Packit |
5e0819 |
case META_GTK_COLOR_TEXT:
|
|
Packit |
5e0819 |
gtk_style_context_get_color (context, state, color);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_GTK_COLOR_TEXT_AA:
|
|
Packit |
5e0819 |
gtk_style_context_get_color (context, state, color);
|
|
Packit |
5e0819 |
set_color_from_style (&other, context, state, META_GTK_COLOR_BASE);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
color->red = (color->red + other.red) / 2;
|
|
Packit |
5e0819 |
color->green = (color->green + other.green) / 2;
|
|
Packit |
5e0819 |
color->blue = (color->blue + other.blue) / 2;
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_GTK_COLOR_MID:
|
|
Packit |
5e0819 |
meta_color_get_light_color (context, state, color);
|
|
Packit |
5e0819 |
meta_color_get_dark_color (context, state, &other);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
color->red = (color->red + other.red) / 2;
|
|
Packit |
5e0819 |
color->green = (color->green + other.green) / 2;
|
|
Packit |
5e0819 |
color->blue = (color->blue + other.blue) / 2;
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_GTK_COLOR_LIGHT:
|
|
Packit |
5e0819 |
meta_color_get_light_color (context, state, color);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_GTK_COLOR_DARK:
|
|
Packit |
5e0819 |
meta_color_get_dark_color (context, state, color);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_GTK_COLOR_LAST:
|
|
Packit |
5e0819 |
default:
|
|
Packit |
5e0819 |
g_assert_not_reached ();
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
static void
|
|
Packit |
5e0819 |
color_composite (const GdkRGBA *bg,
|
|
Packit |
5e0819 |
const GdkRGBA *fg,
|
|
Packit |
5e0819 |
gdouble alpha,
|
|
Packit |
5e0819 |
GdkRGBA *color)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
*color = *bg;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
color->red = color->red + (fg->red - color->red) * alpha;
|
|
Packit |
5e0819 |
color->green = color->green + (fg->green - color->green) * alpha;
|
|
Packit |
5e0819 |
color->blue = color->blue + (fg->blue - color->blue) * alpha;
|
|
Packit |
5e0819 |
color->alpha = color->alpha + (fg->alpha - color->alpha) * alpha;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
static void
|
|
Packit |
5e0819 |
set_custom_color_from_style (GdkRGBA *color,
|
|
Packit |
5e0819 |
GtkStyleContext *context,
|
|
Packit |
5e0819 |
const gchar *color_name,
|
|
Packit |
5e0819 |
MetaColorSpec *fallback)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
if (!gtk_style_context_lookup_color (context, color_name, color))
|
|
Packit |
5e0819 |
meta_color_spec_render (fallback, context, color);
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
static MetaGtkColorComponent
|
|
Packit |
5e0819 |
meta_color_component_from_string (const gchar *str)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
if (strcmp ("fg", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_FG;
|
|
Packit |
5e0819 |
else if (strcmp ("bg", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_BG;
|
|
Packit |
5e0819 |
else if (strcmp ("light", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_LIGHT;
|
|
Packit |
5e0819 |
else if (strcmp ("dark", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_DARK;
|
|
Packit |
5e0819 |
else if (strcmp ("mid", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_MID;
|
|
Packit |
5e0819 |
else if (strcmp ("text", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_TEXT;
|
|
Packit |
5e0819 |
else if (strcmp ("base", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_BASE;
|
|
Packit |
5e0819 |
else if (strcmp ("text_aa", str) == 0)
|
|
Packit |
5e0819 |
return META_GTK_COLOR_TEXT_AA;
|
|
Packit |
5e0819 |
else
|
|
Packit |
5e0819 |
return META_GTK_COLOR_LAST;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
MetaColorSpec *
|
|
Packit |
5e0819 |
meta_color_spec_new (MetaColorSpecType type)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
MetaColorSpec *spec;
|
|
Packit |
5e0819 |
MetaColorSpec dummy;
|
|
Packit |
5e0819 |
gint size;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
size = G_STRUCT_OFFSET (MetaColorSpec, data);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
switch (type)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_BASIC:
|
|
Packit |
5e0819 |
size += sizeof (dummy.data.basic);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_GTK:
|
|
Packit |
5e0819 |
size += sizeof (dummy.data.gtk);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_GTK_CUSTOM:
|
|
Packit |
5e0819 |
size += sizeof (dummy.data.gtkcustom);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_BLEND:
|
|
Packit |
5e0819 |
size += sizeof (dummy.data.blend);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_SHADE:
|
|
Packit |
5e0819 |
size += sizeof (dummy.data.shade);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
default:
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec = g_malloc0 (size);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec->type = type;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
return spec;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
MetaColorSpec *
|
|
Packit |
5e0819 |
meta_color_spec_new_from_string (const gchar *str,
|
|
Packit |
5e0819 |
GError **error)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
MetaColorSpec *spec;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec = NULL;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (strncmp (str, "gtk:custom", 10) == 0)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
const gchar *color_name_start;
|
|
Packit |
5e0819 |
const gchar *fallback_str_start;
|
|
Packit |
5e0819 |
const gchar *end;
|
|
Packit |
5e0819 |
gchar *fallback_str;
|
|
Packit |
5e0819 |
MetaColorSpec *fallback;
|
|
Packit |
5e0819 |
gchar *color_name;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (str[10] != '(')
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("GTK custom color specification must have color name and fallback in parentheses, e.g. gtk:custom(foo,bar); could not parse '%s'"),
|
|
Packit |
5e0819 |
str);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
color_name_start = str + 11;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
fallback_str_start = color_name_start;
|
|
Packit |
5e0819 |
while (*fallback_str_start && *fallback_str_start != ',')
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
if (!(g_ascii_isalnum (*fallback_str_start)
|
|
Packit |
5e0819 |
|| *fallback_str_start == '-' || *fallback_str_start == '_'))
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-_ are valid"),
|
|
Packit |
5e0819 |
*fallback_str_start);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
fallback_str_start++;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
fallback_str_start++;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
end = strrchr (str, ')');
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (color_name_start == NULL || fallback_str_start == NULL || end == NULL)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Gtk:custom format is 'gtk:custom(color_name,fallback)', '%s' does not fit the format"),
|
|
Packit |
5e0819 |
str);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
fallback_str = g_strndup (fallback_str_start, end - fallback_str_start);
|
|
Packit |
5e0819 |
fallback = meta_color_spec_new_from_string (fallback_str, error);
|
|
Packit |
5e0819 |
g_free (fallback_str);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (fallback == NULL)
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
color_name = g_strndup (color_name_start, fallback_str_start - color_name_start - 1);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec = meta_color_spec_new (META_COLOR_SPEC_GTK_CUSTOM);
|
|
Packit |
5e0819 |
spec->data.gtkcustom.color_name = color_name;
|
|
Packit |
5e0819 |
spec->data.gtkcustom.fallback = fallback;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
else if (strncmp (str, "gtk:", 4) == 0)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
const gchar *bracket;
|
|
Packit |
5e0819 |
const gchar *end_bracket;
|
|
Packit |
5e0819 |
gchar *tmp;
|
|
Packit |
5e0819 |
GtkStateFlags state;
|
|
Packit |
5e0819 |
MetaGtkColorComponent component;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
bracket = str;
|
|
Packit |
5e0819 |
while (*bracket && *bracket != '[')
|
|
Packit |
5e0819 |
++bracket;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (*bracket == '\0')
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse '%s'"),
|
|
Packit |
5e0819 |
str);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
end_bracket = bracket;
|
|
Packit |
5e0819 |
++end_bracket;
|
|
Packit |
5e0819 |
while (*end_bracket && *end_bracket != ']')
|
|
Packit |
5e0819 |
++end_bracket;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (*end_bracket == '\0')
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("GTK color specification must have a close bracket after the state, e.g. gtk:fg[NORMAL] where NORMAL is the state; could not parse '%s'"),
|
|
Packit |
5e0819 |
str);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
tmp = g_strndup (bracket + 1, end_bracket - bracket - 1);
|
|
Packit |
5e0819 |
if (!meta_gtk_state_from_string (tmp, &state))
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Did not understand state '%s' in color specification"),
|
|
Packit |
5e0819 |
tmp);
|
|
Packit |
5e0819 |
g_free (tmp);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
g_free (tmp);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
tmp = g_strndup (str + 4, bracket - str - 4);
|
|
Packit |
5e0819 |
component = meta_color_component_from_string (tmp);
|
|
Packit |
5e0819 |
if (component == META_GTK_COLOR_LAST)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Did not understand color component '%s' in color specification"),
|
|
Packit |
5e0819 |
tmp);
|
|
Packit |
5e0819 |
g_free (tmp);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
g_free (tmp);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec = meta_color_spec_new (META_COLOR_SPEC_GTK);
|
|
Packit |
5e0819 |
spec->data.gtk.state = state;
|
|
Packit |
5e0819 |
spec->data.gtk.component = component;
|
|
Packit |
5e0819 |
g_assert (spec->data.gtk.component < META_GTK_COLOR_LAST);
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
else if (strncmp (str, "blend/", 6) == 0)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
gchar **split;
|
|
Packit |
5e0819 |
gdouble alpha;
|
|
Packit |
5e0819 |
gchar *end;
|
|
Packit |
5e0819 |
MetaColorSpec *fg;
|
|
Packit |
5e0819 |
MetaColorSpec *bg;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
split = g_strsplit (str, "/", 4);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (split[0] == NULL || split[1] == NULL ||
|
|
Packit |
5e0819 |
split[2] == NULL || split[3] == NULL)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Blend format is 'blend/bg_color/fg_color/alpha', '%s' does not fit the format"),
|
|
Packit |
5e0819 |
str);
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
alpha = g_ascii_strtod (split[3], &end;;
|
|
Packit |
5e0819 |
if (end == split[3])
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Could not parse alpha value '%s' in blended color"),
|
|
Packit |
5e0819 |
split[3]);
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (alpha < (0.0 - 1e6) || alpha > (1.0 + 1e6))
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Alpha value '%s' in blended color is not between 0.0 and 1.0"),
|
|
Packit |
5e0819 |
split[3]);
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
fg = NULL;
|
|
Packit |
5e0819 |
bg = NULL;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
bg = meta_color_spec_new_from_string (split[1], error);
|
|
Packit |
5e0819 |
if (bg == NULL)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
fg = meta_color_spec_new_from_string (split[2], error);
|
|
Packit |
5e0819 |
if (fg == NULL)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
meta_color_spec_free (bg);
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec = meta_color_spec_new (META_COLOR_SPEC_BLEND);
|
|
Packit |
5e0819 |
spec->data.blend.alpha = alpha;
|
|
Packit |
5e0819 |
spec->data.blend.background = bg;
|
|
Packit |
5e0819 |
spec->data.blend.foreground = fg;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
else if (strncmp (str, "shade/", 6) == 0)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
gchar **split;
|
|
Packit |
5e0819 |
gdouble factor;
|
|
Packit |
5e0819 |
gchar *end;
|
|
Packit |
5e0819 |
MetaColorSpec *base;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
split = g_strsplit (str, "/", 3);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (split[0] == NULL || split[1] == NULL || split[2] == NULL)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Shade format is 'shade/base_color/factor', '%s' does not fit the format"),
|
|
Packit |
5e0819 |
str);
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
factor = g_ascii_strtod (split[2], &end;;
|
|
Packit |
5e0819 |
if (end == split[2])
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Could not parse shade factor '%s' in shaded color"),
|
|
Packit |
5e0819 |
split[2]);
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (factor < (0.0 - 1e6))
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Shade factor '%s' in shaded color is negative"),
|
|
Packit |
5e0819 |
split[2]);
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
base = meta_color_spec_new_from_string (split[1], error);
|
|
Packit |
5e0819 |
if (base == NULL)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
g_strfreev (split);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec = meta_color_spec_new (META_COLOR_SPEC_SHADE);
|
|
Packit |
5e0819 |
spec->data.shade.factor = factor;
|
|
Packit |
5e0819 |
spec->data.shade.base = base;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
else
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
spec = meta_color_spec_new (META_COLOR_SPEC_BASIC);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
if (!gdk_rgba_parse (&spec->data.basic.color, str))
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_set_error (error, META_THEME_ERROR, META_THEME_ERROR_FAILED,
|
|
Packit |
5e0819 |
_("Could not parse color '%s'"), str);
|
|
Packit |
5e0819 |
meta_color_spec_free (spec);
|
|
Packit |
5e0819 |
return NULL;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
g_assert (spec);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
return spec;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
MetaColorSpec *
|
|
Packit |
5e0819 |
meta_color_spec_new_gtk (MetaGtkColorComponent component,
|
|
Packit |
5e0819 |
GtkStateFlags state)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
MetaColorSpec *spec;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec = meta_color_spec_new (META_COLOR_SPEC_GTK);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
spec->data.gtk.component = component;
|
|
Packit |
5e0819 |
spec->data.gtk.state = state;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
return spec;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
void
|
|
Packit |
5e0819 |
meta_color_spec_free (MetaColorSpec *spec)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_return_if_fail (spec != NULL);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
switch (spec->type)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_BASIC:
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_GTK:
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_GTK_CUSTOM:
|
|
Packit |
5e0819 |
if (spec->data.gtkcustom.color_name)
|
|
Packit |
5e0819 |
g_free (spec->data.gtkcustom.color_name);
|
|
Packit |
5e0819 |
if (spec->data.gtkcustom.fallback)
|
|
Packit |
5e0819 |
meta_color_spec_free (spec->data.gtkcustom.fallback);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_BLEND:
|
|
Packit |
5e0819 |
if (spec->data.blend.foreground)
|
|
Packit |
5e0819 |
meta_color_spec_free (spec->data.blend.foreground);
|
|
Packit |
5e0819 |
if (spec->data.blend.background)
|
|
Packit |
5e0819 |
meta_color_spec_free (spec->data.blend.background);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_SHADE:
|
|
Packit |
5e0819 |
if (spec->data.shade.base)
|
|
Packit |
5e0819 |
meta_color_spec_free (spec->data.shade.base);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
default:
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
g_free (spec);
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
void
|
|
Packit |
5e0819 |
meta_color_spec_render (MetaColorSpec *spec,
|
|
Packit |
5e0819 |
GtkStyleContext *context,
|
|
Packit |
5e0819 |
GdkRGBA *color)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
g_return_if_fail (spec != NULL);
|
|
Packit |
5e0819 |
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
switch (spec->type)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_BASIC:
|
|
Packit |
5e0819 |
*color = spec->data.basic.color;
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_GTK:
|
|
Packit |
5e0819 |
set_color_from_style (color, context, spec->data.gtk.state,
|
|
Packit |
5e0819 |
spec->data.gtk.component);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_GTK_CUSTOM:
|
|
Packit |
5e0819 |
set_custom_color_from_style (color, context,
|
|
Packit |
5e0819 |
spec->data.gtkcustom.color_name,
|
|
Packit |
5e0819 |
spec->data.gtkcustom.fallback);
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_BLEND:
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
GdkRGBA bg;
|
|
Packit |
5e0819 |
GdkRGBA fg;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
meta_color_spec_render (spec->data.blend.background, context, &bg;;
|
|
Packit |
5e0819 |
meta_color_spec_render (spec->data.blend.foreground, context, &fg;;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
color_composite (&bg, &fg, spec->data.blend.alpha,
|
|
Packit |
5e0819 |
&spec->data.blend.color);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
*color = spec->data.blend.color;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
case META_COLOR_SPEC_SHADE:
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
meta_color_spec_render (spec->data.shade.base, context,
|
|
Packit |
5e0819 |
&spec->data.shade.color);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
meta_color_shade (&spec->data.shade.color, spec->data.shade.factor,
|
|
Packit |
5e0819 |
&spec->data.shade.color);
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
*color = spec->data.shade.color;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
default:
|
|
Packit |
5e0819 |
break;
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
}
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
/**
|
|
Packit |
5e0819 |
* meta_gtk_state_from_string:
|
|
Packit |
5e0819 |
* @str: state string
|
|
Packit |
5e0819 |
* @state: (out): location to store #GtkStateFlags
|
|
Packit |
5e0819 |
*
|
|
Packit |
5e0819 |
* Convert string to #GtkStateFlags
|
|
Packit |
5e0819 |
*
|
|
Packit |
5e0819 |
* Returns: %TRUE if state string was valid, %FALSE otherwise
|
|
Packit |
5e0819 |
*/
|
|
Packit |
5e0819 |
gboolean
|
|
Packit |
5e0819 |
meta_gtk_state_from_string (const gchar *str,
|
|
Packit |
5e0819 |
GtkStateFlags *state)
|
|
Packit |
5e0819 |
{
|
|
Packit |
5e0819 |
if (g_ascii_strcasecmp ("normal", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_NORMAL;
|
|
Packit |
5e0819 |
else if (g_ascii_strcasecmp ("prelight", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_PRELIGHT;
|
|
Packit |
5e0819 |
else if (g_ascii_strcasecmp ("active", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_ACTIVE;
|
|
Packit |
5e0819 |
else if (g_ascii_strcasecmp ("selected", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_SELECTED;
|
|
Packit |
5e0819 |
else if (g_ascii_strcasecmp ("insensitive", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_INSENSITIVE;
|
|
Packit |
5e0819 |
else if (g_ascii_strcasecmp ("inconsistent", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_INCONSISTENT;
|
|
Packit |
5e0819 |
else if (g_ascii_strcasecmp ("focused", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_FOCUSED;
|
|
Packit |
5e0819 |
else if (g_ascii_strcasecmp ("backdrop", str) == 0)
|
|
Packit |
5e0819 |
*state = GTK_STATE_FLAG_BACKDROP;
|
|
Packit |
5e0819 |
else
|
|
Packit |
5e0819 |
return FALSE;
|
|
Packit |
5e0819 |
|
|
Packit |
5e0819 |
return TRUE;
|
|
Packit |
5e0819 |
}
|