/*-----------------------------------------------------------------------

	Wega 1.00 - Demonstrationsprogramm   (c) 1991/92 by D. Rabich
	==================================   Alle Rechte vorbehalten!

	Das Demonstrationsprogramm demonstriert F„higkeiten der Bibliothek
	Wega. Die Bibliothek ist in erster Linie als einfache Untersttzung
	fr GEM-Programme gedacht. Es erweitert die Objekttypen u. a. um

		-	fette Texte
		-	unterstrichene Texte
		-	Groupboxen (Rahmen mit Titel)
		-	Radiobuttons (runde Kn”pfe, Text auch w„hlbar)
		-	Selectbuttons (Kreuzchen, Text auch w„hlbar)
		-	einheitliche Titel
		-	verschiebbare Dialogboxen
		-	eigene Hintergrundrestaurierung
		-	PopUp-Mens
		-	Cyclebuttons
		-	Arrows

	Ferner sorgt eine eigene form_do()-Routine fr komfortablere
<	Editfelder (z.B. <Control/Shift>+<Cursor links/rechts> sowie
	<Shift>+<Tab>) und die M”glichkeit, eine Tastatursteuerung
	zu implementierten (hier im Demo <Alternate>+<1/2/C>, <Help>,
	<F7> und <F8>).

	Das Wega-Developer Kit wird nach dem Sharewareprinzip weiter-
	gegeben. Eine Nutzung zu Testzwecken ist bis zu 21 Tage nach
	der Installation gestattet. Bei einer weitergehenden Nutzung
	ist der Sharewareobolus in H”he von 100 DM zu entrichten.

	Mit Wega entwickelte Programme mssen die GEM-Richtlinien wie sie
	im Atari ST/STE/TT-Profibuch aufgefhrt sind einhalten. Ferner sind
	die zus„tzlichen Wega-Richtlinien zu bercksichtigen. Dem Autor von
	Wega ist ein kostenloses Belegexemplar zu bersenden.

	Autor von Wega bzw. Wega Developer Kit ist

	Dietmar Rabich,
	Tel. & Fax +49 2594 86103,
	Koppelbusch 37, D-W4408 Dlmen-Hausdlmen.


											Dlmen, im Januar 1993.

-----------------------------------------------------------------------*/

/* Standardbibliotheken */
#include <stddef.h>
#include <stdio.h>
#include <tos.h>

/* Wegabibliothek */
#include <wega.h>

/* Resourcemakros */
#include "resource.h"
#include "windemo.h"

#include "..\handling\handling.h"
#include "global.h"
#include "redraw.h"


/* Name des Programms */
#define	FULLAPPNAME	"Wegawindemo"
#define	APPNAME		"WEGADEMO"
#define	INFAME		APPNAME ".INF"

/* Alertboxen und Texte */
#define	NOACC		"[3][ Das Accessory |"		\
						" " FULLAPPNAME " |"	\
						" konnte nicht|"		\
						" angemeldet werden.|"	\
						" ][ OK ]"
#define	NOVDI		"[3][ |"					\
						" Initialisierung |"	\
						" der Workstation |"	\
						" erfolglos!!|"			\
						" ][ OK ]"
#define	NOWINDOW	"Es kann leider kein Fenster mehr ge”ffnet"	\
					" werden! Schliežen Sie bitte erst ein anderes."
#define	NOAES		"Initialisierung von " FULLAPPNAME " erfolglos!\a"
#define NOAUTO		"Das Programm " FULLAPPNAME " kann nicht\n"	\
					"aus dem AUTO-Ordner gestartet werden!\a"

/* Accessory- und Windowname */
#define	ACCNAME		"  " FULLAPPNAME "..."
#define	WINDOWNAME	" " FULLAPPNAME " "

/* Anzahl der Eintr„ge im PopUp-Men */
#define	NMB_ENTRIES		3
#define	NMB_ENTRIES2	4

#define	OPENHELP		0x5432

/* Flags fr die Windows */
#define	WINDOWFLAGS		NAME | CLOSER | MOVER

/* Anzahl erlaubter Windows */
#define	NMB_WINDOWS		2

/* sonstige */
#define	NIL				-1


/* Funktionsmakros */
#define	TuneHorizontalSlider(tree, full, back, left, right)			\
						{											\
							GListInit(tree, full);					\
							tree[right].ob_x	=					\
								tree[full].ob_width -				\
								tree[right].ob_width;				\
							tree[back].ob_x		=					\
								tree[left].ob_width - 1;			\
							tree[back].ob_width	=					\
								tree[full].ob_width -				\
								tree[left].ob_width -				\
								tree[right].ob_width + 2;			\
						}
#define	TuneVerticalSlider(tree, full, back, up, down)				\
						{											\
							GListInit(tree, full);					\
							tree[down].ob_y	=						\
								tree[full].ob_height -				\
								tree[down].ob_height;				\
							tree[back].ob_y		=					\
								tree[up].ob_height - 1;				\
							tree[back].ob_height	=				\
								tree[full].ob_height -				\
								tree[up].ob_height -				\
								tree[down].ob_height + 2;			\
						}
#define	max(x, y)		(((x) < (y)) ? (y) : (x))
#define	min(x, y)		(((x) > (y)) ? (y) : (x))
#define	objc_grect(r, tree, obj)									\
						{											\
							r	= *(GRECT*)&(tree[obj].ob_x);		\
							objc_offset(tree, obj, &r.g_x, &r.g_y);	\
						}


/* Typen */
typedef struct
{
	WORD	popsret[2];
	CHAR	field1[10];
	CHAR	field2[10];
	CHAR	field3[18];
	WORD	slidepos;
	struct
	{
		UWORD	checked	: 1;
		UWORD	radio	: 1;
	}	bits;
}	PARAMETER;


/* Parameter */
static PARAMETER	parameter =
					{
						{0, 0},
						"Dieses",
						"sind die",
						"Editfelder.",
						5,
						{0, 1}
					},
					lpara;				/* fr Zwischenspeicherung */

/* Texte fr PopUp-Men */
static CHAR			*entries[] =
					{
						"grožartig",
						"prima",
						"erstklassig"
					},
					*entries2[] =
					{
						"gut",
						"besser",
						"noch besser",
						"am besten"
					};

/* Eintr„ge fr Slider */
static CHAR			*months[]	=
					{
						"Jan.",
						"Feb.",
						"M„rz",
						"Apr.",
						"Mai",
						"Juni",
						"Juli",
						"Aug.",
						"Sep.",
						"Okt.",
						"Nov.",
						"Dez."
					};

/* lokale Variablen */
WORD			colors		= 0;		/* verfgbare Farben			*/
static WORD		helpcolor	= RED,		/* Farbe fr Hilfsdialogtext	*/
				applid;					/* Application-ID				*/
static BOOLEAN	rsc_initialized	= FALSE,	/* Resourceinitialisierung	*/
				wega_init		= FALSE;	/* Wega-Initialisierung		*/


/* Prototypen */
static BOOLEAN	openvwk(VOID);
static VOID		closevwk(VOID);
static WORD		hdletoinx(WORD);
static BOOLEAN	init_resources(VOID);
static WORD		openwindow(DLGINFO*);

static LONG		timerinfo(VOID*);
static VOID		openhelp(WININFO*);
static VOID		closehelp(WININFO*, BOOLEAN);
static BOOLEAN	do_help(WININFO*, WORD*, BOOLEAN*);

static VOID		do_undo(WININFO*);
static BOOLEAN	whichradio(OBJECT*, WORD, VOID*);
static VOID		slidedraw(SLIDERINFO*);
static WORD		translate(KEY*, VOID*);
static VOID		prepare(WININFO*);
static VOID		release(WININFO*);
static VOID		openmain(WININFO*);
static VOID		closemain(WININFO*, BOOLEAN);
static BOOLEAN	do_it(WININFO*, WORD*, BOOLEAN*);

WORD			main(VOID);


static SLIDERINFO	sli	=
					{
						0,
						11,
						1,
						3,	/* in der Regel = visible - 1 */
						0,
						0,
						NULL,
						GSLIDER,
						SLBACK,
						SLIDER,
						SLLEFT,
						SLRIGHT,
						(VOID(*)(WORD, VOID*))0L,
						slidedraw,
						(VOID*)months
					};

/* Windowinformationen */
WININFO			wininfo[] =
				{
					{
						NULL, {0}, NIL,
						openmain, closemain, do_it,
						&parameter
					},
					{
						NULL, {0}, NIL,
						openhelp, closehelp, do_help,
						NULL
					}
				};


/* ----------------------------------------------------------------------- */

/* virtuelle Workstation ”ffnen */
static BOOLEAN openvwk(VOID)
{
	wega_init	= GWegaInit();

	if(!wega_init)
	{
		form_alert(1, NOVDI);
		if(ACCESSORY)
			for(;;)
			{
				WORD	msg[8];

				evnt_mesag(msg);
			}
		return(FALSE);
	}

	if(!rsc_initialized)
	{
		if(!init_resources())
			return(FALSE);
		rsc_initialized	= TRUE;
	}
	return(TRUE);
}


/* virtuelle Workstation schliežen */
static VOID closevwk(VOID)
{
	if(wega_init)
		GWegaDone();

	wega_init	= FALSE;
}


/* Index zum Handle bestimmen */
static WORD hdletoinx(WORD handle)
{
	register WORD	i;

	for(i = 0; i < NMB_WINDOWS; i++)
		if(wininfo[i].handle == handle)
			return(i);

	return(NIL);
}


/* Resourcen vorbereiten */
static BOOLEAN init_resources(VOID)
{
	/* Resourcen */
	if(!rsc_init())
		return(FALSE);

	{
		GRECT		gr_start;	/* Rechteck fr Rechtecke		*/

		/* Startrechteck ermitteln */
		wind_get(0, WF_WORKXYWH,
				 &(gr_start.g_x), &(gr_start.g_y),
				 &(gr_start.g_w), &(gr_start.g_h));
		gr_start.g_x = gr_start.g_x + gr_start.g_w / 2 - 8;
		gr_start.g_y = gr_start.g_y + gr_start.g_h / 2 - 8;
		gr_start.g_w =
		gr_start.g_h = 16;

		/* Dialog vorbereiten (nur einmal!!!) */
		GDialInit(wininfo[MAIN].tree, &gr_start, NULL,
					&wininfo[MAIN].dlginfo);
		GDialInit(wininfo[HELP].tree, &gr_start, NULL,
					&wininfo[HELP].dlginfo);

		/* Slider vorbereiten */
		TuneHorizontalSlider(wininfo[MAIN].tree,
								GSLIDER, SLBACK, SLLEFT, SLRIGHT);

		/* Sliderinformation vorbereiten */
		sli.tree	= wininfo[MAIN].tree;
	}
	return(TRUE);
}


/* ™ffne Window */
static WORD openwindow(DLGINFO *di)
{
	WORD handle;

	/* Dialog zentrieren (bezglich Bildschirm) */
	GDialCenter(di, CNTR_SCREEN, NULL);

	{
		GRECT		size;

		/* Window anlegen und ”ffnen */
		wind_calc(WC_BORDER, WINDOWFLAGS,
					di->tree->ob_x,
					di->tree->ob_y,
					di->tree->ob_width,
					di->tree->ob_height,
					&size.g_x, &size.g_y, &size.g_w, &size.g_h);
		handle	= wind_create(WINDOWFLAGS,
									size.g_x, size.g_y, size.g_w, size.g_h);
		if(handle < 0)
		{
			if(GDoAlert(GBitblkStopsign(),
						NOWINDOW,
						" [OK ",
						0,
						FALSE) < 0)
				Bconout(2, '\a');
			return(NIL);
		}

		/* Namen fr Fenster setzen und Fenster ”ffnen */
		wind_set(handle, WF_NAME, WINDOWNAME);
		wind_open(handle, size.g_x, size.g_y, size.g_w, size.g_h);
	}

	return(handle);
}


/* ----------------------------------------------------------------------- */

/* Timer-Funktion fr Hilfedialog */
#pragma warn -par
static LONG timerinfo(VOID* data)
{
	if(colors < 4)
		helpcolor = (helpcolor == WHITE) ? BLACK : WHITE;
	else
	{
		helpcolor++;
		if(helpcolor >= min(colors, 16))
			helpcolor	= RED;
	}

	{
		WORD	*tcolor;

		tcolor	= &wininfo[HELP].tree[QUESTION].ob_spec.tedinfo->te_color;

		*tcolor	&= 0xF0FF;
		*tcolor	|= helpcolor << 8;
	}

	{
		GRECT	invalid;

		objc_grect(invalid, wininfo[HELP].tree, QUESTION);
		win_objc_draw(wininfo[HELP].handle, wininfo[HELP].tree,
						QUESTION, &invalid);
	}

	return(500L);
}
#pragma warn .par


/* Hilfedialog ”ffnen */
static VOID openhelp(WININFO *wi)
{
	wi->handle	= openwindow(&wi->dlginfo);

	if(wi->handle < 0)
	{
		wi->handle	= NIL;
		return;
	}
	GMArrow();
}


/* Hilfedialog schliežen */
#pragma warn -par
static VOID closehelp(WININFO *wi, BOOLEAN save_it)
{
	if(wi->handle < 0)
		return;

	wind_close(wi->handle);
	wind_delete(wi->handle);
}
#pragma warn .par


/* Hilfedialog */
#pragma warn -par
static BOOLEAN do_help(WININFO *wi, WORD *msg, BOOLEAN *si)
{
	WORD	ret;					/* Return-Button		*/
	LONG	edit	= (LONG)ROOT;	/* Start fr Editfelder	*/

	/* Dialog durchfhren */
	ret		= GXFormDo(wi->tree,
						&edit,
						(WORD(*)(KEY*, VOID*))0L,
						timerinfo,
						msg,
						wi->handle,
						NULL,
						NULL);

	/* Message? */
	if(ret == NIL)
		return(TRUE);

	GChgState(MakeObj(wi->tree, ret), SELECTED, MODE_DELETE);

	return(FALSE);
}
#pragma warn .par


/* ----------------------------------------------------------------------- */

/* Sliderausgabe */
static VOID slidedraw(SLIDERINFO *sli)
{
	/* passenden Text setzen */
	GSetText(MakeObj(wininfo[MAIN].tree, SLSHOW),
				"%-4s",
				((CHAR**)sli->data)[sli->current]);

	/* Objekt neu ausgeben */
	GObjcDraw(wininfo[MAIN].tree, SLSHOW);
}


/* Einstellungen rckg„ngig machen */
static VOID do_undo(WININFO *wi)
{
	lpara	= *(PARAMETER*)wi->individuell;
	prepare(wi);

	GObjcDraw(wi->tree, ROOT);
}


/* Tastenbersetzung fr Hauptdialog */
#pragma warn -par
static WORD translate(KEY *k, VOID *data)
{
	if(k->state.scancode)
		switch(k->key)
		{
			case KEY_F7:
				return(SLLEFT);

			case KEY_F8:
				return(SLRIGHT);

			case KEY_HELP:
				return(BHELP);

			case KEY_UNDO:
				return(BUNDO);
		}

	return(-1);
}
#pragma warn .par


/* Suche nachgew„hltem Radiobutton */
static BOOLEAN whichradio(OBJECT *tree, WORD obj, VOID *data)
{
	WORD	*wradio;

	wradio	= (WORD*)data;

	if((tree[obj].ob_flags & RBUTTON) &&
		(tree[obj].ob_state & SELECTED))
	{
		*wradio	= obj;
		return(TRUE);
	}

	return(FALSE);
}


/* Vorbereitungen */
static VOID prepare(WININFO *wi)
{
	OBJECT	*tree;

	tree	= wi->tree;

	/* Text fr PopUp setzen */
	GSetText(MakeObj(tree, POPUP1), entries[parameter.popsret[0]]);
	GSetText(MakeObj(tree, POPUP2), entries2[parameter.popsret[1]]);

	/* Editfelder vorbelegen */
	GSetText(MakeObj(tree, EDFIELD1), parameter.field1);
	GSetText(MakeObj(tree, EDFIELD2), parameter.field2);
	GSetText(MakeObj(tree, EDFIELD3), parameter.field3);

	/* Text fr Slideranzeige */
	sli.current	= parameter.slidepos;
	GSetText(MakeObj(tree, SLSHOW), "%-4s",
				((CHAR**)sli.data)[sli.current]);
	hdle_slider(&sli, INITIAL);

	/* Checkbutton */
	GChgState(MakeObj(tree, CHECK), SELECTED,
				parameter.bits.checked ? MODE_SET : MODE_DELETE);

	/* Radiobutton */
	GChgState(MakeObj(tree, RADIO1), SELECTED,
				parameter.bits.radio ? MODE_SET : MODE_DELETE);
	GChgState(MakeObj(tree, RADIO2), SELECTED,
				parameter.bits.radio ? MODE_DELETE : MODE_SET);
}


/* Nachbereitungen */
static VOID release(WININFO *wi)
{
	OBJECT	*tree;

	tree	= wi->tree;

	GGetText(MakeObj(tree, EDFIELD1), parameter.field1);
	GGetText(MakeObj(tree, EDFIELD2), parameter.field2);
	GGetText(MakeObj(tree, EDFIELD3), parameter.field3);

	{
		WORD	wradio;

		wradio	= NIL;
		GChildWalk(tree, GROUP, whichradio, &wradio);
		switch(wradio)
		{
			case RADIO1:
				parameter.bits.radio	= 1;
				break;

			case RADIO2:
				parameter.bits.radio	= 0;
				break;
		}
	}

	parameter.bits.checked	= (tree[CHECK].ob_state & SELECTED) ? 1 : 0;

	parameter.slidepos	= sli.current;
}


/* Hauptdialog ”ffnen */
static VOID openmain(WININFO *wi)
{

	wi->handle	= openwindow(&wi->dlginfo);

	if(wi->handle < 0)
	{
		wi->handle	= NIL;
		return;
	}

	/* Dialog vorbereiten und ausgeben */
	lpara	= *(PARAMETER*)wi->individuell;
	prepare(wi);

	GMArrow();
}


/* Hauptdialog schliežen */
static VOID closemain(WININFO *wi, BOOLEAN save_it)
{
	if(wi->handle < 0)
		return;

	if(save_it)
	{
		*(PARAMETER*)wi->individuell	= lpara;
		release(wi);
	}

	wind_close(wi->handle);
	wind_delete(wi->handle);
}


/* Hauptdialog */
static BOOLEAN do_it(WININFO *wi, WORD *msg, BOOLEAN *si)
{
	WORD		ret;					/* Return-Button		*/
	LONG		edit	= (LONG)ROOT;	/* Start fr Editfelder	*/
	BOOLEAN		doppel;					/* Doppelklick			*/
	OBJECT		*tree;

	tree	= wi->tree;
	*si		= FALSE;

	{
		/* Schleife, bis OK, Abbruch oder Hilfe gew„hlt wurde */
		for(;;)
		{
			/* Dialog durchfhren */
			ret			= GXFormDo(tree,
									&edit,
									translate,
									(LONG(*)(VOID*))0L,
									msg,
									wi->handle,
									NULL,
									NULL);

			/* Message? */
			if(ret == NIL)
				return(TRUE);

			/* Klicks auswerten? */
			doppel	= (ret & 0x8000) ? TRUE : FALSE;
			ret		&= 0x7FFF;

			/* Status SELECTED zurcksetzen. */
			/* OK oder Abbruch? Dann raus... */
			{
				BOOLEAN	redraw	= FALSE;

				switch(ret)
				{
					case BHELP:
					case BUNDO:
						redraw	= TRUE;

					case BOK:
					case BCANCEL:
						GChgState(MakeObj(wi->tree, ret),
									SELECTED,
									MODE_DELETE);
						break;
				}

				if(redraw)
				{
					GRECT	invalid;

					objc_grect(invalid, tree, BHELP);
					win_objc_draw(wi->handle, tree, BHELP, &invalid);
				}

				if((ret == BHELP) || (ret == BOK) || (ret == BCANCEL))
					break;
			}

			/* Was anderes angeklickt? */
			switch(ret)
			{
				/* Undo? */
				case BUNDO:
					do_undo(wi);
					break;

				/* PopUp-Men? (1) */
				case POPUP1:
					if(!hdle_popup(tree, ret, entries,
								NMB_ENTRIES, &(lpara.popsret[0])))
						hdle_cycle(tree, ret, ret, entries,
									NMB_ENTRIES, &(lpara.popsret[0]),
									FALSE);
					break;

				/* PopUp-Men? (2) */
				case POPUP2:
					if(hdle_popup(tree, ret, entries2,
									NMB_ENTRIES2, &(lpara.popsret[1])))
						break;

				/* Cyclebutton (bezogen auf PopUp 2) */
				case CYCLE:
					hdle_cycle(tree, CYCLE, POPUP2, entries2,
								NMB_ENTRIES2, &(lpara.popsret[1]), doppel);
					break;

				/* Slider? */
				case SLIDER:
					hdle_slider(&sli, VARIOUS);
					break;

				case SLLEFT:
					hdle_slider(&sli, doppel ? MINIMUM : SINGLEUPLEFT);
					break;

				case SLRIGHT:
					hdle_slider(&sli, doppel ? MAXIMUM : SINGLEDOWNRIGHT);
					break;

				case SLBACK:
					{
						WORD	mx, ox, dummy;

						graf_mkstate(&mx, &dummy, &dummy, &dummy);
						objc_offset(tree, SLIDER, &ox, &dummy);

						hdle_slider(&sli,
									(mx < ox) ? PAGEUPLEFT : PAGEDOWNRIGHT);
					}
					break;
			}
		}

		/* OK? Dann sichern... */
		if(ret == BOK)
			*si	= TRUE;

		/* Hilfe durchfhren */
		if(ret == BHELP)
		{
			msg[0]	= OPENHELP;
			return(TRUE);
		}
	}

	return(FALSE);
}


/* ----------------------------------------------------------------------- */

/* Hauptprogramm */
WORD main(VOID)
{
	WORD		menuid,				/* Men-ID (Accessory)			*/
				msg[8];				/* Messagebuffer				*/

	/* Applikation-ID ermitteln */
	GEM_VERSION	= 0;
	applid		= appl_init();

	/* Existiert GEM-Versionnummer? */
	if(!GEM_VERSION)
	{
		puts(NOAUTO);
		return(NIL);
	}

	if(applid < 0)
	{
		puts(NOAES);
		return(NIL);
	}

	if(ACCESSORY)
	{
		menuid	= menu_register(applid, ACCNAME);
		if(menuid < 0)
		{
			form_alert(1, NOACC);
			for(;;)
				evnt_mesag(msg);
		}
	}

	/* Demoaktion; Applikation erst aktivieren */
	if(APPLICATION)
	{
		msg[0]	= AC_OPEN;
		msg[1]	= applid;
		msg[2]	=
		msg[3]	=
		msg[5]	=
		msg[6]	=
		msg[7]	= 0;
		msg[4]	= menuid;
		appl_write(applid, 16, msg);
	}

	{
		BOOLEAN	finish, si;

		finish	= FALSE;

		while(ACCESSORY || !finish)
		{
			/* Auf Nachricht warten! */
			{
				WORD	akthandle, which;

				wind_get(0, WF_TOP, &akthandle);

				which	= hdletoinx(akthandle);

				if(which != NIL)
				{
					if(wininfo[which].handle >= 0)
						if(!wininfo[which].do_it(wininfo + which, msg, &si))
						{
							msg[0]	= WM_CLOSED;
							msg[3]	= wininfo[which].handle;
						}
				}
				else
					evnt_mesag(msg);
			}

			switch(msg[0])
			{
				/* Accessory wurde ge”ffnet. 			*/
				/* Also: ggf. VDI-Workstation ”ffnen,	*/
				/*       ggf. Resourcen initialisieren.	*/
				case AC_OPEN	:
					if(!openvwk())
					{
						finish	= TRUE;
						break;
					}
					if(msg[4] == menuid)
					{
						if(wininfo[MAIN].handle >= 0)
							wind_set(wininfo[MAIN].handle, WF_TOP);
						else
							wininfo[MAIN].open(wininfo + MAIN);
					}
					break;

				/* Hilfedialog ”ffnen */
				case OPENHELP	:
					if(wininfo[HELP].handle >= 0)
						wind_set(wininfo[HELP].handle, WF_TOP);
					else
						wininfo[HELP].open(wininfo + HELP);
					break;

				/* Fenster nach oben? */
				case WM_TOPPED:
					wind_set(msg[3], WF_TOP);
					break;

				/* Accessory wurde geschlossen? 	*/
				/* Dann sind die Fenster schon zu!	*/
				case AC_CLOSE:
					wininfo[MAIN].handle	=
					wininfo[HELP].handle	= NIL;
					closevwk();
					break;

				/* Fenster wurde geschlossen? */
				case WM_CLOSED:
					{
						WORD	which;

						which	= hdletoinx(msg[3]);
						switch(which)
						{
							case MAIN:
								wininfo[MAIN].close(wininfo + MAIN, si);
								wininfo[MAIN].handle	= NIL;
								finish	= TRUE;
								closevwk();

							case HELP:
								if(wininfo[HELP].handle >= 0)
								{
									wininfo[HELP].close(wininfo + HELP, si);
									wininfo[HELP].handle	= NIL;
								}
								break;
						}
					}
					break;

				/* Fenster wurde bewegt? */
				case WM_MOVED:
					{
						GPOINT	np;

						np.g_x	= msg[4];
						np.g_y	= msg[5];
						WMove(msg[3], &np);
					}
					{
						GRECT	work;

						wind_get(msg[3], WF_WORKXYWH,
									&work.g_x,
									&work.g_y,
									&work.g_w,
									&work.g_h);

						{
							WORD	which;

							which	= hdletoinx(msg[3]);
							if(which != NIL)
							{
								wininfo[which].tree->ob_x	= work.g_x;
								wininfo[which].tree->ob_y	= work.g_y;
							}
						}
					}
					break;

				/* Fenster neu zeichnen? */
				case WM_REDRAW:
					{
						GRECT	invalid;

						invalid	= *(GRECT*)(msg + 4);

						win_objc_draw(msg[3],
										wininfo[hdletoinx(msg[3])].tree,
										ROOT, &invalid);
					}
					break;
			}
		}
	}

	/* die folgenden Zeilen erreicht ein Accessory nie */

	/* Applikation abmelden */
	appl_exit();

	/* fertig!!! */
	return(0);
}