home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol2 / iv-3 / screendisplaymodes.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  18KB  |  440 lines

  1. ;/* ScreenDisplayModes.c - V36 Screen Displaymode selector example
  2. ; Compiled with SAS/C 6.56
  3. sc NMINC STRMERGE NOSTKCHK LINK IGNORE=73 ScreenDisplayModes.c
  4. quit
  5.  
  6. Copyright (c) 1990 Commodore-Amiga, Inc.
  7.  
  8. This example is provided in electronic form by Commodore-Amiga,
  9. Inc. for use with the Amiga Mail Volume II technical publication.
  10. Amiga Mail Volume II contains additional information on the correct
  11. usage of the techniques and operating system functions presented in
  12. these examples.  The source and executable code of these examples may
  13. only be distributed in free electronic form, via bulletin board or
  14. as part of a fully non-commercial and freely redistributable
  15. diskette.  Both the source and executable code (including comments)
  16. must be included, without modification, in any copy.  This example
  17. may not be published in printed form or distributed with any
  18. commercial product. However, the programming techniques and support
  19. routines set forth in these examples may be used in the development
  20. of original executable software products for Commodore Amiga
  21. computers.
  22.  
  23. All other rights reserved.
  24.  
  25. This example is provided "as-is" and is subject to change; no
  26. warranties are made.  All use is at your own risk. No liability or
  27. responsibility is assumed.
  28. */
  29.  
  30. #include <string.h>
  31. #include <intuition/intuition.h>
  32. #include <intuition/screens.h>
  33. #include <libraries/gadtools.h>
  34. #include <graphics/displayinfo.h>
  35. #include <graphics/text.h>
  36. #include <exec/memory.h>
  37. #include <exec/ports.h>
  38.  
  39. #include <clib/exec_protos.h>
  40. #include <clib/intuition_protos.h>
  41. #include <clib/graphics_protos.h>
  42. #include <clib/gadtools_protos.h>
  43. #include <clib/alib_protos.h>
  44.  
  45. #include <pragmas/exec_pragmas.h>
  46. #include <pragmas/intuition_pragmas.h>
  47. #include <pragmas/graphics_pragmas.h>
  48. #include <pragmas/gadtools_pragmas.h>
  49.  
  50. #define SWITCH 888
  51. #define QUIT   999
  52.  
  53. struct IntuitionBase *IntuitionBase;
  54. struct GfxBase *GfxBase;
  55. struct Library *GadToolsBase;
  56. extern struct Library *SysBase;
  57.  
  58. void main(void);
  59. void ShowDisplayModes(struct List * dlist);
  60. struct Screen *OpenAScreen(struct DimensionInfo * di, UBYTE * name,
  61.                ULONG overscantype);
  62. struct Window *OpenAWindow(struct Screen * screen, ULONG overscantype);
  63.  
  64. struct DisplayNode {
  65.     struct Node dn_Node;
  66.     struct DimensionInfo dn_Dimensioninfo;
  67. };
  68.  
  69. /* The workbench compatible pens we'll use for that New Look. */
  70. static UWORD dri_Pens[] = {0, 1, 1, 2, 1, 3, 1, 0, 3, ~0};
  71.  
  72. /* Gadtools menu stuff */
  73. struct NewMenu sdm_menu[] =
  74. {
  75.     {NM_TITLE, "Project", 0, 0, 0, 0,},
  76.     {NM_ITEM, "Switch Mode", "S", 0, 0, (void *) SWITCH,},
  77.     {NM_ITEM, "Set Overscan", 0, 0, 0, 0,},
  78.     {NM_SUB, "Text", 0, CHECKIT | CHECKED, ~1, (void *) OSCAN_TEXT,},
  79.     {NM_SUB, "Standard", 0, CHECKIT, ~2, (void *) OSCAN_STANDARD,},
  80.     {NM_SUB, "Max", 0, CHECKIT, ~4, (void *) OSCAN_MAX,},
  81.     {NM_SUB, "Video", 0, CHECKIT, ~8, (void *) OSCAN_VIDEO,},
  82.     {NM_ITEM, NM_BARLABEL, 0, CHECKIT, 0, 0,},
  83.     {NM_ITEM, "Quit", "Q", 0, 0, (void *) QUIT,},
  84.     {NM_END, NULL, 0, 0, 0, 0,},
  85. };
  86.  
  87. UBYTE *OScanDescr[] = {NULL, "OSCAN_TEXT", "OSCAN_STANDARD",
  88.              "OSCAN_MAX", "OSCAN_VIDEO"};
  89.  
  90. struct EasyStruct failedES =
  91. {
  92.     sizeof(struct EasyStruct), 0, "SDM",
  93.     "%s",
  94.     "OK",
  95. };
  96.  
  97. void
  98. main(void)
  99. {
  100.     struct List *dlist;
  101.     struct DisplayNode *dnode;
  102.     struct DisplayNode *wnode, *nnode;
  103.  
  104.     ULONG modeID;
  105.     ULONG skipID;
  106.  
  107.     ULONG result;
  108.     struct DisplayInfo displayinfo;
  109.     struct NameInfo nameinfo;
  110.  
  111.     /* Fails silently if not V36 */
  112.     if (IntuitionBase = OpenLibrary("intuition.library", 36)) {
  113.         if (GfxBase = OpenLibrary("graphics.library", 36)) {
  114.             if (GadToolsBase = OpenLibrary("gadtools.library", 36)) {
  115.                 if (dlist = AllocMem(sizeof(struct List), MEMF_CLEAR)) {
  116.                     NewList(dlist);
  117.  
  118.                     /*
  119.                      * Don't want duplicate entries in the list for the
  120.                      * 'default monitor', so we'll skip the the videomode
  121.                      * for which default.monitor is the alias.
  122.                      */
  123.  
  124.                     /* INVALID_ID indicates the beginning and the end
  125.              * of the list of available keys.
  126.              */
  127.                     modeID = INVALID_ID;
  128.  
  129.                     GetDisplayInfoData(NULL, (UBYTE *) & displayinfo,
  130.                        sizeof(struct DisplayInfo),
  131.                        DTAG_DISP, LORES_KEY);
  132.                     if (displayinfo.PropertyFlags & DIPF_IS_PAL)
  133.                         skipID = PAL_MONITOR_ID;
  134.                     else
  135.                         skipID = NTSC_MONITOR_ID;
  136.                     while ((modeID = NextDisplayInfo(modeID)) != INVALID_ID) {
  137.                         if ((modeID & MONITOR_ID_MASK) != skipID) {
  138.                 /*
  139.                  * For this example,only 'named' keys are accepted.  Others
  140.                  * which have no description are left out
  141.                   * even though they may be available.
  142.                   * HAM and EXTRAHALFBRIGHT are examples of this.
  143.                   * If needed a name could be made like '320x400 HAM Interlace'.
  144.                   */
  145.  
  146.                             if (result = GetDisplayInfoData(NULL,
  147.                                 (UBYTE *) & nameinfo,
  148.                                 sizeof(struct NameInfo),
  149.                                 DTAG_NAME,
  150.                                 modeID)) {
  151.                                 result = GetDisplayInfoData(NULL,
  152.                                 (UBYTE *) & displayinfo,
  153.                                 sizeof(struct DisplayInfo),
  154.                                 DTAG_DISP,
  155.                                 modeID);
  156.                                 if (!(displayinfo.NotAvailable)) {
  157.                                     if (dnode =
  158.                     (struct DisplayNode *)
  159.                     AllocMem(sizeof(struct DisplayNode),
  160.                          MEMF_CLEAR)) {
  161.                                         result = GetDisplayInfoData(NULL,
  162.                            (UBYTE *) &
  163.                            (dnode->dn_Dimensioninfo),
  164.                            sizeof(struct DimensionInfo),
  165.                            DTAG_DIMS,
  166.                            modeID);
  167.                                         /* to keep it short: if NOMEM,
  168.                      * just don't copy
  169.                      */
  170.                                         if (dnode->dn_Node.ln_Name
  171.                         = AllocMem(strlen(nameinfo.Name)
  172.                                + 1, MEMF_CLEAR))
  173.                                             strcpy(dnode->dn_Node.ln_Name,
  174.                            nameinfo.Name);
  175.                                         AddTail(dlist, (struct Node *) dnode);
  176.                                     } else {
  177.                                         EasyRequest(NULL, &failedES, NULL,
  178.                             "Out of memory");
  179.                                         /* Force modeID to INVALID to break */
  180.                                         modeID = INVALID_ID;
  181.                                     }
  182.                                 }
  183.                             }
  184.                         }
  185.                     }
  186.                     ShowDisplayModes(dlist);
  187.  
  188.                     wnode = (struct DisplayNode *) dlist->lh_Head;
  189.                     while (nnode = (struct DisplayNode *)
  190.                (wnode->dn_Node.ln_Succ)) {
  191.  
  192.                         if (wnode->dn_Node.ln_Name)
  193.                             FreeMem(wnode->dn_Node.ln_Name,
  194.                     strlen(wnode->dn_Node.ln_Name) +1);
  195.                         Remove((struct Node *) wnode);
  196.                         FreeMem(wnode, sizeof(struct DisplayNode));
  197.                         wnode = nnode;
  198.                     }
  199.                     FreeMem(dlist, sizeof(struct List));
  200.                 } else
  201.                     EasyRequest(NULL, &failedES, NULL, "Out of memory");
  202.                 CloseLibrary(GadToolsBase);
  203.             }
  204.             CloseLibrary(GfxBase);
  205.         }
  206.         CloseLibrary(IntuitionBase);
  207.     }
  208. }
  209.  
  210. void
  211. ShowDisplayModes(struct List * dlist)
  212. {
  213.     struct Screen *screen;
  214.     struct Window *window;
  215.     struct Gadget *glist, *gadget, *hitgadget;
  216.     struct DrawInfo *drawinfo;
  217.     struct TextFont *defaultfont;
  218.     struct TextAttr *textattr;
  219.     struct IntuiMessage *imsg;
  220.     struct NewGadget *ng;
  221.     struct Menu *menu;
  222.     struct MenuItem *item;
  223.     void *vi;
  224.     ULONG iclass, icode, code;
  225.     struct DisplayNode *dnode;
  226.     struct DimensionInfo *dimensioninfo;
  227.     ULONG overscantype = OSCAN_TEXT;
  228.     ULONG curmode = 0;
  229.     BOOL ABORT = TRUE, OK;
  230.     int i;
  231.  
  232.  
  233.     if (ng = AllocMem(sizeof(struct NewGadget), MEMF_CLEAR)) {
  234.         if (textattr = AllocMem(sizeof(struct TextAttr), MEMF_CLEAR)) {
  235.             if (textattr->ta_Name = AllocMem(48, MEMF_CLEAR)) {
  236.  
  237.                 dnode = (struct DisplayNode *) dlist->lh_Head;
  238.  
  239.                 if (menu = CreateMenus(sdm_menu, TAG_DONE)) {
  240.                     do {
  241.                         dimensioninfo = &(dnode->dn_Dimensioninfo);
  242.                         OK = FALSE;
  243.                         if (screen = OpenAScreen(dimensioninfo,
  244.                          dnode->dn_Node.ln_Name,
  245.                          overscantype)) {
  246.                             drawinfo = GetScreenDrawInfo(screen);
  247.                             defaultfont = drawinfo->dri_Font;
  248.                             strcpy(textattr->ta_Name,
  249.                    defaultfont->tf_Message.mn_Node.ln_Name);
  250.  
  251.                             textattr->ta_YSize = defaultfont->tf_YSize;
  252.                             textattr->ta_Style = defaultfont->tf_Style;
  253.                             textattr->ta_Flags = defaultfont->tf_Flags;
  254.  
  255.                             if (window = OpenAWindow(screen, overscantype)) {
  256.                                 vi = GetVisualInfo(screen, TAG_END);
  257.                                 if (LayoutMenus(menu, vi, TAG_DONE)) {
  258.                                     if (gadget = CreateContext(&glist)) {
  259.                                         ng->ng_LeftEdge =
  260.                       window->BorderLeft + 10;
  261.                                         ng->ng_TopEdge =
  262.                       window->BorderTop + 10;
  263.                                         ng->ng_Width =
  264.                       window->Width -
  265.                         (window->BorderLeft + 10) -
  266.                           (window->BorderRight + 10);
  267.                                         ng->ng_Height =
  268.                       window->Height -
  269.                         (window->BorderTop + 10) -
  270.                           (window->BorderBottom + 10) -
  271.                         (4 + defaultfont->tf_YSize + 2);
  272.                                         ng->ng_TextAttr = textattr;
  273.                                         ng->ng_GadgetText = NULL;
  274.                                         ng->ng_VisualInfo = vi;
  275.                                         ng->ng_GadgetID = 1;
  276.                                         ng->ng_Flags = PLACETEXT_ABOVE;
  277.                                         gadget =
  278.                       CreateGadget(LISTVIEW_KIND, gadget,
  279.                                ng, GTLV_Labels, dlist,
  280.                                GTLV_ShowSelected, NULL,
  281.                                GTLV_Selected, curmode,
  282.                                TAG_END);
  283.  
  284.                                         ng->ng_TopEdge +=
  285.                       gadget->Height +
  286.                         defaultfont->tf_YSize + 10;
  287.                                         ng->ng_Width = 80;
  288.                                         ng->ng_LeftEdge =
  289.                       ((window->Width - window->BorderLeft
  290.                         - window->BorderRight) / 2) - 30;
  291.                                         ng->ng_Height = defaultfont->tf_YSize + 8;
  292.                                         ng->ng_GadgetID = 2;
  293.                                         ng->ng_GadgetText = "OK";
  294.                                         ng->ng_VisualInfo = vi;
  295.                                         ng->ng_Flags = PLACETEXT_IN;
  296.                                         gadget =
  297.                       CreateGadget(BUTTON_KIND, gadget,
  298.                                ng, TAG_END);
  299.  
  300.                                         AddGList(window, glist, -1, -1, NULL);
  301.                                         RefreshGList(glist, window, NULL, -1);
  302.                                         GT_RefreshWindow(window, NULL);
  303.                                         SetMenuStrip(window, menu);
  304.                                         ABORT = FALSE;
  305.                                     } else
  306.                                         EasyRequest(window, &failedES, NULL,
  307.                             "Can't create gadget context");
  308.                                 } else
  309.                                     EasyRequest(window, &failedES, NULL,
  310.                         "Can't layout menus");
  311.  
  312.                                 do {
  313.                                     WaitPort(window->UserPort);
  314.                                     while (imsg = GT_GetIMsg(window->UserPort)) {
  315.                                         iclass = imsg->Class;
  316.                                         icode = imsg->Code;
  317.                                         hitgadget =
  318.                       (struct Gadget *) imsg->IAddress;
  319.                                         GT_ReplyIMsg(imsg);
  320.  
  321.                                         switch (iclass) {
  322.                                         case GADGETUP:
  323.                                             if (hitgadget->GadgetID == 1) {
  324.                                                 dnode =
  325.                           (struct DisplayNode *)
  326.                             dlist->lh_Head;
  327.                                                 for (i = 0; i < icode; i++)
  328.                                                 dnode =
  329.                           (struct DisplayNode *)
  330.                             dnode->dn_Node.ln_Succ;
  331.                                                 curmode = i;
  332.                                             }
  333.                                             if (hitgadget->GadgetID == 2)
  334.                                                 OK = TRUE;
  335.                                             break;
  336.                                         case MENUPICK:
  337.                                             while ((icode != MENUNULL)
  338.                            && (ABORT == FALSE)) {
  339.                                                 item = ItemAddress(menu, icode);
  340.  
  341.                                                 code = (ULONG) MENU_USERDATA(item);
  342.                                                 if (code == QUIT)
  343.                                                     ABORT = TRUE;
  344.                                                 else if
  345.                                                     (code == SWITCH)
  346.                                                     OK = TRUE;
  347.                                                 else
  348.                                                     overscantype = (ULONG) code;
  349.                                                 icode = item->NextSelect;
  350.                                             }
  351.                                             break;
  352.                                         case CLOSEWINDOW:
  353.                                             ABORT = TRUE;
  354.                                             break;
  355.                                         }
  356.                                     }
  357.                                 } while (ABORT == FALSE && OK == FALSE);
  358.                                 ClearMenuStrip(window);
  359.                                 CloseWindow(window);
  360.                                 FreeVisualInfo(vi);
  361.                                 FreeGadgets(glist);
  362.                             } else
  363.                                 EasyRequest(NULL, &failedES, NULL,
  364.                         "Can't open window");
  365.                             FreeScreenDrawInfo(screen, drawinfo);
  366.                             CloseScreen(screen);
  367.                         } else
  368.                             EasyRequest(NULL, &failedES, NULL,
  369.                     "Can't open screen");
  370.                     } while (ABORT == FALSE);
  371.                     FreeMenus(menu);
  372.                 } else
  373.                     EasyRequest(NULL, &failedES, NULL, "Can't create menus");
  374.                 FreeMem(textattr->ta_Name, 48);
  375.             } else
  376.                 EasyRequest(NULL, &failedES, NULL, "Out of memory");
  377.             FreeMem(textattr, sizeof(struct TextAttr));
  378.         } else
  379.             EasyRequest(NULL, &failedES, NULL, "Out of memory");
  380.         FreeMem(ng, sizeof(struct NewGadget));
  381.     } else
  382.         EasyRequest(NULL, &failedES, NULL, "Out of memory");
  383. }
  384.  
  385.  
  386. /*
  387.  * It's advised to use one of the overscan constants and
  388.  * STDSCREENWIDTH and STDSCREENHEIGHT. For this example however, we'll
  389.  * skip all that an use QueryOverscan to get the rectangle describing the
  390.  * requested overscantype and pass that as the displayclip description.
  391.  * Actually, since we pass the standard rectangle from the display database,
  392.  * it is equivalent to the prefered:
  393.  *
  394.  * screen = OpenScreenTags(NULL,
  395.  *                         SA_DisplayID, di->Header.DisplayID,
  396.  *                         SA_Overscan, overscantype,
  397.  *                         SA_Width, STDSCREENWIDTH,
  398.  *                         SA_Height, STDSCREENHEIGHT,
  399.  *                         SA_Title, name,
  400.  *                         SA_Depth, 2,
  401.  *                         SA_SysFont, 1,
  402.  *                         SA_Pens, dri_Pens,
  403.  *                         TAG_END);
  404.  */
  405.  
  406. struct Screen *
  407. OpenAScreen(struct DimensionInfo * di, UBYTE * name, ULONG overscantype)
  408. {
  409.  
  410.     struct Rectangle rectangle;
  411.  
  412.     /* Can't fail, already made sure it's a valid displayID */
  413.     QueryOverscan(di->Header.DisplayID, &rectangle, overscantype);
  414.  
  415.  
  416.     return (OpenScreenTags(NULL,
  417.                            SA_DisplayID, di->Header.DisplayID,
  418.                            SA_DClip, &rectangle,
  419.                            SA_Title, name,
  420.                            SA_Depth, 2,
  421.                            SA_SysFont, 1,   /* Use the prefered WB screen font */
  422.                            SA_Pens, dri_Pens,
  423.                            TAG_END));
  424. }
  425.  
  426. struct Window *
  427. OpenAWindow(struct Screen * screen, ULONG overscantype)
  428. {
  429.     return (OpenWindowTags(NULL,
  430.                            WA_Top, screen->BarHeight + 1,
  431.                            WA_Height, screen->Height - (screen->BarHeight + 1),
  432.                            WA_CustomScreen, screen,
  433.                            WA_IDCMP, CLOSEWINDOW | LISTVIEWIDCMP | MENUPICK,
  434.                            WA_Flags, WINDOWCLOSE | ACTIVATE,
  435.                            WA_Title, OScanDescr[overscantype],
  436.                            TAG_END));
  437. }
  438.  
  439.  
  440.