Commit c506b486 authored by rhp's avatar rhp
Browse files

...

parent 4ae250ae
......@@ -25,8 +25,7 @@
PangoContext*
meta_get_pango_context (Screen *xscreen,
const PangoFontDescription *desc,
Window frame)
const PangoFontDescription *desc)
{
MetaScreen *screen;
......
......@@ -55,8 +55,7 @@ struct _MetaUIColors
};
PangoContext* meta_get_pango_context (Screen *xscreen,
const PangoFontDescription *desc,
Window frame);
const PangoFontDescription *desc);
gulong meta_get_x_pixel (Screen *xscreen,
const PangoColor *color);
......
......@@ -191,6 +191,8 @@ meta_display_close (MetaDisplay *display)
/* If the next node doesn't contain this window
* a second time, delete the window.
*/
g_assert (tmp->data != NULL);
if (tmp->next == NULL ||
(tmp->next && tmp->next->data != tmp->data))
meta_window_free (tmp->data);
......
......@@ -28,8 +28,14 @@ static void
meta_frame_init_info (MetaFrame *frame,
MetaFrameInfo *info)
{
info->flags = 0;
info->frame = frame->xwindow;
info->flags =
META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU |
META_FRAME_ALLOWS_ICONIFY | META_FRAME_ALLOWS_MAXIMIZE |
META_FRAME_ALLOWS_RESIZE;
info->drawable = None;
info->xoffset = 0;
info->yoffset = 0;
info->display = frame->window->display->xdisplay;
info->screen = frame->window->screen->xscreen;
info->visual = frame->window->xvisual;
......@@ -132,13 +138,39 @@ meta_frame_calc_geometry (MetaFrame *frame,
frame->child_x = geom.left_width;
frame->child_y = geom.top_height;
frame->rect.width = frame->rect.width + geom.left_width + geom.right_width;
frame->rect.height = frame->rect.height + geom.top_height + geom.bottom_height;
frame->bg_pixel = geom.background_pixel;
*geomp = geom;
}
static void
set_background_none (MetaFrame *frame)
{
XSetWindowAttributes attrs;
attrs.background_pixmap = None;
XChangeWindowAttributes (frame->window->display->xdisplay,
frame->xwindow,
CWBackPixmap,
&attrs);
}
static void
set_background_color (MetaFrame *frame)
{
XSetWindowAttributes attrs;
attrs.background_pixel = None;
XChangeWindowAttributes (frame->window->display->xdisplay,
frame->xwindow,
CWBackPixel,
&attrs);
}
void
meta_window_ensure_frame (MetaWindow *window)
{
......@@ -176,7 +208,7 @@ meta_window_ensure_frame (MetaWindow *window)
frame->child_x, frame->child_y,
window->size_hints.win_gravity);
attrs.background_pixel = geom.background_pixel;
attrs.background_pixel = frame->bg_pixel;
attrs.event_mask =
StructureNotifyMask | SubstructureNotifyMask | ExposureMask |
ButtonPressMask | ButtonReleaseMask | OwnerGrabButtonMask |
......@@ -308,13 +340,15 @@ meta_frame_child_configure_request (MetaFrame *frame)
meta_frame_calc_initial_pos (frame,
frame->window->size_hints.x,
frame->window->size_hints.y);
set_background_none (frame);
XMoveResizeWindow (frame->window->display->xdisplay,
frame->xwindow,
frame->rect.x,
frame->rect.y,
frame->rect.width,
frame->rect.height);
set_background_color (frame);
}
void
......@@ -322,7 +356,6 @@ meta_frame_recalc_now (MetaFrame *frame)
{
int old_child_x, old_child_y;
MetaFrameGeometry geom;
XSetWindowAttributes attrs;
old_child_x = frame->child_x;
old_child_y = frame->child_y;
......@@ -341,19 +374,15 @@ meta_frame_recalc_now (MetaFrame *frame)
if (old_child_y != frame->child_y)
frame->rect.y += (frame->child_y - old_child_y);
set_background_none (frame);
XMoveResizeWindow (frame->window->display->xdisplay,
frame->xwindow,
frame->rect.x,
frame->rect.y,
frame->rect.width,
frame->rect.height);
attrs.background_pixel = geom.background_pixel;
XChangeWindowAttributes (frame->window->display->xdisplay,
frame->xwindow,
CWBackPixel,
&attrs);
set_background_color (frame);
meta_verbose ("Frame of %s recalculated to %d,%d %d x %d child %d,%d\n",
frame->window->desc, frame->rect.x, frame->rect.y,
frame->rect.width, frame->rect.height,
......@@ -363,15 +392,73 @@ meta_frame_recalc_now (MetaFrame *frame)
void
meta_frame_queue_recalc (MetaFrame *frame)
{
/* FIXME */
/* FIXME, actually queue */
meta_frame_recalc_now (frame);
}
static void
meta_frame_draw_now (MetaFrame *frame,
int x, int y, int width, int height)
{
MetaFrameInfo info;
Pixmap p;
XGCValues vals;
if (frame->xwindow == None)
return;
meta_frame_init_info (frame, &info);
if (width < 0)
width = frame->rect.width;
if (height < 0)
height = frame->rect.height;
if (width == 0 || height == 0)
return;
p = XCreatePixmap (frame->window->display->xdisplay,
frame->xwindow,
width, height,
frame->window->screen->visual_info.depth);
vals.foreground = frame->bg_pixel;
XChangeGC (frame->window->display->xdisplay,
frame->window->screen->scratch_gc,
GCForeground,
&vals);
XFillRectangle (frame->window->display->xdisplay,
p,
frame->window->screen->scratch_gc,
0, 0,
width, height);
info.drawable = p;
info.xoffset = - x;
info.yoffset = - y;
frame->window->screen->engine->expose_frame (&info,
0, 0, width, height,
frame->theme_data);
XCopyArea (frame->window->display->xdisplay,
p, frame->xwindow,
frame->window->screen->scratch_gc,
0, 0,
width, height,
x, y);
XFreePixmap (frame->window->display->xdisplay,
p);
}
void
meta_frame_queue_draw (MetaFrame *frame)
{
/* FIXME */
/* FIXME, actually queue */
meta_frame_draw_now (frame, 0, 0, -1, -1);
}
static void
......@@ -523,10 +610,12 @@ meta_frame_event (MetaFrame *frame,
break;
case META_FRAME_ACTION_NONE:
#if 0
meta_ui_slave_show_tip (frame->window->screen->uislave,
frame->rect.x,
frame->rect.y,
"Hi this is a tooltip");
#endif
break;
default:
break;
......@@ -543,16 +632,11 @@ meta_frame_event (MetaFrame *frame,
case KeymapNotify:
break;
case Expose:
{
MetaFrameInfo info;
meta_frame_init_info (frame, &info);
frame->window->screen->engine->expose_frame (&info,
event->xexpose.x,
event->xexpose.y,
event->xexpose.width,
event->xexpose.height,
frame->theme_data);
}
meta_frame_draw_now (frame,
event->xexpose.x,
event->xexpose.y,
event->xexpose.width,
event->xexpose.height);
break;
case GraphicsExpose:
break;
......
......@@ -39,15 +39,16 @@ struct _MetaFrame
/* reparent window */
Window xwindow;
/* This is trusted info from where we put the
/* This rect is trusted info from where we put the
* frame, not the result of ConfigureNotify
*/
MetaRectangle rect;
int child_x;
int child_y;
gpointer theme_data;
gulong bg_pixel;
MetaFrameAction action;
/* reference point for drags */
int last_x, last_y;
......
......@@ -46,6 +46,7 @@ meta_screen_new (MetaDisplay *display,
Window xroot;
Display *xdisplay;
Cursor cursor;
XGCValues vals;
/* Only display->name, display->xdisplay, and display->error_traps
* can really be used in this function, since normally screens are
......@@ -101,6 +102,11 @@ meta_screen_new (MetaDisplay *display,
meta_screen_init_visual_info (screen);
meta_screen_init_ui_colors (screen);
screen->scratch_gc = XCreateGC (screen->display->xdisplay,
screen->xroot,
0,
&vals);
screen->uislave = meta_ui_slave_new (screen->screen_name,
ui_slave_func,
......@@ -116,6 +122,10 @@ void
meta_screen_free (MetaScreen *screen)
{
meta_ui_slave_free (screen->uislave);
XFreeGC (screen->display->xdisplay,
screen->scratch_gc);
if (screen->pango_context)
g_object_unref (G_OBJECT (screen->pango_context));
g_free (screen->screen_name);
......
......@@ -41,6 +41,11 @@ struct _MetaScreen
XVisualInfo visual_info;
MetaUIColors colors;
/* In screen's visual, no guarantees about colors, shouldn't be
* left with a clip.
*/
GC scratch_gc;
/*< private >*/
......
......@@ -21,14 +21,32 @@
#include "theme.h"
#include "api.h"
#include "util.h"
typedef struct _DefaultFrameData DefaultFrameData;
typedef struct _DefaultScreenData DefaultScreenData;
typedef struct _DefaultFrameData DefaultFrameData;
typedef struct _DefaultScreenData DefaultScreenData;
typedef struct _DefaultFrameGeometry DefaultFrameGeometry;
struct _DefaultFrameGeometry
{
/* We recalculate this every time, to save RAM */
int left_width;
int right_width;
int top_height;
int bottom_height;
MetaRectangle close_rect;
MetaRectangle max_rect;
MetaRectangle min_rect;
MetaRectangle spacer_rect;
MetaRectangle menu_rect;
MetaRectangle title_rect;
};
struct _DefaultFrameData
{
PangoLayout *layout;
int title_height;
int layout_height;
};
struct _DefaultScreenData
......@@ -84,13 +102,12 @@ default_acquire_frame (MetaFrameInfo *info)
d = g_new (DefaultFrameData, 1);
desc = pango_font_description_from_string ("Sans 16");
desc = pango_font_description_from_string ("Sans 12");
d->layout = pango_layout_new (meta_get_pango_context (info->screen,
desc,
info->frame));
desc));
pango_font_description_free (desc);
d->title_height = 0;
d->layout_height = 0;
return d;
}
......@@ -109,11 +126,140 @@ default_release_frame (MetaFrameInfo *info,
g_free (d);
}
#define VERTICAL_TEXT_PAD 3
#define LEFT_WIDTH 15
#define RIGHT_WIDTH 15
#define BOTTOM_HEIGHT 20
#define VERTICAL_TITLE_PAD 2
#define HORIZONTAL_TITLE_PAD 3
#define VERTICAL_TEXT_PAD 2
#define HORIZONTAL_TEXT_PAD 2
#define LEFT_WIDTH 2
#define RIGHT_WIDTH 2
#define BOTTOM_HEIGHT 5
#define SPACER_SPACING 3
#define SPACER_WIDTH 2
#define SPACER_HEIGHT 10
#define BUTTON_WIDTH 12
#define BUTTON_HEIGHT 12
#define BUTTON_PAD 2
#define INNER_BUTTON_PAD 1
static void
calc_geometry (MetaFrameInfo *info,
DefaultFrameData *d,
DefaultFrameGeometry *fgeom)
{
int x;
int button_y;
int title_right_edge;
fgeom->top_height = MAX (d->layout_height + VERTICAL_TITLE_PAD * 2 + VERTICAL_TEXT_PAD * 2,
BUTTON_HEIGHT + BUTTON_PAD * 2);
fgeom->left_width = LEFT_WIDTH;
fgeom->right_width = RIGHT_WIDTH;
fgeom->bottom_height = BOTTOM_HEIGHT;
x = info->width - fgeom->right_width;
button_y = (fgeom->top_height - BUTTON_HEIGHT) / 2;
if (info->flags & META_FRAME_ALLOWS_DELETE)
{
fgeom->close_rect.x = x - BUTTON_PAD - BUTTON_WIDTH;
fgeom->close_rect.y = button_y;
fgeom->close_rect.width = BUTTON_WIDTH;
fgeom->close_rect.height = BUTTON_HEIGHT;
x = fgeom->close_rect.x;
}
else
{
fgeom->close_rect.x = 0;
fgeom->close_rect.y = 0;
fgeom->close_rect.width = 0;
fgeom->close_rect.height = 0;
}
if (info->flags & META_FRAME_ALLOWS_MAXIMIZE)
{
fgeom->max_rect.x = x - BUTTON_PAD - BUTTON_WIDTH;
fgeom->max_rect.y = button_y;
fgeom->max_rect.width = BUTTON_WIDTH;
fgeom->max_rect.height = BUTTON_HEIGHT;
x = fgeom->max_rect.x;
}
else
{
fgeom->max_rect.x = 0;
fgeom->max_rect.y = 0;
fgeom->max_rect.width = 0;
fgeom->max_rect.height = 0;
}
if (info->flags & META_FRAME_ALLOWS_ICONIFY)
{
fgeom->min_rect.x = x - BUTTON_PAD - BUTTON_WIDTH;
fgeom->min_rect.y = button_y;
fgeom->min_rect.width = BUTTON_WIDTH;
fgeom->min_rect.height = BUTTON_HEIGHT;
x = fgeom->min_rect.x;
}
else
{
fgeom->min_rect.x = 0;
fgeom->min_rect.y = 0;
fgeom->min_rect.width = 0;
fgeom->min_rect.height = 0;
}
if (fgeom->close_rect.width > 0 ||
fgeom->max_rect.width > 0 ||
fgeom->min_rect.width > 0)
{
fgeom->spacer_rect.x = x - SPACER_SPACING - SPACER_WIDTH;
fgeom->spacer_rect.y = (fgeom->top_height - SPACER_HEIGHT) / 2;
fgeom->spacer_rect.width = SPACER_WIDTH;
fgeom->spacer_rect.height = SPACER_HEIGHT;
x = fgeom->spacer_rect.x;
}
else
{
fgeom->spacer_rect.x = 0;
fgeom->spacer_rect.y = 0;
fgeom->spacer_rect.width = 0;
fgeom->spacer_rect.height = 0;
}
title_right_edge = x - HORIZONTAL_TITLE_PAD;
/* Now x changes to be position from the left */
x = fgeom->left_width;
if (info->flags & META_FRAME_ALLOWS_MENU)
{
fgeom->menu_rect.x = x + BUTTON_PAD;
fgeom->menu_rect.y = button_y;
fgeom->menu_rect.width = BUTTON_WIDTH;
fgeom->menu_rect.height = BUTTON_HEIGHT;
x = fgeom->menu_rect.x + fgeom->menu_rect.width;
}
else
{
fgeom->menu_rect.x = 0;
fgeom->menu_rect.y = 0;
fgeom->menu_rect.width = 0;
fgeom->menu_rect.height = 0;
}
fgeom->title_rect.x = x + BUTTON_PAD;
fgeom->title_rect.y = VERTICAL_TITLE_PAD;
fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x;
fgeom->title_rect.height = fgeom->top_height - VERTICAL_TITLE_PAD * 2;
if (fgeom->title_rect.width < 0)
fgeom->title_rect.width = 0;
}
static void
default_fill_frame_geometry (MetaFrameInfo *info,
MetaFrameGeometry *geom,
......@@ -121,6 +267,7 @@ default_fill_frame_geometry (MetaFrameInfo *info,
{
DefaultFrameData *d;
PangoRectangle rect;
DefaultFrameGeometry fgeom;
d = frame_data;
......@@ -131,13 +278,14 @@ default_fill_frame_geometry (MetaFrameInfo *info,
pango_layout_get_pixel_extents (d->layout, NULL, &rect);
d->title_height = rect.height + VERTICAL_TEXT_PAD * 2;
geom->top_height = d->title_height;
geom->left_width = LEFT_WIDTH;
geom->right_width = RIGHT_WIDTH;
geom->bottom_height = BOTTOM_HEIGHT;
d->layout_height = rect.height;
calc_geometry (info, d, &fgeom);
geom->top_height = fgeom.top_height;
geom->left_width = fgeom.left_width;
geom->right_width = fgeom.right_width;
geom->bottom_height = fgeom.bottom_height;
geom->background_pixel = meta_get_x_pixel (info->screen,
&info->colors->bg[META_STATE_NORMAL]);
}
......@@ -151,6 +299,7 @@ draw_vline (MetaFrameInfo *info,
int y2,
int x)
{
/* From GTK+ */
int thickness_light;
int thickness_dark;
int i;
......@@ -176,6 +325,76 @@ draw_vline (MetaFrameInfo *info,
}
}
static void
draw_varrow (MetaFrameInfo *info,
Drawable drawable,
GC gc,
gboolean down,
gint x,
gint y,
gint width,
gint height)
{
gint steps, extra;
gint y_start, y_increment;
gint i;
/* From GTK+ */
width = width + width % 2 - 1; /* Force odd */
steps = 1 + width / 2;
extra = height - steps;
if (down)
{
y_start = y;
y_increment = 1;
}
else
{
y_start = y + height - 1;
y_increment = -1;
}
for (i = 0; i < extra; i++)
{
XDrawLine (info->display, drawable,
gc,
x, y_start + i * y_increment,
x + width - 1, y_start + i * y_increment);
}
for (; i < height; i++)
{
XDrawLine (info->display, drawable,
gc,
x + (i - extra), y_start + i * y_increment,
x + width - (i - extra) - 1, y_start + i * y_increment);
}
}
static void
set_clip (Display *display, GC gc, MetaRectangle *rect)
{
if (rect)
{
XRectangle xrect;
xrect.x = rect->x;
xrect.y = rect->y;
xrect.width = rect->width;
xrect.height = rect->height;
XSetClipRectangles (display, gc, 0, 0,
&xrect, 1, YXBanded);
}
else
{
XSetClipMask (display, gc, None);
}
}
static void
default_expose_frame (MetaFrameInfo *info,