/* $Revision Header built automatically *************** (do not edit) ************
**
** © Copyright by M.A.S.H (Modern Art Soft Hietzing)
**
** File             : Calci.c
** Created on       : Thuesday, 04-Apr-89
** Created by       : Wolfgang BREYHA
** Current revision : V2.00
**
**
** Purpose
** -------
**     Calci ist ein kleiner Taschenrechner der nur addieren,
**     subtraieren, multiplizieren und dividieren kann. Das kann er
**     dafür in den vier Zahlensystemen Hex, Dezimal, Octal, Binär.
**     Im Dezimalsystem kann er auch negative Zahlen. Das Ergebnis
**     kann auf Wunsch an ein anderes Fenster geschickt werden.
**
** Revision V2.00
** --------------
** changed on Friday, 18-Dec-92 11:26:45  by  Wolfgang BREYHA.   LogMessage :
**     Get System-Default Font from Kick2.0 and size the
**     window to fit the font.
**
** Revision V1.12
** --------------
** changed on Monday, 15-Apr-89 by  Wolfgang BREYHA.   LogMessage :
**     Better SendNumber-Routine
**
** Revision V1.11
** --------------
** changed on Sunday, 07-Apr-89 by  Wolfgang BREYHA.   LogMessage :
**     Open own Topaz8-Font
**
** Revision V1.10
** --------------
** changed on Saturday, 06-Apr-89 by  Wolfgang BREYHA.   LogMessage :
**     Debug, Debug, Debug!!
**
** Revision V1.01
** --------------
** changed on Friday, 05-Apr-89 by  Wolfgang BREYHA.   LogMessage :
**     Use "console.device" for input. transmit data directly to
**     SuperEd
**
** Revision V1.00
** --------------
**     --- Initial release ---
**
*********************************************************************************/
#define REVISION "2.00"
#define REVDATE  "18-Dec-92"
#define REVTIME  "11:26:45"
#define AUTHOR   "Wolfgang BREYHA"
#define VERNUM   02
#define REVNUM   00

#include <exec/types.h>
#include <exec/tasks.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/devices.h>
#include <devices/inputevent.h>
#include <devices/input.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <proto/intuition.h>
#include <proto/exec.h>
#include <proto/console.h>
#include <proto/graphics.h>
#include <proto/dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>


/***************************************************************************/
/*	Allgemeine defines						   */
/***************************************************************************/

#define	false		0L
#define	true		1L
#define	OVERFLOW	2L
#define	eos 		'\0'
#define	uppercase(c) ((c)-32)
#define	CODE ((Message!=NULL) ?	Message->Code :	0)
#define	CLASS ((Message!=NULL) ? Message->Class	: 0)
#define	QUALIFIER ((Message!=NULL) ? Message->Qualifier	: 0)
#define	F1 0x50
#define	F2 0x51
#define	F3 0x52
#define	F4 0x53
#define	F6 0x55
#define	F7 0x56
#define	F8 0x57
#define	F9 0x58
#define	F10 0x59
#define	YOff 3L
#define	XOff 9L

/***************************************************************************/
/*	Strukturen							   */
/***************************************************************************/

struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
struct IntuiMessage *Message = NULL;
struct Screen *Screen;
struct Window *Window;
struct Library *ConsoleDevice =	NULL;
struct TextAttr	CalcAttr;
struct TextFont	*CalcFont = NULL;
struct TagItem MyWinTag[16];
struct InputEvent inputEvent =
{
	0,IECLASS_RAWKEY,0,0,0
};

/***************************************************************************/
/*	selbstdefinierte Routinen					   */
/***************************************************************************/

ULONG ConvertToDec(char	number[33]);
ULONG hoch(int fakt,int	k);
void  reverse(char *s);
void  ltoa(ULONG n,char	s[]);
void  ConvertFromDec(ULONG number,char *result);
void  addnum(char num);
void  ChangeVorz(void);
void  calculate(void);
void  ClearDisplay(void);
void  DisplayWORD(void);
void  DisplayPM(void);
void  DisplayOVFL(void);
void  ClearOVFL(void);
void  DisplayTTS(void);
void  Display(ULONG x,ULONG err);
void  DisplaySystem(void);
void  DisplayChange(void);
void  SetCalcDisp(BOOL SetCorn);
struct Window *	SearchEdWindow(struct Screen *ES);
struct Screen *	SearchEdScreen(void);
int   EdTitle(struct Screen *ES);
void  SendNumber(struct	Window *EW);
void  SetPen(ULONG x, ULONG y);
extern void ChkAdd(void);
extern void CMul32(void);
void cleanup(void);

/***************************************************************************/
/*	globale	Variablen						   */
/***************************************************************************/

long _stack = 4000L;
long _priority = 0L;
long _BackGroundIO = NULL;
char *_procname	= "Calci";
static const char Version[]="\0$VER: Calci " REVISION
                            " (" REVDATE ")\r\n";
char display[33];
char helpdisp[33];
char operator,oldoperator,oldoldoperator;
char Minus[1] =	{ '-' };
ULONG Zahl,OldZahl,newnum;
int basis[4] = { 2,8,10,16 };
int faktoren[4]	= { 31,10,9,7 };
int stellen[4] = { 16,11,10,8 };
int oldbasis,NumSys = 2;
int first = true;
long i;
ULONG ISX,ISY,FSX,FSY;
LONG error = 0xffffffff;
BOOL Word = 0;
BOOL PM	= 0;
BOOL TTS = true;
char dispsys[4][4] = { 'B','I','N','\0',
		       'O','C','T','\0',
		       'D','E','C','\0',
		       'H','E','X','\0'	  };

/***************************************************************************/
/*	Routinen							   */
/***************************************************************************/

void reverse(s)
char *s;
{
	int c,i,j;
	for(i =	0, j = strlen(s) -1; i < j; i++, j--)
	{
		c    = s[i];
		s[i] = s[j];
		s[j] = c;
	}
}

void ltoa(n,s)
char s[];
ULONG n;
{
	int i =	0;
	do
	{
		s[i++] = n % 10	+ '0';
	}
	while ((n /= 10) > 0);
	for(;i<16;i++)
		s[i] = ' ';
	s[16] =	eos;
	reverse(s);
}

ULONG ConvertToDec(number)
char number[33];
{
char help;
register ULONG sammel =	0;
long	wertigkeit = 1;
int	index =	strlen(number) - 1;
	while (index >=	0)
	{
		help = number[index];
		if (help == ' ')
		{
			index =	0;
			help = 0;
		}
		else
		if (help >= 'A')
			help +=	10 - 'A';
		else
			help -=	'0';
		sammel += wertigkeit * help;
		index--;
		wertigkeit *= basis[NumSys];
	}
	return(sammel);
}

ULONG hoch(fakt,k)
register int fakt;
int k;
{
	int j;
register ULONG summe;
	summe =	1;
	for (j=0;j<k;j++)
	{
		summe *= fakt;
	}
	return(summe);
}

void ConvertFromDec(number,result)
register ULONG number;
char *result;
{
int k,j;
register ULONG help;
BOOL fst = true;
	for (k=0;k<32;k++)
		result[k] = ' ';
	result[32] = eos;
	for (k=faktoren[NumSys];k>=0;k--)
	{
		help = hoch(basis[NumSys],k);
		j = number/help;
		number %= help;
		if (!(fst) || j)
		{
			fst = false;
			if (j <	10)
				result[k] = '0'	+ j;
			else
			if (j >	9 && j < 16)
				result[k] = 'A'	+ j - 10;
		}
	}
	reverse(result);
}


void addnum(num)
char num;
{
	int k;
	if (Zahl == 0)
	{
		ClearDisplay();
		display[15] = ' ';
		helpdisp[31] = ' ';
		ClearOVFL();
	}
	if (NumSys == 0)
	{
		if ((Zahl != 0 || num >	'0') &&	helpdisp[0] < '1')
		{
			if (!(Word))
			{
				Word = true;
				Display(Zahl,error);
			}
			if (first == true && OldZahl)
			{
				OldZahl	= 0;
			}
			for(k=1;k<32;k++)
				helpdisp[k-1] =	helpdisp[k];
			helpdisp[31] = num;
			helpdisp[32] = eos;
			Zahl = ConvertToDec(helpdisp);
			for(k=0;k<16;k++)
				display[k] = helpdisp[k+16];
			display[16]=eos;
		}
	}
	else
	if ((Zahl != 0 || num >	'0') &&	display[16-stellen[NumSys]] < '1')
	{
		if (first == true && OldZahl)
		{
			OldZahl	= 0;
		}
		for(k=2;k<16;k++)
			display[k-1] = display[k];
		display[15] = num;
		display[16] = eos;
;		strcpy(helpdisp,display);
		Zahl = ConvertToDec(display);
		if (display[0]=='-')
			Zahl = -Zahl;
	}
	SetPen(XOff,FSY	+ YOff);
	Text(Window->RPort,display,(long)strlen(display));
}

void ChangeVorz()
{
	if (display[0] !='-')	display[0] = '-';
	else			display[0] = ' ';
	Zahl = -Zahl;
	SetPen(XOff,FSY	+ YOff);
	Text(Window->RPort,display,(long)strlen(display));
}


void calculate()
{
	switch(first)
	{
		case true:
		{
			if (operator !=	'=')
			{
				if (!(OldZahl))
					OldZahl	= Zahl;
				Zahl = 0;
				first =	false;
				oldoperator = operator;
				break;
			}
		}
		case false:
		{
			switch(oldoperator)
			{
				case '-':
					if (OldZahl < Zahl)
						error =	OVERFLOW;
					OldZahl	-= Zahl;
					Zahl = 0;
					oldoldoperator = oldoperator;
					oldoperator = operator;
					break;
				case '+':
					ChkAdd();
					Zahl = 0;
					oldoldoperator = oldoperator;
					oldoperator = operator;
					break;
				case '*':
					CMul32();
					OldZahl	*= Zahl;
					Zahl = 0;
					oldoldoperator = oldoperator;
					oldoperator = operator;
					break;
				case '/':
					if (Zahl)
					{
						OldZahl	/= Zahl;
						Zahl = 0;
						oldoldoperator = oldoperator;
						oldoperator = operator;
						break;
					}
					else
					error =	true;
			}
			Display(OldZahl,error);
			if (oldoperator	== '=')
			{
				Zahl = 0;
				first =	true;
				oldoperator = oldoldoperator;
			}
		}
	}
}

void SetPen(x,y)
ULONG x,y;
{
	SetAPen(Window->RPort,1L);
	SetBPen(Window->RPort,2L);
	Move(Window->RPort,x,y);
}

void ClearDisplay()
{
int k;
	for(k=0;k<15;k++)
	{
		display[k] = ' ';
	}
	display[15] = '0';
	display[16] = eos;
	for(k=0;k<31;k++)
	{
		helpdisp[k] = ' ';
	}
	helpdisp[31] = '0';
	helpdisp[32] = eos;
}

void DisplaySystem()
{
	SetPen(XOff,FSY*2 + YOff);
	Text(Window->RPort,dispsys[NumSys],(long)strlen(dispsys[NumSys]));
	Move(Window->RPort,FSX*4 + XOff,FSY + YOff);
	Text(Window->RPort,(UBYTE *)"     ",5L);
}

void DisplayOVFL()
{
	if (!PM)
	{
		SetPen(FSX*12 +	XOff,FSY*2 + YOff);
		Text(Window->RPort,(UBYTE *)"OVFL",4L);
	}
	error =	false;

}

void ClearOVFL()
{
	SetPen(FSX*12 +	XOff,FSY*2 + YOff);
	Text(Window->RPort,(UBYTE *)"    ",4L);
}

void DisplayTTS()
{
	SetPen(FSX*10 +	XOff,FSY*2 + YOff);
	if (TTS)	Text(Window->RPort,(UBYTE *)"A",1L);
	else		Text(Window->RPort,(UBYTE *)"W",1L);
}

void DisplayWORD()
{
	SetPen(FSX*4 + XOff,FSY*2 + YOff);
	if (Word)	Text(Window->RPort,(UBYTE *)"LWORD",5L);
	else		Text(Window->RPort,(UBYTE *)"HWORD",5L);
}

void DisplayPM()
{
	SetPen(FSX*4 + XOff,FSY*2 + YOff);
	if (PM)		Text(Window->RPort,(UBYTE *)"±    ",5L);
	else		Text(Window->RPort,(UBYTE *)"     ",5L);
}

void DisplayChange()
{
	DisplayTTS();
	DisplaySystem();
	if (OldZahl)	Display(OldZahl,error);
	else		Display(Zahl,error);
}

void Display(x,err)
ULONG x;
ULONG err;
{
int k;
long Help;
	if (err == true)
	{
		ClearDisplay();
		display[15] = 'R';
		display[14] = 'O';
		display[13] = 'R';
		display[12] = 'R';
		display[11] = 'E';
	}
	else
	switch(NumSys)
	{
		case 0:
			ConvertFromDec(x,helpdisp);
			if (Word)
				for (k=0;k<17;k++)
					display[k]=helpdisp[k+16];
			else
			{
				for (k=0;k<17;k++)
					display[k]=helpdisp[k];
				display[16]=eos;
			}
			DisplayWORD();
			break;
		case 1:
			ConvertFromDec(x,helpdisp);
			for (k=0;k<17;k++)
				display[k] = helpdisp[k+16];
			break;
		case 2:
			DisplayPM();
			if (PM && x>(ULONG)0x7FFFFFFF)
			{
				Help = x;
				Help *=	(-1);
				ltoa(Help,helpdisp);
				strcpy(display,helpdisp);
				display[0]='-';
			}
			else
			{
				ltoa(x,helpdisp);
				strcpy(display,helpdisp);
			}
			break;
		case 3:
			ConvertFromDec(x,helpdisp);
			for (k=0;k<17;k++)
				display[k] = helpdisp[k+16];
			break;
	}
	if (NumSys > 0 && x == 0)
		display[15] = '0';
	SetPen(XOff,FSY	+ YOff);
	Text(Window->RPort,display,(long)strlen(display));
	if (error == OVERFLOW)
		DisplayOVFL();
}

void SetCalcDisp(BOOL SetCorn)
{
	if (CalcFont) CloseFont(CalcFont);
/*	CalcAttr = Screen->Font;		*/
     	CalcFont = GfxBase->DefaultFont;
	CalcAttr.ta_Name  = CalcFont->tf_Message.mn_Node.ln_Name;
	CalcAttr.ta_YSize = CalcFont->tf_YSize;
	CalcAttr.ta_Style = CalcFont->tf_Style;
	CalcAttr.ta_Flags = CalcFont->tf_Flags;
	CalcFont = NULL;
	if ((CalcFont =	OpenFont(&CalcAttr)) == NULL) cleanup();
	FSX = CalcFont->tf_XSize;
	FSY = CalcFont->tf_YSize;
	ISX = (ULONG) FSX*17 + 9;
	ISY = (ULONG) FSY*2 + 8;
	MyWinTag[11].ti_Data = ISX;		/* InnerWidth  */
	MyWinTag[12].ti_Data = ISY;		/* InnerHeight */
	if (SetCorn)
	{
		MyWinTag[13].ti_Data = (ULONG)Screen->Width - ISX - 8;/* Left */
		MyWinTag[14].ti_Data = (ULONG)FSY+2;  /* Top */
	}
	if ((Window = (struct Window *)
		OpenWindowTagList(NULL,(struct TagItem *)&MyWinTag))
		== NULL) cleanup();
	SetFont(Window->RPort,CalcFont);
	SetAPen(Window->RPort,2L);
	SetBPen(Window->RPort,2L);
	RectFill(Window->RPort,0L,0L,ISX,ISY);
	SetPen(4L,2L);
	Draw(Window->RPort,ISX-4,2L);
	Draw(Window->RPort,ISX-4,ISY-2);
	Draw(Window->RPort,4L,ISY-2);
	Draw(Window->RPort,4L,2L);
}

struct Screen *
SearchEdScreen()
{
struct Screen *ES;
int i =	0;

	ES = IntuitionBase->FirstScreen;
	while (!(i = EdTitle(ES)) && ES->NextScreen)
		ES = ES->NextScreen;
	if (!(i)) ES = NULL;
	return(ES);
}

int EdTitle(ES)
struct Screen *ES;
{
char Ed[7];
int i;
int TitleOk = true;
	Ed[0] =	'S';
	Ed[1] =	'u';
	Ed[2] =	'p';
	Ed[3] =	'e';
	Ed[4] =	'r';
	Ed[5] =	'E';
	Ed[6] =	'd';
	for (i=0;i<7;i++)
		if (ES->Title[i] != Ed[i])
			TitleOk	= false;
	return (TitleOk);
}

struct Window *
SearchEdWindow(ES)
struct Screen *ES;
{
struct Window *EW;
	EW = ES->FirstWindow;
	while (EW->NextWindow)
		EW = EW->NextWindow;
	return(EW);
}

void SendNumber(EW)
struct Window *EW;
{
int i;
BOOL sendoperator;
struct IOStdReq	*inputRequestBlock;
struct MsgPort *inputDevPort;
struct InputEvent sendevent;

	sendevent.ie_Class = IECLASS_NULL;
	sendevent.ie_NextEvent = NULL;

	if ((inputDevPort = CreatePort(0L,0L)) != NULL)
	{
		if (inputRequestBlock =	CreateStdIO(inputDevPort))
		{
			if (!(OpenDevice((UBYTE	*)"input.device",0L,
					(struct	IORequest *)inputRequestBlock,0L)))
			{
				inputRequestBlock->io_Command =	IND_WRITEEVENT;
				inputRequestBlock->io_Flags = 0;
				inputRequestBlock->io_Length = sizeof(struct InputEvent);
				inputRequestBlock->io_Data = (APTR) &sendevent;

				sendevent.ie_NextEvent = NULL;
				sendevent.ie_Class = IECLASS_RAWKEY;
				sendevent.ie_TimeStamp.tv_secs = 0;
				sendevent.ie_TimeStamp.tv_micro	= 0;
				sendevent.ie_Qualifier = 0L;

				if (!(EW))
				{
					ModifyIDCMP(Window,INACTIVEWINDOW);
					Wait(1L<<Window->UserPort->mp_SigBit);
					Delay(10L);
				}
				else
				{
					ModifyIDCMP(Window,CLOSEWINDOW | RAWKEY);
					ActivateWindow(EW);
				}

				switch (NumSys)
				{
					case 0:
						sendevent.ie_Code=05;
						sendevent.ie_Qualifier=IEQUALIFIER_LSHIFT;
						sendoperator=true;
						break;
					case 1:
						sendevent.ie_Code=0x0d;
						sendevent.ie_Qualifier=0L;
						sendoperator=true;
						break;
					case 2:
						sendoperator=false;
						break;
					case 3:
						sendevent.ie_Code=04;
						sendevent.ie_Qualifier=IEQUALIFIER_LSHIFT;
						sendoperator=true;
						break;
				}
				if (sendoperator)
					DoIO((struct IORequest *)inputRequestBlock);
				for (i=0;i<33;i++)
				{
					sendevent.ie_Qualifier=0L;
					if (helpdisp[i]	!= 32 && helpdisp[i] !=	0)
					{
						if (helpdisp[i]	>= '1' && helpdisp[i] <= '9')
							sendevent.ie_Code=helpdisp[i]-'0';
						switch (helpdisp[i])
						{
							case '0':
								sendevent.ie_Code=0x0a;
								break;
							case 'A':
								sendevent.ie_Code=0x20;
								break;
							case 'B':
								sendevent.ie_Code=0x35;
								break;
							case 'C':
								sendevent.ie_Code=0x33;
								break;
							case 'D':
								sendevent.ie_Code=0x22;
								break;
							case 'E':
								sendevent.ie_Code=0x12;
								break;
							case 'F':
								sendevent.ie_Code=0x23;
								break;
						}
						if (helpdisp[i]	>= 'A' && helpdisp[i] <= 'F')
							sendevent.ie_Qualifier=IEQUALIFIER_LSHIFT;
						DoIO((struct IORequest *)inputRequestBlock);
						Delay(3L);
					}
				}
				ActivateWindow(Window);
				ModifyIDCMP(Window,CLOSEWINDOW | RAWKEY	|
						   ACTIVEWINDOW	| INACTIVEWINDOW);
				CloseDevice((struct IORequest *)inputRequestBlock);
			}
			DeleteStdIO(inputRequestBlock);
		}
		DeletePort(inputDevPort);
	}
}

/***************************************************************************/
/*	Hauptprogramm							   */
/***************************************************************************/

main()
{
struct Screen *EdScreen;
struct Window *EdWindow;
BOOL WindowSave	= false;
/* struct MsgPort *CalcUserPort	= NULL;	*/
struct IOStdReq	CalcStdReq;
UBYTE inputPuffer[128];
UWORD inputLen = 0;
char inp;
BOOL Saved = false;
long x,y,h;

error = false;

if (!(GfxBase =	(struct	GfxBase*)
		OpenLibrary((UBYTE *)"graphics.library",33L))) cleanup();

if (!(IntuitionBase = (struct IntuitionBase *)
		OpenLibrary((UBYTE *)"intuition.library",33L)))	cleanup();

if (!(OpenDevice((UBYTE	*)"console.device",-1L,(struct IORequest *)&CalcStdReq,0L)))
	ConsoleDevice =	(struct	Library	*)CalcStdReq.io_Device;
else
cleanup();

Screen = IntuitionBase->ActiveScreen;

	MyWinTag[0].ti_Tag = WA_DetailPen;	MyWinTag[0].ti_Data = 0;
	MyWinTag[1].ti_Tag = WA_BlockPen;	MyWinTag[1].ti_Data = 1;
	MyWinTag[2].ti_Tag = WA_Title;		MyWinTag[2].ti_Data = (ULONG)((UBYTE *)"Calci");
	MyWinTag[3].ti_Tag = WA_Flags;
	MyWinTag[3].ti_Data = WINDOWCLOSE | SMART_REFRESH | GIMMEZEROZERO |
			      WINDOWDRAG | ACTIVATE | WINDOWDEPTH;
	MyWinTag[4].ti_Tag = WA_IDCMP;
	MyWinTag[4].ti_Data = CLOSEWINDOW | RAWKEY |
			      ACTIVEWINDOW | INACTIVEWINDOW;
	MyWinTag[5].ti_Tag = TAG_IGNORE;   /*WA_Type;*/
		MyWinTag[5].ti_Data = CUSTOMSCREEN;
	MyWinTag[6].ti_Tag = WA_CustomScreen;	MyWinTag[6].ti_Data = (ULONG) Screen;
	MyWinTag[7].ti_Tag = WA_MinWidth;	MyWinTag[7].ti_Data = 0;
	MyWinTag[8].ti_Tag = WA_MaxWidth;	MyWinTag[8].ti_Data = 0;
	MyWinTag[9].ti_Tag = WA_MinHeight;	MyWinTag[9].ti_Data = 0;
	MyWinTag[10].ti_Tag = WA_MaxHeight;	MyWinTag[10].ti_Data = 0;
	MyWinTag[11].ti_Tag = WA_InnerWidth;
	MyWinTag[12].ti_Tag = WA_InnerHeight;
	MyWinTag[13].ti_Tag = WA_Left;
	MyWinTag[14].ti_Tag = WA_Top;
	MyWinTag[15].ti_Tag = TAG_DONE;
	MyWinTag[15].ti_Data = 0L;

SetCalcDisp(TRUE);

ClearDisplay();
Display(0L,0);
DisplayTTS();
DisplaySystem();

FOREVER
{
	Wait(1L<<Window->UserPort->mp_SigBit);
while  (Message	= (struct IntuiMessage *)GetMsg(Window->UserPort))
{
	ReplyMsg((struct Message *)Message);
	switch(CLASS)
	{
		case CLOSEWINDOW:
			cleanup();
		case RAWKEY:
			switch(CODE)
			{
				case F1:
					NumSys = 0;
					Word = (BOOL)1 - Word;
					DisplayChange();
					break;
				case F2:
					NumSys = 1;
					DisplayChange();
					Word=0;
					break;
				case F3:
					if (NumSys==2) PM = (BOOL)1 - PM;
					NumSys = 2;
					DisplayChange();
					Word=0;
					break;
				case F4:
					NumSys = 3;
					DisplayChange();
					Word=0;
					break;
				case F6:
					TTS = (BOOL) 1 - TTS;
					DisplayTTS();
					break;
				case F7:
					WindowSave = (BOOL) 1 -	WindowSave;
					break;
				case F8:
					if (TTS)
					{
						EdScreen = SearchEdScreen();
						if (EdScreen)
						{
							EdWindow = SearchEdWindow(EdScreen);
							if (EdWindow)
								SendNumber(EdWindow);
						}
					}
					else
					{
						SendNumber(NULL);
					}
					break;
				case F9:
					MyWinTag[13].ti_Data = (ULONG)Window->LeftEdge;
					MyWinTag[14].ti_Data = (ULONG)Window->TopEdge;
					CloseWindow(Window);
					SetCalcDisp(FALSE);
					DisplayChange();
					break;
				case F10:
					if (Screen->NextScreen)
					{
						Screen = Screen->NextScreen;
						MyWinTag[13].ti_Data = Screen->Width - ISX - 8;
						MyWinTag[14].ti_Data = 20L;  /*	TopEdge	*/
						MyWinTag[6].ti_Data = (ULONG)Screen;
						CloseWindow(Window);
						SetCalcDisp(TRUE);
						DisplayChange();
					}
					else
					{
						Screen = IntuitionBase->FirstScreen;
						MyWinTag[13].ti_Data = Screen->Width - ISX - 8;
						MyWinTag[14].ti_Data = 10L;  /*	TopEdge	*/
						MyWinTag[6].ti_Data = (ULONG)Screen;
						CloseWindow(Window);
						SetCalcDisp(TRUE);
						DisplayChange();
					}
					break;
				default:
					if (!(CODE & IECODE_UP_PREFIX))
					{
						inputEvent.ie_Code	= CODE;
						inputEvent.ie_Qualifier	= QUALIFIER;
						if ((inputLen =
							RawKeyConvert(&inputEvent,inputPuffer,128L,NULL)) == 1)
						{
							inp = inputPuffer[0];
							if (inp	== '\177')	/* 177 => DEL */
							{
								ClearDisplay();
								Zahl = 0;
								OldZahl	= 0;
								first =	true;
								error =	false;
								SetPen(XOff,FSY	+ YOff);
								Text(Window->RPort,display,(long)strlen(display));
								ClearOVFL();
								break;
							}
							if (!(error))
							{
								if (inp>='0' &&	inp<='9')
								{
									newnum = inp - '0';
									if (newnum < basis[NumSys])
									{
										addnum(inp);
									}
									break;
								}
								if (inp>='a' &&	inp<='f')
								{
									newnum = inp - 'a' + 10;
									if (newnum < basis[NumSys])
									{
										addnum(uppercase(inp));
									}
									break;
								}
								if (inp>='A' &&	inp<='F')
								{
									newnum = inp - 'A' + 10;
									if (newnum < basis[NumSys])
									{
										addnum(inp);
									}
									break;
								}
								switch(inp)
								{
									case '+':
										operator = '+';
										calculate();
										break;
									case '-':
										operator = '-';
										calculate();
										break;
									case '*':
										operator = '*';
										calculate();
										break;
									case '/':
										operator = '/';
										calculate();
										break;
									case '=':
										operator = '=';
										calculate();
										break;
									case '.':
										if (PM == 1) ChangeVorz();
										break;
									case '\15':	/* Return */
										operator = '=';
										calculate();
										break;
									case '\10':	/* <- */
										if (first == true && OldZahl)
											OldZahl	= 0;
										if (NumSys == 0)
										{
											if (!(Word))
											{
												Word = true;
												Display(Zahl,error);
											}
											for(i=31;i>0;i--)
											{
												helpdisp[i] = helpdisp[i-1];
											}
											helpdisp[0] = ' ';
											Zahl = ConvertToDec(helpdisp);
											if (Zahl == 0)
												helpdisp[31] = '0';
											for(i=0;i<16;i++)
											display[i] = helpdisp[i+16];
										}
										else
										{
											for(i=15;i>0;i--)
											{
												display[i] = display[i-1];
											}
											display[0] = ' ';
											Zahl = ConvertToDec(display);
											if (Zahl == 0)
												display[15] = '0';
											strcpy(helpdisp,display);
										}
										SetPen(XOff,FSY	+ YOff);
										Text(Window->RPort,display,(long)strlen(display));
										ClearOVFL();
										break;
								}
							}
			   			}
					}
					break;
			}
			break;
		case INACTIVEWINDOW:
			if (WindowSave)
			{
				x = Window->LeftEdge;
				y = Window->TopEdge;
				h = Window->Height;
				CloseWindow(Window);
				MyWinTag[11].ti_Tag = WA_Width;
				MyWinTag[11].ti_Data = ISX;
				MyWinTag[12].ti_Tag = WA_Height;
				MyWinTag[12].ti_Data = 10L;
				MyWinTag[13].ti_Data = Screen->Width / 2;
				MyWinTag[14].ti_Data = 0L;  /* TopEdge */
				MyWinTag[3].ti_Data = WINDOWCLOSE | SMART_REFRESH |
						  	WINDOWDRAG | WINDOWDEPTH;
				if ((Window = (struct Window *)
				   OpenWindowTagList(NULL,(struct TagItem *)&MyWinTag))
					== NULL) cleanup();
				Saved =	true;
				break;
			}
		case ACTIVEWINDOW:
			if (Saved)
			{
				MyWinTag[11].ti_Tag = WA_InnerWidth;
				MyWinTag[11].ti_Data = ISX;
				MyWinTag[12].ti_Tag = WA_InnerHeight;
				MyWinTag[12].ti_Data = ISY;
				MyWinTag[13].ti_Data = (ULONG)x;
				MyWinTag[14].ti_Data = (ULONG)y;  /* TopEdge */
				MyWinTag[3].ti_Data = WINDOWCLOSE | SMART_REFRESH | GIMMEZEROZERO |
			      				WINDOWDRAG | ACTIVATE |	WINDOWDEPTH;
				CloseWindow(Window);
				SetCalcDisp(FALSE);
				DisplayChange();
				Saved =	false;
				break;
			}
	}
}
}
}

/***************************************************************************/
/*	Say Goodbye							   */
/***************************************************************************/

void cleanup()
{
	if (CalcFont) CloseFont(CalcFont);
	if (Window) CloseWindow(Window);
	if (GfxBase) CloseLibrary((struct Library *)GfxBase);
	if (IntuitionBase) CloseLibrary((struct	Library	*)IntuitionBase);
	exit(0);
}

