summaryrefslogtreecommitdiff
path: root/src/colors.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/colors.c')
-rw-r--r--src/colors.c344
1 files changed, 335 insertions, 9 deletions
diff --git a/src/colors.c b/src/colors.c
index 5f6066bb..e0b1d69f 100644
--- a/src/colors.c
+++ b/src/colors.c
@@ -21,22 +21,348 @@
#include "colors.h"
+
+static void
+visual_decompose_mask (gulong mask,
+ gint *shift,
+ gint *prec)
+{
+ /* This code is from GTK+, (C) GTK+ Team */
+ *shift = 0;
+ *prec = 0;
+
+ while (!(mask & 0x1))
+ {
+ (*shift)++;
+ mask >>= 1;
+ }
+
+ while (mask & 0x1)
+ {
+ (*prec)++;
+ mask >>= 1;
+ }
+}
+
+void
+meta_screen_init_visual_info (MetaScreen *screen)
+{
+ Visual *xvisual;
+ int nxvisuals;
+ XVisualInfo *visual_list;
+ XVisualInfo visual_template;
+
+ /* root window visual */
+ xvisual = DefaultVisual (screen->display->xdisplay,
+ screen->number);
+
+ visual_template.visualid = XVisualIDFromVisual (xvisual);
+ visual_list = XGetVisualInfo (screen->display->xdisplay,
+ VisualIDMask, &visual_template, &nxvisuals);
+
+ if (nxvisuals != 1)
+ meta_warning ("Matched weird number of visuals %d\n", nxvisuals);
+
+ screen->visual_info = *visual_list;
+
+ meta_verbose ("Using visual class %d\n", screen->visual_info.class);
+
+ XFree (visual_list);
+}
+
gulong
meta_screen_get_x_pixel (MetaScreen *screen,
const PangoColor *color)
{
+ /* This code is derived from GTK+, (C) GTK+ Team */
+ gulong pixel;
+
+ if (screen->visual_info.class == TrueColor ||
+ screen->visual_info.class == DirectColor)
+ {
+ int red_prec, red_shift, green_prec, green_shift, blue_prec, blue_shift;
+
+ visual_decompose_mask (screen->visual_info.red_mask,
+ &red_shift, &red_prec);
+ visual_decompose_mask (screen->visual_info.green_mask,
+ &green_shift, &green_prec);
+ visual_decompose_mask (screen->visual_info.blue_mask,
+ &blue_shift, &blue_prec);
+
+ pixel = (((color->red >> (16 - red_prec)) << red_shift) +
+ ((color->green >> (16 - green_prec)) << green_shift) +
+ ((color->blue >> (16 - blue_prec)) << blue_shift));
+ }
+ else
+ {
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
- double r, g, b;
+ double r, g, b;
+
+ r = color->red / (double) 0xffff;
+ g = color->green / (double) 0xffff;
+ b = color->blue / (double) 0xffff;
+
+ /* Now this is a low-bloat GdkRGB replacement! */
+ if (INTENSITY (r, g, b) > 0.5)
+ pixel = WhitePixel (screen->display->xdisplay, screen->number);
+ else
+ pixel = BlackPixel (screen->display->xdisplay, screen->number);
+#undef INTENSITY
+ }
+
+ return pixel;
+}
+
+void
+meta_screen_set_ui_colors (MetaScreen *screen,
+ const MetaUIColors *colors)
+{
+ screen->colors = *colors;
+ meta_screen_queue_frame_redraws (screen);
+}
- r = color->red / (double) 0xffff;
- g = color->green / (double) 0xffff;
- b = color->blue / (double) 0xffff;
+/* Straight out of gtkstyle.c */
+static PangoColor meta_default_normal_fg = { 0, 0, 0 };
+static PangoColor meta_default_active_fg = { 0, 0, 0 };
+static PangoColor meta_default_prelight_fg = { 0, 0, 0 };
+static PangoColor meta_default_selected_fg = { 0xffff, 0xffff, 0xffff };
+static PangoColor meta_default_insensitive_fg = { 0x7530, 0x7530, 0x7530 };
- /* Now this is a low-bloat GdkRGB replacement! */
- if (INTENSITY (r, g, b) > 0.5)
- return WhitePixel (screen->display->xdisplay, screen->number);
+static PangoColor meta_default_normal_bg = { 0xd6d6, 0xd6d6, 0xd6d6 };
+static PangoColor meta_default_active_bg = { 0xc350, 0xc350, 0xc350 };
+static PangoColor meta_default_prelight_bg = { 0xea60, 0xea60, 0xea60 };
+static PangoColor meta_default_selected_bg = { 0, 0, 0x9c40 };
+static PangoColor meta_default_insensitive_bg = { 0xd6d6, 0xd6d6, 0xd6d6 };
+
+static void
+rgb_to_hls (gdouble *r,
+ gdouble *g,
+ gdouble *b)
+{
+ gdouble min;
+ gdouble max;
+ gdouble red;
+ gdouble green;
+ gdouble blue;
+ gdouble h, l, s;
+ gdouble delta;
+
+ red = *r;
+ green = *g;
+ blue = *b;
+
+ if (red > green)
+ {
+ if (red > blue)
+ max = red;
+ else
+ max = blue;
+
+ if (green < blue)
+ min = green;
+ else
+ min = blue;
+ }
else
- return BlackPixel (screen->display->xdisplay, screen->number);
+ {
+ if (green > blue)
+ max = green;
+ else
+ max = blue;
+
+ if (red < blue)
+ min = red;
+ else
+ min = blue;
+ }
-#undef INTENSITY
+ l = (max + min) / 2;
+ s = 0;
+ h = 0;
+
+ if (max != min)
+ {
+ if (l <= 0.5)
+ s = (max - min) / (max + min);
+ else
+ s = (max - min) / (2 - max - min);
+
+ delta = max -min;
+ if (red == max)
+ h = (green - blue) / delta;
+ else if (green == max)
+ h = 2 + (blue - red) / delta;
+ else if (blue == max)
+ h = 4 + (red - green) / delta;
+
+ h *= 60;
+ if (h < 0.0)
+ h += 360;
+ }
+
+ *r = h;
+ *g = l;
+ *b = s;
+}
+
+static void
+hls_to_rgb (gdouble *h,
+ gdouble *l,
+ gdouble *s)
+{
+ gdouble hue;
+ gdouble lightness;
+ gdouble saturation;
+ gdouble m1, m2;
+ gdouble r, g, b;
+
+ lightness = *l;
+ saturation = *s;
+
+ if (lightness <= 0.5)
+ m2 = lightness * (1 + saturation);
+ else
+ m2 = lightness + saturation - lightness * saturation;
+ m1 = 2 * lightness - m2;
+
+ if (saturation == 0)
+ {
+ *h = lightness;
+ *l = lightness;
+ *s = lightness;
+ }
+ else
+ {
+ hue = *h + 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ r = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ r = m2;
+ else if (hue < 240)
+ r = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ r = m1;
+
+ hue = *h;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ g = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ g = m2;
+ else if (hue < 240)
+ g = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ g = m1;
+
+ hue = *h - 120;
+ while (hue > 360)
+ hue -= 360;
+ while (hue < 0)
+ hue += 360;
+
+ if (hue < 60)
+ b = m1 + (m2 - m1) * hue / 60;
+ else if (hue < 180)
+ b = m2;
+ else if (hue < 240)
+ b = m1 + (m2 - m1) * (240 - hue) / 60;
+ else
+ b = m1;
+
+ *h = r;
+ *l = g;
+ *s = b;
+ }
+}
+
+static void
+style_shade (PangoColor *a,
+ PangoColor *b,
+ gdouble k)
+{
+ gdouble red;
+ gdouble green;
+ gdouble blue;
+
+ red = (gdouble) a->red / 65535.0;
+ green = (gdouble) a->green / 65535.0;
+ blue = (gdouble) a->blue / 65535.0;
+
+ rgb_to_hls (&red, &green, &blue);
+
+ green *= k;
+ if (green > 1.0)
+ green = 1.0;
+ else if (green < 0.0)
+ green = 0.0;
+
+ blue *= k;
+ if (blue > 1.0)
+ blue = 1.0;
+ else if (blue < 0.0)
+ blue = 0.0;
+
+ hls_to_rgb (&red, &green, &blue);
+
+ b->red = red * 65535.0;
+ b->green = green * 65535.0;
+ b->blue = blue * 65535.0;
+}
+
+#define LIGHTNESS_MULT 1.3
+#define DARKNESS_MULT 0.7
+void
+meta_screen_init_ui_colors (MetaScreen *screen)
+{
+ int i;
+ MetaUIColors *colors;
+
+ colors = &screen->colors;
+
+ colors->fg[META_STATE_NORMAL] = meta_default_normal_fg;
+ colors->fg[META_STATE_ACTIVE] = meta_default_active_fg;
+ colors->fg[META_STATE_PRELIGHT] = meta_default_prelight_fg;
+ colors->fg[META_STATE_SELECTED] = meta_default_selected_fg;
+ colors->fg[META_STATE_INSENSITIVE] = meta_default_insensitive_fg;
+
+ colors->bg[META_STATE_NORMAL] = meta_default_normal_bg;
+ colors->bg[META_STATE_ACTIVE] = meta_default_active_bg;
+ colors->bg[META_STATE_PRELIGHT] = meta_default_prelight_bg;
+ colors->bg[META_STATE_SELECTED] = meta_default_selected_bg;
+ colors->bg[META_STATE_INSENSITIVE] = meta_default_insensitive_bg;
+
+ for (i = 0; i < 4; i++)
+ {
+ colors->text[i] = colors->fg[i];
+ colors->base[i].red = G_MAXUSHORT;
+ colors->base[i].green = G_MAXUSHORT;
+ colors->base[i].blue = G_MAXUSHORT;
+ }
+
+ colors->base[META_STATE_SELECTED] = meta_default_selected_bg;
+ colors->base[META_STATE_INSENSITIVE] = meta_default_prelight_bg;
+ colors->text[META_STATE_INSENSITIVE] = meta_default_insensitive_fg;
+
+ for (i = 0; i < 5; i++)
+ {
+ style_shade (&colors->bg[i], &colors->light[i], LIGHTNESS_MULT);
+ style_shade (&colors->bg[i], &colors->dark[i], DARKNESS_MULT);
+
+ colors->mid[i].red = (colors->light[i].red + colors->dark[i].red) / 2;
+ colors->mid[i].green = (colors->light[i].green + colors->dark[i].green) / 2;
+ colors->mid[i].blue = (colors->light[i].blue + colors->dark[i].blue) / 2;
+
+ colors->text_aa[i].red = (colors->text[i].red + colors->base[i].red) / 2;
+ colors->text_aa[i].green = (colors->text[i].green + colors->base[i].green) / 2;
+ colors->text_aa[i].blue = (colors->text[i].blue + colors->base[i].blue) / 2;
+ }
}