home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 274.lha / SimGen_Src / MESSAGE.c < prev    next >
C/C++ Source or Header  |  1989-07-26  |  12KB  |  506 lines

  1. /*
  2.  *--- Put up a requester with a message and get a reply ---*
  3.  */
  4.  
  5. #include "exec/types.h"
  6. #include "intuition/intuition.h"
  7. #include "intuition/intuitionbase.h"
  8. #include "functions.h"
  9.  
  10. extern    struct    IntuitionBase    *IntuitionBase;
  11. extern    struct    GfxBase        *GfxBase;
  12.  
  13. #ifdef TEST
  14. #define LOCAL
  15. #else
  16. #define LOCAL static
  17. #endif
  18.  
  19. LOCAL    struct    IntuitionBase    *itemp;
  20. LOCAL    struct    GfxBase        *gtemp;
  21.  
  22. #define LEFT    1
  23. #define CENTER    2
  24.  
  25. #define MESSLEFT  32
  26. #define MESSTOP   20
  27. #define MESSWIDTH 260
  28.  
  29. LOCAL struct NewWindow    NewMessWindow = {
  30.     MESSLEFT, MESSTOP,    /* Left, Top Edge        */
  31.     MESSWIDTH, 0,        /* Width, Height        */
  32.     0, 0,            /* DetailPen, BlockPen        */
  33.     GADGETUP,        /* IDCMP Flags            */
  34.     BORDERLESS | ACTIVATE,    /* WINDOWFLAGS            */
  35.     NULL,            /* User Gadgets            */
  36.     NULL,            /* Check Mark            */
  37.     NULL,            /* Title            */
  38.     NULL,            /* Screen            */
  39.     NULL,            /* SuperBitMap            */
  40.     0,0,0,0,        /* Min, Max Size        */
  41.     WBENCHSCREEN        /* Screen Type            */
  42. };
  43.  
  44. LOCAL SHORT MessLines[] = {
  45.               0,  0,
  46.     MESSWIDTH-3,  0,
  47.     MESSWIDTH-3, 11,
  48.               0, 11,
  49.           0,  0,
  50.           0,  0, /* Set to HEIGHT-2 */
  51.     MESSWIDTH-3,  0, /* Set to HEIGHT-2 */
  52.     MESSWIDTH-3,  0,
  53.     MESSWIDTH-3,  2, 
  54.     MESSWIDTH-2,  2,
  55.     MESSWIDTH-2,  0, /* Set to HEIGHT-1 */
  56.           2,  0, /* Set to HEIGHT-1 */
  57.           2,  0, /* Set to HEIGHT-1 */
  58.     MESSWIDTH-1,  0, /* Set to HEIGHT-1 */
  59.     MESSWIDTH-1,  2 };
  60.  
  61. LOCAL SHORT MessHeadingLines[] = {
  62.           1,  1,
  63.     MESSWIDTH-4,  1,
  64.     MESSWIDTH-4, 10,
  65.           1, 10 };
  66.  
  67. LOCAL SHORT MessCorner1Lines[] = {
  68.           0,  0,    /* Set to Height -1 */
  69.           1,  0 };    /* Set to Height -1 */
  70.  
  71. LOCAL SHORT MessCorner2Lines[] = {
  72.     MESSWIDTH-2,  0,
  73.     MESSWIDTH-1,  0,
  74.     MESSWIDTH-1,  1,
  75.     MESSWIDTH-2,  1 };
  76.  
  77. LOCAL struct Border MessBorder[] = {
  78.      0,  0, 0,NULL, JAM1,15,MessLines,        &MessBorder[1],
  79.      0,  0, 0,NULL, JAM1, 4,MessHeadingLines,    &MessBorder[2],
  80.      0,  0, 0,NULL, JAM1, 2,MessCorner1Lines,    &MessBorder[3],
  81.      0,  0, 0,NULL, JAM1, 4,MessCorner2Lines,    NULL };
  82.  
  83. #define GHEIGHT 13
  84.  
  85. LOCAL SHORT OrigGLines[20] = {
  86. /* Width - 3 */      -3,  0,        /*  0,  1 */
  87.            0,  0,        /*  2,  3 */
  88.            0,  GHEIGHT - 2,    /*  4,  5 */
  89. /* Width - 3 */      -3,  GHEIGHT - 2,    /*  6,  7 */
  90. /* Width - 3 */   -3,  1,        /*  8,  9 */
  91. /* Width - 1 */   -1,  1,        /* 10, 11 */
  92. /* Width - 1 */   -1,  GHEIGHT - 1,    /* 12, 13 */
  93.            2,  GHEIGHT - 1,    /* 14, 15 */
  94. /* Width - 2 */   -2,  GHEIGHT - 1,    /* 16, 17 */
  95. /* Width - 2 */      -2,  1,        /* 18, 19 */
  96. };
  97.  
  98. LOCAL struct TextAttr MessageFont = {
  99.     (UBYTE *)"topaz.font",/* Font Name    */
  100.     TOPAZ_EIGHTY,    /* Font Height        */
  101.     FS_NORMAL,    /* Style        */
  102.     FPF_ROMFONT };    /* Preferences        */
  103.  
  104. LOCAL struct IntuiText OrigGIText = {
  105.   30,31,JAM2,2,2,&MessageFont, NULL, NULL,
  106. };
  107.  
  108. LOCAL struct Border OrigGBord = {
  109.   0, 0, 30, 0, JAM1, 10, NULL, NULL,
  110. };
  111.  
  112. #define GFLAGS    GADGHCOMP
  113. #define GAFLAGS    RELVERIFY | ENDGADGET
  114. #define BGFLAGS REQGADGET | BOOLGADGET
  115.  
  116. LOCAL struct Gadget OrigMessageGadget = {
  117.  0L,0,0,0,13,GFLAGS,GAFLAGS,BGFLAGS,0L,0L,0L,0L,0L,1,0L,
  118. };
  119.  
  120. LOCAL struct IntuiText MessageText[16];
  121. LOCAL char TextLines[16][33];
  122.  
  123. LOCAL struct Requester MessageRequester = {
  124.     NULL,            /* Old Requester    */
  125.     MESSLEFT,        /* Left Edge        */
  126.     MESSTOP,        /* Top Edge        */
  127.     MESSWIDTH,        /* Width        */
  128.     0,            /* Height        */
  129.     0,0,            /* Mouse Relative POS.    */
  130.     0L,            /* First Gadget        */
  131.     &MessBorder[0],        /* First Border        */
  132.     &MessageText[0],    /* First IntuiText    */
  133.     NULL,            /* Flags        */
  134.     29,            /* Back Fill        */
  135.     NULL,            /* Layer for Requester  */
  136. };
  137.  
  138. LOCAL struct Gadget     *MGadget;
  139. LOCAL struct Gadget    *LeftGad;
  140. LOCAL struct Gadget    *RightGad;
  141. LOCAL char        *GOptions;
  142. LOCAL int         TotalLines,
  143.             TotalChoices,
  144.             HeadingColor = 31,
  145.             MessageColor = 29,
  146.             TextColor    = 30,
  147.             BorderColor =  30;
  148.  
  149. struct Gadget *
  150. FreeChoice (Gad)
  151. struct Gadget *Gad;
  152. {
  153.     struct Gadget *next;
  154.  
  155. /*** If this Gadget has a Border ***/
  156.     if (Gad->GadgetRender) {
  157.     /*** Then if this Border has some lines ***/
  158.         if (((struct Border *)Gad->GadgetRender)->XY) {
  159.         /*** Free the Lines ***/
  160.             FreeMem (((struct Border *)Gad->GadgetRender)->XY, 40);
  161.         }
  162.     /*** Free the Border ***/
  163.         FreeMem (Gad->GadgetRender, sizeof (struct Border));
  164.     }
  165. /*** If this Gadget has an IText ***/
  166.     if (Gad->GadgetText) {
  167.     /*** Free the IText ***/
  168.         FreeMem (Gad->GadgetText, sizeof (struct IntuiText));
  169.     }
  170. /*** Free this Gadget and Return the next one ***/
  171.     next = Gad->NextGadget;
  172.     FreeMem (Gad, sizeof (struct Gadget));
  173.     return (next);
  174. }
  175.  
  176. struct Gadget *
  177. AddChoice (choice)
  178. char *choice;
  179. {
  180.     int i, j, x, width;
  181.     struct IntuiText *IText;
  182.     struct Gadget     *Gad;
  183.     struct Border    *Border;
  184.     SHORT         *lines;
  185.  
  186. /*** Allocate a Gadget struct ***/
  187.     if ((Gad = AllocMem (sizeof (struct Gadget), NULL)) == NULL) {
  188.         return (NULL);
  189.     }
  190. /*** Copy an pre-initialized Gadget into this newone ***/
  191.     *Gad = OrigMessageGadget;
  192.  
  193. /*** Allocate an IntuiText struct ***/
  194.     if ((IText = AllocMem (sizeof (struct IntuiText), NULL)) == NULL) {
  195.         FreeChoice (Gad);
  196.         return (NULL);
  197.     }
  198. /*** Copy an pre-initialized IntuiText into this new one ***/
  199.     *IText = OrigGIText;
  200.  
  201. /*** Link it to this button's gadget ***/
  202.     Gad->GadgetText = IText;
  203.  
  204. /*** Allocate a Border struct ***/
  205.     if ((Border = (struct Border *)AllocMem (sizeof (struct Border), 0L))
  206.        == NULL) {
  207.         FreeChoice (Gad);
  208.         return (NULL);
  209.     }
  210. /*** Copy a pre-initialize Border into this new one ***/
  211.     *Border = OrigGBord;
  212.  
  213. /*** Link it to this Gadget ***/
  214.     Gad->GadgetRender = (APTR)Border;
  215.  
  216. /*** Allocate lines for Border ***/
  217.     if ((lines = AllocMem (40, 0L)) == NULL) {
  218.         FreeChoice (Gad);
  219.         return (NULL);
  220.     }
  221. /*** Link them into the Border ***/
  222.     Border->XY = lines;
  223.  
  224. /*** Link this button's Text in ***/
  225.     IText->IText = (UBYTE *)choice;
  226.  
  227.     width = strlen (choice) * 8 + 6;
  228.  
  229. /*** 'Create' the border lines while copying an original ***/
  230.     for (i = 0; i < 20; i+=2) {
  231.         j = i + 1;
  232.         if (OrigGLines[i] >= 0) {
  233.             lines[i] = OrigGLines[i];
  234.         } else {
  235.             lines[i] = width + OrigGLines[i];
  236.         }
  237.         lines[j] = OrigGLines[j];
  238.     }
  239.  
  240.     switch (TotalChoices % 3) {
  241.         case 0:    x = MESSWIDTH - 6 - width;
  242.             RightGad = Gad;
  243.             break;
  244.         case 1: x = 4;
  245.             LeftGad = Gad;
  246.             break;
  247.         case 2: x = ( RightGad->LeftEdge -
  248.                 ( LeftGad->LeftEdge +
  249.                 LeftGad->Width - 1 ) ) / 2 -
  250.                 width / 2 +
  251.                 LeftGad->LeftEdge +
  252.                 LeftGad->Width;
  253.             break;
  254.     }
  255.  
  256.     Gad->LeftEdge = x;
  257.     Gad->TopEdge  = TotalLines * 8 + 8 + (TotalChoices / 3) * 14;
  258.     Gad->Width    = width;
  259.     TotalChoices++;
  260.     Gad->GadgetID = TotalChoices;
  261.  
  262.     return (Gad);
  263. }
  264.  
  265. AddLine (mode, line)
  266. int mode;
  267. char *line;
  268. {
  269.  
  270.     int length;
  271.  
  272.     length = strlen (line);
  273.     switch (mode) {
  274.         case LEFT:    strcpy (TextLines[TotalLines], " ");
  275.                 strcat  (TextLines[TotalLines], line);
  276.                 strncat (TextLines[TotalLines],
  277.                     "                                ",
  278.                 (31-length));
  279.                 break;
  280.         case CENTER:    strncpy (TextLines[TotalLines],
  281.                     "                                ",
  282.                     (32-length)/2);
  283.                 TextLines[TotalLines][(32-length)/2] = '\0';
  284.                 strcat    (TextLines[TotalLines], line);
  285.                 strncat (TextLines[TotalLines],
  286.                     "                                ",
  287.                 (32-length)/2 + length % 2);
  288.                 break;
  289.     }
  290.  
  291.     MessageText[TotalLines].FrontPen = TextColor;
  292.     MessageText[TotalLines].BackPen  = (TotalLines == 0) ? HeadingColor :
  293.                                    MessageColor ;
  294.     MessageText[TotalLines].DrawMode = JAM2;
  295.     MessageText[TotalLines].LeftEdge = 1;
  296.     MessageText[TotalLines].TopEdge  = TotalLines * 8 + 2 + 
  297.                         (TotalLines > 0) * 3;
  298.     MessageText[TotalLines].ITextFont= &MessageFont;
  299.     MessageText[TotalLines].IText    = (UBYTE *)TextLines[TotalLines];
  300.     MessageText[TotalLines].NextText = NULL;
  301.     if (TotalLines > 0) {
  302.         MessageText[TotalLines-1].NextText = &MessageText[TotalLines];
  303.     }
  304.     TotalLines++;
  305. }
  306.  
  307. int GetInput (InputWindow)
  308. struct Window *InputWindow;
  309. {
  310.     struct IntuiMessage *MessMessage;
  311.     struct Screen *OldScreen;
  312.     ULONG IDCMPFlags;
  313.     int flag, i;
  314. #ifndef TEST
  315.     SetColors (InputWindow);
  316. #endif
  317.     flag = 0;
  318.     
  319.     IDCMPFlags = InputWindow->IDCMPFlags;
  320.     ModifyIDCMP (InputWindow, GADGETUP);
  321.     if (Request (&MessageRequester, InputWindow)) {
  322.         ClearPointer (InputWindow);
  323.         OldScreen = IntuitionBase->ActiveScreen;
  324.         if (InputWindow->WScreen != OldScreen) {
  325.             ScreenToFront (InputWindow->WScreen);
  326.         }        
  327.         do {
  328.             while ((MessMessage = (struct IntuiMessage *)
  329.                 GetMsg (InputWindow->UserPort)) != NULL) {
  330.                 if (MessMessage->Class == GADGETUP) {
  331.                     flag = ((struct Gadget *)MessMessage->
  332.                         IAddress)->GadgetID;
  333.                 }
  334.                 ReplyMsg (MessMessage);
  335.             }
  336.             if (flag == 0) {
  337.                 Wait (1 << InputWindow->UserPort->mp_SigBit);
  338.             }
  339.         } while (flag == 0);
  340.         if (OldScreen != IntuitionBase->ActiveScreen) {
  341.             ScreenToFront (OldScreen);
  342.         }
  343.     }
  344.     ModifyIDCMP (InputWindow, IDCMPFlags);
  345. #ifndef TEST
  346.     RestoreColors (InputWindow);
  347. #endif
  348.     return (flag);
  349. }
  350.  
  351.  
  352. int Message (MessWindow, heading, message, options)
  353. struct Window *MessWindow;
  354. char *heading;
  355. char *message;
  356. char *options;
  357. {
  358.     int i, j, length, height, space, mode;
  359.     struct Gadget *Gad = 0;
  360.     struct Gadget *LastGad;
  361.     char *owork;
  362.     char work[31];
  363.     int input = 0;
  364.     int icon = 0;
  365.  
  366.     TotalLines   = 0;
  367.     TotalChoices = 0;
  368.     MGadget      = 0L;
  369.     GOptions     = options;
  370.  
  371.     AddLine (CENTER, heading); 
  372.  
  373.     i = 0;
  374.     while (message[i] != NULL) {
  375.         length = 0;
  376.         mode = 0;
  377.         while(length < 30 && message[i] != NULL && mode == 0) {
  378.             if (message[i] == '\n') {
  379.                 mode = LEFT;
  380.             } else if (message[i] == '\t') {
  381.                 mode = CENTER;
  382.             } else {
  383.                 work[length] = message[i];
  384.                 length++;
  385.             }
  386.             i++;
  387.             if (message[i] == ' ') {
  388.                 space = length;
  389.             }
  390.         }
  391.         if (mode == 0 && message[i] != NULL) {
  392.             work[space] = NULL;
  393.             i = i - (length - space) + 1;
  394.         } else {
  395.             work[length] = NULL;
  396.         }
  397.         if (mode == 0) {
  398.             mode = LEFT;
  399.         }
  400.         AddLine (mode, work);
  401.  
  402.     }
  403.  
  404.     i=-1;
  405.     do {
  406.         i++;
  407.         owork = &options[i];
  408.         length = 0;
  409.         while (options[i] != '|' && options[i] != '\0') {
  410.             length++; i++;
  411.         }
  412.         j = owork[length];
  413.         owork[length] = '\0';
  414.         if ((Gad = AddChoice (owork)) == NULL) {
  415.             FreeAll ();
  416.             return (NULL);
  417.         }
  418.         if (!MGadget) {
  419.             MGadget = Gad;
  420.         } else {
  421.             LastGad->NextGadget = Gad;
  422.         }
  423.         LastGad = Gad;
  424.     } while (j != '\0');
  425.  
  426.     height = TotalLines * 8 + 10 + GHEIGHT + 2 + 
  427.          ((TotalChoices- 1) / 3) * 14;
  428.  
  429.     MessLines[11] = height - 2;
  430.     MessLines[13] = height - 2;
  431.     MessLines[21] = height - 1;
  432.     MessLines[23] = height - 1;
  433.     MessLines[25] = height - 1;
  434.     MessLines[27] = height - 1;
  435.     MessCorner1Lines[1] = height - 1;
  436.     MessCorner1Lines[3] = height - 1;
  437.     MessageRequester.Height    = height;
  438.     MessageRequester.ReqGadget = MGadget;
  439.     NewMessWindow.Height = height;
  440.     if (MessWindow == NULL) {
  441.         MessageRequester.TopEdge = 0;
  442.         MessageRequester.LeftEdge = 0;
  443.     } else {
  444.         MessageRequester.TopEdge = MESSTOP;
  445.         MessageRequester.LeftEdge = MESSLEFT;
  446.     }
  447.  
  448.     MessageRequester.BackFill = MessageColor;
  449.     MessBorder[0].FrontPen = BorderColor;
  450.     MessBorder[1].FrontPen = HeadingColor;
  451.     MessBorder[1].BackPen  = HeadingColor;
  452.  
  453.     itemp = IntuitionBase;
  454.     if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0L))) {
  455.         gtemp = GfxBase;
  456.         if ((GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0L))) {
  457.             if (MessWindow == NULL) {
  458.                 MessWindow = OpenWindow(&NewMessWindow);
  459.                 if (MessWindow != NULL) {
  460.                     input = GetInput (MessWindow);
  461.                     CloseWindow(MessWindow);
  462.                 }
  463.             } else {
  464.                 input = GetInput (MessWindow);
  465.             }
  466.             CloseLibrary (GfxBase);
  467.         }
  468.         GfxBase = gtemp;
  469.         CloseLibrary (IntuitionBase);
  470.     }
  471.     IntuitionBase = itemp;
  472.  
  473.     FreeAll ();
  474.     return (input);
  475. }
  476.  
  477. FreeAll ()
  478. {
  479.     int i;
  480.     struct Gadget *oldGad;
  481.  
  482.     while (MGadget) {
  483.         oldGad = MGadget->NextGadget;
  484.         FreeChoice (MGadget);
  485.         MGadget = oldGad;
  486.     }
  487.     for (i = 0; i < TotalChoices - 1; i++) {
  488.         while (*GOptions != '\0') {
  489.             GOptions++;
  490.         }
  491.         *GOptions++ = '|';
  492.     }
  493. }
  494.  
  495. #ifdef TEST
  496. struct IntuitionBase *IntuitionBase;
  497. struct GfxBase *GfxBase;
  498.  
  499. main (argc, argv)
  500. int argc;
  501. char **argv;
  502. {
  503.     exit (5 * (Message (NULL, argv[1], argv[2], argv[3]) - 1));
  504. }
  505. #endif
  506.