
#include "psm.h"

/**
 ** Definition of newscrn window
 **/

enum {
    
    PUBNAME_ID = 1,
    TITLE_ID,

    MODELIST_ID,
    MODEINFO_ID,

    STDCLIP_ID,
    MINCLIPX_ID,
    MINCLIPY_ID,
    MAXCLIPX_ID,
    MAXCLIPY_ID,
    WIDTH_ID,
    DEFWIDTH_ID,
    HEIGHT_ID,
    DEFHEIGHT_ID,
    AUTOSCROLL_ID,
    
    SETFONT_ID,
    SETFONTKEY_ID,
    FONTNAME_ID,
    FONTSIZE_ID,
    
    DEPTH_ID,
    SCRNPAL_ID,
    SCRNPALKEY_ID,
    PALRED_ID,
    PALREDKEY_ID,
    PALGREEN_ID,
    PALGREENKEY_ID,
    PALBLUE_ID,
    PALBLUEKEY_ID,
    
    CURPEN_ID,
    PENPAL_ID,
    PENPALKEY_ID,
    
    OPEN_ID,
    MODIFY_ID,

    WINTAGS_ID
};

#define CUSTCLIP_GID GO_GRPID_A
#define FOLLOWMOUSE_GID GO_GRPID_B
#define SMALLWIN_GID GO_GRPID_C

#define TEXT_LEN 124 //MAXPUBSCREENNAME //252
#define FONT_LEN 32
#define DIMEN_LEN 128

#define CLIP_STANDARD 0
#define CLIP_MINIMUM 1
#define CLIP_TEXT 2
#define CLIP_VIDEO 3
#define CLIP_MAXIMUM 4
#define CLIP_CUSTOM 5

UBYTE *ClipLabels[] = {
    "Standard", "Minimum", "Text", "Video", "Maximum", "Custom", NULL,
};

#define SIZE_PEN_ARRAY 9

UBYTE *PenLabels[SIZE_PEN_ARRAY+1] = {
    "Detail", "Block", "Text", "Shine", "Shadow", "Fill", "FillText",
    "Backgrnd", "Highlight", NULL
};

#define SIZE_DEPTH_ARRAY 8

UBYTE *DepthLabels[SIZE_DEPTH_ARRAY+1] = {
    "2 colors", "4 colors", "8 colors", "16 colors", "32 colors",
    "64 colors", "128 colors", "256 colors", NULL
};

#define GOUS_VisibleSize (GOCT_User+1)
#define GOUS_MinimumSize (GOCT_User+2)
#define GOUS_MaximumSize (GOCT_User+3)
#define GOUS_MaximumColors (GOCT_User+4)
#define GOUS_ClippingSize (GOCT_User+5)

static ULONG __saveds __interrupt
newscrn_handler(struct GadOutline *go, ULONG command, struct GOIMsg *msg);

static ULONG ModeInfoDrawing[] = {

    GODT_ResetBounds, GO_FRMBOUNDS(1,1,1,1, 5,5,5,5),
    GODT_SetStdFillPat, 1,
    GODT_ChooseBPen, BACKGROUNDPEN,
    GODT_SetRastMode, FLGALL(JAM2),
    GODT_FillRect, GO_SCLPNT(SHADOWPEN,0,16,63,48),

    GODT_SetStdFillPat, 0,
    GODT_DrawStrFrame, GO_SCLPNT(SHADOWPEN,0,16,63,48),
    GODT_ResetBounds, GO_BOXBOUNDS(3,3,3,3),
    GODT_SetTextMode, FLGALL(TXTMD_LEFT | TXTMD_ENDRIGHT | TXTMD_RELTOP),

    GODT_SetLeftBound, GO_TSIZE(GOM_Add,2,GOT_Pixels),
    GODT_SetTopBound, GO_TSIZE(GOM_Add,2,GOT_Pixels),
    GODT_MoveTo, GO_SCLPNT(0,0,0,0,0),
    GODT_SetRastMode, FLGALL(JAM1),
    GODT_ChooseTextAPen, SHADOWPEN,
    GODT_DrawText, (ULONG)&"Vis Size: ",
    GODT_DrawTextTag, GOUS_VisibleSize,
    GODT_NewLine, 1,
    GODT_DrawText, (ULONG)&"Min Size: ",
    GODT_DrawTextTag, GOUS_MinimumSize,
    GODT_NewLine, 1,
    GODT_DrawText, (ULONG)&"Max Size: ",
    GODT_DrawTextTag, GOUS_MaximumSize,
    GODT_NewLine, 1,
    GODT_DrawText, (ULONG)&"Max Colors: ",
    GODT_DrawTextTag, GOUS_MaximumColors,
    GODT_NewLine, 1,
    GODT_DrawText, (ULONG)&"Clip: ",
    GODT_DrawTextTag, GOUS_ClippingSize,

    GODT_SetLeftBound, GO_TSIZE(GOM_Add,-2,GOT_Pixels),
    GODT_SetTopBound, GO_TSIZE(GOM_Add,-2,GOT_Pixels),
    GODT_MoveTo, GO_SCLPNT(0,0,0,0,0),
    GODT_ChooseTextAPen, FILLPEN,
    GODT_DrawHighText, (ULONG)&"Vis Size: ",
    GODT_DrawTextTag, GOUS_VisibleSize,
    GODT_NewLine, 1,
    GODT_DrawHighText, (ULONG)&"Min Size: ",
    GODT_DrawTextTag, GOUS_MinimumSize,
    GODT_NewLine, 1,
    GODT_DrawHighText, (ULONG)&"Max Size: ",
    GODT_DrawTextTag, GOUS_MaximumSize,
    GODT_NewLine, 1,
    GODT_DrawHighText, (ULONG)&"Max Colors: ",
    GODT_DrawTextTag, GOUS_MaximumColors,
    GODT_NewLine, 1,
    GODT_DrawHighText, (ULONG)&"Clip: ",
    GODT_DrawTextTag, GOUS_ClippingSize,
    TAG_END
};

#define FL_LEFT 12
#define FL_MIDLEFT 30
#define FL_TOP 12
#define FL_MIDTOP 22
#define FL_BOTTOM 51
#define FL_RIGHT 51
#define FL_BOLDEN 5

#define FL_TABLEFT FL_MIDLEFT+5
#define FL_TABRIGHT FL_RIGHT-5
#define FL_TABBOTTOM FL_MIDTOP+FL_BOLDEN+6

static ULONG FolderDrawing[] = {
    GODT_FillRect, GO_SCLPNT(BACKGROUNDPEN,0,0,63,63),
    GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63),
    GODT_FillRect,
        GO_SCLPNT(TEXTPEN,FL_LEFT,FL_MIDTOP,FL_LEFT+FL_BOLDEN,FL_BOTTOM),
    GODT_FillRect,
        GO_SCLPNT(TEXTPEN,FL_LEFT,FL_MIDTOP,FL_MIDLEFT,FL_MIDTOP+FL_BOLDEN),
    GODT_MoveTo,
        GO_SCLPNT(0,FL_MIDLEFT,FL_MIDTOP,0,0),
    GODT_DrawTo2,
        GO_SCLPNT(TEXTPEN,FL_TABLEFT,FL_TOP,FL_TABRIGHT,FL_TOP),
    GODT_DrawTo2,
        GO_SCLPNT(TEXTPEN,FL_RIGHT,FL_MIDTOP,FL_RIGHT,FL_BOTTOM),
    GODT_DrawTo,
        GO_SCLPNT(TEXTPEN,FL_LEFT,FL_BOTTOM,0,0),
    GODT_MoveTo,
        GO_SCLPNT(0,FL_MIDLEFT,FL_MIDTOP+FL_BOLDEN,0,0),
    GODT_DrawTo2,
        GO_SCLPNT(TEXTPEN,FL_TABLEFT,FL_TABBOTTOM,FL_RIGHT,FL_TABBOTTOM),
    TAG_END,
};

#define STD_REPORT_LEVEL \
          (1L<<GOTYPE_FINE)  | (1L<<GOTYPE_FINE2) \
        | (1L<<GOTYPE_NOTE)  | (1L<<GOTYPE_NOTE2) \
        | (1L<<GOTYPE_WARN)  | (1L<<GOTYPE_WARN2) \
        | (1L<<GOTYPE_ALERT) | (1L<<GOTYPE_ALERT2) | (1L<<GOTYPE_ALERT3) \
        | (1L<<GOTYPE_FAIL)  | (1L<<GOTYPE_FAIL2)  | (1L<<GOTYPE_FAIL3)

static ULONG newscrn_outline[] = {

GO_OUTLINETAGS(0,0),
    TAG_END,
    GOA_BaseName,           (ULONG)&__BaseName[0],
    GOA_SetUserHandler,     (ULONG)&newscrn_handler,
    GOA_SetTransHookData,   NULL,
    GOA_ErrorReportLevel,   STD_REPORT_LEVEL,
    TAG_END,

GO_WINDOWTAGS(0,WINTAGS_ID),
    TAG_END,
    WA_Title,           (ULONG)&"Open Screen",
    WA_ScreenTitle,     (ULONG)&__LongTitle[0],
    WA_IDCMP,           IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW,
    WA_Activate,        TRUE,
    WA_CloseGadget,     TRUE,
    WA_DepthGadget,     TRUE,
    WA_DragBar,         TRUE,
    WA_SizeGadget,      TRUE,
    WA_SizeBBottom,     TRUE,
    WA_SimpleRefresh,   TRUE,
    WA_BackFill,        NULL,
    TAG_END,

GO_COMMANDTAGS(0,0),
    TAG_END,
    TAG_END,

GO_VERTGRP(0,0,1),
GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,80,GOT_PercCharH),
GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,80,GOT_PercCharW),
GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
TAG_END,

    GO_HORIZGRP(0,0,1), TAG_END,
    
        GO_VERTGRP(0,0,1), TAG_END,
        
            GO_VDRAWGRP(0,0,0),
            GOCT_SizeSpaceAbove, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
            GOCT_SizeSpaceBelow, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
            GOCT_SizeSpaceLeft, GO_TSIZE(GOM_StdSet,50,GOT_PercCharW),
            GOCT_SizeSpaceRight, GO_TSIZE(GOM_StdSet,50,GOT_PercCharW),
            TAG_END,
            GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63),
            TAG_END,
        
                GO_GTBOX(STRING_KIND,0,PUBNAME_ID,0,(ULONG)&"Public _Name:",PLACETEXT_LEFT|NG_HIGHLABEL),
                GOCT_SetHotKey, HOTKEY_LOWONLY | 'n',
                TAG_END,
                GTST_MaxChars, TEXT_LEN,
                GTST_String, (ULONG)&"",
                GT_Underscore, '_',
                GA_Disabled, FALSE,
                TAG_END,

                GO_GTBOX(STRING_KIND,0,TITLE_ID,0,(ULONG)&"_Title:",PLACETEXT_LEFT|NG_HIGHLABEL),
                GOCT_SetHotKey, HOTKEY_LOWONLY | 't',
                TAG_END,
                GTST_MaxChars, TEXT_LEN,
                GTST_String, (ULONG)&"",
                GT_Underscore, '_',
                GA_Disabled, FALSE,
                TAG_END,

            GO_ENDGRP(),

            GO_EMPTYBOX(0,0,0), TAG_END,

            GO_HORIZGRP(0,0,1), TAG_END,
            
                GO_GTBOX(LISTVIEW_KIND, 0, MODELIST_ID, 1,
                    (ULONG)&"_Modes", PLACETEXT_ABOVE|NG_HIGHLABEL),
                GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,500,GOT_PercCharH),
                GOCT_SizeUser1, GO_TSIZE(GOM_VarSet,200,GOT_PercCharW),
                GOCT_CopyUser1ToTag, GTLV_ScrollWidth,
                GOCT_SetHotKey, 'm',
                TAG_END,
                GTLV_Labels, NULL,
                GTLV_Top, 0,
                GTLV_Selected, ~0,
                GTLV_ShowSelected, NULL,
                GTLV_ScrollWidth, 16,
                GT_Underscore, '_',
                GA_Disabled, FALSE,
                TAG_END,
                
                GO_EMPTYBOX(0,0,0), TAG_END,
                
                GO_DRAWBOX(GOSD_Normal,0,MODEINFO_ID,1),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_StdSet,2,GOT_Pixels),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_StdSet,2,GOT_Pixels),
                GOCT_SizeSpaceAbove, GO_TSIZE(GOM_StdSet,1,GOT_Pixels),
                GOCT_SizeSpaceBelow, GO_TSIZE(GOM_StdSet,1,GOT_Pixels),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,50,GOT_PercCharW),
                GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
                GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,50,GOT_PercCharH),
                GOCT_SizeBodyWidth, GO_TSIZE(GOM_PadSet,500,GOT_PercCharW),
                GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdSet,300,GOT_PercCharH),
                TAG_END,
                GOUS_VisibleSize, NULL,
                GOUS_MinimumSize, NULL,
                GOUS_MaximumSize, NULL,
                GOUS_MaximumColors, NULL,
                GOUS_ClippingSize, NULL,
                GODT_ExecDrawing, (ULONG)&ModeInfoDrawing[0],
                TAG_END,

            GO_ENDGRP(),
        
        GO_HORIZGRP(0,0,0), TAG_END,
        
            GO_VERTGRP(SMALLWIN_GID,0,0), TAG_END,
            
                GO_GTBOX(CYCLE_KIND,0,STDCLIP_ID,0,(ULONG)&"O_verscan:",PLACETEXT_LEFT|NG_HIGHLABEL),
                GOCT_SetHotKey, 'v',
                TAG_END,
                GTCY_Labels, (ULONG)&ClipLabels[0],
                GTCY_Active, 0,
                GT_Underscore, '_',
                GA_Disabled, FALSE,
                TAG_END,
                
                GO_HORIZGRP(0,0,0), TAG_END,
                
                    GO_GTBOX(INTEGER_KIND,CUSTCLIP_GID,MINCLIPX_ID,1,(ULONG)&"M_in:",PLACETEXT_LEFT|NG_HIGHLABEL),
                    GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,300,GOT_PercChar0),
                    GOCT_SetHotKey, HOTKEY_LOWONLY | 'i',
                    TAG_END,
                    GTIN_Number, 0,
                    GTIN_MaxChars, 5,
                    GT_Underscore, '_',
                    GA_Disabled, FALSE,
                    TAG_END,
                
                    GO_GTBOX(TEXT_KIND,0,0,0,(ULONG)&"x",PLACETEXT_IN),
                    TAG_END,
                    GT_Underscore, '_',
                    GA_Disabled, FALSE,
                    TAG_END,
                
                    GO_GTBOX(INTEGER_KIND,CUSTCLIP_GID,MINCLIPY_ID,1,NULL,0),
                    GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,300,GOT_PercChar0),
                    GOCT_SetHotKey, HOTKEY_UPONLY | 'i',
                    TAG_END,
                    GTIN_Number, 0,
                    GTIN_MaxChars, 5,
                    GT_Underscore, '_',
                    GA_Disabled, FALSE,
                    TAG_END,
                    
                GO_ENDGRP(),
                
                GO_HORIZGRP(0,0,0), TAG_END,
                
                    GO_GTBOX(INTEGER_KIND,CUSTCLIP_GID,MAXCLIPX_ID,1,(ULONG)&"M_ax:",PLACETEXT_LEFT|NG_HIGHLABEL),
                    GOCT_SetHotKey, HOTKEY_LOWONLY | 'a',
                    GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,300,GOT_PercChar0),
                    TAG_END,
                    GTIN_Number, 0,
                    GTIN_MaxChars, 5,
                    GT_Underscore, '_',
                    GA_Disabled, FALSE,
                    TAG_END,
                
                    GO_GTBOX(TEXT_KIND,0,0,0,(ULONG)&"x",PLACETEXT_IN),
                    TAG_END,
                    GT_Underscore, '_',
                    GA_Disabled, FALSE,
                    TAG_END,
                
                    GO_GTBOX(INTEGER_KIND,CUSTCLIP_GID,MAXCLIPY_ID,1,NULL,0),
                    GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,300,GOT_PercChar0),
                    GOCT_SetHotKey, HOTKEY_UPONLY | 'a',
                    TAG_END,
                    GTIN_Number, 0,
                    GTIN_MaxChars, 5,
                    GT_Underscore, '_',
                    GA_Disabled, FALSE,
                    TAG_END,
                    
                GO_ENDGRP(),
                
            GO_ENDGRP(),
            
            GO_VERTGRP(0,0,0), TAG_END,
            
                GO_VERTGRP(0,0,0), GOCT_FitToGroup, TRUE, TAG_END,
                
                    GO_HORIZGRP(0,0,0), TAG_END,

                        GO_GTBOX(INTEGER_KIND,0,WIDTH_ID,1,(ULONG)&"_Width:",PLACETEXT_LEFT|NG_HIGHLABEL),
                        GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,300,GOT_PercChar0),
                        GOCT_SetHotKey, HOTKEY_LOWONLY | 'w',
                        TAG_END,
                        GTIN_Number, 0,
                        GTIN_MaxChars, 5,
                        GT_Underscore, '_',
                        GA_Disabled, FALSE,
                        TAG_END,

                        GO_GTBOX(CHECKBOX_KIND,0,DEFWIDTH_ID,0,(ULONG)&"Defa_ult",PLACETEXT_RIGHT),
                        GOCT_SetHotKey, 'u',
                        TAG_END,
                        GTCB_Checked, FALSE,
                        GT_Underscore, '_',
                        GA_Disabled, FALSE,
                        TAG_END,
                        
                    GO_ENDGRP(),
                
                    GO_HORIZGRP(0,0,0), TAG_END,

                        GO_GTBOX(INTEGER_KIND,0,HEIGHT_ID,1,(ULONG)&"_Height:",PLACETEXT_LEFT|NG_HIGHLABEL),
                        GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,300,GOT_PercChar0),
                        GOCT_SetHotKey, HOTKEY_LOWONLY | 'h',
                        TAG_END,
                        GTIN_Number, 0,
                        GTIN_MaxChars, 5,
                        GT_Underscore, '_',
                        GA_Disabled, FALSE,
                        TAG_END,
                        
                        GO_GTBOX(CHECKBOX_KIND,0,DEFHEIGHT_ID,0,(ULONG)&"Defau_lt",PLACETEXT_RIGHT),
                        GOCT_SetHotKey, 'l',
                        TAG_END,
                        GTCB_Checked, FALSE,
                        GT_Underscore, '_',
                        GA_Disabled, FALSE,
                        TAG_END,
                        
                    GO_ENDGRP(),
                    
                GO_ENDGRP(),
                
                GO_GTBOX(CHECKBOX_KIND,0,AUTOSCROLL_ID,
                    GO_WEIGHT(GO_WDIST(1,0,0,0,0,1),0,0),
                    (ULONG)&"Auto_Scroll",PLACETEXT_RIGHT),
                GOCT_SetHotKey, 's',
                TAG_END,
                GTCB_Checked, TRUE,
                GT_Underscore, '_',
                GA_Disabled, FALSE,
                TAG_END,
                
            GO_ENDGRP(),
            
        GO_ENDGRP(),

        GO_HORIZGRP(0,0,0), TAG_END,

            GO_GTBOX(TEXT_KIND, 0, SETFONTKEY_ID, 0, (ULONG)&"_Font:", PLACETEXT_LEFT|NG_HIGHLABEL),
            TAG_END,
            GT_Underscore, '_',
            GA_Disabled, FALSE,
            TAG_END,

            GO_HORIZGRP(0,0,1), GOCT_FitToGroup, TRUE, TAG_END,
            
                GO_DRAWBOX(GOSD_BoopsiGad,0,SETFONT_ID,0),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdSet,4,GOT_Pixels),
                GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,200,GOT_PercCharW),
                GOCT_SizeBodyWidth, GO_TSIZE(GOM_PadSet,4,GOT_Pixels),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SetHotKey, HOTKEY_UPONLY | 'f',
                TAG_END,
                GODT_ExecDrawing, (ULONG)&FolderDrawing[0],
                TAG_END,
            
                GO_GTBOX(STRING_KIND, 0, FONTNAME_ID, 1, NULL, 0),
                GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,400,GOT_PercCharW),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SetHotKey, HOTKEY_LOWONLY | 'f',
                TAG_END,
                GTST_MaxChars, FONT_LEN, GTST_String, (ULONG)&"",
                GT_Underscore, '_',
                GA_Disabled, FALSE,
                TAG_END,

                GO_GTBOX(INTEGER_KIND, 0, FONTSIZE_ID, 0, (ULONG)&"pnt_.", PLACETEXT_RIGHT),
                GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdAdd,400,GOT_PercChar0),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SetHotKey, HOTKEY_LOWONLY | '.',
                TAG_END,
                GTIN_MaxChars, 3, GTIN_Number, 0,
                GT_Underscore, '_',
                GA_Disabled, FALSE,
                TAG_END,
            
            GO_ENDGRP(),
    
            GO_EMPTYBOX(0,0,0), TAG_END,

            GO_VDRAWGRP(0,0,0),
            TAG_END,
            GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63),
            TAG_END,
            
                GO_GTBOX(BUTTON_KIND, 0, OPEN_ID, 0, (ULONG)&"_Open", PLACETEXT_IN),
                GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,1,GOT_Pixels),
                GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,1,GOT_Pixels),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,2,GOT_Pixels),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,2,GOT_Pixels),
                GOCT_IgnoreMinDimens, TRUE,
                GOCT_IgnoreFinDimens, TRUE,
                GOCT_IgnoreCreation, TRUE,
                TAG_END,
                GA_Disabled, FALSE,
                GT_Underscore, '_',
                TAG_END,

                GO_GTBOX(BUTTON_KIND, 0, MODIFY_ID, 0, (ULONG)&"M_odify", PLACETEXT_IN),
                GOCT_SizeSpaceAbove, GO_TSIZE(GOM_PadSet,1,GOT_Pixels),
                GOCT_SizeSpaceBelow, GO_TSIZE(GOM_PadSet,1,GOT_Pixels),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_PadSet,2,GOT_Pixels),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_PadSet,2,GOT_Pixels),
                GOCT_IgnoreMinDimens, TRUE,
                GOCT_IgnoreFinDimens, TRUE,
                GOCT_IgnoreCreation, TRUE,
                TAG_END,
                GA_Disabled, FALSE,
                GT_Underscore, '_',
                TAG_END,
            
            GO_ENDGRP(),

        GO_ENDGRP(),
        
    GO_ENDGRP(),

    GO_EMPTYBOX(0,0,0), TAG_END,
    
    GO_VERTGRP(SMALLWIN_GID,0,0),
    GOCT_IgnoreMinDimens, TRUE,
    GOCT_IgnoreFinDimens, TRUE,
    GOCT_IgnoreCreation, TRUE,
    TAG_END,
    
        GO_VDRAWGRP(0,0,1),
        GOCT_SizeSpaceAbove, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
        GOCT_SizeSpaceBelow, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
        GOCT_SizeSpaceLeft, GO_TSIZE(GOM_StdSet,50,GOT_PercCharW),
        GOCT_SizeSpaceRight, GO_TSIZE(GOM_StdSet,50,GOT_PercCharW),
        TAG_END,
        GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63),
        TAG_END,

            GO_GTBOX(CYCLE_KIND,0,DEPTH_ID,0,(ULONG)&"_Palette",PLACETEXT_ABOVE|NG_HIGHLABEL),
            GOCT_SetHotKey, 'd',
            TAG_END,
            GTCY_Labels, (ULONG)&DepthLabels[0],
            GTCY_Active, 0,
            GT_Underscore, '_',
            GA_Disabled, FALSE,
            TAG_END,
                
            GO_GTBOX(PALETTE_KIND, 0, SCRNPAL_ID, 1, NULL, 0),
            GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,500,GOT_PercCharW),
            GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,200,GOT_PercCharH),
            GOCT_CopyFromTSize, GO_TSIZE(GOM_StdSet,15,GOT_Pixels),
            GOCT_CopyTSizeToTag, GTPA_IndicatorHeight,
            GOCT_SizeUser1, GO_TSIZE(GOM_VarSet,20,GOT_PercBodyH),
            GOCT_SizeUser1, GO_TSIZE(GOM_VarMin,250,GOT_PercCharH),
            GOCT_SizeUser1, GO_TSIZE(GOM_VarMax,6,GOT_Pixels),
            GOCT_CopyUser1ToTag, GTPA_IndicatorHeight,
            GOCT_SetHotKey, 'p',
            TAG_END,
            GTPA_IndicatorHeight, 15,
            GT_Underscore, '_',
            GTPA_Color, 0,
            GTPA_Depth, 2,
            TAG_END,

            GO_HORIZGRP(0,0,0), TAG_END,

                GO_GTBOX(SLIDER_KIND, FOLLOWMOUSE_GID, PALRED_ID, 1, NULL, 0),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SetHotKey, 'r',
                TAG_END,
                GA_RelVerify, TRUE, GA_Immediate, TRUE,
                PGA_FREEDOM, LORIENT_HORIZ,
                GTSL_Min, 0, GTSL_Max, 15,
                GTSL_Level, 0, GTSL_LevelFormat, (ULONG)&"%02ld",
                GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2,
                GT_Underscore, '_',
                TAG_END,

                GO_GTBOX(TEXT_KIND, 0, PALREDKEY_ID, 0, (ULONG)&"_R", PLACETEXT_IN|NG_HIGHLABEL),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                TAG_END,
                GTTX_Border, TRUE, // GTTX_Text, GTTX_CopyText
                GT_Underscore, '_',
                TAG_END,

            GO_ENDGRP(),
            
            GO_HORIZGRP(0,0,0), TAG_END,
            
                GO_GTBOX(SLIDER_KIND, FOLLOWMOUSE_GID, PALGREEN_ID, 1, NULL, 0),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SetHotKey, 'g',
                TAG_END,
                GA_RelVerify, TRUE, GA_Immediate, TRUE,
                PGA_FREEDOM, LORIENT_HORIZ,
                GTSL_Min, 0, GTSL_Max, 15,
                GTSL_Level, 0, GTSL_LevelFormat, (ULONG)&"%02ld",
                GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2,
                GT_Underscore, '_',
                TAG_END,

                GO_GTBOX(TEXT_KIND, 0, PALGREENKEY_ID, 0, (ULONG)&"_G", PLACETEXT_IN|NG_HIGHLABEL),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                TAG_END,
                GTTX_Border, TRUE, // GTTX_Text, GTTX_CopyText
                GT_Underscore, '_',
                TAG_END,

            GO_ENDGRP(),

            GO_HORIZGRP(0,0,0), TAG_END,
            
                GO_GTBOX(SLIDER_KIND, FOLLOWMOUSE_GID, PALBLUE_ID, 1, NULL, 0),
                GOCT_SizeSpaceRight, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                GOCT_SetHotKey, 'b',
                TAG_END,
                GA_RelVerify, TRUE, GA_Immediate, TRUE,
                PGA_FREEDOM, LORIENT_HORIZ,
                GTSL_Min, 0, GTSL_Max, 15,
                GTSL_Level, 0, GTSL_LevelFormat, (ULONG)&"%02ld",
                GTSL_LevelPlace, PLACETEXT_LEFT, GTSL_MaxLevelLen, 2,
                GT_Underscore, '_',
                TAG_END,

                GO_GTBOX(TEXT_KIND, 0, PALBLUEKEY_ID, 0, (ULONG)&"_B", PLACETEXT_IN|NG_HIGHLABEL),
                GOCT_SizeSpaceLeft, GO_TSIZE(GOM_AllSet,0,GOT_Pixels),
                TAG_END,
                GTTX_Border, TRUE, // GTTX_Text, GTTX_CopyText
                GT_Underscore, '_',
                TAG_END,

            GO_ENDGRP(),
            
        GO_ENDGRP(),

        GO_EMPTYBOX(0,0,0), TAG_END,
    
        GO_VDRAWGRP(0,0,1),
        GOCT_SizeSpaceAbove, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
        GOCT_SizeSpaceBelow, GO_TSIZE(GOM_StdSet,50,GOT_PercCharH),
        GOCT_SizeSpaceLeft, GO_TSIZE(GOM_StdSet,50,GOT_PercCharW),
        GOCT_SizeSpaceRight, GO_TSIZE(GOM_StdSet,50,GOT_PercCharW),
        TAG_END,
        GODT_DrawStdFrame, GO_SCLPNT(SHINEPEN,0,0,63,63),
        TAG_END,

            GO_GTBOX(CYCLE_KIND,0,CURPEN_ID,0,(ULONG)&"Drawing P_ens",PLACETEXT_ABOVE|NG_HIGHLABEL),
            GOCT_SetHotKey, 'e',
            TAG_END,
            GTCY_Labels, (ULONG)&PenLabels[0],
            GTCY_Active, 0,
            GT_Underscore, '_',
            GA_Disabled, FALSE,
            TAG_END,
                
            GO_GTBOX(PALETTE_KIND, 0, PENPAL_ID, 1, NULL, 0),
            GOCT_SizeBodyWidth, GO_TSIZE(GOM_StdMax,500,GOT_PercCharW),
            GOCT_SizeBodyHeight, GO_TSIZE(GOM_StdMax,200,GOT_PercCharH),
            GOCT_CopyFromTSize, GO_TSIZE(GOM_StdSet,15,GOT_Pixels),
            GOCT_CopyTSizeToTag, GTPA_IndicatorHeight,
            GOCT_SizeUser1, GO_TSIZE(GOM_VarSet,20,GOT_PercBodyH),
            GOCT_SizeUser1, GO_TSIZE(GOM_VarMin,250,GOT_PercCharH),
            GOCT_SizeUser1, GO_TSIZE(GOM_VarMax,6,GOT_Pixels),
            GOCT_CopyUser1ToTag, GTPA_IndicatorHeight,
            GOCT_SetHotKey, 'z',
            TAG_END,
            GTPA_IndicatorHeight, 15,
            GT_Underscore, '_',
            GTPA_Color, 0,
            GTPA_Depth, 2,
            TAG_END,
            
        GO_ENDGRP(),

    GO_ENDGRP(),

GO_ENDGRP(),

GO_ENDOUTLINE()
};

/**
 ** Handler for NewScreen window
 **/

struct newscrn_globals {
    struct FontRequester *font_req;
    ULONG flags;
    
    #define NSF_MODIFY (1<<0)

    struct ModeEntry *cur_mode;
    struct ColorSpec *cur_color;
    UWORD *cur_pen;
    struct Rectangle *cur_clip;

    struct Hook bf_hook;
    UBYTE *depth_labels[SIZE_DEPTH_ARRAY+1];
    UBYTE *pen_labels[SIZE_PEN_ARRAY+1];
    struct ColorSpec color_specs[(1<<SIZE_DEPTH_ARRAY)+1];
    struct ColorSpec orig_specs[(1<<SIZE_DEPTH_ARRAY)+1];
    UWORD pens[SIZE_PEN_ARRAY+1];
    UWORD cur_depth;
    struct Rectangle clip;

    UBYTE vis_size[DIMEN_LEN];
    UBYTE min_size[DIMEN_LEN];
    UBYTE max_size[DIMEN_LEN];
    UBYTE max_colors[DIMEN_LEN];
    UBYTE clip_size[DIMEN_LEN];
};

#define CURPUBNAME ((UBYTE *)GO_GetObjAttr(go,PUBNAME_ID,0, GTST_String,(ULONG)&""))

#define OSERR_LAST (OSERR_UNKNOWNMODE+1)

static UBYTE *open_errs[OSERR_LAST+1] = {
    "None", "Monitor not available",
    "Requires newer custom chips", "Not enough memory",
    "Not enough chip memory", "Public name not unique",
    "Don't recognize requested mode", "Unknown error"
};

static void set_modify(struct GadOutline *go,struct Screen *scrn)
{
    struct newscrn_globals *gl;

    if(!go) return;
    gl = go->go_UserData;
    
    if(scrn) gl->flags |= NSF_MODIFY;
    else gl->flags &= ~(NSF_MODIFY);

    GO_SetObjAttrs(go,WINTAGS_ID,0,
        WA_Title,scrn ? "Modify Screen" : "Open Screen", TAG_END);
    GO_SetCmdAttrs(go,MODIFY_ID,0,
                        GOCT_IgnoreMinDimens, !scrn,
                        GOCT_IgnoreFinDimens, !scrn,
                        GOCT_IgnoreCreation, !scrn,
                        TAG_END);
    GO_SetCmdAttrs(go,OPEN_ID,0,
                        GOCT_IgnoreMinDimens, scrn,
                        GOCT_IgnoreFinDimens, scrn,
                        GOCT_IgnoreCreation, scrn,
                        TAG_END);
    GO_AttachHotKey(go,'o',0);
    GO_AttachHotKey(go,'o',scrn ? MODIFY_ID : OPEN_ID);
}

UBYTE *strdup_track(void *track,UBYTE *str)
{
    UBYTE *dup;

    if(!str) return NULL;

    dup = AllocScrnTrackMem(track,strlen(str)+2);
    if(dup != NULL) strcpy(dup,str);
    return dup;
}

void mem_err(struct GadOutline *go,void *track)
{
    if(track) FreeScrnTrack(track);
    GO_ShowError(go,GO_MAKEERR(GOTYPE_FAIL,0),NULL,"Not enough memory.");
}

static struct Window *open_window(struct GadOutline *go,ULONG tags,...)
{
    // Window must be unlocked.
    UnlockGadOutline(go);

    // Tell GadOutline library to be quiet.
    UpdateGadOutline(go,GOA_ErrorReportLevel,0,TAG_END);

    // And start out trying a full-size window.
    GO_SetCmdGrpAttrs(go,GO_CMDID(SMALLWIN_GID,0),0,
                        GOCT_IgnoreMinDimens, FALSE,
                        GOCT_IgnoreFinDimens, FALSE,
                        GOCT_IgnoreCreation, FALSE,
                        TAG_END);

    if( !GO_OpenWindowA(go,(struct TagItem *)&tags) || go->go_LastReqReturn ) {
        GO_SetCmdGrpAttrs(go,GO_CMDID(SMALLWIN_GID,0),0,
                            GOCT_IgnoreMinDimens, TRUE,
                            GOCT_IgnoreFinDimens, TRUE,
                            GOCT_IgnoreCreation, TRUE,
                            TAG_END);

        UpdateGadOutline(go,GOA_ErrorReportLevel,STD_REPORT_LEVEL,TAG_END);
        
        if( !GO_OpenWindowA(go,(struct TagItem *)&tags) || go->go_LastReqReturn ) {
            return NULL;
        }
    }

    UpdateGadOutline(go,GOA_ErrorReportLevel,STD_REPORT_LEVEL,TAG_END);
    return go->go_Window;
}

static struct Screen *open_screen(struct GadOutline *go)
{
    void *track;
    struct Screen *scrn;
    struct newscrn_globals *gl;
    struct TextAttr *ta;
    UBYTE *title;
    LONG error;
    UBYTE depth;

    if( !(track = AllocScrnTrack()) ) {
        mem_err(go,track);
        return NULL;
    }

    if( !(ta=AllocScrnTrackMem(track,sizeof(struct TextAttr))) ) {
        mem_err(go,track);
        return NULL;
    }

    if( !(ta->ta_Name=strdup_track(track,
            (UBYTE *)GO_GetObjAttr(go,FONTNAME_ID,0, GTST_String,NULL))) ) {
        mem_err(go,track);
        return NULL;
    }

    ta->ta_YSize = GO_GetObjAttr(go,FONTSIZE_ID,0, GTIN_Number,0);
    ta->ta_Style = FS_NORMAL;
    ta->ta_Flags = FPF_DISKFONT;
    depth = GO_GetObjAttr(go,DEPTH_ID,0, GTCY_Active,0)+1;

    if(!go) return NULL;
    gl = go->go_UserData;
    
    gl->color_specs[1<<depth].ColorIndex = -1;
    
    // Make sure the font is available in RAM.
    {
        struct TextFont *font;
        
        if(font = OpenDiskFont(ta)) CloseFont(font);
    }
    
    title = (UBYTE *)GO_GetObjAttr(go,TITLE_ID,0, GTST_String,NULL);
    if( !title || title[0] == 0 ) {
        title = (UBYTE *)GO_GetObjAttr(go,PUBNAME_ID,0, GTST_String,NULL);
    }

    scrn = OpenScreenTags(NULL,
        SA_Width, GO_GetObjAttr(go,WIDTH_ID,0, GTIN_Number,0),
        SA_Height, GO_GetObjAttr(go,HEIGHT_ID,0, GTIN_Number,0),
        SA_Depth, GO_GetObjAttr(go,DEPTH_ID,0, GTCY_Active,0)+1,
        SA_Title, strdup_track(track,title),
        SA_Colors, &gl->color_specs,
        SA_Font, ta,
        SA_PubName, GO_GetObjAttr(go,PUBNAME_ID,0, GTST_String,NULL),
        SA_DisplayID, gl->cur_mode ? gl->cur_mode->mode : 0,
        SA_DClip, gl->cur_clip,
        SA_Pens, &gl->pens,
        SA_FullPalette, TRUE,
        SA_AutoScroll, GO_GetObjAttr(go,AUTOSCROLL_ID,0, GTCB_Checked,TRUE),
        SA_ErrorCode, &error,
        TAG_END);
    
    gl->color_specs[1<<depth].ColorIndex = 1<<depth;
    gl->orig_specs[1<<SIZE_DEPTH_ARRAY].ColorIndex = 
        gl->color_specs[1<<SIZE_DEPTH_ARRAY].ColorIndex = -1;

    if(!scrn) {
        FreeScrnTrack(track);
        GO_ShowError(go,GO_MAKEERR(GOTYPE_FAIL,0),NULL,
            "Error #%ld opening screen:\n%ls.",
            error, open_errs[(error > OSERR_LAST) ? OSERR_LAST : error]);
    } else {
        AddScrnTrack(track,scrn);
        
        // We want to return with this screen public, but locked.  If someone
        // somehow manages to swipe the screen out from under us... Oh well.
        Forbid();
        PubScreenStatus(scrn,0);
        scrn = LockPubScreen(CURPUBNAME);
        Permit();
    }

    return scrn;
}

static void update_size(struct GadOutline *go)
{
    struct newscrn_globals *gl;

    if(!go) return;
    gl = go->go_UserData;
    
    if(GO_GetObjAttr(go,DEFWIDTH_ID,0, GTCB_Checked,TRUE)) {
        GO_SetObjAttrs(go,WIDTH_ID,0,
            GTIN_Number, (gl->cur_clip)
                             ? (gl->cur_clip->MaxX - gl->cur_clip->MinX + 1)
                             : 0,
            GA_Disabled, TRUE,
            TAG_END);
    } else {
        GO_SetObjAttrs(go,WIDTH_ID,0,GA_Disabled,FALSE,TAG_END);
    }

    if(GO_GetObjAttr(go,DEFHEIGHT_ID,0, GTCB_Checked,TRUE)) {
        GO_SetObjAttrs(go,HEIGHT_ID,0,
            GTIN_Number, (gl->cur_clip)
                             ? (gl->cur_clip->MaxY - gl->cur_clip->MinY + 1)
                             : 0,
            GA_Disabled, TRUE,
            TAG_END);
    } else {
        GO_SetObjAttrs(go,HEIGHT_ID,0,GA_Disabled,FALSE,TAG_END);
    }
}

static BOOL comp_clip(struct Rectangle *rect1,struct Rectangle *rect2)
{
    if( rect1->MinX == rect2->MinX
        && rect1->MinY == rect2->MinY
        && rect1->MaxX == rect2->MaxX
        && rect1->MaxY == rect2->MaxY ) return TRUE;
    
    return FALSE;
}

static void update_clipping(struct GadOutline *go)
{
    struct newscrn_globals *gl;
    ULONG new_clip;

    if(!go) return;
    gl = go->go_UserData;
    
    new_clip = GO_GetObjAttr(go,STDCLIP_ID,0,GTCY_Active,CLIP_CUSTOM);

    gl->cur_clip = NULL;

    if(new_clip == CLIP_CUSTOM) {
        GO_SetObjGrpAttrs(go,GO_CMDID(CUSTCLIP_GID,0),0,GA_Disabled,FALSE,TAG_END);
        gl->cur_clip = &gl->clip;
    } else {
        GO_SetObjGrpAttrs(go,GO_CMDID(CUSTCLIP_GID,0),0,GA_Disabled,TRUE,TAG_END);
        
        if(gl->cur_mode) {
            if(new_clip == CLIP_MINIMUM) gl->cur_clip = &gl->cur_mode->dims.Nominal;
            else if(new_clip == CLIP_STANDARD) gl->cur_clip = &gl->cur_mode->dims.StdOScan;
            else if(new_clip == CLIP_TEXT) gl->cur_clip = &gl->cur_mode->dims.TxtOScan;
            else if(new_clip == CLIP_VIDEO) gl->cur_clip = &gl->cur_mode->dims.VideoOScan;
            else if(new_clip == CLIP_MAXIMUM) gl->cur_clip = &gl->cur_mode->dims.MaxOScan;
        }
    }

    if(gl->cur_clip) {
        sprintf(&gl->clip_size[0],"(%ld,%ld) - (%ld,%ld)",
            gl->cur_clip->MinX,gl->cur_clip->MinY,gl->cur_clip->MaxX,gl->cur_clip->MaxY);
        /**
        if( GO_GetObjAttr(go,WIDTH_ID,0, GTIN_Number,0)
            == (gl->cur_clip->MaxX - gl->cur_clip->MinX + 1) ) {
            GO_SetObjAttrs(go,DEFWIDTH_ID,0, GTCB_Checked,TRUE,TAG_END);
        } else {
            GO_SetObjAttrs(go,DEFWIDTH_ID,0, GTCB_Checked,FALSE,TAG_END);
        }
        if( GO_GetObjAttr(go,HEIGHT_ID,0, GTIN_Number,0)
            == (gl->cur_clip->MaxY - gl->cur_clip->MinY + 1) ) {
            GO_SetObjAttrs(go,DEFHEIGHT_ID,0, GTCB_Checked,TRUE,TAG_END);
        } else {
            GO_SetObjAttrs(go,DEFHEIGHT_ID,0, GTCB_Checked,FALSE,TAG_END);
        }
        **/
    } else {
        gl->clip_size[0] = 0;
    }
    
    update_size(go);
}

static void redraw_clipping(struct GadOutline *go)
{
    struct newscrn_globals *gl;

    if(!go) return;
    gl = go->go_UserData;
    
    update_clipping(go);
    
    GO_SetObjAttrs(go,MODEINFO_ID,0,
        GOUS_ClippingSize, &gl->clip_size[0],
        TAG_END);
}

static void update_pen(struct GadOutline *go)
{
    struct newscrn_globals *gl;
    ULONG new_pen;

    if(!go) return;
    gl = go->go_UserData;
    
    new_pen = GO_GetObjAttr(go,CURPEN_ID,0,GTCY_Active,0);
    if(new_pen >= (1<<SIZE_PEN_ARRAY)) new_pen = (1<<SIZE_PEN_ARRAY)-1;

    gl->cur_pen = &gl->pens[new_pen];
    GO_SetObjAttrs(go,PENPAL_ID,0,
        GTPA_Color,gl->pens[new_pen]&((1<<gl->cur_depth)-1),TAG_END);
}

static void update_color(struct GadOutline *go)
{
    struct newscrn_globals *gl;
    ULONG new_color;

    if(!go) return;
    gl = go->go_UserData;
    
    new_color = GO_GetObjAttr(go,SCRNPAL_ID,0,GTPA_Color,0);
    if(new_color >= (1<<gl->cur_depth)) {
        new_color &= (1<<gl->cur_depth)-1;
        GO_SetObjAttrs(go,SCRNPAL_ID,0,GTPA_Color,new_color,TAG_END);
    }
    if(new_color >= (1<<SIZE_DEPTH_ARRAY)) new_color = (1<<SIZE_DEPTH_ARRAY)-1;

    gl->cur_color = &gl->color_specs[new_color];
    GO_SetObjAttrs(go,PALRED_ID,0,GTSL_Level,gl->cur_color->Red,TAG_END);
    GO_SetObjAttrs(go,PALGREEN_ID,0,GTSL_Level,gl->cur_color->Green,TAG_END);
    GO_SetObjAttrs(go,PALBLUE_ID,0,GTSL_Level,gl->cur_color->Blue,TAG_END);
}

static void update_depth(struct GadOutline *go)
{
    struct newscrn_globals *gl;
    ULONG new_depth;
    
    if(!go) return;
    gl = go->go_UserData;
    
    new_depth = GO_GetObjAttr(go,DEPTH_ID,0,GTCY_Active,0) + 1;
    if( new_depth < gl->cur_depth
        || new_depth != GO_GetObjAttr(go,SCRNPAL_ID,0,GTPA_Depth,1) ) {

        gl->cur_depth = new_depth;
        update_color(go);
        update_pen(go);
        GO_SetObjAttrs(go,SCRNPAL_ID,0,GTPA_Depth,gl->cur_depth,TAG_END);
        GO_SetObjAttrs(go,PENPAL_ID,0,GTPA_Depth,gl->cur_depth,TAG_END);
        RebuildGadOutline(go,TAG_END);
    }
}

static void update_mode(struct GadOutline *go)
{
    struct newscrn_globals *gl;
    struct ModeEntry *curmode;
    ULONG i;

    if(!go) return;
    gl = go->go_UserData;
    
    gl->cur_mode = curmode =
        num_to_node(&ScreenModeList,GO_GetObjAttr(go,MODELIST_ID,0,GTLV_Selected,-1));
    if(curmode) {
        sprintf(&gl->vis_size[0],"%5ld x %5ld",
            curmode->dims.StdOScan.MaxX - curmode->dims.StdOScan.MinX + 1,
            curmode->dims.StdOScan.MaxY - curmode->dims.StdOScan.MinY + 1);
        sprintf(&gl->min_size[0],"%5ld x %5ld",
            curmode->dims.Nominal.MaxX - curmode->dims.Nominal.MinX + 1,
            curmode->dims.Nominal.MaxY - curmode->dims.Nominal.MinY + 1);
        sprintf(&gl->max_size[0],"%5ld x %5ld",
            curmode->dims.MaxRasterWidth,curmode->dims.MaxRasterHeight);
        sprintf(&gl->max_colors[0],"%3ld",1<<curmode->dims.MaxDepth);
        for(i=0;DepthLabels[i] && i < curmode->dims.MaxDepth;i++) {
            gl->depth_labels[i] = DepthLabels[i];
        }
        gl->depth_labels[i] = NULL;
    } else {
        gl->vis_size[0] = gl->min_size[0] =
            gl->max_size[0] = gl->max_colors[0] = 0;
    }
    
    update_depth(go);
    update_clipping(go);

    GO_SetObjAttrs(go,MODEINFO_ID,0,
        GOUS_VisibleSize, &gl->vis_size[0],
        GOUS_MinimumSize, &gl->min_size[0],
        GOUS_MaximumSize, &gl->max_size[0],
        GOUS_MaximumColors, &gl->max_colors[0],
        GOUS_ClippingSize, &gl->clip_size[0],
        TAG_END);
    GO_SetObjAttrs(go,DEPTH_ID,0, GTCY_Labels,&gl->depth_labels[0],TAG_END);
}

static void *GetVPortTag(struct ColorMap *cm,ULONG vtag)
{
    struct TagItem tags[] = {
        { 0, 0 }, { VTAG_END_CM, 0 }
    };
    
    tags[0].ti_Tag = vtag;
    if(VideoControl(cm,&tags[0])==NULL) {
        return (void *)tags[0].ti_Data;
    }
    return NULL;
}

static void get_colors(struct GadOutline *go,struct Screen *scrn)
{
    struct newscrn_globals *gl;
    struct ColorMap *cm;
    ULONG i;

    if(!go) return;
    gl = go->go_UserData;
    
    // --------------------------------
    // Set up default palette
    // --------------------------------
    
    cm = GetColorMap(1<<SIZE_DEPTH_ARRAY);
        
    for(i=0;i<(1<<SIZE_DEPTH_ARRAY);i++) {
        UWORD color;

        if(scrn && i < (1<<scrn->BitMap.Depth))
            color = GetRGB4(scrn->ViewPort.ColorMap,i);
        else if(cm)
            color = GetRGB4(cm,i);
        else
            color = 0;
        gl->orig_specs[i].ColorIndex = gl->color_specs[i].ColorIndex = i;
        gl->orig_specs[i].Red = gl->color_specs[i].Red = (color>>8)&0xF;
        gl->orig_specs[i].Green = gl->color_specs[i].Green = (color>>4)&0xF;
        gl->orig_specs[i].Blue = gl->color_specs[i].Blue = (color>>0)&0xF;
    }

    gl->orig_specs[1<<SIZE_DEPTH_ARRAY].ColorIndex = 
        gl->color_specs[1<<SIZE_DEPTH_ARRAY].ColorIndex = -1;

    if(cm) FreeColorMap(cm);
}

static void update_from_screen(struct GadOutline *go,UBYTE *name,struct Screen *scrn)
{
    struct newscrn_globals *gl;
    struct ModeEntry *scrn_entry = NULL;
    struct ViewPortExtra *vpe;
    ULONG scrn_mode;
    UWORD num_pens;
    
    if(!go) return;
    
    if(!(gl = go->go_UserData)) return;

    // --------------------------------
    // Set up default palette
    // --------------------------------
    
    get_colors(go,scrn);

    // --------------------------------
    // Set up default display mode.
    // --------------------------------
    
    scrn_mode = INVALID_ID;
    if(scrn) scrn_mode = GetVPModeID(&scrn->ViewPort);

    if(scrn_mode != INVALID_ID) {
        scrn_entry = head_node(&ScreenModeList);
        while(scrn_entry && scrn_mode != scrn_entry->mode) {
            scrn_entry = next_node(scrn_entry);
        }
    }
    if(scrn_entry) gl->cur_mode = scrn_entry;
    else gl->cur_mode = head_node(&ScreenModeList);

    GO_SetObjAttrs(go,MODELIST_ID,0, GTLV_Labels,&ScreenModeList,TAG_END);
    if(scrn_entry) {
        GO_SetObjAttrs(go,MODELIST_ID,0, 
            GTLV_Selected,node_to_num(&ScreenModeList,scrn_entry),TAG_END);
    }

    // --------------------------------
    // Set up default pens.
    // --------------------------------
    
    num_pens = SIZE_PEN_ARRAY;
    if(scrn) {
        struct DrawInfo *di;
        
        if( (di=GetScreenDrawInfo(scrn)) ) {
            if(di->dri_Version >= 1) {
                UWORD num_pens = di->dri_NumPens;
        
                if(num_pens > SIZE_PEN_ARRAY) num_pens = SIZE_PEN_ARRAY;
                memcpy(&gl->pens[0],di->dri_Pens,num_pens*sizeof(UWORD));
            }
        }
    }

    if(num_pens < 2) num_pens = 2;
    gl->pens[num_pens] = 0xFFFF;
    memcpy(&gl->pen_labels[0],&PenLabels[0],num_pens*sizeof(UBYTE *));
    gl->pen_labels[num_pens] = NULL;
    GO_SetObjAttrs(go,CURPEN_ID,0, GTCY_Labels,&gl->pen_labels[0],TAG_END);

    // --------------------------------
    // Set up default clipping.
    // --------------------------------
    
    if( scrn && (vpe = GetVPortTag(scrn->ViewPort.ColorMap,VTAG_VIEWPORTEXTRA_GET)) ) {
        gl->clip.MinX = vpe->DisplayClip.MinX;
        gl->clip.MinY = vpe->DisplayClip.MinY;
        gl->clip.MaxX = vpe->DisplayClip.MaxX;
        gl->clip.MaxY = vpe->DisplayClip.MaxY;
        if(gl->cur_mode) {
            if(comp_clip(&vpe->DisplayClip,&gl->cur_mode->dims.StdOScan)) {
                GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_STANDARD,TAG_END);
            } else if(comp_clip(&vpe->DisplayClip,&gl->cur_mode->dims.TxtOScan)) {
                GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_TEXT,TAG_END);
            } else if(comp_clip(&vpe->DisplayClip,&gl->cur_mode->dims.VideoOScan)) {
                GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_VIDEO,TAG_END);
            } else if(comp_clip(&vpe->DisplayClip,&gl->cur_mode->dims.Nominal)) {
                GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_MINIMUM,TAG_END);
            } else if(comp_clip(&vpe->DisplayClip,&gl->cur_mode->dims.MaxOScan)) {
                GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_MAXIMUM,TAG_END);
            } else {
                GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_CUSTOM,TAG_END);
            }
        } else {
            GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_CUSTOM,TAG_END);
        }
    } else if(gl->cur_mode) {
        gl->clip.MinX = gl->cur_mode->dims.StdOScan.MinX;
        gl->clip.MinY = gl->cur_mode->dims.StdOScan.MinY;
        gl->clip.MaxX = gl->cur_mode->dims.StdOScan.MaxX;
        gl->clip.MaxY = gl->cur_mode->dims.StdOScan.MaxY;
        GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_STANDARD,TAG_END);
    } else {
        gl->clip.MinX = gl->clip.MinY = 0;
        gl->clip.MaxX = gl->clip.MaxY = 0;
        GO_SetObjAttrs(go,STDCLIP_ID,0,GTCY_Active,CLIP_STANDARD,TAG_END);
    }

    GO_SetObjAttrs(go,MINCLIPX_ID,0, GTIN_Number,gl->clip.MinX,TAG_END);
    GO_SetObjAttrs(go,MINCLIPY_ID,0, GTIN_Number,gl->clip.MinY,TAG_END);
    GO_SetObjAttrs(go,MAXCLIPX_ID,0, GTIN_Number,gl->clip.MaxX,TAG_END);
    GO_SetObjAttrs(go,MAXCLIPY_ID,0, GTIN_Number,gl->clip.MaxY,TAG_END);
    
    // --------------------------------
    // Set up default screen size.
    // --------------------------------
    
    if(scrn) {
        GO_SetObjAttrs(go,WIDTH_ID,0, GTIN_Number,scrn->Width,TAG_END);
        GO_SetObjAttrs(go,HEIGHT_ID,0, GTIN_Number,scrn->Height,TAG_END);
    } else {
        GO_SetObjAttrs(go,WIDTH_ID,0,
            GTIN_Number,gl->clip.MaxX - gl->clip.MinX + 1,TAG_END);
        GO_SetObjAttrs(go,HEIGHT_ID,0,
            GTIN_Number,gl->clip.MaxY - gl->clip.MinY + 1,TAG_END);
    }
    GO_SetObjAttrs(go,DEFWIDTH_ID,0,GTCB_Checked,FALSE,TAG_END);
    GO_SetObjAttrs(go,DEFHEIGHT_ID,0, GTCB_Checked,FALSE,TAG_END);

    // --------------------------------
    // Set up other defaults.
    // --------------------------------
    
    if(scrn) {
        if(name) {
            GO_SetObjAttrs(go,TITLE_ID,0, GTST_String,scrn->DefaultTitle,TAG_END);
            GO_SetObjAttrs(go,PUBNAME_ID,0, GTST_String,name,TAG_END);
        }

        if( (scrn->Flags&AUTOSCROLL) ) {
            GO_SetObjAttrs(go,AUTOSCROLL_ID,0, GTCB_Checked,TRUE,TAG_END);
        } else {
            GO_SetObjAttrs(go,AUTOSCROLL_ID,0, GTCB_Checked,FALSE,TAG_END);
        }

        if(scrn->Font) {
            GO_SetObjAttrs(go,FONTNAME_ID,0, 
                GTST_String,scrn->Font->ta_Name,TAG_END);
            GO_SetObjAttrs(go,FONTSIZE_ID,0, 
                GTIN_Number,scrn->Font->ta_YSize,TAG_END);
        }

        GO_SetObjAttrs(go,DEPTH_ID,0, GTCY_Active,scrn->BitMap.Depth-1,TAG_END);
    }

    gl->cur_depth = 0xFF;
    update_mode(go);
    update_depth(go);
    update_color(go);
    update_pen(go);
    update_clipping(go);

    if(gl->cur_clip) {
        if( GO_GetObjAttr(go,WIDTH_ID,0, GTIN_Number,0)
            == (gl->cur_clip->MaxX - gl->cur_clip->MinX + 1) ) {
            GO_SetObjAttrs(go,DEFWIDTH_ID,0, GTCB_Checked,TRUE,TAG_END);
        } else {
            GO_SetObjAttrs(go,DEFWIDTH_ID,0, GTCB_Checked,FALSE,TAG_END);
        }
        if( GO_GetObjAttr(go,HEIGHT_ID,0, GTIN_Number,0)
            == (gl->cur_clip->MaxY - gl->cur_clip->MinY + 1) ) {
            GO_SetObjAttrs(go,DEFHEIGHT_ID,0, GTCB_Checked,TRUE,TAG_END);
        } else {
            GO_SetObjAttrs(go,DEFHEIGHT_ID,0, GTCB_Checked,FALSE,TAG_END);
        }
    }

    update_size(go);
}

static ULONG __saveds __interrupt
newscrn_handler(struct GadOutline *go, ULONG command, struct GOIMsg *msg)
{
    struct newscrn_globals *gl;
    struct Gadget *gadget;
    ULONG class;
    UWORD code;
    UWORD qual;

    if(go == NULL) return HNDRES_CLOSEWIN;

    if( !(gl = (struct newscrn_globals *)go->go_UserData) ) {
        return HNDRES_CLOSEWIN;
    }

    if(command == HNDCMD_IDCMPMSG) {
        if( msg ) {
            class = msg->StdIMsg.Class;
            code = msg->StdIMsg.Code;
            qual = msg->StdIMsg.Qualifier;
            gadget = (struct Gadget *)msg->StdIMsg.IAddress;
        } else {
            return HNDRES_CLOSEWIN;
        }
    } else if(command == HNDCMD_SHUTDOWN) {
        if(go == (struct GadOutline *)msg) {
            if( (gl->flags&NSF_MODIFY) && go->go_Screen ) {
                ULONG i;
                
                for(i=0;i<(1<<go->go_Screen->BitMap.Depth);i++) {
                    SetRGB4(&go->go_Screen->ViewPort,
                        gl->orig_specs[i].ColorIndex,
                        gl->orig_specs[i].Red&0xF,
                        gl->orig_specs[i].Green&0xF,
                        gl->orig_specs[i].Blue&0xF);
                }
            }
            DestroyNewScrn(go);
        }
        return HNDRES_NORMAL;
    } else if(command == HNDCMD_MOVEWIN && !(gl->flags&NSF_MODIFY)) {
        if(msg) {
            if( !open_window(go,WA_CustomScreen,(struct Window *)msg,TAG_END) ) {
                return HNDRES_CLOSEWIN;
            }
            return HNDRES_NORMAL;
        } else return HNDRES_CLOSEWIN;
    } else if(command == HNDCMD_HIDEWIN && !(gl->flags&NSF_MODIFY)) {
        UnlockGadOutline(go);   // Window must be unlocked.
        GO_CloseScreen(go);
        return HNDRES_NORMAL;
    } else if(command == HNDCMD_LOCK) {
        LockGadOutline(go);
        return HNDRES_NORMAL;
    } else if(command == HNDCMD_UNLOCK) {
        UnlockGadOutline(go);
        return HNDRES_NORMAL;
    } else {
        return HNDRES_NORMAL;
    }

    if(class == IDCMP_MOUSEMOVE && go->go_ActCmdInfo) {
        gadget = go->go_ActCmdInfo->ci_Object;
        if( (GETGRPID(go->go_ActCmdInfo->ci_CmdID)&FOLLOWMOUSE_GID) ) {
            class = IDCMP_GADGETUP;
        }
    }

    switch (class) {

        case IDCMP_CLOSEWINDOW:
        {
            return HNDRES_CLOSEWIN;
        } break;

        case IDCMP_REFRESHWINDOW:
        {
            GO_BeginRefresh(go);
            GO_EndRefresh(go, TRUE);
        } break;

        case IDCMP_GADGETUP:
        {
        
            switch(gadget->GadgetID) {
            
                case MODELIST_ID:
                {
                    update_mode(go);
                } break;

                case STDCLIP_ID:
                case MAXCLIPX_ID:
                case MAXCLIPY_ID:
                case MINCLIPX_ID:
                case MINCLIPY_ID:
                {
                    gl->clip.MinX = GO_GetObjAttr(go,MINCLIPX_ID,0, GTIN_Number,0);
                    gl->clip.MinY = GO_GetObjAttr(go,MINCLIPY_ID,0, GTIN_Number,0);
                    gl->clip.MaxX = GO_GetObjAttr(go,MAXCLIPX_ID,0, GTIN_Number,0);
                    gl->clip.MaxY = GO_GetObjAttr(go,MAXCLIPY_ID,0, GTIN_Number,0);
                    redraw_clipping(go);
                } break;

                case DEFWIDTH_ID:
                case DEFHEIGHT_ID:
                {
                    update_size(go);
                } break;

                case SETFONT_ID:
                {
                    if( AslRequestTags(gl->font_req,
                        ASL_FontName,
                            GO_GetObjAttr(go,FONTNAME_ID,0, GTST_String,(ULONG)&""),
                        ASL_FontHeight,
                            GO_GetObjAttr(go,FONTSIZE_ID,0, GTIN_Number,0),
                        ASL_Window, go->go_Window,
                        TAG_END) ) {
                    
                        GO_SetObjAttrs(go,FONTNAME_ID,0,
                            GTST_String,gl->font_req->fo_Attr.ta_Name,
                            TAG_END);
                        GO_SetObjAttrs(go,FONTSIZE_ID,0,
                            GTIN_Number,gl->font_req->fo_Attr.ta_YSize,
                            TAG_END);
                                
                    }
                } break;

                case DEPTH_ID:
                {
                    update_depth(go);
                } break;

                case SCRNPAL_ID:
                {
                    update_color(go);
                } break;

                case CURPEN_ID:
                {
                    update_pen(go);
                } break;

                case PALRED_ID:
                {
                    struct Screen *scrn;

                    if(gl->cur_color) {
                        gl->cur_color->Red = code;
                        
                        // DON'T LAUGH!!  My 3000 is fast enough, and who
                        // cares about anyone else? :)
                        if( (gl->flags&NSF_MODIFY)
                            && (scrn=LockPubScreen(CURPUBNAME)) ) {
                            
                            SetRGB4(&scrn->ViewPort,
                                gl->cur_color->ColorIndex,
                                gl->cur_color->Red&0xF,
                                gl->cur_color->Green&0xF,
                                gl->cur_color->Blue&0xF);
                            UnlockPubScreen(NULL,scrn);
                        }
                    }
                } break;

                case PALGREEN_ID:
                {
                    struct Screen *scrn;

                    if(gl->cur_color) {
                        gl->cur_color->Green = code;
                        if( (gl->flags&NSF_MODIFY)
                            && (scrn=LockPubScreen(CURPUBNAME)) ) {
                            
                            SetRGB4(&scrn->ViewPort,
                                gl->cur_color->ColorIndex,
                                gl->cur_color->Red&0xF,
                                gl->cur_color->Green&0xF,
                                gl->cur_color->Blue&0xF);
                            UnlockPubScreen(NULL,scrn);
                        }
                    }
                } break;

                case PALBLUE_ID:
                {
                    struct Screen *scrn;

                    if(gl->cur_color) {
                        gl->cur_color->Blue = code;
                        if( (gl->flags&NSF_MODIFY)
                            && (scrn=LockPubScreen(CURPUBNAME)) ) {
                            
                            SetRGB4(&scrn->ViewPort,
                                gl->cur_color->ColorIndex,
                                gl->cur_color->Red&0xF,
                                gl->cur_color->Green&0xF,
                                gl->cur_color->Blue&0xF);
                            UnlockPubScreen(NULL,scrn);
                        }
                    }
                } break;

                case PENPAL_ID:
                {
                    if(gl->cur_pen) {
                        *gl->cur_pen = code;
                    }
                } break;

                case OPEN_ID:
                {
                    struct Screen *scrn;
                    
                    if(scrn=open_screen(go)) {
                        UnlockGadOutline(go);   // Window must be unlocked.
                        GO_CloseScreen(go);
                        set_modify(go,scrn);
                        if( !open_window(go,WA_PubScreen,scrn,TAG_END) ) {
                            UnlockPubScreen(NULL,scrn);
                            return HNDRES_CLOSEWIN;
                        }
                        get_colors(go,scrn);
                        UnlockPubScreen(NULL,scrn);
                    }
                } break;

                case MODIFY_ID:
                {
                    struct Screen *scrn;
                    
                    // First, find the screen we are going to modify.
                    scrn = LockPubScreen(CURPUBNAME);

                    // Close our window and detach from screen.
                    UnlockGadOutline(go);   // Window must be unlocked.
                    GO_CloseScreen(go);

                    // Quick!  Before anyone sees us!
                    Forbid();
                    if(scrn) {
                        // Unlock the screen...
                        UnlockPubScreen(NULL,scrn);

                        // ... And close it!
                        if( CloseScrnTrack(scrn) ) {
                            scrn = NULL;            // It's all gone.
                        } else {
                            // Couldn't be closed... Lock it again.
                            scrn = LockPubScreen(CURPUBNAME);
                        }
                    }
                    Permit();

                    // If it no longer exists, try to re-open.
                    if(!scrn) scrn = open_screen(go);
                    
                    if( scrn ) {
                        set_modify(go,scrn);
                        if( !open_window(go,WA_PubScreen,scrn,TAG_END) ) {
                            UnlockPubScreen(NULL,scrn);
                            return HNDRES_CLOSEWIN;
                        }
                        get_colors(go,scrn);
                        UnlockPubScreen(NULL,scrn);
                    } else {
                        set_modify(go,NULL);
                        if( !open_window(go,WA_PubScreen,NULL,TAG_END) ) {
                            return HNDRES_CLOSEWIN;
                        }
                    }

                } break;

            }
        }
    }
    
    return HNDRES_NORMAL;
}

void DestroyNewScrn(struct GadOutline *go)
{
    struct newscrn_globals *gl;

    if(!go) return;
    gl = go->go_UserData;
    
    UnlockGadOutline(go);   // Window must be unlocked.
    FreeGadOutline(go);
        
    if(gl) {
        if(gl->font_req) FreeAslRequest(gl->font_req);
        FreeVec(gl);
    }
}

struct GadOutline *CreateNewScrn(struct GadOutline *par_go,
                                 UBYTE *name,struct Screen *scrn,BOOL modify)
{
    struct GadOutline *go;
    struct newscrn_globals *gl;
    
    if(!par_go || !par_go->go_Window) return NULL;
    
    go = AllocGadOutline(&newscrn_outline[0],
            GOA_OutlineSize,    sizeof(newscrn_outline),
            GOA_UserIDCMP,      par_go->go_MsgPort,
            TAG_END);
    if(!go) return NULL;
    
    gl = AllocVec(sizeof(struct newscrn_globals),MEMF_PUBLIC|MEMF_CLEAR);
    if(!gl) {
        DestroyNewScrn(go);
        return NULL;
    }
    
    go->go_UserData = gl;

    if( (gl->font_req = (struct FontRequester *)
        AllocAslRequestTags(ASL_FontRequest,
            ASL_MinHeight,3,
            ASL_MaxHeight,999,
            TAG_END)) == NULL) {
        DestroyNewScrn(go);
        return NULL;
    }

    SetupBackFillHook(&gl->bf_hook,go);
    GO_SetObjAttrs(go,WINTAGS_ID,0,WA_BackFill,&gl->bf_hook,TAG_END);

    if(modify) gl->flags |= NSF_MODIFY;

    update_from_screen(go,name,scrn);

    if(gl->flags & NSF_MODIFY) {
    
        set_modify(go,scrn);
        if( !open_window(go,WA_PubScreen,scrn,TAG_END) ) {
            DestroyNewScrn(go);
            return NULL;
        }

    } else {
    
        set_modify(go,NULL);
        if( !open_window(go,WA_CustomScreen,par_go->go_Screen,TAG_END) ) {
            DestroyNewScrn(go);
            return NULL;
        }
    }

    return go;
}
