/* $Id: Draw.c,v 1.2 1997/06/10 15:29:13 archer Exp $
 *	DRAW.C - Collection of commonly used drawing subroutines
 *
 * Includes shadows, and others GCs...
 */
#include <Widget/WidgetsP.h>
#include <Widget/drawP.h>
#include "pixmap/gray.xbm"
#include "pixmap/stipple.xbm"


/**
 ** Public variables
 **/
GC		x11__default_gc;
GC		x11__stippled_gc,
		x11__fore_gc,
		x11__back_gc,
		x11__active_gc,
		x11__topleft_gc,
		x11__bottomright_gc;
Window		x11__cur_id;
Pixmap		x11__stipple;
Pixmap		x11__stipple_light;
X11_widget	x11__draw_in;
int		x11__x_left,
		x11__y_top,
		x11__x_right,
		x11__y_bot;
int		x11__x_w,
		x11__y_h;


/**
 ** Private variables
 **/
static int	saved__x_left,
		saved__y_top,
		saved__x_right,
		saved__y_bot;
static int	saved__x_w,
		saved__y_h;


/**
 ** X11_DRAW_POP
 **	Copies saved values into rectangular array
 **/
void x11__draw_pop(void)
{
	x11__x_left  = saved__x_left;
	x11__y_top   = saved__y_top;
	x11__x_right = saved__x_right;
	x11__y_bot   = saved__y_bot;
	x11__x_w     = saved__x_w;
	x11__y_h     = saved__y_h;
}


/**
 ** X11_DRAW_PUSH
 **	Copies current values into save array
 **/
void x11__draw_push(void)
{
	saved__x_left  = x11__x_left;
	saved__y_top   = x11__y_top;
	saved__x_right = x11__x_right;
	saved__y_bot   = x11__y_bot;
	saved__x_w     = x11__x_w;
	saved__y_h     = x11__y_h;
}


/**
 ** Internal: X11_DRAW_FIT_V
 **	Fit the drawing in horizontal coordinates (centering)
 **/
void x11__draw_fit_v(int w)
{
	if (w < x11__x_w)
		x11__x_left += (x11__x_w - w) / 2;
	x11__x_w     = w;
	x11__x_right = x11__x_left + w - 1;
}


/**
 ** Internal: X11_DRAW_FIT_H
 **	Fit the drawing in vertical coordinates (centering)
 **/
void x11__draw_fit_h(int h)
{
	if (h < x11__y_h)
		x11__y_top += (x11__y_h - h) / 2;
	x11__y_h   = h;
	x11__y_bot = x11__y_top + h - 1;
}


/**
 ** Internal: X11_DRAW_XXSHADOW
 **	Draw a shadow pointing ... somewhere
 **/
static void x11__draw_xxshadow(GC topleft, GC bottomright, unsigned int thick)
{
	while (thick-- > 0) {
		XDrawLine(x11__screen, x11__cur_id, topleft,
			x11__x_left, x11__y_bot, x11__x_left, x11__y_top);
		x11__x_left++;
		XDrawLine(x11__screen, x11__cur_id, topleft,
			x11__x_left, x11__y_top, x11__x_right, x11__y_top);
		XDrawLine(x11__screen, x11__cur_id, bottomright,
			x11__x_right, x11__y_top, x11__x_right, x11__y_bot);
		x11__y_top++;
		x11__x_right--;
		XDrawLine(x11__screen, x11__cur_id, bottomright,
			x11__x_left, x11__y_bot, x11__x_right, x11__y_bot);
		x11__y_bot--;
		x11__x_w -= 2;
		x11__y_h -= 2;
	}
}


/**
 ** X11_DRAW_UPSHADOW
 **	Draw a shadow pointing upwards
 **/
void x11__draw_upshadow(unsigned int thick)
{
	x11__draw_xxshadow(x11__topleft_gc, x11__bottomright_gc, thick);
}


/**
 ** X11_DRAW_DOWNSHADOW
 **	Draw a shadow pointing downwards
 **/
void x11__draw_downshadow(unsigned int thick)
{
	x11__draw_xxshadow(x11__bottomright_gc, x11__topleft_gc, thick);
}


/**
 ** X11_DRAW_FILLED
 **	Fill a rectangular area around the widget
 **/
void x11__draw_filled(X11_color pixel)
{
	XSetForeground(x11__screen, x11__back_gc, pixel);
	XFillRectangle(x11__screen, x11__cur_id, x11__back_gc,
			x11__x_left, x11__y_top, x11__x_w, x11__y_h);
}


/**
 ** X11_DRAW_LINED
 **	Draw a rectangular area around the widget
 **/
void x11__draw_lined(X11_color pixel, unsigned int thick)
{
	XSetForeground(x11__screen, x11__default_gc, pixel);
	while (thick-- > 0) {
		x11__x_w--;
		x11__y_h--;
		XDrawRectangle(x11__screen, x11__cur_id, x11__default_gc,
					x11__x_left++ , x11__y_top++,
					x11__x_w, x11__y_h);
		x11__x_right--;
		x11__y_bot--;
		x11__x_w--;
		x11__y_h--;
	}
}


/**
 ** X11_DRAW_DASHED
 **	Draw a rectangular area around the widget. It is drawn using a dash
 **	motif
 **/
void x11__draw_dashed(X11_color pixel, unsigned int thick)
{
	XSetForeground(x11__screen, x11__stippled_gc, pixel);
	XSetBackground(x11__screen, x11__stippled_gc, x11__draw_in->background);
	while (thick-- > 0) {
		x11__x_w--;
		x11__y_h--;
		XDrawRectangle(x11__screen, x11__cur_id, x11__stippled_gc,
					x11__x_left++ , x11__y_top++,
					x11__x_w, x11__y_h);
		x11__x_right--;
		x11__y_bot--;
		x11__x_w--;
		x11__y_h--;
	}
}


/**
 ** X11_SHADOWS_GC
 **	Initialize the shadowGCs for the widget
 **/
void x11__shadows_gc(void)
{
	XSetForeground(x11__screen, x11__topleft_gc, x11__draw_in->tl_color);
	XSetForeground(x11__screen, x11__bottomright_gc,x11__draw_in->br_color);
}


/**
 ** X11_DRAW_NOTHING
 **	Leave a rectangular area untouched
 **/
void x11__draw_nothing(unsigned int m)
{
	x11__x_left  += m;
	x11__y_top   += m;
	x11__x_right -= m;
	x11__y_bot   -= m;
	m *= 2;
	x11__x_w -= m;
	x11__y_h -= m;
}


/**
 ** X11_DRAW_START
 **	Start drawing around the widget
 **/
void x11__draw_start(X11_widget o)
{
	x11__x_w     = o->w - o->border2;
	x11__y_h     = o->h - o->border2;
	x11__x_left  = 0;
	x11__y_top   = 0;
	x11__x_right = x11__x_w - 1;
	x11__y_bot   = x11__y_h - 1;
	x11__draw_in = o;
	x11__cur_id  = o->id;
}


/**
 ** X11_DRAW_INIT
 **	Initialize: Allocate the two GCs
 **/
void x11__draw_init(void)
{
XGCValues	val;
#define GCF (GCForeground|GCBackground|GCStipple|GCGraphicsExposures)
#define GCFF (GCF|GCFillStyle)
/*
 * Common values
 */
	val.stipple = x11__stipple
	            = XCreateBitmapFromData(x11__screen, x11__root_id,
						gray_bits,
						gray_width, gray_height);
	x11__stipple_light = XCreateBitmapFromData(x11__screen, x11__root_id,
						stipple_bits,
						stipple_width, stipple_height);
	val.background         = x11__widget_root->background;
	val.graphics_exposures = False;
/*
 * Foreground color
 */
	val.foreground = x11__widget_root->foreground;
	x11__fore_gc = XCreateGC(x11__screen, x11__root_id, GCF, &val);
/*
 * Stippled GC
 */
	val.fill_style = FillOpaqueStippled;
	x11__stippled_gc = XCreateGC(x11__screen, x11__root_id, GCFF, &val);
/*
 * Background color
 */
	val.foreground = x11__widget_root->background;
	x11__back_gc = XCreateGC(x11__screen, x11__root_id, GCF, &val);
/*
 * Active background color
 */
	val.foreground = x11__widget_root->active_bk;
	x11__active_gc = XCreateGC(x11__screen, x11__root_id, GCF, &val);
/*
 * Topleft color
 */
	val.foreground = x11__widget_root->tl_color;
	x11__topleft_gc = XCreateGC(x11__screen, x11__root_id, GCF, &val);
/*
 * Bottomright color
 */
	val.foreground = x11__widget_root->br_color;
	if (x11__is_monochrome)
		x11__bottomright_gc = XCreateGC(x11__screen, x11__root_id,
								GCFF, &val);
	else
		x11__bottomright_gc = XCreateGC(x11__screen, x11__root_id,
								GCF, &val);
/*
 * Clear GraphicsExposures on default GC
 */
	XSetGraphicsExposures(x11__screen, x11__default_gc, False);
#undef GCF
#undef GCFF
}
