(c)  Copyright 1990 Commodore-Amiga, Inc.   All rights reserved.
The information contained herein is subject to change without notice,
and is provided "as is" without warranty of any kind, either expressed
or implied.  The entire risk as to the use of this information is
assumed by the user.

/* 
 * V36 Simple public screen example.
 * 
 * Compiled with SAS C 5.10:  lc -cfist -v -L pub.c
 * Use V36 include files.
 */

#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <graphics/displayinfo.h>
#include <libraries/gadtools.h>
#include <exec/memory.h>
#include <dos/dosextens.h>

#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/intuition_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/intuition_pragmas.h>

struct IntuitionBase *IntuitionBase;
struct Library *GadToolsBase;

static UWORD dri_Pens[] =
{0, 1, 1, 2, 1, 3, 1, 0, 3, ~0};

/* Gadtools menu stuff */
#define QUIT 1
struct NewMenu sdm_menu[] =
{
    {NM_TITLE, "Project", 0, 0, 0, 0,},
    {NM_ITEM, "Quit", "Q", 0, 0, (void *) QUIT,},
    {NM_END, NULL, 0, 0, 0, 0,},
};

struct EasyStruct failedES =
{
    sizeof(struct EasyStruct), 0, "AMPub",
    "%s",
    "OK",
};

void main(void);

void
main(void)
{

    struct Screen *pubscreen;
    struct Window *window;
    struct Menu *menu;
    void *vi;

    struct IntuiMessage *msg;
    UBYTE defaultpubname[MAXPUBSCREENNAME];
    UWORD oldstatus;
    UWORD oldmodes;
    ULONG signal, wsignal, lastsignal, allocsignal;
    ULONG oserror;
    BOOL ABORT = FALSE;
    BOOL CLOSEDOWN = FALSE;
    struct Task *task;

    /* Fails silently if not V36 */
    if (IntuitionBase = OpenLibrary("intuition.library", 36)) {
        if (GadToolsBase = OpenLibrary("gadtools.library", 36)) {
            if ((allocsignal = AllocSignal(-1)) != -1) {
                lastsignal = 1 << allocsignal;

                /* We'll use our task address to get signaled when the last
                 * visitor window leaves. */
                task = 
                  (struct Task *)&((struct Process *)FindTask(NULL))->pr_Task;

                /* Get the name of the currently default 
                 * public screen (normally WB) */
                GetDefaultPubScreen(defaultpubname);

                /* Note that no checking is done to make sure the 
                 * public screen name is unique.  If the public name is 
                 * not unique, OSERR_PUBNOTUNIQUE is returned in an
                 * application supplied variable as data for the SA_ErrorCode
                 * tag.  In this case however, if OpenScreen fails, for 
                 * whatever reason, we just bail out.
                 */

                if (pubscreen = OpenScreenTags(NULL,
                                 SA_DisplayID, HIRES_KEY,
                                 SA_Depth, 2,
                                 SA_Title,  "AmigaMail Test Public Screen",
                                 SA_PubName,"AmigaMail Test Public Screen",

                                 SA_PubSig, allocsignal,
                                 SA_PubTask, task, 
                                          /* Normally you'd supply 0L, if you
                                          * the task which opened the screen to
                                          * be signaled.
                                          */
                                 SA_Pens, dri_Pens, SA_ErrorCode, &oserror,
                                 TAG_END)) {
                    if (menu = CreateMenus(sdm_menu, TAG_DONE)) {
                        if (window = OpenWindowTags(NULL,
                                      WA_Top, pubscreen->BarHeight + 1,
                                      WA_Height, pubscreen->Height 
                                                 - (pubscreen->BarHeight + 1),
                                      WA_CustomScreen, pubscreen,
                                      WA_IDCMP, MENUPICK,
                                      WA_Flags, ACTIVATE|BACKDROP|
                                                    BORDERLESS|NOCAREREFRESH,
                                      TAG_END)) {

                            vi = GetVisualInfo(pubscreen, TAG_END);
                            if (LayoutMenus(menu, vi, TAG_DONE)) {
                                SetMenuStrip(window, menu);
    
                                /* Now we have a screen, named "AmigaMail Test
                                 * Public Screen", which is still marked 
                                 * private, but ready to be made public.
                                 */
                                oldstatus = PubScreenStatus(pubscreen, 0);
                                /* Now it is really public. We'll make it the
                                 * default (and shanghai attempts to open 
                                 * windows on the Workbench.
                                 */
                                SetDefaultPubScreen(
                                               "AmigaMail Test Public Screen");

                                oldmodes = SetPubScreenModes(SHANGHAI|
                                                             POPPUBSCREEN);
    
                                wsignal = 1 << window->UserPort->mp_SigBit;

                                do {
                                    signal = Wait(wsignal|lastsignal);
                                    /* The last visitor just left our screen */
                                    if (signal & lastsignal) {
                                        if (CLOSEDOWN)
                                            if ((oldstatus = 
                                                 PubScreenStatus(pubscreen, 
                                                           PSNF_PRIVATE)) & 1)
                                                ABORT = TRUE;
                                    }

                                    /* If not wsignal, this while-loop will not
                                     * be executed. 
                                     */
                                    while(msg = (struct IntuiMessage *)
                                          GetMsg(window->UserPort)) {
                                    if (msg->Class == MENUPICK) {
                                            if ((UWORD)(MENU_USERDATA
                                                    (ItemAddress(menu, 
                                                        msg->Code))) == QUIT) {
                                            /* If we can't make our screen
                                             * private again, we got 
                                             * visitor window(s). Note
                                             * window(s) you open without
                                             * specifiying SA_PubScreenName, 
                                             * are NOT considered visitor 
                                             * windows.  So it's easy to try
                                             * to make your public screen
                                             * private again, without having
                                             * to close down your own windows
                                             * first.
                                             */

                                            if ((oldstatus = 
                                                 PubScreenStatus(pubscreen, 
                                                          PSNF_PRIVATE)) & 1) {
                                                ABORT = TRUE;
                                                }
                                            else {
                                                /* Close as soon as possible */
                                                     CLOSEDOWN = TRUE;
                                                    EasyRequest(window, 
                                                                &failedES, 
                                                                NULL, 
                       "Can't make screen private.\nPlease close all windows");
                                                }
                                            }
                                        }
                                        ReplyMsg((struct Message *)msg);
                                    }
                                } while (ABORT == FALSE);

                                /* Restore orignal default */
                                SetDefaultPubScreen(defaultpubname);
                                ClearMenuStrip(window);
                                FreeVisualInfo(vi);
                            } else
                                EasyRequest(NULL, 
                                            &failedES, 
                                            NULL, 
                                            "Can't layout menu's");
                            CloseWindow(window);
                        } else
                            EasyRequest(NULL, 
                                        &failedES, 
                                        NULL, 
                                        "Can't open window");
                        FreeMenus(menu);
                    } else EasyRequest(NULL, 
                                       &failedES,
                                       NULL, 
                                       "Can't create menu's");
                    CloseScreen(pubscreen);
                } else
                    EasyRequest(NULL, 
                                &failedES, 
                                NULL, 
                                "Can't open public screen");
                FreeSignal(allocsignal);
            } else
            EasyRequest(NULL, &failedES, NULL, "No signal available");
            CloseLibrary(GadToolsBase);
        }
    CloseLibrary(IntuitionBase);
    }
}



















































/*
 * V36 Clone Workbench screen
 *
 * Compiled with SAS C 5.10:  lc -cfist -v -L CloneWB.c
 * Use V36 include files.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <graphics/displayinfo.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/graphics_pragmas.h>

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

struct EasyStruct failedES = {
    sizeof(struct EasyStruct), 0, "CWB",
    "%s",
    "OK",
};

void            main(void);

void
main(void)
{
    struct Screen *wbscreen;
    struct Screen *clonescreen;
    struct Window *window;
    struct ViewPort *vp;
    struct IntuiMessage *msg;
    ULONG modeID;

    struct DisplayInfo displayinfo;
    struct MonitorInfo monitorinfo;
    struct DimensionInfo dimensioninfo;
    struct NameInfo nameinfo;
    struct DrawInfo *drawinfo;

    ULONG result;

    /* Fails silently when not V36 */
    if (IntuitionBase = OpenLibrary("intuition.library", 36)) {
        if (GfxBase = OpenLibrary("graphics.library", 36)) {

            if (wbscreen = LockPubScreen("Workbench")) {
                /* Using intuition.library/GetScreenDrawInfo(), we get the pen
                 * array we'll use for the screen clone the easy way. */
                drawinfo = GetScreenDrawInfo(wbscreen);

                vp = &(wbscreen->ViewPort);
                /* Use graphics.library/GetVPModeID() to get the ModeID of the
                 * Workbench screen. */
                if ((modeID = GetVPModeID(vp)) != INVALID_ID) {
                    /* OK, we got a valid ModeID for the Workbench 
                     * screen (surprise) */

                    /* With just the ModeID, the lock on the Workbench 
                     * screen & drawinfo->dri_Pens we're able to clone the
                     * Workbench exactly, displaymode and all. When you want 
                     * to know everything there is to know about this 
                     * displaymode, use graphics.library/GetDisplayInfoData().
                     */
                    /* 'result' is the actual # of bytes copies
                     * into the buffer.
                     * See graphics/displayinfo.h for definitions
                     * of the various structures.
                     */
                    result = GetDisplayInfoData(NULL, 
                                                (UBYTE *)&monitorinfo, 
                                                sizeof(struct MonitorInfo), 
                                                DTAG_MNTR, modeID);
                    result = GetDisplayInfoData(NULL, 
                                                (UBYTE *)&displayinfo,
                                                sizeof(struct DisplayInfo),
                                                DTAG_DISP, modeID);
                    result = GetDisplayInfoData(NULL,
                                                (UBYTE *)&dimensioninfo, 
                                                sizeof(struct DimensionInfo),
                                                DTAG_DIMS,
                                                modeID);
                    result = GetDisplayInfoData(NULL,
                                                (UBYTE *)&nameinfo,
                                                sizeof(struct NameInfo),
                                                DTAG_NAME, 
                                                modeID);

                    /* If you don't want to clone the workbench exactly,
                     * you could use one of the other overscan modes
                     * and/or min/max.
                     * dimensions in dimensioninfo or open a regular screen.
                     */
                    if (clonescreen = OpenScreenTags(NULL,
                        /* Could use STDSCREENWIDTH/HEIGHT for non-scrollable
                         * screens. Those make */
                        SA_Width, wbscreen->Width,

                        /* OpenScreen() use the textoverscan values */
                        SA_Height, wbscreen->Height,        

                        SA_DisplayID, modeID,

                        SA_Depth, wbscreen->BitMap.Depth,

                        /*Workbench always sizes up to OSCAN_TEXT, so do we */
                        SA_Overscan, OSCAN_TEXT,

                        SA_Pens, drawinfo->dri_Pens,

                        SA_Title, nameinfo.Name,

                        /* Doesn't hurt for screens which don't scroll */
                        SA_AutoScroll, TRUE,

                        TAG_END)) {

                        if (window = OpenWindowTags(NULL,
                            WA_Top, clonescreen->BarHeight + 1,
                            WA_Height, clonescreen->Height 
                                                - (clonescreen->BarHeight + 1),
                            WA_CustomScreen, clonescreen,
                            WA_MinWidth, 320,
                            WA_MinHeight, 100,
                            WA_MaxWidth, clonescreen->Width,
                            WA_MaxHeight, clonescreen->Height,

                            /* I'm only interested in CLOSEWINDOW messages */
                            WA_IDCMP, CLOSEWINDOW, 
                            WA_Flags, WINDOWSIZING|WINDOWDRAG|
                                           WINDOWDEPTH|WINDOWCLOSE|ACTIVATE,
                            WA_Title, "Close to exit.",
                            TAG_END)) {

                            /* Wait for the closewindow message */
                            WaitPort(window->UserPort);
                            /* And remove message from the port */
                            while(msg = (struct IntuiMessage *)
                                  GetMsg(window->UserPort))
                                ReplyMsg((struct Message *)msg);
                            CloseWindow(window);
                        } else
                            EasyRequest(NULL, &failedES, NULL, 
                                        "Can't open window");
                        CloseScreen(clonescreen);
                    } else
                        EasyRequest(NULL, &failedES, NULL, 
                                    "Can't open screen");
                } else
                    EasyRequest(NULL, &failedES, NULL, "Invalide ModeID");
                FreeScreenDrawInfo(wbscreen, drawinfo);
                UnlockPubScreen(NULL, wbscreen);
            } else
                EasyRequest(NULL, &failedES, NULL, 
                            "Can't lock Workbench screen");
            CloseLibrary(GfxBase);
        }
        CloseLibrary(IntuitionBase);
    }
}










/* 
 * V36 Screen Displaymode selector example
 * 
 * Compiled with SAS C 5.05:  lc -cfist -v -L ScreenDisplayModes.c
 * Use V36 include files.
 */

#include <string.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <graphics/text.h>
#include <exec/memory.h>
#include <exec/ports.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/alib_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/gadtools_pragmas.h>

#define SWITCH 888
#define QUIT   999

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *GadToolsBase;

void main(void);
void ShowDisplayModes(struct List * dlist);
struct Screen *OpenAScreen(struct DimensionInfo * di, UBYTE * name,
			   ULONG overscantype);
struct Window *OpenAWindow(struct Screen * screen, ULONG overscantype);

struct DisplayNode {
    struct Node dn_Node;
    struct DimensionInfo dn_Dimensioninfo;
};

/* The workbench compatible pens we'll use for that New Look. */
static UWORD dri_Pens[] = {0, 1, 1, 2, 1, 3, 1, 0, 3, ~0};

/* Gadtools menu stuff */
struct NewMenu sdm_menu[] =
{
    {NM_TITLE, "Project", 0, 0, 0, 0,},
    {NM_ITEM, "Switch Mode", "S", 0, 0, (void *) SWITCH,},
    {NM_ITEM, "Set Overscan", 0, 0, 0, 0,},
    {NM_SUB, "Text", 0, CHECKIT | CHECKED, ~1, (void *) OSCAN_TEXT,},
    {NM_SUB, "Standard", 0, CHECKIT, ~2, (void *) OSCAN_STANDARD,},
    {NM_SUB, "Max", 0, CHECKIT, ~4, (void *) OSCAN_MAX,},
    {NM_SUB, "Video", 0, CHECKIT, ~8, (void *) OSCAN_VIDEO,},
    {NM_ITEM, NM_BARLABEL, 0, CHECKIT, 0, 0,},
    {NM_ITEM, "Quit", "Q", 0, 0, (void *) QUIT,},
    {NM_END, NULL, 0, 0, 0, 0,},
};

UBYTE *OScanDescr[] = {NULL, "OSCAN_TEXT", "OSCAN_STANDARD",
			 "OSCAN_MAX", "OSCAN_VIDEO"};

struct EasyStruct failedES =
{
    sizeof(struct EasyStruct), 0, "SDM",
    "%s",
    "OK",
};

void
main(void)
{
    struct List *dlist;
    struct DisplayNode *dnode;
    struct DisplayNode *wnode, *nnode;

    ULONG modeID;
    ULONG skipID;

    ULONG result;
    struct DisplayInfo displayinfo;
    struct NameInfo nameinfo;

    /* Fails silently if not V36 */
    if (IntuitionBase = OpenLibrary("intuition.library", 36)) {
        if (GfxBase = OpenLibrary("graphics.library", 36)) {
            if (GadToolsBase = OpenLibrary("gadtools.library", 36)) {
                if (dlist = AllocMem(sizeof(struct List), MEMF_CLEAR)) {
                    NewList(dlist);

                    /*
                     * Don't want duplicate entries in the list for the
                     * 'default monitor', so we'll skip the the videomode
                     * for which default.monitor is the alias.
                     */

                    /* INVALID_ID indicates the beginning and the end
		     * of the list of available keys.
		     */
                    modeID = INVALID_ID;

                    GetDisplayInfoData(NULL, (UBYTE *) & displayinfo,
				       sizeof(struct DisplayInfo),
				       DTAG_DISP, LORES_KEY);
                    if (displayinfo.PropertyFlags & DIPF_IS_PAL)
                        skipID = PAL_MONITOR_ID;
                    else
                        skipID = NTSC_MONITOR_ID;
                    while ((modeID = NextDisplayInfo(modeID)) != INVALID_ID) {
                        if ((modeID & MONITOR_ID_MASK) != skipID) {
			    /*
			     * For this example,only 'named' keys are accepted.  Others
			     * which have no description are left out
 			     * even though they may be available.
 			     * HAM and EXTRAHALFBRIGHT are examples of this.
 			     * If needed a name could be made like '320x400 HAM Interlace'.
 			     */

                            if (result = GetDisplayInfoData(NULL, 
							    (UBYTE *) & nameinfo,
							    sizeof(struct NameInfo),
							    DTAG_NAME,
							    modeID)) {
                                result = GetDisplayInfoData(NULL,
							    (UBYTE *) & displayinfo,
							    sizeof(struct DisplayInfo),
							    DTAG_DISP,
							    modeID);
                                if (!(displayinfo.NotAvailable)) {
                                    if (dnode = 
					(struct DisplayNode *) 
					AllocMem(sizeof(struct DisplayNode), 
						 MEMF_CLEAR)) {
                                        result = GetDisplayInfoData(NULL, 
						   (UBYTE *) &
						   (dnode->dn_Dimensioninfo),
						   sizeof(struct DimensionInfo), 
						   DTAG_DIMS, 
						   modeID);
                                        /* to keep it short: if NOMEM,
					 * just don't copy
					 */
                                        if (dnode->dn_Node.ln_Name 
					    = AllocMem(strlen(nameinfo.Name)
						       + 1, MEMF_CLEAR))
                                            strcpy(dnode->dn_Node.ln_Name,
						   nameinfo.Name);
                                        AddTail(dlist, (struct Node *) dnode);
                                    } else {
                                        EasyRequest(NULL, &failedES, NULL,
						    "Out of memory");
                                        /* Force modeID to INVALID to break */
                                        modeID = INVALID_ID;
                                    }
                                }
                            }
                        }
                    }
                    ShowDisplayModes(dlist);

                    wnode = (struct DisplayNode *) dlist->lh_Head;
                    while (nnode = (struct DisplayNode *)
			   (wnode->dn_Node.ln_Succ)) {

                        if (wnode->dn_Node.ln_Name)
                            FreeMem(wnode->dn_Node.ln_Name,
				    strlen(wnode->dn_Node.ln_Name) +1);
                        Remove((struct Node *) wnode);
                        FreeMem(wnode, sizeof(struct DisplayNode));
                        wnode = nnode;
                    }
                    FreeMem(dlist, sizeof(struct List));
                } else
                    EasyRequest(NULL, &failedES, NULL, "Out of memory");
                CloseLibrary(GadToolsBase);
            }
            CloseLibrary(GfxBase);
        }
        CloseLibrary(IntuitionBase);
    }
}

void
ShowDisplayModes(struct List * dlist)
{
    struct Screen *screen;
    struct Window *window;
    struct Gadget *glist, *gadget, *hitgadget;
    struct DrawInfo *drawinfo;
    struct TextFont *defaultfont;
    struct TextAttr *textattr;
    struct IntuiMessage *imsg;
    struct NewGadget *ng;
    struct Menu *menu;
    struct MenuItem *item;
    void *vi;
    ULONG iclass, icode, code;
    struct DisplayNode *dnode;
    struct DimensionInfo *dimensioninfo;
    ULONG overscantype = OSCAN_TEXT;
    ULONG curmode = 0;
    BOOL ABORT = TRUE, OK;
    int i;


    if (ng = AllocMem(sizeof(struct NewGadget), MEMF_CLEAR)) {
        if (textattr = AllocMem(sizeof(struct TextAttr), MEMF_CLEAR)) {
            if (textattr->ta_Name = AllocMem(48, MEMF_CLEAR)) {

                dnode = (struct DisplayNode *) dlist->lh_Head;

                if (menu = CreateMenus(sdm_menu, TAG_DONE)) {
                    do {
                        dimensioninfo = &(dnode->dn_Dimensioninfo);
                        OK = FALSE;
                        if (screen = OpenAScreen(dimensioninfo, 
						 dnode->dn_Node.ln_Name, 
						 overscantype)) {
                            drawinfo = GetScreenDrawInfo(screen);
                            defaultfont = drawinfo->dri_Font;
                            strcpy(textattr->ta_Name, 
				   defaultfont->tf_Message.mn_Node.ln_Name);

                            textattr->ta_YSize = defaultfont->tf_YSize;
                            textattr->ta_Style = defaultfont->tf_Style;
                            textattr->ta_Flags = defaultfont->tf_Flags;

                            if (window = OpenAWindow(screen, overscantype)) {
                                vi = GetVisualInfo(screen, TAG_END);
                                if (LayoutMenus(menu, vi, TAG_DONE)) {
                                    if (gadget = CreateContext(&glist)) {
                                        ng->ng_LeftEdge = 
					  window->BorderLeft + 10;
                                        ng->ng_TopEdge = 
					  window->BorderTop + 10;
                                        ng->ng_Width = 
					  window->Width -
					    (window->BorderLeft + 10) -
					      (window->BorderRight + 10);
                                        ng->ng_Height =
					  window->Height -
					    (window->BorderTop + 10) -
					      (window->BorderBottom + 10) -
						(4 + defaultfont->tf_YSize + 2);
                                        ng->ng_TextAttr = textattr;
                                        ng->ng_GadgetText = NULL;
                                        ng->ng_VisualInfo = vi;
                                        ng->ng_GadgetID = 1;
                                        ng->ng_Flags = PLACETEXT_ABOVE;
                                        gadget =
					  CreateGadget(LISTVIEW_KIND, gadget,
						       ng, GTLV_Labels, dlist,
						       GTLV_ShowSelected, NULL,
						       GTLV_Selected, curmode,
						       TAG_END);

                                        ng->ng_TopEdge +=
					  gadget->Height +
					    defaultfont->tf_YSize + 10;
                                        ng->ng_Width = 80;
                                        ng->ng_LeftEdge =
					  ((window->Width - window->BorderLeft
					    - window->BorderRight) / 2) - 30;
                                        ng->ng_Height = defaultfont->tf_YSize + 8;
                                        ng->ng_GadgetID = 2;
                                        ng->ng_GadgetText = "OK";
                                        ng->ng_VisualInfo = vi;
                                        ng->ng_Flags = PLACETEXT_IN;
                                        gadget = 
					  CreateGadget(BUTTON_KIND, gadget,
						       ng, TAG_END);

                                        AddGList(window, glist, -1, -1, NULL);
                                        RefreshGList(glist, window, NULL, -1);
                                        GT_RefreshWindow(window, NULL);
                                        SetMenuStrip(window, menu);
                                        ABORT = FALSE;
                                    } else
                                        EasyRequest(window, &failedES, NULL, 
						    "Can't create gadget context");
                                } else
                                    EasyRequest(window, &failedES, NULL, 
						"Can't layout menus");

                                do {
                                    WaitPort(window->UserPort);
                                    while (imsg = GT_GetIMsg(window->UserPort)) {
                                        iclass = imsg->Class;
                                        icode = imsg->Code;
                                        hitgadget = 
					  (struct Gadget *) imsg->IAddress;
                                        GT_ReplyIMsg(imsg);

                                        switch (iclass) {
                                        case GADGETUP:
                                            if (hitgadget->GadgetID == 1) {
                                                dnode = 
						  (struct DisplayNode *) 
						    dlist->lh_Head;
                                                for (i = 0; i < icode; i++)
                                                dnode = 
						  (struct DisplayNode *)
						    dnode->dn_Node.ln_Succ;
                                                curmode = i;
                                            }
                                            if (hitgadget->GadgetID == 2)
                                                OK = TRUE;
                                            break;
                                        case MENUPICK:
                                            while ((icode != MENUNULL) 
						   && (ABORT == FALSE)) {
                                                item = ItemAddress(menu, icode);

                                                code = (ULONG) MENU_USERDATA(item);
                                                if (code == QUIT)
                                                    ABORT = TRUE;
                                                else if
                                                    (code == SWITCH)
                                                    OK = TRUE;
                                                else
                                                    overscantype = (ULONG) code;
                                                icode = item->NextSelect;
                                            }
                                            break;
                                        case CLOSEWINDOW:
                                            ABORT = TRUE;
                                            break;
                                        }
                                    }
                                } while (ABORT == FALSE && OK == FALSE);
                                ClearMenuStrip(window);
                                CloseWindow(window);
                                FreeVisualInfo(vi);
                                FreeGadgets(glist);
                            } else
                                EasyRequest(NULL, &failedES, NULL, 
					    "Can't open window");
                            FreeScreenDrawInfo(screen, drawinfo);
                            CloseScreen(screen);
                        } else
                            EasyRequest(NULL, &failedES, NULL, 
					"Can't open screen");
                    } while (ABORT == FALSE);
                    FreeMenus(menu);
                } else
                    EasyRequest(NULL, &failedES, NULL, "Can't create menus");
                FreeMem(textattr->ta_Name, 48);
            } else
                EasyRequest(NULL, &failedES, NULL, "Out of memory");
            FreeMem(textattr, sizeof(struct TextAttr));
        } else
            EasyRequest(NULL, &failedES, NULL, "Out of memory");
        FreeMem(ng, sizeof(struct NewGadget));
    } else
        EasyRequest(NULL, &failedES, NULL, "Out of memory");
}


/*
 * It's advised to use one of the overscan constants and
 * STDSCREENWIDTH and STDSCREENHEIGHT. For this example however, we'll
 * skip all that an use QueryOverscan to get the rectangle describing the
 * requested overscantype and pass that as the displayclip description.
 * Actually, since we pass the standard rectangle from the display database,
 * it is equivalent to the prefered:
 *
 * screen = OpenScreenTags(NULL,
 *                         SA_DisplayID, di->Header.DisplayID,
 *                         SA_Overscan, overscantype,
 *                         SA_Width, STDSCREENWIDTH,
 *                         SA_Height, STDSCREENHEIGHT,
 *                         SA_Title, name,
 *                         SA_Depth, 2,
 *                         SA_SysFont, 1,
 *                         SA_Pens, dri_Pens,
 *                         TAG_END);
 */

struct Screen *
OpenAScreen(struct DimensionInfo * di, UBYTE * name, ULONG overscantype)
{

    struct Rectangle rectangle;

    /* Can't fail, already made sure it's a valid displayID */
    QueryOverscan(di->Header.DisplayID, &rectangle, overscantype);


    return (OpenScreenTags(NULL,
                           SA_DisplayID, di->Header.DisplayID,
                           SA_DClip, &rectangle,
                           SA_Title, name,
                           SA_Depth, 2,
                           SA_SysFont, 1,   /* Use the prefered WB screen font */
                           SA_Pens, dri_Pens,
                           TAG_END));
}

struct Window *
OpenAWindow(struct Screen * screen, ULONG overscantype)
{
    return (OpenWindowTags(NULL,
                           WA_Top, screen->BarHeight + 1,
                           WA_Height, screen->Height - (screen->BarHeight + 1),
                           WA_CustomScreen, screen,
                           WA_IDCMP, CLOSEWINDOW | LISTVIEWIDCMP | MENUPICK,
                           WA_Flags, WINDOWCLOSE | ACTIVATE,
                           WA_Title, OScanDescr[overscantype],
                           TAG_END));
}


