/*****************************************************************************
 *
 * File: vgui.c, Fredrik Kling 1997
 * Desc: This file holds all main gui handling routines... (font,drivers,devices etc).
 *
 * Updates:
 * -- Date -- | ----- Name ----- |-- Did what....
 * 1997-08-03 | Fredrik Kling    | Implementation
 *
 * Todo:
 *     ţ Varje f”nster ska ha en xkeylist och en keylist...   <- Done!
 *
 * Dialog boxar:
 *		Todo: Vid anrop till vguidbox_run (int handle) skall gui'et placeras i ett speciellt l„ge
 *				  d„r man inte till†ter taskswitchning etc...  Alla dialog boxar blir 'modal', dvs m†ste avslutas innan ngt annat
 *					kan forts„tta...
 *
 *				  Hantering av app_current, (om vi ska nyttja samma main funktioner som f”r applikationer)
 *					Hantering av dialog_exit, hur ska det se ut och hur ska det fungera praktiskt...
 *
 *          M†ste skriva speciell message_box rutin ocks†....
 *
 *					int vgui_messagebox (char *caption,char *text,int flags);
 *          flags = BUTT_OK, BUTT_NO, BUTT_YES, BUTT_CANCLE etc...
 *
 *          Icon hantering...  <- plocka iconer fr†n n„tet och skapa ett 'icon-lib' mha dbfs... '.vio'
 *
 *
 ****************************************************************************/

#include <stdarg.h>
#include "vgui/vgui.h"
#include "system/xstddef.h"
#include "system/xstdlib.h"
#include "system/xstdio.h"
#include "system/xstring.h"
#include "drivers/drv8.h"
#include "misc/col.h"


DRV *drv;
BUFF *buf;
static VGUICLIST clist;
static RGB palette[256];
static FONT *mfont;
static VGUIMESSAGE u_mbox[MAXMESSAGE],u_sbox[MAXMESSAGE];
static VGUIMESSAGE *mbox,*sbox;
static int vgui_mode = APPFLAG_NORMAL;

static VGUIWIN *activewin;	// This should be a list!!!

static APPLIST *app_first,*app_last,*app_current;

//static int cappstack=0;
//static VGUIWIN *appstack[MAX_APP];

static int xskeynum = 0;
static KEYL xskeylist[]={165,VGS_COMMAND,VGC_MBAR,1,0};		// 165 - Alt+TAB

void vgui_xcopybuff (int x1, int y1, int x2, int y2)
{
	drv->xcopybuff (x1,y1,x2,y2);
}
void vgui_xmovebuff (int x1, int y1, int x2, int y2,int c)
{
	drv->xmovebuff (x1,y1,x2,y2,c);
}
void vgui_copybuff (int a, int b)
{
	drv->copybuff (a,b);
}
void vgui_line (int x1,int y1,int x2,int y2,int c)
{
	XYZ p1,p2;

	p1.x = x1, p1.y = y1;
	p2.x = x2, p2.y = y2;

	drv->line (p1,p2,c);
}
/************************************************************************
 * Func: vgui_bar
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: ritar en "bar"
 *
 ************************************************************************/
void vgui_bar (int x1, int y1, int x2, int y2,int c)
{
	XYZ p1,p2;
	int i;

	p1.x = x1, p1.y = y1;
	p2.x = x2, p2.y = y2;


	p2.y = p1.y;

	for (i=p1.y;i<y2;i++)
	{
		drv->line (p1,p2,c);
		p1.y++,p2.y++;
	}
}
/************************************************************************
 * Func: font handling routines...
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 ************************************************************************/
int vgui_getsxyc (int x1, int y1, int x2, int y2,int c, char *str)
{
	int k1,k2,q,pos,np,d,xp,f;

	// 	q - quit, np - nopost...
	q=np=FALSE;
	xp=pos=0;
	f=1;

	if (str[0]!='\0')
	{
		xp = vgui_printfxyc (x1,y1,VG_CWHITE,"%s",str);
		while (str[pos]!='\0') pos++;
	}

	vgui_line (x1+xp,y1,x1+xp,y1+8,VG_CWHITE);
	vgui_copybuff(0,0);


	while (!q)
	{
		d=0;
		while (vgui_kbhit())
		{
			k2 = 0;
			switch (k1=vgui_getkey())
			{
				case 0 :
							k2 = vgui_getkey ();
							break;
				case VG_KEYESC :
						q = TRUE;
					 	np = TRUE;
						break;
				case VG_KEYENTER :
						q = TRUE;
						break;
				case VG_KEYBSPACE :
						if (f)
						{
							pos=0;
							str[pos]='\0';
							d = 1;
						} else
							if (pos>0)
							{
								pos--;
								str[pos]='\0';
								d=1;
							}
						break;
				default :
						if (k1>31) str[pos++]=k1;
						str[pos]='\0';
						d=1;
						break;
			} // Switch
			f=0;
		} // While
		if (d)
		{
			vgui_bar (x1,y1,x2,y2,VG_CBLACK);
			xp = vgui_printfxyc (x1,y1,VG_CWHITE,"%s",str);
			vgui_line (x1+xp,y1,x1+xp,y1+8,VG_CWHITE);
			vgui_copybuff(0,0);
		}
	} //while
	if (np) return FALSE;
	return TRUE;
}

// Mostly ripped from Igge's lousy code...
// Font handling routines...  prints and loads dp2enh fonts...
int vgui_charwidth (char s)
{
	FONTOFS *ofs;
	int pek;
	pek = (int)mfont[s+1];
	ofs = (FONTOFS *) &((char *)mfont)[pek];
	return ofs -> width;
}
int vgui_strlen (char *s)
{
	int i,l;

	for (l=0,i=0;i<strlen (s);i++) l+=vgui_charwidth (s[i]);
	return l;
}
/************************************************************************
 * Func: vgui_putchxy
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Plottar ut en bokstav p† en viss position p† sk„rmen...
 *
 ************************************************************************/
int vgui_putchxy (int xp, int yp, int c,char s)
{
  int tab[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
	int i,j,x,y;
	XYZ p;
	FONTOFS *ofs;
	int pek;

	pek = (int)mfont[s+1];
	ofs = (FONTOFS *) &((char *)mfont)[pek];

	j=0;
	if (ofs->rows)
	{
		yp += ofs->yoffs;
		p.l=32;

    for (y=0; y<ofs->rows; y++)
      for (x=0; x<ofs->cols; x++)
      {
        for (i=0; i<8; i++)
				{
					if ((x*8+i)<ofs->width)
          	if (ofs->data[j]&tab[i])
						{
							p.x=xp+x*8+i;
							p.y=yp+y;
							drv->plot(p,c);
						}
				}
        j++;
      }
	}
	return ofs->width;
}
/************************************************************************
 * Func: vgui_outstrxy
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Skriver ut en oformaterad str„ng..  internally use only!
 *
 ************************************************************************/
int vgui_outstrxy (int x, int y,int c, char *s)
{
	int i,xp;
	xp=0;
	for (i=0;i<strlen(s);i++)
	{
		if ((int)s[i]>=32)
		{
				xp+=vgui_putchxy (x+xp,y,c,s[i]);
		} else
				switch (s[i])
				{
					case '\n' : 	// Newline
							y+=10,xp=0;
							break;
				}

//		xp+=vgui_putchxy (x+xp,y,c,s[i]);
	}
	return xp;
}
/************************************************************************
 * Func: vgui_printfxy
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Printar ut en formaterad str„ng p† sk„rmen...
 *
 ************************************************************************/
int vgui_printfxy (int x,int y,char *str, ...)
{
	va_list values;
	char newstr[1024];
	int xp;

	if (!mfont) return 0;

	va_start( values, str );
	vsprintf( newstr, str, values);
	va_end( values);
	xp = vgui_outstrxy (x,y,255,newstr);

//	vgui_postmessage (VGS_UPDATE,0,0,0);

	return xp;
}
/************************************************************************
 * Func: vgui_printfxyc
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Printar ut en formaterad str„ng p† sk„rmen med en f„rg...
 *
 ************************************************************************/
int vgui_printfxyc (int x,int y,int c,char *str, ...)
{
	va_list values;
	char newstr[1024];
	int xp;

	if (!mfont) return 0;

	va_start( values, str );
	vsprintf( newstr, str, values);
	va_end( values);
	xp = vgui_outstrxy (x,y,c,newstr);

//	vgui_postmessage (VGS_UPDATE,0,0,0);

	return xp;
}
FONT *vgui_loadfont (char *s)
{
	FONT *font;

  mfont = font = (FONT *) fload (s,NULL);
	return font;
}
/************************************************************************
 * Func: vgui_command
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: System command handling...
 *
 ************************************************************************/
int vgui_command (int com, int p1, int p2)
{
	switch (com)
	{
		case VGC_MBAR : vguimbar_choice (p1);
										return TRUE;
										break;
		case VGC_CHECK :
//		case VGC_STRING :
		case VGC_LISTBOX :
		case VGC_SBOX :
		case VGC_BUTTON :
											if (p1!=p2)
											{
												vguigad_draw (p2);
												vguigad_highlight (p1);
											} else
											{
												vguigad_select (p1);
											}
											return TRUE;
											break;
		case VGC_SLIDE :
		default:	return FALSE;
						break;
	}
	return FALSE;
}
int vgui_getcol (int col)
{
	return (clist.ci[col]);
}
//=======================================================================================================
/************************************************************************
 * Func: app_listadd_set
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Application list mangeing routines...
 *
 ************************************************************************/
static void app_listadd_set (APPLIST *app,VGUIWIN *win,int flags)
{
	app -> win = win;
	app -> flags = flags;
}
/************************************************************************
 * Func: app_listadd
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Adds an application in gui's application list...
 *
 ************************************************************************/
static APPLIST * app_listadd (VGUIWIN *win, int c)
{
	APPLIST *app;
	if (app_first==NULL)
	{
		app = (APPLIST *)xmalloc (sizeof (APPLIST));
		app->next = NULL;
		app->prev = NULL;
		app_first = app;
		if (c) app_current = app_first;
		app_last = app_first;
	} else
		{
			app = (APPLIST *)xmalloc (sizeof (APPLIST));
			app -> next = app_first;
			app_first -> prev = app;
			app -> prev = NULL;
			if (c) app_current = app;
			app_first = app;
		}
//	app -> win = win;
	return app;
}
/************************************************************************
 * Func: app_appfrmhand
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Get an application pointer from its handle...
 ************************************************************************/
static APPLIST *app_appfrmhand (int handle)
{
	APPLIST *app;

	for (app=app_first;app!=NULL;app=app->next)
	{
		if (vgui_mode != APPFLAG_DIALOG)
		{
			if (app -> flags & APPFLAG_NORMAL)
				if (app -> win -> handle == handle) return app;
		} else if (app -> flags & APPFLAG_DIALOG) if (app -> win -> handle == handle) return app;
	}

	return NULL;
}
/************************************************************************
 * Func: app_dboxfrmhand
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Gets an dialogbox from its handle... dialogs and application
 *			 have the same structure and are placed in the same list...
 *
 ************************************************************************/
APPLIST *app_dboxfrmhand (int handle)
{
	APPLIST *app;

	for (app=app_first;app!=NULL;app=app->next)
		if (app -> flags & APPFLAG_DIALOG)
			if (app -> win -> handle == handle) return app;

	return NULL;
}
/************************************************************************
 * Func: app_getcurrent
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Returns current application...  This function shouldn't be
 *			 used by applications
 *
 ************************************************************************/
APPLIST *app_getcurrent (int *status)
{
	*status = vgui_mode;
	return (app_current);
}
/************************************************************************
 * Func: app_setcurrent
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Set's current application...  This is an internal function ONLY!
 *
 ************************************************************************/
void app_setcurrent (APPLIST *app,int status)
{
	vgui_mode = status;
	app_current = app;
}
static void app_listdel (int handle)
{

}
static void app_nextapp (void)
{
	vguiwin_inactivate (app_current->win);

	if (app_current->next!=NULL) app_current = app_current->next;
		else app_current = app_first;

	if (app_current->flags & APPFLAG_DIALOG)
	{
		if (app_current->next!=NULL) app_current = app_current->next;
			else app_current = app_first;
	}

	vgui_postmessage (VG_HELLOW,0,0,0);
	vgui_postmessage (VGS_REDRAW,0,0,0);
}
static void app_listactivate (int handle)
{
	APPLIST *app;

	app = app_appfrmhand (handle);
	app_current = app;

}
//=======================================================================================================
//  Message handling routines....
static int top=0,num=0;
static int mtop=0,stop=0;
/************************************************************************
 * Func: vgui_postmessage
 * Auth: Fredrik Kling
 * Date: 1997-08-04 - Implementation
 *
 * Desc: Message handling from windowsystem...
 *
 ************************************************************************/
int vgui_postmessage (int m, int p1, int p2, int p3)
{
	VGUIWIN *win = vgui_activewin ();

	if (mtop>MAXMESSAGE) return FALSE;
	mbox[mtop].message=m;
	mbox[mtop].handle = win->handle;
	mbox[mtop].p1=p1;
	mbox[mtop].p2=p2;
	mbox[mtop].p3=p3;
	mtop++;
	return TRUE;
}
int vgui_spawnmessagebox (void)
{
	int m_update = 0,m_redraw = 0;
	int mtmp;
	VGUIWIN *win;
	APPLIST *app;

	VGUIMESSAGE *tmp;
	VGUIGADGET *gad;

	tmp = sbox;
	sbox = mbox;
	mbox = tmp;

	stop = mtop;
	mtop = 0;


	while (stop)
	{
		stop--;
		switch (sbox[stop].message)
		{
			case VGS_GADREDRAW :
					gad = vguigad_gadfrmhand (sbox[stop].p1);
					drv->xmovebuff (gad->x1,gad->y1,gad->x2,gad->y2,VG_CBLACK);
					break;
			case VGS_GADUPDATE :
					gad = vguigad_gadfrmhand (sbox[stop].p1);
					drv->xcopybuff (gad->x1,gad->y1,gad->x2,gad->y2);
					break;
			case VGS_EXIT :
					return 0;
			case VGS_UPDATE :
					m_update = 1;
					break;
			case VGS_REDRAW :
					m_redraw = 1;
					break;
			case VGS_COMMAND :
					vgui_command (sbox[stop].p1,sbox[stop].p2,sbox[stop].p3);
					break;
			case VGS_SWITCHAPP :
					if (vgui_mode != APPFLAG_DIALOG)	app_nextapp ();
					break;
			default :
					app = app_appfrmhand (sbox[stop].handle);
					if (app!=NULL)
					{
						win = app->win;
						win->vgui_main (sbox[stop].message,sbox[stop].p1,sbox[stop].p2,sbox[stop].p3);
					}
					break;
		}
	}
	if (m_update)
	{
		drv->vsync ();
		drv->setbuff (buf);
		drv->copybuff (0,0);
	}
	if (m_redraw) vguiwin_update (NULL);
	return 1;
}
int vgui_peekmessage (int handle, int *m, int *p1, int *p2, int *p3)
{
	return TRUE;
}
void vgui_zapmbox (void)
{
	stop=0;
	mtop=0;
}
int vgui_registerdbox (VGUIDBOX *dbox)
{
	APPLIST *app;
	app = app_listadd ((VGUIWIN *)dbox,FALSE);
	app -> win = (VGUIWIN *) dbox;
	app -> flags = APPFLAG_DIALOG;
	return TRUE;
}
/************************************************************************
 *
 * Func: vgui_register
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: Registrerar ett f”nster...  (ska skrivas om som lista...)
 *
 ************************************************************************/
int vgui_register (VGUIWIN *win)
{
	APPLIST *app;
	activewin = win;
	app = app_listadd (win,TRUE);

	app -> win = win;
	app -> flags = APPFLAG_NORMAL;

//	app_listadd_set (app_current,win,APPFLAG_NORMAL);

	vgui_postmessage (VG_HELLOW,0,0,0);


	return TRUE;
}
/************************************************************************
 *
 * Func: vgui_dispose
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: Registrerar ett f”nster...  (ska skrivas om som lista...)
 *
 ************************************************************************/
//void vgui_dispose

VGUIWIN *vgui_activewin (void)
{
	//return activewin;
	return app_current->win;
}
/************************************************************************
 *
 * Func: vgui_addtabstop
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: Adderar tab stop grejja till listan...
 *
 ************************************************************************/
void vgui_addtabstop (int mess, int p1, int p2, int p3)
{
	VGUIWIN *win = vgui_activewin ();
	win->tablist[win->tabnum].key = 0;	// Not used...
	win->tablist[win->tabnum].mess = mess;
	win->tablist[win->tabnum].p1 = p1;
	win->tablist[win->tabnum].p2 = p2;
	win->tablist[win->tabnum].p3 = p3;
	win->tabnum++;
}

/************************************************************************
 *
 * Func: vgui_setxkeylist
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: S„tter Xtended keylist tabellen...
 *
 ************************************************************************/
KEYL *vgui_setxkeylist (KEYL *keyl,int num)
{
	VGUIWIN *win=vgui_activewin ();
	int i;


	win->xkeynum = num;
	for (i=0;i<num;i++)
		win->xkeylist[i] = keyl[i];

	return NULL;
}
KEYL *vgui_clearxkeylist (void)
{
	VGUIWIN *win=vgui_activewin ();
	win->xkeynum = 0;
	return NULL;

}
/************************************************************************
 *
 * Func: vgui_inkeylist
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: Kolla om tangenten har registreats...
 *       Eller om den „r en system tangent...
 *
 ************************************************************************/
int vgui_inkeylist (int k1, int k2)
{
	VGUIWIN *win = vgui_activewin ();
	int i,op;
	// Extended key?
	if (k1==0)
	{
		switch (k2)
		{
			case VG_XKEY_ALT_TAB :
					if (vgui_mode != APPFLAG_DIALOG)	vgui_postmessage (VGS_SWITCHAPP,0,0,0);
					break;

			case VG_XKEYSHBSPACE :
					if (win->tabnum>0)
					{
						op = win->tabpos;
						win->tabpos--;
						if (win->tabpos<0) win->tabpos=win->tabnum-1;
						vgui_postmessage (win->tablist[win->tabpos].mess,win->tablist[win->tabpos].p1,win->tablist[win->tabpos].p2,win->tablist[op].p2);
						return TRUE;
					}
					break;
			default :
					for (i=0;i<win->xkeynum;i++)
					if (win->xkeylist[i].key == k2)
					{
						vgui_postmessage (win->xkeylist[i].mess,win->xkeylist[i].p1,win->xkeylist[i].p2,win->xkeylist[i].p3);
						return TRUE;
					}
					break;
		} // switch...
	} else
			switch (k1)
			{
				case VG_KEYTAB : // Tab
						if (win->tabnum>0)
						{
							op=win->tabpos;
							win->tabpos ++;
							if (win->tabpos>=win->tabnum) win->tabpos=0;
							vgui_postmessage (win->tablist[win->tabpos].mess,win->tablist[win->tabpos].p1,win->tablist[win->tabpos].p2,win->tablist[op].p2);
							return TRUE;
						}
						break;
				case VG_KEYSPACE : //SPACE
						if (win->tabnum>0)	vgui_postmessage (win->tablist[win->tabpos].mess,win->tablist[win->tabpos].p1,win->tablist[win->tabpos].p2,win->tablist[win->tabpos].p2);
						return TRUE;
						break;
			} // Switch

	return FALSE;
}
/************************************************************************
 *
 * Func: vgui_kbhit,vgui_getkey
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: interface mot drivrutiner
 *
 ************************************************************************/
int vgui_kbhit (void)
{
	return (drv->kbhit());
}
int vgui_getkey (void)
{
	return (drv->getkey());
}

/************************************************************************
 *
 * Func: vgui_checkkeys
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: Checks for all kind of keystrokes..
 *
 ************************************************************************/
void vgui_checkkeys (void)
{
	int mess = VG_KEYPRESS;
	int p1,p2,c;

	p1 = p2 = 0;
	while( drv->kbhit())
	{
		switch(c=drv->getkey())
		{
			case 0: p1 = 0;
							p2 = drv->getkey ();
						  break;
			case 27 : mess = VGS_EXIT;
								p1 = -1;
								p2 = -1;
								break;
			default : p1 = c;
								break;
		}
		if (!vgui_inkeylist (p1,p2)) vgui_postmessage (mess,p1,p2,0);
	}
}
/************************************************************************/
static void fillclist (void)
{

}
static int setupcolor (void)
{

// Fill in the colors we support in the bloody system...

	palette[VG_CDARK].r = 20 << 2;
	palette[VG_CDARK].g = 20 << 2;
	palette[VG_CDARK].b = 20 << 2;

	palette[VG_CMEDIUM].r = 32 << 2;
	palette[VG_CMEDIUM].g = 32 << 2;
	palette[VG_CMEDIUM].b = 32 << 2;

	palette[VG_CLIGHT].r = 58 << 2;
	palette[VG_CLIGHT].g = 58 << 2;
	palette[VG_CLIGHT].b = 58 << 2;

	palette[VG_CMBLUE].r = 12 << 2;
	palette[VG_CMBLUE].g = 8  << 2;
	palette[VG_CMBLUE].b = 48 << 2;

	palette[VG_CDBLUE].r = 4 << 2;
	palette[VG_CDBLUE].g = 2  << 2;
	palette[VG_CDBLUE].b = 12 << 2;

	palette[VG_CLGREEN].r = 24 << 2;
	palette[VG_CLGREEN].g = 63  << 2;
	palette[VG_CLGREEN].b = 20 << 2;

	palette[VG_CMGREEN].r = 12 << 2;
	palette[VG_CMGREEN].g = 48 << 2;
	palette[VG_CMGREEN].b = 8 << 2;

	palette[VG_CDGREEN].r = 8 << 2;
	palette[VG_CDGREEN].g = 24  << 2;
	palette[VG_CDGREEN].b = 4 << 2;

	palette[VG_CLYELLOW].r = 63 << 2;
	palette[VG_CLYELLOW].g = 63 << 2;
	palette[VG_CLYELLOW].b = 20 << 2;

	palette[VG_CMYELLOW].r = 48 << 2;
	palette[VG_CMYELLOW].g = 48 << 2;
	palette[VG_CMYELLOW].b = 12 << 2;

	palette[VG_CDYELLOW].r = 24 << 2;
	palette[VG_CDYELLOW].g = 24  << 2;
	palette[VG_CDYELLOW].b = 8 << 2;

	palette[VG_CLRED].r = 63 << 2;
	palette[VG_CLRED].g = 24  << 2;
	palette[VG_CLRED].b = 20 << 2;

	palette[VG_CMRED].r = 48 << 2;
	palette[VG_CMRED].g = 12 << 2;
	palette[VG_CMRED].b = 8 << 2;

	palette[VG_CDRED].r = 24 << 2;
	palette[VG_CDRED].g = 8  << 2;
	palette[VG_CDRED].b = 4 << 2;

	palette[VG_CWHITE].r = 63 << 2;
	palette[VG_CWHITE].g = 63 << 2;
	palette[VG_CWHITE].b = 63 << 2;

  drv->setpalette( palette);
	return TRUE;
}

static int setupdriver (DRV *drv)
{
	int i;

	if (!drv->setup ())
	{
    printf ("[!] Error: Driver setup failed!\n");
		exit (1);
	} else {
           printf("ţ Available modes:\n");
					 for( i=0; i<drv->modes; i++)
             printf("  - %dx%d\n", drv->modelist[i].width, drv->modelist[i].height);
				 }

  //if(!drv->init(drv->modelist[0].width, drv->modelist[0].height, DRVCFG_ZBUFFER))
	if(!drv->init(drv->modelist[0].width, drv->modelist[0].height, 0))
	{
    printf("[!] Error: Unable to initilize %s.(%s)\n", drv->name, drv->geterror());
		exit(0);
	}
  if (!drv->mouseinit( 0, 0, drv->width - 1, drv->height - 1))
	{
		drv->exit();
    printf("[!] Error: Unable to initilize mousedriver.\n");
		exit(0);
	}
  buf = drv->createbuff( drv->width, drv->height);
	drv->setbuff( buf);

	return TRUE;
}
/************************************************************************
 *
 * Func: vgui_init
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: Initierar f”nster systemet....
 *
 ************************************************************************/
int vgui_init (DRV *driver, int reinit)
{
  mfont = vgui_loadfont ("fonts\\system8.fnt");
	app_first = app_last = app_current = NULL;

	mbox = u_mbox;
	sbox = u_sbox;

	if (reinit == VG_INIT)
	{
		return (setupdriver (driver));
	} else {
				   drv = driver;
					 buf = drv->activebuff;
					 setupcolor ();
					 fillclist ();
				 }
	//drv->mousecallback (vgui_mousemove);  // This function is not yet implemented...
	return TRUE;
}
DRV *vgui_getdriver (void)
{
	return drv;
}
/************************************************************************
 *
 * Func: vgui_main
 * Auth: Fredrik Kling
 * Date: 1997-08-03 - Implementation
 *
 * Desc: The main routine for the interface...
 *
 ************************************************************************/
int vgui_main (void)
{
	int q=FALSE;
	while (!q)
	{
		vgui_checkkeys ();
		if (!vgui_spawnmessagebox ()) q=TRUE;
	}
	return 0;
}
