home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Milan_1991 / Devcon91.1 / Libraries / Intuition / other_examples / PubSc / psmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-01  |  12.4 KB  |  521 lines

  1. /* main.c -- new public screen demo :ts=8 */
  2. /*
  3. Copyright (c) 1989 Commodore-Amiga, Inc.
  4.  
  5. Executables based on this information may be used in software
  6. for Commodore Amiga computers. All other rights reserved.
  7. This information is provided "as is"; no warranties are made.
  8. All use is at your own risk, and no liability or responsibility
  9. is assumed.
  10. */
  11.  
  12. #include "sysall.h"
  13. #include "tmsg.h"
  14. #include "pubsc.h"
  15.  
  16. #define D(x)    ;
  17. #define DL(x)    ;
  18. #define DPS(x)    ;
  19.  
  20. struct Gadget    *commandGadgets();
  21. struct Gadget     *buttonGadgets();
  22. struct  Window    *getVisitor();
  23. struct TextMsg    *CreateTextMsg();
  24.  
  25. struct Library    *IntuitionBase = NULL;
  26. struct Library    *GfxBase = NULL;
  27. struct Library    *OpenLibrary();
  28.  
  29. #define ASIZE(a)    (sizeof( a )/sizeof ( a[0] ))
  30. #define IDMASK    (0x00ff)    /* mask with this to get id in category    */
  31.  
  32. UBYTE    *commstr[] = {
  33.     (UBYTE *) "Close Screen",
  34.     (UBYTE *) "Make Default",
  35.     (UBYTE *) "Open New",
  36.     (UBYTE *) "Jump",
  37. };
  38.  
  39. #define COMMAND_ID    (0x0200)
  40.  
  41. /*** button state gadget bookkeeping    ***/
  42. UBYTE    *buttonstr[] = {
  43.     (UBYTE *) "Auto Pop-to-front",
  44.     (UBYTE *) "Hijack Workbench",
  45. };
  46.  
  47. #define BUTTON_ID    (0x0100)
  48. struct Gadget    *buttons[ ASIZE( buttonstr ) ];
  49.  
  50. /*
  51.  * The ways these work:
  52.  *    Currname is the name of the screen we're open on, or would
  53.  *    like to open on.  
  54.  *    It's the null string if we're open on the Workbench.
  55.  */
  56. UBYTE        currname[ MAXPUBSCREENNAME] = "";
  57. struct Screen    *lockedscreen = NULL;
  58. struct Window   *window = NULL;
  59.  
  60. struct Gadget    *usergadgets = NULL;
  61.  
  62. struct TextMsg    *currmsg = NULL;
  63. struct TextMsg    *defmsg;
  64. struct TextMsg    *statusmsg;
  65.  
  66. WORD        saveWLeft = 120;
  67. WORD        saveWTop = 80;
  68.  
  69. struct RastPort    *windowrp;    /* my window's RastPort            */
  70. UBYTE            defname[ MAXPUBSCREENNAME ] = "";
  71.  
  72. main()
  73. {
  74.     struct  IntuiMessage    *msg;
  75.     UBYTE            toUpper();
  76.  
  77.     /* hold data from *msg  */
  78.     ULONG           class;
  79.     USHORT          code;
  80.     struct Gadget        *iaddr;
  81.     UWORD        qualifier;
  82.     int            gid;
  83.  
  84.  
  85.     if (! (IntuitionBase =  OpenLibrary("intuition.library", 36L) ) )
  86.         cleanup( "no v36 Intuition", 20 );
  87.  
  88.     if ( ! (GfxBase =   OpenLibrary("graphics.library", 36L) ) )
  89.         cleanup( "no v36 Graphics", 20 );
  90.  
  91.  
  92.     /* Open up on default public screen    */
  93.     lockPubScreen();
  94.     upWindow();
  95.  
  96.     FOREVER
  97.     {
  98.     if ((msg = (struct IntuiMessage *)GetMsg(window->UserPort)) == NULL)
  99.     {
  100.         Wait(1L<<window->UserPort->mp_SigBit);
  101.         continue;
  102.     }
  103.  
  104.     /* Stash message contents and reply,
  105.      * important when message triggers some
  106.      * lengthy processing
  107.      */
  108.  
  109.     class   = msg->Class;
  110.     code    = msg->Code;
  111.     iaddr   = (struct Gadget *) msg->IAddress;
  112.     qualifier = msg->Qualifier;
  113.  
  114.     ReplyMsg(msg);
  115.  
  116.     switch (class)
  117.     {
  118.     case REFRESHWINDOW:
  119.         BeginRefresh( window );
  120.  
  121.         RefreshTextMsg( windowrp, currmsg, -1 );
  122.  
  123.         EndRefresh( window, 1L );
  124.         break;
  125.  
  126.     case VANILLAKEY:
  127.         /* look for key in command gadget list    */
  128.         /* ZZZZ: do case conversion    */
  129.         if ( code == 'q' || code == 'Q' ) cleanup( "quit.", 0 );
  130.  
  131.         code = toUpper( code );
  132.  
  133.         for ( gid = 0; gid < c_number; ++gid )
  134.         {
  135.         if ( toUpper( *(commstr[ gid ]) ) == code )
  136.         {
  137.             doCommand( gid );
  138.             break;
  139.         }
  140.         }
  141.         break;
  142.  
  143.     case GADGETDOWN:
  144.         setPSModes();
  145.  
  146.         break;
  147.  
  148.     case GADGETUP:
  149.         gid = iaddr->GadgetID;
  150.         if ( ( gid & ~IDMASK ) == COMMAND_ID )
  151.         {
  152.         doCommand( gid & IDMASK );
  153.         }
  154.         break;
  155.  
  156.     case CLOSEWINDOW:
  157.         cleanup( "all done", 0 );
  158.     }
  159.     }
  160. }
  161.  
  162. cleanup( str, code )
  163. UBYTE    *str;
  164. {
  165.  
  166.     downWindow();
  167.  
  168.     if ( str ) printf( "%s\n", str );
  169.  
  170.     if (GfxBase) CloseLibrary(GfxBase);
  171.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  172.  
  173.     exit ( code );
  174. }
  175.  
  176. UBYTE toUpper(u)
  177. UBYTE u;
  178. {
  179.  
  180.     if ((u >= 0x61 && u <= 0x7a) ||
  181.         (u >= 0xe0 && u <= 0xf6) || 
  182.         (u >= 0xf8 && u <= 0xfe)) u &= 0xdf;
  183.  
  184.     return(u);
  185. }
  186.  
  187. psstatus( str )
  188. char    *str;
  189. {
  190.     D( printf("psstatus: %s\n", str ) );
  191.     ChangeTextMsg( windowrp, statusmsg, str );
  192. }
  193.  
  194. /*
  195.  * fetches screen names and updates display
  196.  */
  197. updateMessages()
  198. {
  199.     GetDefaultPubScreen( defname );
  200.  
  201.     ChangeTextMsg( windowrp, currmsg, "Current screen: %s", 
  202.         currname[0]? currname: (UBYTE *) defname );
  203.     ChangeTextMsg( windowrp, defmsg, "Default screen: %s", defname );
  204.     ChangeTextMsg( windowrp, statusmsg, "" );
  205. }
  206.  
  207. /*
  208.  * read gadgets and tell Intuition
  209.  */
  210. setPSModes()
  211. {
  212.     UWORD    modes = 0;
  213.  
  214.     if ( buttons[ b_autopop ]->Flags & SELECTED )  modes |= POPPUBSCREEN;
  215.     if ( buttons[ b_hijack ]->Flags & SELECTED )  modes |= SHANGHAI;
  216.  
  217.     SetPubScreenModes( (long) modes );
  218. }
  219.  
  220. /*
  221.  * sync my gadgets up with actual modes.
  222.  * no refresh.  returns non-zero if my gadgets were wrong.
  223.  */
  224. getPSModes()
  225. {
  226.     UWORD    modes;
  227.     UWORD    mymodes = 0;
  228.  
  229.     /* get modes    */
  230.     Forbid();
  231.     modes = SetPubScreenModes( 0L );
  232.     SetPubScreenModes( (long) modes );
  233.     Permit();
  234.  
  235.     /* get my modes, to detect change    */
  236.     if ( buttons[ b_autopop ]->Flags & SELECTED )  mymodes |= POPPUBSCREEN;
  237.     if ( buttons[ b_hijack ]->Flags & SELECTED )  mymodes |= SHANGHAI;
  238.  
  239.     if ( modes & SHANGHAI )    buttons[ b_hijack ]->Flags |= SELECTED;
  240.     if ( modes & POPPUBSCREEN )    buttons[ b_autopop ]->Flags |= SELECTED;
  241.  
  242.     return ( mymodes ^ modes );
  243. }
  244.  
  245.  
  246. /* ---------------------------------------------------------------    */
  247. /*    Layout and initialization of application window            */
  248. /* ---------------------------------------------------------------    */
  249.  
  250. upWindow()
  251. {
  252.     DPS( printf("upWindow, currname: %s\n", currname ) );
  253.     if ( ! lockedscreen ) cleanup( "upWindow: no lock on screen\n" );
  254.  
  255.     DPS( printf("upWindow locked screen: %lx\n", lockedscreen ) );
  256.  
  257.     initWindow( lockedscreen, saveWLeft, saveWTop ); /* will cleanup() */
  258.     windowrp = window->RPort;
  259.  
  260.     UnlockPubScreen( NULL, lockedscreen );
  261.     lockedscreen = NULL;
  262.  
  263.     updateMessages();
  264. }
  265.  
  266. downWindow()
  267. {
  268.     DPS( printf("down window.  currname %s\n", currname) );
  269.  
  270.     if (window)
  271.     {
  272.     saveWLeft = window->LeftEdge;
  273.     saveWTop = window->TopEdge;        /* scale these back    */
  274.  
  275.     DeleteTextMsg( currmsg, -1 );
  276.     currmsg = NULL;
  277.  
  278.     if ( usergadgets )
  279.     {
  280.         RemoveGList( window, usergadgets, -1L );
  281.         FreeGadgets( usergadgets );
  282.         usergadgets = 0;
  283.         cleanupCommGadgets();
  284.         cleanupButtonGadgets();
  285.     }
  286.     CloseWindow(window);
  287.     window = NULL;
  288.     }
  289. }
  290.  
  291. struct LayoutBox {
  292.     WORD    Left;
  293.     WORD    Top;
  294.     WORD    Width;
  295.     WORD    Height;
  296. };
  297.  
  298. /* These quantities should scale by resolution
  299.  * or otherwise determined by more dynamic means
  300.  */
  301. #define LAYOUT_LEFT    (20)
  302. #define LAYOUT_TOP    (5)    /* add this to title bar height        */
  303. #define RIGHT_MARGIN    (60)    /* right side slop            */
  304. #define BOTTOM_MARGIN    (5)
  305. #define VFILL        (2)    /* vertical space between items        */
  306. #define HFILL        (28)    /* horizontal space between columns    */
  307. /* Also, need to communicate gadgetborder thicknesses to
  308.  * gadget building routines
  309.  */
  310.  
  311.  
  312. initWindow( sc, wleft, wtop )
  313. struct Screen    *sc;
  314. {
  315.     struct RastPort    *rp;    /* used only for text size calculations    */
  316.     struct Gadget    *g = (struct Gadget *) &usergadgets; /* tail of list */
  317.  
  318.     /* layout    */
  319.     struct LayoutBox    lbox;
  320.     int        gleft = LAYOUT_LEFT;    /* running position    */
  321.     int        gtop;
  322.     WORD    tmheight;
  323.  
  324.     int        wwidth;
  325.     int        wheight;
  326.  
  327.     rp = &sc->RastPort;
  328.     DL( printf("rastport text height: %d\n", rp->TxHeight ));
  329.  
  330.     /* start placement within window borders    */
  331.     gleft = sc->WBorLeft + LAYOUT_LEFT;
  332.     DL( printf("left before commgads: %d\n", gleft ));
  333.     gtop = LAYOUT_TOP + sc->WBorTop + rp->TxHeight + 1;
  334.  
  335.     /* initialize layout    */
  336.     initLayoutBox( &lbox );
  337.  
  338.     g->NextGadget = commandGadgets(rp, commstr, ASIZE(commstr), COMMAND_ID);
  339.     if ( ! g->NextGadget )    cleanup( "commandGadget failed.", 20 );
  340.  
  341.     /* column placement.  note trick of walking to end of list    */
  342.     while ( g->NextGadget )
  343.     {
  344.     g = g->NextGadget;
  345.  
  346.     g->LeftEdge = gleft;
  347.     g->TopEdge = gtop;
  348.     gtop += (g->Height + VFILL);
  349.  
  350.     gadgetExpand( &lbox, g );        /* track layout    */
  351.     }
  352.  
  353.     /* next column    */
  354.     gtop = lbox.Top;
  355.     gleft = lbox.Left + lbox.Width + HFILL;
  356.     DL( printf("left after commgads: %d\n", gleft ));
  357.  
  358.     /* start column with two screen status messages    */
  359.     if (!(currmsg = CreateTextMsg( 128 ) ) ) cleanup( "no TextMessage!", 20 );
  360.     if (!(defmsg = CreateTextMsg( 128 ) ) ) cleanup( "no TextMessage!", 20 );
  361.     if (!(statusmsg = CreateTextMsg( 128 ) ) )
  362.         cleanup( "no TextMessage!", 20 );
  363.  
  364.     currmsg->tm_Next = defmsg;
  365.     defmsg->tm_Next = statusmsg;
  366.  
  367.  
  368.     /* position current screen message */
  369.     PositionTextMsg( currmsg, gleft, gtop );
  370.     TextMsgSize( rp, currmsg, NULL, &tmheight );
  371.     expandLayout( &lbox, gleft, gtop, 0, tmheight );
  372.     gtop += tmheight + VFILL;
  373.  
  374.     /* position default screen message */
  375.     PositionTextMsg( defmsg, gleft, gtop );
  376.     TextMsgSize( rp, defmsg, NULL, &tmheight );
  377.     expandLayout( &lbox, gleft, gtop, 0, tmheight );
  378.     gtop += tmheight + VFILL;
  379.  
  380.     /* position status message later    */
  381.  
  382.     g->NextGadget = buttonGadgets(rp, buttonstr, ASIZE(buttonstr), BUTTON_ID);
  383.     if ( ! g->NextGadget ) cleanup( "buttonGadgets failed.", 20 );
  384.  
  385.     /* column placement.  note trick of walking to end of list    */
  386.     while ( g->NextGadget )
  387.     {
  388.     g = g->NextGadget; 
  389.     /* position */
  390.     g->LeftEdge = gleft;
  391.     g->TopEdge = gtop;
  392.     gtop += (g->Height + VFILL);
  393.  
  394.     gadgetExpand( &lbox, g );        /* track layout    */
  395.  
  396.     /* stash in array    */
  397.     buttons[ g->GadgetID & IDMASK ] = g;
  398.     }
  399.  
  400.     getPSModes();    /* init my SELECTED flags    */
  401.  
  402.     /* layout, limit text message, to be aligned with others    */
  403.     PositionTextMsg( statusmsg, lbox.Left, lbox.Top + lbox.Height + VFILL );
  404.     TextMsgSize( rp, statusmsg, NULL, &tmheight );
  405.     expandLayout( &lbox, lbox.Left,
  406.     lbox.Top + lbox.Height + VFILL , 0, tmheight );
  407.  
  408.     D( printf("layout l/t/w/h: %d/%d/%d/%d\n", lbox.Left, lbox.Top,
  409.     lbox.Width, lbox.Height ) );
  410.  
  411.     /* determine desired window dimensions                */
  412.     wwidth = lbox.Left + lbox.Width + RIGHT_MARGIN;
  413.     wheight = lbox.Top + lbox.Height + BOTTOM_MARGIN;
  414.  
  415.     D(printf("naive dims %d/%d/%d/%d\n", wleft, wtop, wwidth, wheight ) );
  416.  
  417.     /* adjust left top to make more room, if necessary    */
  418.     wleft = jmax( 0, jmin( wleft, sc->Width - wwidth ) );
  419.     wtop = jmax( 0, jmin( wtop, sc->Height - wheight ) );
  420.  
  421.     D( printf("shifted dims %d/%d/%d/%d\n", wleft, wtop, wwidth, wheight ) );
  422.     D( printf("screen w/h %d/%d\n", sc->Width, sc->Height ) );
  423.  
  424.     /* double check for legal width, height                */
  425.     wwidth = jmin( wwidth, sc->Width - wleft );
  426.     wheight = jmin( wheight, sc->Height - wtop );
  427.  
  428.     /* just keep the messages in window    */
  429.     LimitTextMsg( statusmsg, wwidth - sc->WBorRight -  lbox.Left );
  430.     LimitTextMsg( currmsg, wwidth - sc->WBorRight -  gleft );
  431.     LimitTextMsg( defmsg, wwidth - sc->WBorRight -  gleft );
  432.  
  433.     D( printf("window %d/%d/%d/%d\n", wleft, wtop, wwidth, wheight ) );
  434.  
  435.     window = getVisitor( wleft, wtop, wwidth, wheight, sc );
  436.     DPS( printf("visitor open at %lx\n", window ));
  437.     if ( ! window ) cleanup( "can't get window", 20 );
  438.  
  439.     /* show me    */
  440.     AddGList( window, usergadgets, -1L, -1L );
  441.     RefreshGList( usergadgets, window, NULL, -1L );
  442. }
  443.  
  444. /* ---------------------------------------------------------------    */
  445. /*    Layout utilities                        */
  446. /* ---------------------------------------------------------------    */
  447.  
  448. initLayoutBox( lb )
  449. struct LayoutBox    *lb;
  450. {
  451.     lb->Left = lb->Top  = 32000;
  452.     lb->Width = lb->Height = -32000;
  453. }
  454.  
  455. expandLayout( lb, l, t, w, h )
  456. struct LayoutBox    *lb;
  457. {
  458.     int    margin;
  459.  
  460.     if ( (margin = lb->Left - l) > 0 )
  461.     {
  462.     lb->Left = l;
  463.     lb->Width += margin;
  464.     }
  465.  
  466.     if ( (margin = lb->Top - t) > 0 )
  467.     {
  468.     lb->Top = t;
  469.     lb->Height += margin;
  470.     }
  471.  
  472.     forceHigh( &lb->Width, l + w - lb->Left );
  473.     forceHigh( &lb->Height, t + h - lb->Top );
  474. }
  475.  
  476. forceHigh( valp, low )
  477. WORD    *valp;
  478. WORD    low;
  479. { if ( *valp < low ) *valp = low; }
  480.  
  481. gadgetExpand( lb, g )
  482. struct LayoutBox    *lb;
  483. struct Gadget        *g;
  484. { expandLayout( lb, g->LeftEdge, g->TopEdge, g->Width, g->Height ); }
  485.  
  486. struct  Window * getVisitor(left, top, width, height, screen )
  487. WORD   left, top, width, height;
  488. struct Screen    *screen;        /* locked public screen, or NULL */
  489. {
  490.     struct  Window  *OpenWindowTags();
  491.  
  492.     DPS( printf("getVisitor: screen %lx\n", screen ) );
  493.  
  494.     return ( OpenWindowTags( NULL,
  495.         WA_Left,    left,
  496.         WA_Top,        top,
  497.         WA_Width,    width,
  498.         WA_Height,    height,
  499.         WA_IDCMP,  GADGETDOWN|GADGETUP|VANILLAKEY|CLOSEWINDOW|REFRESHWINDOW,
  500.     WA_Activate,    TRUE,
  501.     WA_CloseGadget,    TRUE,
  502.     WA_DepthGadget,    TRUE,
  503.     WA_DragBar,    TRUE,
  504.     WA_SimpleRefresh, TRUE,
  505.         WA_Title,     " Public Screen Demo ",
  506.         WA_PubScreen,    screen,
  507.     TAG_END ) );
  508. }
  509.  
  510. /* convert varargs to array    */
  511. struct Window    *
  512. OpenWindowTags( nw, tag1 )
  513. struct NewWindow    *nw;
  514. ULONG            tag1;
  515. {
  516.     struct  Window  *OpenWindowTagList();
  517.  
  518.     return ( OpenWindowTagList( nw, &tag1 ) );
  519. }
  520.  
  521.