/* vim: ts=4 noet
 * Oroborus Window Manager
 *
 * Copyright (C) 2001 Ken Lynch
 * Copyright (C) 2002 Stefan Pfetzing
 *
 * OroboROX Window Manager
 * 
 * Copyright (C) 2004 Guido Schimmels
 *
* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
 */

#include "config.h"
#include <stdio.h>
#include <glib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include <X11/extensions/shape.h>
#include <ft2build.h>
#include <X11/Xft/Xft.h>
#include "main.h"
#include "keyboard.h"
#include "pixmap.h"
#include "hints.h"
#include "client.h"
#include "i18n.h"
#include "frame.h"
#include "settings.h"
#include "workspaces.h"
#include "xinerama.h"
#include "focus.h"
#include "xerror.h"

#define DBUG_FRAME(x)		//fprintf(stderr, "[OROBOROX]: %s\n", x)

static Window info_win = None;
static int middle_x, middle_y;
static XftDraw *info_xftdraw;
XColor info_fg, info_bg;

void infoWinCreate(void)
{
	int m, mx, my;

	if ((info_win == None) && get_mouse_xy(dpy, root, &mx, &my))
	{
		m = xineramaGetMonitorUnderPoint(mx, my);
		middle_x = xinerama_screen_info[m].x_org + (xinerama_screen_info[m].width / 2);
		middle_y = xinerama_screen_info[m].y_org + (xinerama_screen_info[m].height / 2);
		info_win = XCreateSimpleWindow(dpy, root, 0, 0, 10, 10, 1, info_fg.pixel, info_bg.pixel);
		info_xftdraw = XftDrawCreate(dpy, info_win, visual, cmap);
		XMapWindow(dpy, info_win);
	}
}


void infoWinSet(char *s)
{
	g_return_if_fail(info_win != None);
	
	int textWidth = getTextWidth(s, &title_font), y;
	int fontHeight = title_font.xftfont->height;	

	XWindowChanges wc;
	wc.width = textWidth + 16;
	wc.height = fontHeight + 16;
	wc.x = middle_x - (wc.width / 2);
	wc.y = middle_y - (wc.height / 2);
	y = (wc.height / 2) + (fontHeight / 2);
	XConfigureWindow(dpy, info_win, CWX | CWY | CWWidth | CWHeight, &wc);

	//XMoveResizeWindow(dpy, info_win, middle_x - (textWidth / 2), 
	//				  middle_y - (fontHeight / 2), textWidth + 16, fontHeight + 16);
	XClearWindow(dpy, info_win);
	XftDrawChange(info_xftdraw, info_win);
	XftDrawStringUtf8(info_xftdraw, &textcolor, title_font.xftfont, 8, y, s,
					  strlen(s));
}

void infoWinDelete(void)
{
	if (info_win != None)
	{
		XftDrawDestroy(info_xftdraw);
		XDestroyWindow(dpy, info_win);
		info_win = None;
	}
}

int frameLeft(Client * c)
{
	DBUG_FRAME("entering frameLeft");

	if (c->has_decor)
		return sides[SIDE_LEFT][ACTIVE].width;
	else
		return 0;
}

int frameRight(Client * c)
{
	DBUG_FRAME("entering frameRight");

	if (c->has_decor)
		return sides[SIDE_RIGHT][ACTIVE].width;
	else
		return 0;
}

int frameTop(Client * c)
{
	DBUG_FRAME("entering frameTop");

	if (c->has_decor)
		return title[TITLE_3][ACTIVE].height;
	else
		return 0;
}

int frameBottom(Client * c)
{
	DBUG_FRAME("entering frameBottom");

	if (c->has_decor && !(c->state & STATE_SHADED))
		return sides[SIDE_BOTTOM][ACTIVE].height;
	else
		return 0;
}

int frameX(Client * c)
{
	DBUG_FRAME("entering frameX");

	if (c->has_decor)
		return c->geometry.x - frameLeft(c);
	else
		return c->geometry.x;
}

int frameY(Client * c)
{
	DBUG_FRAME("entering frameY");

	if (c->has_decor)
		return c->geometry.y - frameTop(c);
	else
		return c->geometry.y;
}

int frameWidth(Client * c)
{
	DBUG_FRAME("entering frameWidth");

	if (c->has_decor)
		return c->geometry.width + frameLeft(c) + frameRight(c);
	else
		return c->geometry.width;
}

int frameHeight(Client * c)
{
	DBUG_FRAME("entering frameHeight");

	if (c->state & STATE_SHADED)
		return frameTop(c);
	else if (c->has_decor)
		return c->geometry.height + frameTop(c) + frameBottom(c);
	else
		return c->geometry.height;
}

static void fillRectangle(Display * dpy, Drawable d, Pixmap pm, int x, int y, int width, int height)
{
	XGCValues gv;
	GC gc;
	unsigned long mask;

	DBUG_FRAME("entering fillRectangle");

	gv.fill_style = FillTiled;
	gv.tile = pm;
	gv.ts_x_origin = x;
	gv.ts_y_origin = y;
	gv.foreground = WhitePixel(dpy, DefaultScreen(dpy));
	if (gv.tile != None)
		mask = GCTile | GCFillStyle | GCTileStipXOrigin;
	else
		mask = GCForeground;
	gc = XCreateGC(dpy, d, mask, &gv);

	XFillRectangle(dpy, d, gc, x, y, width, height);
	XFreeGC(dpy, gc);
}

static void frameCreateTitlePixmap(Client * c, int state, int left, int right, MyPixmap * pm)
{
	int width, x = 0, tp = 0, w1 = 0, w2, w3, w4, w5, temp;
	MyPixmap title1, title3, title5;

	DBUG_FRAME("entering frameCreateTitlePixmap");

	if (left > right)
	{
		temp = left;
		left = right;
		right = temp;
	}

	width = frameWidth(c) - corners[CORNER_TOP_LEFT][ACTIVE].width -
		corners[CORNER_TOP_RIGHT][ACTIVE].width;
	if (left < corners[CORNER_TOP_LEFT][ACTIVE].width)
		left = corners[CORNER_TOP_LEFT][ACTIVE].width;
	if (right > frameWidth(c) - corners[CORNER_TOP_RIGHT][ACTIVE].width)
		right = frameWidth(c) - corners[CORNER_TOP_RIGHT][ACTIVE].width;
	if (right < corners[CORNER_TOP_LEFT][ACTIVE].width)
		right = corners[CORNER_TOP_LEFT][ACTIVE].width;

	left = left - corners[CORNER_TOP_LEFT][ACTIVE].width;
	right = right - corners[CORNER_TOP_LEFT][ACTIVE].width;

	int text_width = getTextWidth(c->title_string, &title_font);

	w2 = title[TITLE_2][ACTIVE].width;
	w4 = title[TITLE_4][ACTIVE].width;
	if (full_width_title)
	{
		w1 = left;
		w5 = width - right;
		w3 = width - w1 - w2 - w4 - w5;
		if (w3 < 0)
			w3 = 0;
		switch (title_alignment)
		{
			case ALIGN_RIGHT:
				tp = w3 - text_width;
				break;
			case ALIGN_CENTER:
				tp = (w3 / 2) - (text_width / 2);
				break;
		}
		if (tp < 0)
			tp = 0;
	}
	else
	{
		w3 = text_width + 4;	//"+4" is an ugly fix?
		w5 = width;
		if (w3 > width - w2 - w4)
			w3 = width - w2 - w4;
		if (w3 < 0)
			w3 = 0;
		switch (title_alignment)
		{
			case ALIGN_LEFT:
				w1 = left;
				break;
			case ALIGN_RIGHT:
				w1 = right - w2 - w3 - w4;
				break;
			case ALIGN_CENTER:
				w1 = left + ((right - left) / 2) - (w3 / 2) - w2;
				break;
		}
		if (w1 < left)
			w1 = left;
	}

	pm->pixmap = XCreatePixmap(dpy, root, width, frameTop(c), depth);
	pm->mask = XCreatePixmap(dpy, pm->pixmap, width, frameTop(c), 1);

	if (w1 > 0)
	{
		scalePixmap(dpy, &title[TITLE_1][state], &title1, w1, frameTop(c));
		fillRectangle(dpy, pm->pixmap, title1.pixmap, 0, 0, w1, frameTop(c));
		fillRectangle(dpy, pm->mask, title1.mask, 0, 0, w1, frameTop(c));
		x += w1;
	}

	fillRectangle(dpy, pm->pixmap, title[TITLE_2][state].pixmap, x, 0, w2, frameTop(c));
	fillRectangle(dpy, pm->mask, title[TITLE_2][state].mask, x, 0, w2, frameTop(c));
	x += w2;

	if (w3 > 0)
	{
		scalePixmap(dpy, &title[TITLE_3][state], &title3, w3, frameTop(c));
		fillRectangle(dpy, pm->pixmap, title3.pixmap, x, 0, w3, frameTop(c));
		fillRectangle(dpy, pm->mask, title3.mask, x, 0, w3, frameTop(c));
		drawString(c, dpy, pm->pixmap, &title_font, &title_font.xft_detail[state], x + tp,
				   title_font.xftfont->ascent + (frameTop(c) - title_font.xftfont->height) / 2,
				   c->title_string);

		x = x + w3;
	}

	if (x > right - w4)
		x = right - w4;
	fillRectangle(dpy, pm->pixmap, title[TITLE_4][state].pixmap, x, 0, w4, frameTop(c));
	fillRectangle(dpy, pm->mask, title[TITLE_4][state].mask, x, 0, w4, frameTop(c));
	x += w4;

	if (w5 > 0)
	{
		scalePixmap(dpy, &title[TITLE_5][state], &title5, w5, frameTop(c));
		fillRectangle(dpy, pm->pixmap, title5.pixmap, x, 0, w5, frameTop(c));
		fillRectangle(dpy, pm->mask, title5.mask, x, 0, w5, frameTop(c));
	}
	freePixmap(dpy, &title1);
	freePixmap(dpy, &title3);
	freePixmap(dpy, &title5);
}

static int getButtonFromLetter(char c)
{
	int b;

	DBUG_FRAME("entering getButtonFromLetter");

	switch (c)
	{
		case 'H':
			b = HIDE_BUTTON;
			break;
		case 'C':
			b = CLOSE_BUTTON;
			break;
		case 'M':
			b = MAXIMIZE_BUTTON;
			break;
		case 'S':
			b = SHADE_BUTTON;
			break;
		case 'T':
			b = STICK_BUTTON;
			if ((workspace_count < 2))
				b = -1;
			break;
		case '0':
			b = -1;
			break;
		default:
			b = -2;
	}
	return b;
}

static char getLetterFromButton(int b)
{
	char c;

	DBUG_FRAME("entering getLetterFromButton");

	switch (b)
	{
		case HIDE_BUTTON:
			c = 'H';
			break;
		case CLOSE_BUTTON:
			c = 'C';
			break;
		case MAXIMIZE_BUTTON:
			c = 'M';
			break;
		case SHADE_BUTTON:
			c = 'S';	
			break;
		case STICK_BUTTON:
			c = 'T';
			break;
		default:
			c = 0;
	}
	return c;
}


static void combine_shape(Window temp, int x_off, int y_off, Window src)
{
	XShapeCombineShape(dpy, temp, ShapeBounding, x_off, y_off, src, ShapeBounding, ShapeUnion);
}


static void frameSetShape(Client * c, int state, MyPixmap * title, MyPixmap pm_sides[3],
						  int button_x[BUTTON_COUNT])
{
	Window temp;
	int i;
	XRectangle rect;

	DBUG_FRAME("entering frameSetShape");

	if (!shape)
		return;

	int top = frameTop(c);
	int bottom = frameBottom(c);
	int width = frameWidth(c);
	int height = frameHeight(c);

	temp = XCreateSimpleWindow(dpy, root, 0, 0, width, height, 0, 0, 0);
	
	if (c->state & STATE_SHADED)
	{
		rect.x = 0;
		rect.y = 0;
		rect.width = width;
		rect.height = height;
		XShapeCombineRectangles(dpy, temp, ShapeBounding, 0, 0, &rect, 1, ShapeSubtract, 0);
	}
	else
		XShapeCombineShape(dpy, temp, ShapeBounding, frameLeft(c), top, c->window, ShapeBounding, ShapeSet);

	if (c->has_decor)
	{
		XShapeCombineMask(dpy, c->title, ShapeBounding, 0, 0, title->mask, ShapeSet);
		for (i = 0; i < 3; i++)
			XShapeCombineMask(dpy, c->sides[i], ShapeBounding, 0, 0, pm_sides[i].mask, ShapeSet);
		for (i = 0; i < 4; i++)
			XShapeCombineMask(dpy, c->corners[i], ShapeBounding, 0, 0, corners[i][state].mask,
							  ShapeSet);
		for (i = 0; i < BUTTON_COUNT; i++)
		{
			if (c->button_pressed[i])
				XShapeCombineMask(dpy, c->buttons[i], ShapeBounding,
								  0, 0, buttons[i][PRESSED].mask, ShapeSet);
			else
				XShapeCombineMask(dpy, c->buttons[i], ShapeBounding,
								  0, 0, buttons[i][state].mask, ShapeSet);
		}

		if (corners[CORNER_TOP_LEFT][ACTIVE].height > (height - bottom + 1))
		{
			rect.x = 0;
			rect.y = height - bottom + 1;
			rect.width = corners[CORNER_TOP_LEFT][ACTIVE].width;
			rect.height = corners[CORNER_TOP_LEFT][ACTIVE].height - (height - bottom + 1);
			XShapeCombineRectangles(dpy, c->corners[CORNER_TOP_LEFT], ShapeBounding, 0, 0, &rect, 1,
									ShapeSubtract, 0);
		}
		if (corners[CORNER_TOP_RIGHT][ACTIVE].height > (height - bottom + 1))
		{
			rect.x = 0;
			rect.y = height - bottom + 1;
			rect.width = corners[CORNER_TOP_RIGHT][ACTIVE].width;
			rect.height = corners[CORNER_TOP_RIGHT][ACTIVE].height - (height - bottom + 1);
			XShapeCombineRectangles(dpy, c->corners[CORNER_TOP_RIGHT], ShapeBounding, 0, 0, &rect,
									1, ShapeSubtract, 0);
		}
		if (corners[CORNER_BOTTOM_LEFT][ACTIVE].height > (height - top + 1))
		{
			rect.x = 0;
			rect.y = 0;
			rect.width = corners[CORNER_BOTTOM_LEFT][ACTIVE].width;
			rect.height = corners[CORNER_BOTTOM_LEFT][ACTIVE].height - (height - top + 1);
			XShapeCombineRectangles(dpy, c->corners[CORNER_BOTTOM_LEFT], ShapeBounding, 0, 0, &rect,
									1, ShapeSubtract, 0);
		}
		if (corners[CORNER_BOTTOM_RIGHT][ACTIVE].height > (height - top + 1))
		{
			rect.x = 0;
			rect.y = 0;
			rect.width = corners[CORNER_BOTTOM_RIGHT][ACTIVE].width;
			rect.height = corners[CORNER_BOTTOM_RIGHT][ACTIVE].height - (height - top + 1);
			XShapeCombineRectangles(dpy, c->corners[CORNER_BOTTOM_RIGHT], ShapeBounding, 0, 0,
									&rect, 1, ShapeSubtract, 0);
		}

		combine_shape(temp, 0, top, c->sides[SIDE_LEFT]);
		combine_shape(temp, width - frameRight(c), top, c->sides[SIDE_RIGHT]);
		combine_shape(temp, corners[CORNER_TOP_LEFT][ACTIVE].width, 0,  c->title);
		combine_shape(temp, corners[CORNER_BOTTOM_LEFT][ACTIVE].width, height-bottom, c->sides[SIDE_BOTTOM]);
		combine_shape(temp, 0, height-corners[CORNER_BOTTOM_LEFT][ACTIVE].height, c->corners[CORNER_BOTTOM_LEFT]);
		combine_shape(temp, width - corners[CORNER_BOTTOM_RIGHT][ACTIVE].width, 
							height - corners[CORNER_BOTTOM_RIGHT][ACTIVE].height, 
														c->corners[CORNER_BOTTOM_RIGHT]);
		combine_shape(temp, 0, 0, c->corners[CORNER_TOP_LEFT]);
		combine_shape(temp, width-corners[CORNER_TOP_RIGHT][ACTIVE].width, 0, c->corners[CORNER_TOP_RIGHT]);
		
		for (i = 0; i < BUTTON_COUNT; i++)
			if (strchr(button_layout, getLetterFromButton(i)))
				combine_shape(temp, button_x[i], (top - buttons[i][ACTIVE].height) / 2, c->buttons[i]);
	}

	XShapeCombineShape(dpy, c->frame, ShapeBounding, 0, 0, temp, ShapeBounding, ShapeSet);
	XDestroyWindow(dpy, temp);
}

static Pixmap buttonStatePixmap(Client * c, int button, int state)
{
	int retstate = state;
	Pixmap retpixmap;

	if (buttons_show_state)
		switch (button)
		{
			case HIDE_BUTTON:
				if (!(c->actions & ACTION_MINIMIZE))
				{
					retstate += ACTIVE_DISABLED;
					state = INACTIVE;
				}
				break;
			case SHADE_BUTTON:	
				if (c->state & STATE_SHADED)
					retstate += ACTIVE_TOGGLED;
				else if (!(c->actions & ACTION_SHADE))
				{
					retstate += ACTIVE_DISABLED;
					state = INACTIVE;
				}
				break;
			case MAXIMIZE_BUTTON:			
				if (c->state & (STATE_MAXIMIZED_VERT | STATE_MAXIMIZED_HORZ))
					retstate += ACTIVE_TOGGLED;
				else if (!(c->actions & (ACTION_MAXIMIZE_HORZ | ACTION_MAXIMIZE_VERT)))
				{
					retstate += ACTIVE_DISABLED;
					state = INACTIVE;
				}
				break;
			case CLOSE_BUTTON:
				if (!(c->actions & ACTION_CLOSE))
				{
					retstate += ACTIVE_DISABLED;
					state = INACTIVE;
				}
				break;
			case STICK_BUTTON:
				if (c->state & STATE_STICKY)
					retstate += ACTIVE_TOGGLED;
				else if (!(c->actions & STATE_STICKY))
				{
					retstate += ACTIVE_DISABLED;
					state = INACTIVE;
				}
				break;
		}

	if ((retpixmap = buttons[button][retstate].pixmap))
		return retpixmap;
	else
		return buttons[button][state].pixmap;
}

void undecorate(Client * c)
{	
	dbg("%s\n", __func__);
	dbg("%s: %s\n", __func__, c && c->title_string ? c->title_string : "None");


	//g_return_if_fail(client_exists(c));

	int i;
	for (i = 0; i < 3; i++)
		XUnmapWindow(dpy, c->sides[i]);
	for (i = 0; i < 4; i++)
		XUnmapWindow(dpy, c->corners[i]);
	for (i = 0; i < BUTTON_COUNT; i++)
		XUnmapWindow(dpy, c->buttons[i]);
	XUnmapWindow(dpy, c->title);
	frameSetShape(c, 0, NULL, NULL, NULL);
}

void decorate(Client * c, int state)
{
	dbg("%s\n", __func__);

	c->decor_state = state;

	int i, x, button, left, right, top_width;
	int bottom_width, left_height, right_height, button_x[BUTTON_COUNT];
	MyPixmap pm_title, pm_sides[3];

		XMapWindow(dpy, c->title);
		for (i = 0; i < 3; i++)
			XMapWindow(dpy, c->sides[i]);
		for (i = 0; i < 4; i++)
			XMapWindow(dpy, c->corners[i]);


		for (i = 0; i < BUTTON_COUNT; i++)
			if (strchr(button_layout, getLetterFromButton(i)))
				XMapWindow(dpy, c->buttons[i]);

		x = frameLeft(c) + button_offset;

		for (i = 0; i < strlen(button_layout); i++)
		{
			button = getButtonFromLetter(button_layout[i]);
			if (button >= 0)
			{
				XMoveResizeWindow(dpy,
								  c->buttons[button], x, (frameTop(c) -
														  buttons[button][ACTIVE].height) / 2,
								  buttons[button][ACTIVE].width, buttons[button][ACTIVE].height);
				button_x[button] = x;
				x = x + buttons[button][ACTIVE].width + button_spacing;
			}
			else if (button == -2)	//title found...
				break;
		}
		left = x - button_spacing;

		x = frameWidth(c) - frameRight(c) + button_spacing - button_offset;
		for (i = strlen(button_layout) - 1; i >= 0; i--)
		{
			button = getButtonFromLetter(button_layout[i]);
			if (button >= 0)
			{
				x = x - buttons[button][ACTIVE].width - button_spacing;
				XMoveResizeWindow(dpy, c->buttons[button], x,
								  (frameTop(c) -
								   buttons[button][ACTIVE].height) / 2,
								  buttons[button][ACTIVE].width, buttons[button][ACTIVE].height);
				button_x[button] = x;
			}
			else if (button == -2)	//title found...
				break;
		}
		right = x;


		top_width =
			frameWidth(c) - corners[CORNER_TOP_LEFT][ACTIVE].width -
			corners[CORNER_TOP_RIGHT][ACTIVE].width;
		bottom_width =
			frameWidth(c) - corners[CORNER_BOTTOM_LEFT][ACTIVE].width -
			corners[CORNER_BOTTOM_RIGHT][ACTIVE].width;
		left_height = frameHeight(c) - frameTop(c) - corners[CORNER_BOTTOM_LEFT][ACTIVE].height;
		right_height = frameHeight(c) - frameTop(c) - corners[CORNER_BOTTOM_RIGHT][ACTIVE].height;

		frameCreateTitlePixmap(c, state, left, right, &pm_title);
		scalePixmap(dpy, &sides[SIDE_LEFT][state], &pm_sides[SIDE_LEFT], frameLeft(c), left_height);
		scalePixmap(dpy, &sides[SIDE_RIGHT][state], &pm_sides[SIDE_RIGHT],
					frameRight(c), right_height);
		scalePixmap(dpy, &sides[SIDE_BOTTOM][state],
					&pm_sides[SIDE_BOTTOM], bottom_width, frameBottom(c));

		XSetWindowBackgroundPixmap(dpy, c->title, pm_title.pixmap);
		for (i = 0; i < 3; i++)
			XSetWindowBackgroundPixmap(dpy, c->sides[i], pm_sides[i].pixmap);
		for (i = 0; i < 4; i++)
			XSetWindowBackgroundPixmap(dpy, c->corners[i], corners[i][state].pixmap);

		for (i = 0; i < BUTTON_COUNT; i++)
		{
			if (c->button_pressed[i])
				XSetWindowBackgroundPixmap(dpy, c->buttons[i], buttons[i][PRESSED].pixmap);
			else
				XSetWindowBackgroundPixmap(dpy, c->buttons[i],
										   buttonStatePixmap(c, i, state));
		}

		XMoveResizeWindow(dpy, c->title,
						  corners[CORNER_TOP_LEFT][ACTIVE].width, 0,
						  top_width < 1 ? 1 : top_width, frameTop(c));
		XMoveResizeWindow(dpy, c->sides[SIDE_BOTTOM],
						  corners[CORNER_BOTTOM_LEFT][ACTIVE].width,
						  frameHeight(c) - frameBottom(c),
						  bottom_width < 1 ? 1 : bottom_width, frameBottom(c));
		XMoveResizeWindow(dpy, c->sides[SIDE_LEFT], 0, frameTop(c),
						  frameLeft(c), left_height < 1 ? 1 : left_height);
		XMoveResizeWindow(dpy, c->sides[SIDE_RIGHT],
						  frameWidth(c) - frameRight(c), frameTop(c),
						  frameRight(c), right_height < 1 ? 1 : right_height);

		XMoveResizeWindow(dpy, c->corners[CORNER_TOP_LEFT], 0, 0,
						  corners[CORNER_TOP_LEFT][ACTIVE].width,
						  corners[CORNER_TOP_LEFT][ACTIVE].height);
		XMoveResizeWindow(dpy, c->corners[CORNER_TOP_RIGHT],
						  frameWidth(c) -
						  corners[CORNER_TOP_RIGHT][ACTIVE].width, 0,
						  corners[CORNER_TOP_RIGHT][ACTIVE].width,
						  corners[CORNER_TOP_RIGHT][ACTIVE].height);
		XMoveResizeWindow(dpy, c->corners[CORNER_BOTTOM_LEFT], 0,
						  frameHeight(c) -
						  corners[CORNER_BOTTOM_LEFT][ACTIVE].height,
						  corners[CORNER_BOTTOM_LEFT][ACTIVE].width,
						  corners[CORNER_BOTTOM_LEFT][ACTIVE].height);
		XMoveResizeWindow(dpy, c->corners[CORNER_BOTTOM_RIGHT],
						  frameWidth(c) -
						  corners[CORNER_BOTTOM_RIGHT][ACTIVE].width,
						  frameHeight(c) -
						  corners[CORNER_BOTTOM_RIGHT][ACTIVE].height,
						  corners[CORNER_BOTTOM_RIGHT][ACTIVE].width,
						  corners[CORNER_BOTTOM_RIGHT][ACTIVE].height);

		XClearWindow(dpy, c->title);
		for (i = 0; i < 3; i++)
			XClearWindow(dpy, c->sides[i]);
		for (i = 0; i < 4; i++)
			XClearWindow(dpy, c->corners[i]);
		for (i = 0; i < BUTTON_COUNT; i++)
			XClearWindow(dpy, c->buttons[i]);
		frameSetShape(c, state, &pm_title, pm_sides, button_x);
		freePixmap(dpy, &pm_title);
		for (i = 0; i < 3; i++)
			freePixmap(dpy, &pm_sides[i]);

}

void frameDraw(Client * c)
{
	dbg("%s\n", __func__);

	g_return_if_fail(client_exists(c));

	if (c->has_decor)
		decorate(c, (get_input_focus() == c->window) ? ACTIVE : INACTIVE);
	else
		undecorate(c);
}

