Commit 4ae250ae authored by rhp's avatar rhp
Browse files

...

parent 11fde3a1
......@@ -28,10 +28,36 @@
#include <X11/Xlib.h>
#include <pango/pangox.h>
PangoContext* meta_get_pango_context (Screen *xscreen,
const PangoFontDescription *desc,
Window frame);
gulong meta_get_x_pixel (Screen *xscreen,
const PangoColor *color);
/* Colors/state stuff matches GTK since we get the info from
* the GTK UI slave
*/
typedef struct _MetaUIColors MetaUIColors;
typedef enum
{
META_STATE_NORMAL,
META_STATE_ACTIVE,
META_STATE_PRELIGHT,
META_STATE_SELECTED,
META_STATE_INSENSITIVE
} MetaUIState;
struct _MetaUIColors
{
PangoColor fg[5];
PangoColor bg[5];
PangoColor light[5];
PangoColor dark[5];
PangoColor mid[5];
PangoColor text[5];
PangoColor base[5];
PangoColor text_aa[5];
};
PangoContext* meta_get_pango_context (Screen *xscreen,
const PangoFontDescription *desc,
Window frame);
gulong meta_get_x_pixel (Screen *xscreen,
const PangoColor *color);
#endif
......@@ -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;
}
}
......@@ -28,8 +28,13 @@
#include "screen.h"
#include "util.h"
#include "api.h"
gulong meta_screen_get_x_pixel (MetaScreen *screen,
const PangoColor *color);
void meta_screen_init_visual_info (MetaScreen *screen);
void meta_screen_set_ui_colors (MetaScreen *screen,
const MetaUIColors *colors);
void meta_screen_init_ui_colors (MetaScreen *screen);
gulong meta_screen_get_x_pixel (MetaScreen *screen,
const PangoColor *color);
#endif
......@@ -148,26 +148,56 @@ meta_display_open (const char *name)
}
static void
free_window (gpointer key, gpointer value, gpointer data)
listify_func (gpointer key, gpointer value, gpointer data)
{
MetaWindow *window;
GSList **listp;
window = value;
listp = data;
*listp = g_slist_prepend (*listp, value);
}
meta_window_free (window);
static gint
ptrcmp (gconstpointer a, gconstpointer b)
{
if (a < b)
return -1;
else if (a > b)
return 1;
else
return 0;
}
void
meta_display_close (MetaDisplay *display)
{
GSList *winlist;
GSList *tmp;
if (display->error_traps)
meta_bug ("Display closed with error traps pending\n");
winlist = NULL;
g_hash_table_foreach (display->window_ids,
free_window,
NULL);
listify_func,
&winlist);
g_hash_table_destroy (display->window_ids);
winlist = g_slist_sort (winlist, ptrcmp);
tmp = winlist;
while (tmp != NULL)
{
/* If the next node doesn't contain this window
* a second time, delete the window.
*/
if (tmp->next == NULL ||
(tmp->next && tmp->next->data != tmp->data))
meta_window_free (tmp->data);
tmp = tmp->data;
}
g_slist_free (winlist);
meta_event_queue_free (display->events);
XCloseDisplay (display->xdisplay);
......
......@@ -22,6 +22,7 @@
#include "frame.h"
#include "errors.h"
#include "uislave.h"
#include "colors.h"
static void
meta_frame_init_info (MetaFrame *frame,
......@@ -36,6 +37,7 @@ meta_frame_init_info (MetaFrame *frame,
info->title = frame->window->title;
info->width = frame->rect.width;
info->height = frame->rect.height;
info->colors = &(frame->window->screen->colors);
}
static void
......@@ -119,8 +121,9 @@ meta_frame_calc_geometry (MetaFrame *frame,
geom.right_width = 0;
geom.top_height = 0;
geom.bottom_height = 0;
geom.background_pixel = BlackPixel (window->display->xdisplay,
window->screen->number);
geom.background_pixel =
meta_screen_get_x_pixel (frame->window->screen,
&frame->window->screen->colors.bg[META_STATE_NORMAL]);
geom.shape_mask = None;
......
......@@ -2,6 +2,13 @@
if test -z "$SCREENS"; then
SCREENS=2
fi
if test "$DEBUG" = none; then
DEBUG=
elif test -z "$DEBUG"; then
DEBUG=gdb
fi
Xnest :1 -scrns $SCREENS -geometry 270x270 &
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute gdb ./metacity
METACITY_UISLAVE_DIR=./uislave DISPLAY=:1 unst libtool --mode=execute $DEBUG ./metacity
killall Xnest
......@@ -25,6 +25,7 @@
#include "window.h"
#include "colors.h"
#include "uislave.h"
#include "frame.h"
#include <X11/cursorfont.h>
#include <locale.h>
......@@ -98,6 +99,9 @@ meta_screen_new (MetaDisplay *display,
screen->engine = &meta_default_engine;
meta_screen_init_visual_info (screen);
meta_screen_init_ui_colors (screen);
screen->uislave = meta_ui_slave_new (screen->screen_name,
ui_slave_func,
screen);
......@@ -332,3 +336,76 @@ get_screen_name (MetaDisplay *display,
return scr;
}
static gint
ptrcmp (gconstpointer a, gconstpointer b)
{
if (a < b)
return -1;
else if (a > b)
return 1;
else
return 0;
}
static void
listify_func (gpointer key, gpointer value, gpointer data)
{
GSList **listp;
listp = data;
*listp = g_slist_prepend (*listp, value);
}
void
meta_screen_foreach_window (MetaScreen *screen,
MetaScreenWindowFunc func,
gpointer data)
{
GSList *winlist;
GSList *tmp;
/* If we end up doing this often, just keeping a list
* of windows might be sensible.
*/
winlist = NULL;
g_hash_table_foreach (screen->display->window_ids,
listify_func,
&winlist);
winlist = g_slist_sort (winlist, ptrcmp);
tmp = winlist;
while (tmp != NULL)
{
/* If the next node doesn't contain this window
* a second time, delete the window.
*/
if (tmp->next == NULL ||
(tmp->next && tmp->next->data != tmp->data))
{
MetaWindow *window = tmp->data;
if (window->screen == screen)
(* func) (screen, window, data);
}
tmp = tmp->data;
}
g_slist_free (winlist);
}
static void
queue_draw (MetaScreen *screen, MetaWindow *window, gpointer data)
{
if (window->frame)
meta_frame_queue_draw (window->frame);
}
void
meta_screen_queue_frame_redraws (MetaScreen *screen)
{
meta_screen_foreach_window (screen, queue_draw, NULL);
}
......@@ -24,6 +24,10 @@
#include "display.h"
#include "theme.h"