/****************************************************************
** charmap.c : Display an ASCII table of a given Amiga font.   **
**             Written (mainly) by T.Pierron                   **
**             11-Dec-1999                                     **
**-------------------------------------------------------------**
** Special Requirements: WorkBench 2.0, version 36 or above    **
****************************************************************/

#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/rastport.h>
#include <graphics/gfxmacros.h>
#include <graphics/text.h>
#include <libraries/gadtools.h>
#include <intuition/screens.h>

#include "cmap.h"
#define  CATCOMP_NUMBERS		/* We will need the string id */
#define  CATCOMP_STRINGS		/* and the english string corresponding to the id */
#include "cmap_strings.h"

/* Shared libraries we'll need to open */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase       = NULL;
struct Library *GadToolsBase  = NULL;
struct Library *AslBase       = NULL;
struct Library *DiskfontBase  = NULL;
struct Library *CxBase			= NULL;
struct Library *IconBase		= NULL;
struct Library *KeymapBase		= NULL;
struct Library *LocaleBase    = NULL;
struct Library *UtilityBase   = NULL;
void           *clipdev			= NULL;

/* Graphics area: */
struct RastPort *RP,RPT;
struct TextFont *font,*newfont=0;

struct Menu   *menu   = NULL;				/* Menu attached to the window */
struct Screen *screen = NULL;				/* Screen where window will be opened */
struct Window *window = NULL;				/* Main window ptr */
struct Gadget *glist  = NULL;  		   /* Gadget list pointer */
struct Gadget *gad;							/* our running Gadget pointer */
struct Gadget *copy_gad, *paste_gad;	/* Copy and paste gadget (for menu action) */
void   *vi = NULL;							/* VisualInfo pointer */

WORD  ZoomData[4];							/* Position of iconified window */
WORD  xdeb,ydeb,xfin,yfin,X,Y;			/* Position of ASCII table */
UBYTE CharWid[256],Char[]=" ";			/* Data of ASCII table */
UBYTE Font_height;							/* Font information */
UBYTE GadDisable=0;							/* If a ressource is unavailable */
UBYTE Layout;									/* Types of layout */
UBYTE VertSort=1;								/* TRUE if chars are sorted vertically first */
WORD  Wid[6];									/* Width of various gadgets */

/* For the "version" command */
const UBYTE VERSION[]= "$VER:CharMap v" CHARMAP_VERSION " " CHARMAP_DATE "\n";

/* Tag list for opening the main window: */
ULONG WinTags[] = {
	WA_Zoom,(ULONG)ZoomData,
	WA_NewLookMenus,TRUE,
	TAG_DONE
};

/* Set the color of the menu to Newlook (only 3.0+) */
ULONG MenuTags[] = {
	GTMN_FrontPen, 1,
	TAG_DONE
};

ULONG BoxTags[] = {
	GT_VisualInfo,0,
	TAG_DONE,FALSE,
	TAG_DONE
};

/* Our gadtools gadget text */
UBYTE *GadTxt[7+NUM_CHARSET+5]={
	"<=",0,0,
	/* MSG_FONTTYPE_STR      **
	** MSG_MENUCHARSET_STR   */
	MSG_COPY_STR,
	MSG_PASTE_STR,
	MSG_STRGAD_STR,0,0,0,
	/* MSG_MENUASCII8_STR    **
	** MSG_MENUISOLATIN1_STR **
	** MSG_MENUSTDAMIGA_STR  */
	NULL,
	MSG_NEWFONT_STR    /* GT **
	** MSG_MENUFONTSCREEN_ST **
	** MSG_MENUTEXTFONT_STR  **
	** MSG_MENUCUSTOMFONT_ST */
};

#define	CBLen		Wid[0]			/* "Paste" */
#define	ChrLen	Wid[1]			/* "Charset" */
#define	FtLen		Wid[2]			/* "Font" */
#define	VaLen		Wid[3]			/* Various */
#define	CyCLen	Wid[4]			/* Charset cycle gadget */
#define	CyFLen	Wid[5]			/* Font type cycle gadget */

/* Tags associated with the charset cycle gadget */
ULONG CycleTags[]={
	GTCY_Labels, (ULONG) &GadTxt[6],
	GTCY_Active, 1,
	TAG_DONE
};

/* The ones associated with the font type */
ULONG FontTags[]={
	GTCY_Labels, (ULONG) &GadTxt[GT+1],
	GTCY_Active, 0,
	TAG_DONE
};

/* here we declare the information for our new window - notice that GadTools
 * provides some constants which describe which IDCMP events the Window will
 * need to handle the GadTools Gadgets properly. Just OR them into your
 * normal IDCMPFlags field.
 */

ULONG sigwin=0;
struct NewWindow new_window = {
	50, 20, 510, 150,
	~0, ~0,						/* DetailPen, BlockPen */
	CLOSEWINDOW | REFRESHWINDOW | MOUSEBUTTONS | MOUSEMOVE | RAWKEY | MENUPICK | MENUVERIFY | GADGETUP,
	ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | REPORTMOUSE,
	NULL,							/* FirstGadget */
	NULL,							/* CheckMark */
	NULL,							/* Title */
	NULL,							/* Screen */
	NULL,							/* BitMap */
	0, 0, 0, 0,					/* min/max sizes */
	CUSTOMSCREEN
};

/* Error messages */
UBYTE *Errors[]= {
	MSG_BADOS_STR,
	MSG_SCREENLOCK_STR,
	MSG_ERRLAYOUT_STR,
	MSG_FONTREALLYBIG_STR,
	MSG_ERRGADGET_STR,
	MSG_ERRNOMEM_STR,
	MSG_NOASL_STR,
	MSG_NEXTSCR_STR,			/* When commo is not present */
	MSG_KSNOTFOUND_STR
};

struct EasyStruct Request= {
	sizeof(struct EasyStruct),0,
	MSG_ABOUT_STR,
	MSG_ABOUTMSG_STR,
	MSG_CONTINUE_STR
};

/**********************************************************
*****					MENU DATA MANAGMENT:						*****
**********************************************************/

/* NewMenu menu declaration */
struct NewMenu newmenu[] =
{
	{NM_TITLE, MSG_MENUTITLE_STR,0 , 0, 0, 0},
	{  NM_ITEM, MSG_FONTTYPE_STR, 0, 0, 0, 0},
	{   NM_SUB,   MSG_MENUFONTSCREEN_STR,"S", CHECKIT|CHECKED, ~1, (APTR) 111},
	{   NM_SUB,   MSG_MENUTEXTFONT_STR,  "T", CHECKIT, ~2, (APTR)112},
	{   NM_SUB,   MSG_MENUCUSTOMFONT_STR,"F", CHECKIT, ~4, (APTR)113},
	{  NM_ITEM, MSG_MENUCHARSET_STR,   0, 0, 0, 0},
	{   NM_SUB,   MSG_MENUASCII8_STR,    "1", CHECKIT, ~1, (APTR)141},
	{   NM_SUB,   MSG_MENUISOLATIN1_STR, "2", CHECKIT, ~2, (APTR)142},
	{   NM_SUB,   MSG_MENUSTDAMIGA_STR,  "3", CHECKIT, ~4, (APTR)143},
	{  NM_ITEM, NM_BARLABEL,  0, 0, 0, 0},
	{  NM_ITEM, MSG_MENUABOUT_STR,       "?", 0, 0, (APTR)15},
	{  NM_ITEM, NM_BARLABEL,  0, 0,  0, 0},
	{  NM_ITEM, MSG_MENUICONOFY_STR,     "I", 0, 0, (APTR)16},
	{  NM_ITEM, MSG_MENUHIDE_STR,        "H", 0, 0, (APTR)17},
	{  NM_ITEM, MSG_MENUQUIT_STR,        "Q", 0, 0, (APTR)18},

	{NM_TITLE, MSG_EDITMENU_STR ,0, 0, 0, 0},
	{  NM_ITEM, MSG_CUT_STR,             "X", 0, 0, (APTR)21},
	{  NM_ITEM, NM_BARLABEL,             "C", 0, 0, (APTR)22},
	{  NM_ITEM, NM_BARLABEL,             "V", 0, 0, (APTR)23},
	{  NM_ITEM, NM_BARLABEL,  0, 0,  0, 0},
	{  NM_ITEM, MSG_MENUCLEARTXT_STR,  "Del", NM_COMMANDSTRING, 0, (APTR)24},
	{  NM_ITEM, MSG_MENUSORT_STR,      "Tab", NM_COMMANDSTRING|CHECKIT|MENUTOGGLE, 0, (APTR)26},
/*	{  NM_ITEM, NM_BARLABEL,  0, 0,  0, 0},
	{  NM_ITEM, MSG_SAVESETTINGS,          0, 0,  0, (APTR)27},
*/	{NM_END, 0, 0, 0, 0, 0},
},*checked=&newmenu[NM_FONTTYPE],
  *checkset;

/* Different width of box for each charset */
UBYTE MaxWid,NumChars,CharsetNum=0;

/* Colors pens */
UWORD fillpen=3,txtpen=1,poppen=2,filltxt=2,shine=2,darkpen=1;

/* Position of normal and minimized window */
WORD Offset[]={0x7fff,0x7fff,0x7fff,0x7fff};

/* Function prototypes */
BYTE setup();										/* Open window, ressources, font... */
void cleanup(UBYTE *,WORD);					/* Quit properly */
void create_gadgets(void);						/* Create the gadget using gadtools lib */

/**** Definition of the main loop: ****/
int main(int argc, char *argv[])
{
	extern BOOL PopWin;							/* True if the window is poped up at start */

	/* If no locale, use english as default */
	if(LocaleBase = (struct Library *)OpenLibrary("locale.library", 38))
		Translate_srings();

	/* These libraries are located in ROM. If it failed to open, it's   **
	** because we are attempting to run this programme on an old system */
	if( !(GfxBase       = (struct GfxBase *)      OpenLibrary("graphics.library", MIN_VERSION)) ||
	    !(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",MIN_VERSION)) ||
	    !(GadToolsBase  = (struct Library *)      OpenLibrary("gadtools.library", MIN_VERSION)) ||
		 !(UtilityBase   = (struct Library *)      OpenLibrary("utility.library",  MIN_VERSION)) ||
	    !(KeymapBase    = (struct Library *)      OpenLibrary("keymap.library",   37)) )
		cleanup(ErrMsg(MSG_BADOS),30);

	/* Open ze libraries */
	if( (IconBase = (void *) OpenLibrary("icon.library",        MIN_VERSION)) &&
	    (CxBase   = (void *) OpenLibrary("commodities.library", 37L)) )
		/* If the icon and commodities.library are present, and the **
		** programme failed to init as a commodity, it's probably   **
		** because it is already running, and user want to quit:    */
	{	if( Init_commodity(argc,argv)==FALSE )
			cleanup(0,0);
	} else {
		/* If commo. is not present, change menu "Hide" by "Next screen" */
		newmenu[13].nm_Label = ErrMsg(MSG_NEXTSCR);
		newmenu[13].nm_CommKey = "J";
		newmenu[13].nm_UserData = (APTR)25;
	}

	/* Same as gadget or menu text: */
	newmenu[17].nm_Label=GadTxt[3];
	newmenu[18].nm_Label=GadTxt[4];

	/* Init cycle font-type gadget text list and charset cycle gad */
	for(checkset=&newmenu[NM_CHARSET], X=6; X<7+NUM_CHARSET+4; X++,checkset++)
	{
		if(X==GT-1) X+=2,checkset=&newmenu[2];
		GadTxt[ X ]=checkset->nm_Label;
	}

	/* No ASL or diskfont library, no font requester */
	if( !(DiskfontBase = (struct Library *)OpenLibrary("diskfont.library",0)) ||
	    !(AslBase = (struct Library *)OpenLibrary("asl.library",MIN_VERSION)) ) {
		newmenu[NM_FONTTYPE+2].nm_Flags |= NM_ITEMDISABLED;
		GadTxt[GT+3] = 0;
	}

	/* For temporary font measurement */
	InitRastPort( &RPT );

	/* Get access to the frontmost screen */
	screen = IntuitionBase->ActiveScreen;
	font = screen->RastPort.Font;

	/* Initial charset displayed */
	if(CharsetNum<1 || CharsetNum>NUM_CHARSET) Init_charset(font);
	checkset=&newmenu[CharsetNum+NM_CHARSET-1];
	checkset->nm_Flags |= CHECKED;

	if(PopWin)
		/* If setup failed at start (font too big) */
		if(setup()) Handle_menu(113L);

	handle_input();
}

/*** Setup the window, return 1 if init failed ***/
BYTE setup()
{
	struct DrawInfo *di;

	/* Get the screen's visual information data */
	if( !(vi = (void *) GetVisualInfoA( screen,NULL )) )
		cleanup(ErrMsg(MSG_SCREENLOCK),30);

	BoxTags[1]=(ULONG)vi;

	/* Adjust the pen numbers to what the screen uses */
	if( di = (void *)GetScreenDrawInfo(screen))
	{
		/* Get a copy of the correct pens for the screen */
		fillpen = di->dri_Pens[FILLPEN];
		txtpen  = di->dri_Pens[TEXTPEN];
		filltxt = di->dri_Pens[FILLTEXTPEN];
		shine   = di->dri_Pens[SHINEPEN];
		darkpen = di->dri_Pens[SHADOWPEN];
		poppen  = 3; if(txtpen==3) poppen=fillpen;

		/* This one is only available on system V39+ */
		if(di->dri_Version>=2) MenuTags[1] = di->dri_Pens[BARDETAILPEN];
		FreeScreenDrawInfo(screen,di);
	}
	/* Those string can be set to NULL, to reduce interface's width */
	GadTxt[1]=newmenu[1].nm_Label;
	GadTxt[2]=newmenu[NM_CHARSET-1].nm_Label;
	if(VertSort) newmenu[21].nm_Flags |= CHECKED;
	else         newmenu[21].nm_Flags &= ~CHECKED;

	/* Build the menu-strip and compute menu items size */
	if( !(menu = (void *) CreateMenusA(newmenu, MenuTags)) ||
	    !LayoutMenusA(menu, vi, NULL) )
	   cleanup(ErrMsg(MSG_ERRLAYOUT),30);

	SetFont(&RPT,font);
	/* Read the size of the 256 characters of the current font, **
	** and compute the maximal width of the box chars           */
	NumChars = CharsetNum==1 ? 32 : CharsetNum == 2 ? 28 : 24;
	{
		register WORD I;
		register UBYTE *W;
		for(I=0,W=CharWid,MaxWid=0; I<256; I++,W++) {
			*Char = I;
			*W = TextLength(&RPT,Char,1);

			/* Compute the width of each box: */
			switch( CharsetNum )
			{
				case 3: if(I>=127 && I<160) break;
				case 2: if(I<32) break;
				case 1: if(MaxWid < *W+6) MaxWid=*W+6;
			}
		}
	}

	/* Some important font size-depending values */
	Font_height = font->tf_YSize+4;
	SetFont(&RPT,screen->RastPort.Font);

	/* Measure length of strings */
	for(X=0; X<4; X++)
	{
		static char Len[]={15,10,10,10}, offs[]={4,2,1,5};
		register BYTE *str = GadTxt[ offs[X] ];
		Wid[ X ] = TextLength(&RPT,str,strlen(str))+Len[X];
	}
	CyCLen = Meas_table(GadTxt+6)+30;
	CyFLen = Meas_table(GadTxt+GT+1)+30;
	/* If "Font" text length is shorter than "String", right aligns text */
	if(FtLen < VaLen) FtLen=VaLen;

	for(X=1;;) {
		/* Computes the width of our window */
		new_window.Width = xfin = MaxWid*NumChars+20;

		/* Does the width of the window fit in the screen? */
		if(xfin > screen->Width)
		{
			/* No! force the window width */
			MaxWid = (screen->Width-20) / NumChars;
			continue;
		}

		if(X==0) break;
		/* Is there place for gadgets? */
		if( (X=FtLen + CyCLen + CyFLen)+30 > xfin)
			MaxWid=(X + 10) / NumChars + 1, X=0;
		else break;
	}

	/* Try to optimize rendering of layout */
	X=new_window.Width-ChrLen-FtLen-40; xdeb = X/3; Layout = LARGE_LAYOUT;
	if(CBLen < X - CyCLen - CyFLen)
		if(CyCLen <= xdeb && CyFLen <= xdeb)
			CBLen = CyCLen = CyFLen = xdeb;
		else /* One of cycle gadget is too wide, adjust just copy/paste gad: */
			CBLen = X - CyCLen - CyFLen;
	else /* Expand just cycle gadgets */
		if(X + 10 >= CyCLen + CyFLen)
			CyCLen=CyFLen= (X + 10) / 2, Layout = MIDDLE_LAYOUT;
		else /* Not enough place for both gadget's caption & gadget */
			CyCLen=CyFLen=(X+10+ChrLen)/2, ChrLen=0,
			GadTxt[2]=NULL, Layout = SMALL_LAYOUT;

	/* Setup normal and minimized position of main window */
	new_window.TopEdge  = Adjust_pos(Offset[1],screen->Height,
	new_window.Height   = Font_height*8+4*screen->Font->ta_YSize+41 );
	new_window.LeftEdge = Adjust_pos(Offset[0],screen->Width,xfin);

	/* Title of the window is the name of our font */
	new_window.Title    = font->tf_Message.mn_Node.ln_Name;
	new_window.Screen   = screen;

	/* Init the position and the size of the minimized window */
	ZoomData[0] = Adjust_pos(Offset[2],screen->Width,
	ZoomData[2] = TextLength(&screen->RastPort,new_window.Title,strlen(new_window.Title))+100);
	ZoomData[1] = Adjust_pos(Offset[3],screen->Height,
	ZoomData[3] = screen->BarHeight+1);

	/* If this call failed, the font is VERY too much big! */
	if( !(window = (void *) OpenWindowTagList(&new_window,WinTags)) )
		/* If ASL is avaible, show a requester to change the font: */
		if( avert(ErrMsg(MSG_FONTREALLYBIG)) && AslBase )
			return TRUE;
		else cleanup(0,0);	/* Game over! */

	/* Signal bit, to process events from the window */
	sigwin = 1 << window->UserPort->mp_SigBit;
	SetMenuStrip(window, menu);	/* Attach the menu to the window */
	Init_helpwin(window);			/* Draws information bar */
	create_gadgets();					/* Creates all gadgets */
	return FALSE;
}

/*** Desallocate all ressources: ***/
void cleanup(UBYTE *msg,WORD err)
{
	extern APTR FR;
	extern void *catalog;

	if (msg)			puts(msg);
	if (window)	{
		/* Save the positions of the window before to close it */
		CopyMem(&window->LeftEdge,Offset,2*sizeof(WORD));
		CopyMem(ZoomData,Offset+2,2*sizeof(WORD));
		/* Now we can restore it's place if it will be reopen */
		ClearMenuStrip(window);
		CloseWindow(window);
		window=NULL; sigwin=0;
	}

	/* These two functions can take a NULL, but let's stay consistent */
	if (glist) FreeGadgets(glist);	glist=0;
	if (vi) FreeVisualInfo(vi);		vi=0;
	if (menu) FreeMenus(menu);			menu=0;

	if (err<0) return;
	Free_commodity();
	if (FR)					FreeAslRequest(FR);
	if (newfont)			CloseFont(newfont);
	if (catalog)			CloseCatalog(catalog);
	if (clipdev)			CBClose(clipdev);
	if (CxBase)				CloseLibrary(CxBase);
	if (AslBase)			CloseLibrary(AslBase);
	if (IconBase)			CloseLibrary(IconBase);
	if (KeymapBase)		CloseLibrary(KeymapBase);
	if (LocaleBase)		CloseLibrary(LocaleBase);
	if (DiskfontBase)		CloseLibrary(DiskfontBase);
	if (GadToolsBase)		CloseLibrary(GadToolsBase);
	if (IntuitionBase)	CloseLibrary(IntuitionBase);
	if (GfxBase)			CloseLibrary(GfxBase);
	exit(err);
}

/*** Draw the table of characters ***/
void Draw_ASCIIChart( void )
{
	extern   WORD OldX;
	register WORD i,x,y;

	/* Initial bevel box, which will be copied 256 times */
	SetFont(RP,font); SetABPenDrMd(RP,0,0,JAM1); BoxTags[2] = TAG_DONE; OldX=0;
	RectFill(RP,xdeb,ydeb,xdeb+MaxWid,ydeb+Font_height);
	DrawBevelBoxA(RP,xdeb,ydeb,MaxWid,Font_height,BoxTags);

	/* Exponential copy (very fast :-) */
	for(x=MaxWid,i=xdeb+x,y=window->Width-10; i<xfin; ) {
		ClipBlit(RP,xdeb,ydeb,RP,i,ydeb,x,Font_height,0xC0);
		i+=x; x<<=1; if(i+x>y) x=y-i;
	}

	for(x=Font_height,i=ydeb+x; i<yfin; i+=x,x<<=1)
		ClipBlit(RP,xdeb,ydeb,RP,xdeb,i,y,x,0xC0);

	SetAPen(RP,txtpen);
	/* Character in each box */
	for(i=CharsetNum==1?0:32,x=xdeb,y=ydeb+font->tf_Baseline+2;
	    i<256; i++, VertSort ? (y+=Font_height):(x+=MaxWid) )
	{
		if( x>=xfin ) x=xdeb, y+=Font_height;
		if( y>=yfin ) x+=MaxWid, y-=Font_height<<3;
		/* 127th char for Amiga charset isn't displayed */
		if(CharsetNum==3 && i==127) { i=159; continue; }
		*Char = i;
		Move(RP,x+(MaxWid-CharWid[i]>>1),y);
		Text(RP,Char,1);
	}
}

/*** Create the gadgets associated with the window ***/
void create_gadgets()
{
#ifdef	__GNUC__
#	define tmpgad		((struct Gadget *)RP)
#else
	struct Gadget *tmpgad;
#endif
	static UBYTE  goff[]={3,0,0,5,4}, toff[]={0,3,4,1,2};
	extern UBYTE *StrBuf;
	struct NewGadget ng;
	UWORD  top,I;

	/* Init some variables */
	top = window->BorderTop + 1;
	gad = (void *) CreateContext(&glist);
	RP  = &screen->RastPort;

	ng.ng_TextAttr = screen->Font;
	ng.ng_VisualInfo = vi;
	I = Layout==LARGE_LAYOUT ? CBLen:(CBLen<<1)+10;

	/* The NewGadget stucture is not modified by any Gadget creation call, so   **
	** you'll only need to change information that actually needs to be changed */
	ng.ng_Flags      = PLACETEXT_LEFT | NG_HIGHLABEL;
	ng.ng_GadgetText = GadTxt[5];
	ng.ng_LeftEdge   = VaLen+10;
	if(ng.ng_LeftEdge+10 > FtLen) ng.ng_LeftEdge=FtLen+10;
 	ng.ng_Width      = window->Width - 20 - I - ng.ng_LeftEdge - (
	ng.ng_Height     = VaLen = screen->Font->ta_YSize+6);
	ng.ng_TopEdge    = top+5;
	ng.ng_GadgetID   = 10;

	/** String gadget **/
	tmpgad = gad = (void *) CreateGadget(STRING_KIND, gad, &ng, GTST_MaxChars,50,TAG_DONE);
	StrBuf = sti(gad)->Buffer;

	/** Name of the charset displayed in the cycle gad: **/
	CycleTags[3]=CharsetNum-1;

	/** Creates the 5 gadgets shortcut (Sorry for this very crap code...) **/
	ng.ng_LeftEdge -= 10;
	ng.ng_Flags     = PLACETEXT_IN;
	for(I=0; I<5; I++)
	{
		ng.ng_GadgetID    = I;
		ng.ng_GadgetText  = GadTxt[ toff[I] ];
		if(I!=2 || Layout!=LARGE_LAYOUT) ng.ng_LeftEdge+=ng.ng_Width+10; else goto next_row;
		ng.ng_Width       = Wid[ goff[I] ];

		if(I==3) { ng.ng_Flags = PLACETEXT_LEFT | NG_HIGHLABEL; ng.ng_LeftEdge = FtLen+10;
		           if( Layout != LARGE_LAYOUT )
		next_row:  ng.ng_Height -= 2, top = (ng.ng_TopEdge += ng.ng_Height+6); }

		if(I==4) ng.ng_LeftEdge += ChrLen;

		tmpgad = (void *) CreateGadgetA(I<=2 ? BUTTON_KIND:CYCLE_KIND, tmpgad, &ng,
								I==4 ? CycleTags : I==3 ? FontTags:NULL);

		if(I==1) copy_gad=tmpgad; if(I==2) paste_gad=tmpgad;

		/* If a ressource isn't available, disable the corresponding gadget */
		if(GadDisable & (1<<I)) tmpgad->Flags |= GADGDISABLED;
	}

	/*	Now we're ready to add the Gadget list. Quit if the final Gadget pointer is **
	** NULL - this means that one of the Gadget allocations failed. If it exists,  **
	** add it to the window and refresh, then add the new GT_RefreshWindow() call. */
	if (!tmpgad)
		cleanup(ErrMsg(MSG_ERRGADGET),30);

	/** Refresh everything **/
	AddGList(window, glist, (UWORD)-1, (UWORD)-1, NULL);
	RefreshGList(glist, window, NULL, (UWORD)-1);
	GT_RefreshWindow(window, NULL);
	RP=window->RPort;

	/** Draw the ASCII table **/
	xdeb = 10;			ydeb = top+ng.ng_Height+5;
	xfin -= 10;			yfin  = ydeb+Font_height*8;
	Draw_ASCIIChart();
}
