/******************************************************************************/
/*  FILE: init_x.c                                                            */
/*  VERSION: vu0.0                                                            */
/*  REVISION DATE: 6/20/89                                                    */
/*  AUTHOR: Tom Riddle                                                        */
/*  PURPOSE: Initializes X Windows, loads font, defines colors.               */
/******************************************************************************/


#include "../include/utils.h"
#include "../include/uf.h"

int err;
Display *disp;
int cur_wind;
XFontStruct *font_info;
int font_width, font_height, font_ascent;
struct wind_struct wind_list[max_windows];
int color_display;

/*            { full_w, bigmenu_w, fatmenu_w, menu_w, title_w, msg_w, key_w }*/
int x1[max_windows] = { 1,      1,         9,     18,       1,     2,     1 };
int y1[max_windows] = { 1,      3,         6,      5,       1,    21,    25 };
int x2[max_windows] = {80,     80,        71,     63,      80,    79,    80 };
int y2[max_windows] = {25,     24,        23,     17,       2,    24,    25 };
int draw_border[max_windows] = 
		  { false,   true,      true,   true,   false,  true, false };

char *color_names[] = { "black", "blue", "green", "cyan", "red", "magenta",
	"brown", "light gray", "dark slate gray", "light blue", "lime green",
	"sky blue", "orange red", "medium slate blue", "yellow", "white" };
unsigned long color_pixels[max_colors];

int initfont(info)
XFontStruct **info;
{
	if ((*info = XLoadQueryFont(disp,def_fontName)) == NULL)
		return err_cantLoadFont;
	else  {	
		font_height = (*info)->ascent + (*info)->descent;
		font_width  = (*info)->max_bounds.width;
		font_ascent = (*info)->ascent;
		return err_noError;
	}
}

int initcolors(screen, depth)
int screen, depth;
{
	Colormap colormap;
	XColor color_def;
	int i;

	depth = DisplayPlanes(disp, screen);
	if (depth == 1)  {    /* monochrome display */
		color_display = false;
		color_pixels[black] = BlackPixel(disp, screen);
		color_pixels[white] = WhitePixel(disp, screen);
	} else {
		color_display = true;
		colormap = DefaultColormap(disp, screen);
		for (i = 0; i <= max_colors - 1; i++)  {
			XParseColor(disp, colormap, color_names[i],
				    &color_def);
			XAllocColor(disp, colormap, &color_def);
			color_pixels[i] = color_def.pixel;
		}
	}
}

GC MakeGC(drawable)
Drawable drawable;
{
	GC gc;
	unsigned long gc_mask;
	XGCValues values;

	/* set foreground and  background mask for gc */
	gc_mask = GCForeground | GCBackground;
	values.foreground = color_pixels[black];
	values.background = color_pixels[white];

	gc = XCreateGC(disp, drawable, gc_mask, &values);
	XSetFont(disp, gc, font_info->fid);
	XSetGraphicsExposures(disp, gc, false);

	return(gc);
}

unsigned long SetManAttr(attrib)
XSetWindowAttributes *attrib;
{
	unsigned long mask, bg_color, bd_color;

	/* select attributes for managed window */
	bd_color = color_pixels[black];
	if (color_display == true)
		bg_color = color_pixels[blue];
	else
		bg_color = color_pixels[white];
	mask = CWBackPixel | CWBorderPixel | CWColormap |
		CWBackingStore | CWEventMask;
	attrib->background_pixel = bg_color;
	attrib->border_pixel = bd_color;
	attrib->colormap = CopyFromParent;
	attrib->backing_store = WhenMapped;
	attrib->event_mask = KeyPressMask;

	return(mask);
}

unsigned long SetPopAttr(attrib)
XSetWindowAttributes *attrib;
{
	unsigned long mask, bg_color, bd_color;

	/* select attributes for pop_up windows */
	bg_color = color_pixels[white];
	if (color_display == true) 
		bd_color = color_pixels[yellow];
	else 
		bd_color = color_pixels[black];
	mask = CWBackPixel | CWBorderPixel | CWColormap |
		CWOverrideRedirect | CWSaveUnder | CWEventMask;
	attrib->background_pixel = bg_color;
	attrib->border_pixel = bd_color;
	attrib->colormap = CopyFromParent;
	attrib->override_redirect = True;
	attrib->save_under = True;
	attrib->event_mask = 0;

	return(mask);
}

void SetManHints(hints, x, y, width, height)
XSizeHints *hints;
int x, y, width, height;
{
	/* set position and size hints for window manager */
	hints->flags = PPosition | PSize | PMinSize | PMaxSize;
	hints->x = x;
	hints->y = y;
	hints->width = width;
	hints->height = height;
	hints->min_width = width;
	hints->min_height = height;
	hints->max_width = width;
	hints->max_height = height;
}
			
void init_x(argc, argv)
int argc;
char **argv;
{
	int screen,depth;	
	unsigned long man_mask, pop_up_mask;
	Visual *visual;
	XSetWindowAttributes man_attrib, pop_up_attrib;
	XSizeHints man_hints;
	Window root, wind;
	int i,c,border_width, width, height, x, y, start_x, start_y;
	
	if ((disp = XOpenDisplay(NULL)) == NULL)
		err = err_cantConnectX;
	else  {
		if (initfont(&font_info) == err_noError)  {
			screen = DefaultScreen(disp);
			depth = DefaultDepth(disp, screen);
			visual = DefaultVisual(disp, screen);
			initcolors(screen, depth);

			man_mask = SetManAttr(&man_attrib);
			pop_up_mask = SetPopAttr(&pop_up_attrib);

			start_x = 335;
			start_y = 294;
			width  = (x2[full_w] - x1[full_w] + 1) * font_width;
			height = (y2[full_w] - y1[full_w] + 1) * font_height; 

			SetManHints(&man_hints, start_x, start_y, width, height);

			root = DefaultRootWindow(disp);

			wind_list[full_w].x_wind = XCreateWindow(disp, root,
				start_x, start_y, width, height, 0,
				depth, InputOutput, visual, man_mask,
				&man_attrib);

			wind_list[full_w].x_gc = MakeGC(wind_list[full_w].x_wind);
			wind_list[full_w].cur_x_char = 1;
			wind_list[full_w].cur_y_char = 1;

			XSetStandardProperties(disp, wind_list[full_w].x_wind,
				"calce", "calce", None, argv, argc, &man_hints);

			XMapRaised(disp,wind_list[full_w].x_wind);
			cur_wind = full_w;
			XFlush(disp);

			for(i = 1; i <= max_windows-1; i++)  {
				if (draw_border[i] == true)  {
					border_width = 2;
					x = (x1[i] * font_width) - 
					     border_width;
					y = (y1[i] * font_height) -
					     border_width;
					width  = (x2[i] - x1[i] - 1) *
						font_width;
					height = (y2[i] - y1[i] - 1) * 
						font_height; 
				}  else  {
					border_width = 0;
					x = (x1[i] - 1) * font_width;
					y = (y1[i] - 1) * font_height;
					width  = (x2[i] - x1[i] + 1) *
						font_width;
					height = (y2[i] - y1[i] + 1) * 
						font_height; 
				}
				wind_list[i].x_wind = XCreateWindow(disp,
					wind_list[full_w].x_wind,
					x, y, width, height,
					border_width, depth, InputOutput,
					visual, pop_up_mask, &pop_up_attrib);

				wind_list[i].x_gc = MakeGC(wind_list[i].x_wind);
				wind_list[i].cur_x_char = 1;
				wind_list[i].cur_y_char = 1;
			}
		}
	}
}

