home *** CD-ROM | disk | FTP | other *** search
- /* main.c -- new public screen demo :ts=8 */
- /*
- Copyright (c) 1989 Commodore-Amiga, Inc.
-
- Executables based on this information may be used in software
- for Commodore Amiga computers. All other rights reserved.
- This information is provided "as is"; no warranties are made.
- All use is at your own risk, and no liability or responsibility
- is assumed.
- */
-
- #include "sysall.h"
- #include "tmsg.h"
- #include "pubsc.h"
-
- #define D(x) ;
- #define DL(x) ;
- #define DPS(x) ;
-
- struct Gadget *commandGadgets();
- struct Gadget *buttonGadgets();
- struct Window *getVisitor();
- struct TextMsg *CreateTextMsg();
-
- struct Library *IntuitionBase = NULL;
- struct Library *GfxBase = NULL;
- struct Library *OpenLibrary();
-
- #define ASIZE(a) (sizeof( a )/sizeof ( a[0] ))
- #define IDMASK (0x00ff) /* mask with this to get id in category */
-
- UBYTE *commstr[] = {
- (UBYTE *) "Close Screen",
- (UBYTE *) "Make Default",
- (UBYTE *) "Open New",
- (UBYTE *) "Jump",
- };
-
- #define COMMAND_ID (0x0200)
-
- /*** button state gadget bookkeeping ***/
- UBYTE *buttonstr[] = {
- (UBYTE *) "Auto Pop-to-front",
- (UBYTE *) "Hijack Workbench",
- };
-
- #define BUTTON_ID (0x0100)
- struct Gadget *buttons[ ASIZE( buttonstr ) ];
-
- /*
- * The ways these work:
- * Currname is the name of the screen we're open on, or would
- * like to open on.
- * It's the null string if we're open on the Workbench.
- */
- UBYTE currname[ MAXPUBSCREENNAME] = "";
- struct Screen *lockedscreen = NULL;
- struct Window *window = NULL;
-
- struct Gadget *usergadgets = NULL;
-
- struct TextMsg *currmsg = NULL;
- struct TextMsg *defmsg;
- struct TextMsg *statusmsg;
-
- WORD saveWLeft = 120;
- WORD saveWTop = 80;
-
- struct RastPort *windowrp; /* my window's RastPort */
- UBYTE defname[ MAXPUBSCREENNAME ] = "";
-
- main()
- {
- struct IntuiMessage *msg;
- UBYTE toUpper();
-
- /* hold data from *msg */
- ULONG class;
- USHORT code;
- struct Gadget *iaddr;
- UWORD qualifier;
- int gid;
-
-
- if (! (IntuitionBase = OpenLibrary("intuition.library", 36L) ) )
- cleanup( "no v36 Intuition", 20 );
-
- if ( ! (GfxBase = OpenLibrary("graphics.library", 36L) ) )
- cleanup( "no v36 Graphics", 20 );
-
-
- /* Open up on default public screen */
- lockPubScreen();
- upWindow();
-
- FOREVER
- {
- if ((msg = (struct IntuiMessage *)GetMsg(window->UserPort)) == NULL)
- {
- Wait(1L<<window->UserPort->mp_SigBit);
- continue;
- }
-
- /* Stash message contents and reply,
- * important when message triggers some
- * lengthy processing
- */
-
- class = msg->Class;
- code = msg->Code;
- iaddr = (struct Gadget *) msg->IAddress;
- qualifier = msg->Qualifier;
-
- ReplyMsg(msg);
-
- switch (class)
- {
- case REFRESHWINDOW:
- BeginRefresh( window );
-
- RefreshTextMsg( windowrp, currmsg, -1 );
-
- EndRefresh( window, 1L );
- break;
-
- case VANILLAKEY:
- /* look for key in command gadget list */
- /* ZZZZ: do case conversion */
- if ( code == 'q' || code == 'Q' ) cleanup( "quit.", 0 );
-
- code = toUpper( code );
-
- for ( gid = 0; gid < c_number; ++gid )
- {
- if ( toUpper( *(commstr[ gid ]) ) == code )
- {
- doCommand( gid );
- break;
- }
- }
- break;
-
- case GADGETDOWN:
- setPSModes();
-
- break;
-
- case GADGETUP:
- gid = iaddr->GadgetID;
- if ( ( gid & ~IDMASK ) == COMMAND_ID )
- {
- doCommand( gid & IDMASK );
- }
- break;
-
- case CLOSEWINDOW:
- cleanup( "all done", 0 );
- }
- }
- }
-
- cleanup( str, code )
- UBYTE *str;
- {
-
- downWindow();
-
- if ( str ) printf( "%s\n", str );
-
- if (GfxBase) CloseLibrary(GfxBase);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
-
- exit ( code );
- }
-
- UBYTE toUpper(u)
- UBYTE u;
- {
-
- if ((u >= 0x61 && u <= 0x7a) ||
- (u >= 0xe0 && u <= 0xf6) ||
- (u >= 0xf8 && u <= 0xfe)) u &= 0xdf;
-
- return(u);
- }
-
- psstatus( str )
- char *str;
- {
- D( printf("psstatus: %s\n", str ) );
- ChangeTextMsg( windowrp, statusmsg, str );
- }
-
- /*
- * fetches screen names and updates display
- */
- updateMessages()
- {
- GetDefaultPubScreen( defname );
-
- ChangeTextMsg( windowrp, currmsg, "Current screen: %s",
- currname[0]? currname: (UBYTE *) defname );
- ChangeTextMsg( windowrp, defmsg, "Default screen: %s", defname );
- ChangeTextMsg( windowrp, statusmsg, "" );
- }
-
- /*
- * read gadgets and tell Intuition
- */
- setPSModes()
- {
- UWORD modes = 0;
-
- if ( buttons[ b_autopop ]->Flags & SELECTED ) modes |= POPPUBSCREEN;
- if ( buttons[ b_hijack ]->Flags & SELECTED ) modes |= SHANGHAI;
-
- SetPubScreenModes( (long) modes );
- }
-
- /*
- * sync my gadgets up with actual modes.
- * no refresh. returns non-zero if my gadgets were wrong.
- */
- getPSModes()
- {
- UWORD modes;
- UWORD mymodes = 0;
-
- /* get modes */
- Forbid();
- modes = SetPubScreenModes( 0L );
- SetPubScreenModes( (long) modes );
- Permit();
-
- /* get my modes, to detect change */
- if ( buttons[ b_autopop ]->Flags & SELECTED ) mymodes |= POPPUBSCREEN;
- if ( buttons[ b_hijack ]->Flags & SELECTED ) mymodes |= SHANGHAI;
-
- if ( modes & SHANGHAI ) buttons[ b_hijack ]->Flags |= SELECTED;
- if ( modes & POPPUBSCREEN ) buttons[ b_autopop ]->Flags |= SELECTED;
-
- return ( mymodes ^ modes );
- }
-
-
- /* --------------------------------------------------------------- */
- /* Layout and initialization of application window */
- /* --------------------------------------------------------------- */
-
- upWindow()
- {
- DPS( printf("upWindow, currname: %s\n", currname ) );
- if ( ! lockedscreen ) cleanup( "upWindow: no lock on screen\n" );
-
- DPS( printf("upWindow locked screen: %lx\n", lockedscreen ) );
-
- initWindow( lockedscreen, saveWLeft, saveWTop ); /* will cleanup() */
- windowrp = window->RPort;
-
- UnlockPubScreen( NULL, lockedscreen );
- lockedscreen = NULL;
-
- updateMessages();
- }
-
- downWindow()
- {
- DPS( printf("down window. currname %s\n", currname) );
-
- if (window)
- {
- saveWLeft = window->LeftEdge;
- saveWTop = window->TopEdge; /* scale these back */
-
- DeleteTextMsg( currmsg, -1 );
- currmsg = NULL;
-
- if ( usergadgets )
- {
- RemoveGList( window, usergadgets, -1L );
- FreeGadgets( usergadgets );
- usergadgets = 0;
- cleanupCommGadgets();
- cleanupButtonGadgets();
- }
- CloseWindow(window);
- window = NULL;
- }
- }
-
- struct LayoutBox {
- WORD Left;
- WORD Top;
- WORD Width;
- WORD Height;
- };
-
- /* These quantities should scale by resolution
- * or otherwise determined by more dynamic means
- */
- #define LAYOUT_LEFT (20)
- #define LAYOUT_TOP (5) /* add this to title bar height */
- #define RIGHT_MARGIN (60) /* right side slop */
- #define BOTTOM_MARGIN (5)
- #define VFILL (2) /* vertical space between items */
- #define HFILL (28) /* horizontal space between columns */
- /* Also, need to communicate gadgetborder thicknesses to
- * gadget building routines
- */
-
-
- initWindow( sc, wleft, wtop )
- struct Screen *sc;
- {
- struct RastPort *rp; /* used only for text size calculations */
- struct Gadget *g = (struct Gadget *) &usergadgets; /* tail of list */
-
- /* layout */
- struct LayoutBox lbox;
- int gleft = LAYOUT_LEFT; /* running position */
- int gtop;
- WORD tmheight;
-
- int wwidth;
- int wheight;
-
- rp = &sc->RastPort;
- DL( printf("rastport text height: %d\n", rp->TxHeight ));
-
- /* start placement within window borders */
- gleft = sc->WBorLeft + LAYOUT_LEFT;
- DL( printf("left before commgads: %d\n", gleft ));
- gtop = LAYOUT_TOP + sc->WBorTop + rp->TxHeight + 1;
-
- /* initialize layout */
- initLayoutBox( &lbox );
-
- g->NextGadget = commandGadgets(rp, commstr, ASIZE(commstr), COMMAND_ID);
- if ( ! g->NextGadget ) cleanup( "commandGadget failed.", 20 );
-
- /* column placement. note trick of walking to end of list */
- while ( g->NextGadget )
- {
- g = g->NextGadget;
-
- g->LeftEdge = gleft;
- g->TopEdge = gtop;
- gtop += (g->Height + VFILL);
-
- gadgetExpand( &lbox, g ); /* track layout */
- }
-
- /* next column */
- gtop = lbox.Top;
- gleft = lbox.Left + lbox.Width + HFILL;
- DL( printf("left after commgads: %d\n", gleft ));
-
- /* start column with two screen status messages */
- if (!(currmsg = CreateTextMsg( 128 ) ) ) cleanup( "no TextMessage!", 20 );
- if (!(defmsg = CreateTextMsg( 128 ) ) ) cleanup( "no TextMessage!", 20 );
- if (!(statusmsg = CreateTextMsg( 128 ) ) )
- cleanup( "no TextMessage!", 20 );
-
- currmsg->tm_Next = defmsg;
- defmsg->tm_Next = statusmsg;
-
-
- /* position current screen message */
- PositionTextMsg( currmsg, gleft, gtop );
- TextMsgSize( rp, currmsg, NULL, &tmheight );
- expandLayout( &lbox, gleft, gtop, 0, tmheight );
- gtop += tmheight + VFILL;
-
- /* position default screen message */
- PositionTextMsg( defmsg, gleft, gtop );
- TextMsgSize( rp, defmsg, NULL, &tmheight );
- expandLayout( &lbox, gleft, gtop, 0, tmheight );
- gtop += tmheight + VFILL;
-
- /* position status message later */
-
- g->NextGadget = buttonGadgets(rp, buttonstr, ASIZE(buttonstr), BUTTON_ID);
- if ( ! g->NextGadget ) cleanup( "buttonGadgets failed.", 20 );
-
- /* column placement. note trick of walking to end of list */
- while ( g->NextGadget )
- {
- g = g->NextGadget;
- /* position */
- g->LeftEdge = gleft;
- g->TopEdge = gtop;
- gtop += (g->Height + VFILL);
-
- gadgetExpand( &lbox, g ); /* track layout */
-
- /* stash in array */
- buttons[ g->GadgetID & IDMASK ] = g;
- }
-
- getPSModes(); /* init my SELECTED flags */
-
- /* layout, limit text message, to be aligned with others */
- PositionTextMsg( statusmsg, lbox.Left, lbox.Top + lbox.Height + VFILL );
- TextMsgSize( rp, statusmsg, NULL, &tmheight );
- expandLayout( &lbox, lbox.Left,
- lbox.Top + lbox.Height + VFILL , 0, tmheight );
-
- D( printf("layout l/t/w/h: %d/%d/%d/%d\n", lbox.Left, lbox.Top,
- lbox.Width, lbox.Height ) );
-
- /* determine desired window dimensions */
- wwidth = lbox.Left + lbox.Width + RIGHT_MARGIN;
- wheight = lbox.Top + lbox.Height + BOTTOM_MARGIN;
-
- D(printf("naive dims %d/%d/%d/%d\n", wleft, wtop, wwidth, wheight ) );
-
- /* adjust left top to make more room, if necessary */
- wleft = jmax( 0, jmin( wleft, sc->Width - wwidth ) );
- wtop = jmax( 0, jmin( wtop, sc->Height - wheight ) );
-
- D( printf("shifted dims %d/%d/%d/%d\n", wleft, wtop, wwidth, wheight ) );
- D( printf("screen w/h %d/%d\n", sc->Width, sc->Height ) );
-
- /* double check for legal width, height */
- wwidth = jmin( wwidth, sc->Width - wleft );
- wheight = jmin( wheight, sc->Height - wtop );
-
- /* just keep the messages in window */
- LimitTextMsg( statusmsg, wwidth - sc->WBorRight - lbox.Left );
- LimitTextMsg( currmsg, wwidth - sc->WBorRight - gleft );
- LimitTextMsg( defmsg, wwidth - sc->WBorRight - gleft );
-
- D( printf("window %d/%d/%d/%d\n", wleft, wtop, wwidth, wheight ) );
-
- window = getVisitor( wleft, wtop, wwidth, wheight, sc );
- DPS( printf("visitor open at %lx\n", window ));
- if ( ! window ) cleanup( "can't get window", 20 );
-
- /* show me */
- AddGList( window, usergadgets, -1L, -1L );
- RefreshGList( usergadgets, window, NULL, -1L );
- }
-
- /* --------------------------------------------------------------- */
- /* Layout utilities */
- /* --------------------------------------------------------------- */
-
- initLayoutBox( lb )
- struct LayoutBox *lb;
- {
- lb->Left = lb->Top = 32000;
- lb->Width = lb->Height = -32000;
- }
-
- expandLayout( lb, l, t, w, h )
- struct LayoutBox *lb;
- {
- int margin;
-
- if ( (margin = lb->Left - l) > 0 )
- {
- lb->Left = l;
- lb->Width += margin;
- }
-
- if ( (margin = lb->Top - t) > 0 )
- {
- lb->Top = t;
- lb->Height += margin;
- }
-
- forceHigh( &lb->Width, l + w - lb->Left );
- forceHigh( &lb->Height, t + h - lb->Top );
- }
-
- forceHigh( valp, low )
- WORD *valp;
- WORD low;
- { if ( *valp < low ) *valp = low; }
-
- gadgetExpand( lb, g )
- struct LayoutBox *lb;
- struct Gadget *g;
- { expandLayout( lb, g->LeftEdge, g->TopEdge, g->Width, g->Height ); }
-
- struct Window * getVisitor(left, top, width, height, screen )
- WORD left, top, width, height;
- struct Screen *screen; /* locked public screen, or NULL */
- {
- struct Window *OpenWindowTags();
-
- DPS( printf("getVisitor: screen %lx\n", screen ) );
-
- return ( OpenWindowTags( NULL,
- WA_Left, left,
- WA_Top, top,
- WA_Width, width,
- WA_Height, height,
- WA_IDCMP, GADGETDOWN|GADGETUP|VANILLAKEY|CLOSEWINDOW|REFRESHWINDOW,
- WA_Activate, TRUE,
- WA_CloseGadget, TRUE,
- WA_DepthGadget, TRUE,
- WA_DragBar, TRUE,
- WA_SimpleRefresh, TRUE,
- WA_Title, " Public Screen Demo ",
- WA_PubScreen, screen,
- TAG_END ) );
- }
-
- /* convert varargs to array */
- struct Window *
- OpenWindowTags( nw, tag1 )
- struct NewWindow *nw;
- ULONG tag1;
- {
- struct Window *OpenWindowTagList();
-
- return ( OpenWindowTagList( nw, &tag1 ) );
- }
-
-