home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / disk / misc / dcmp / source / source.lha / req.c < prev    next >
C/C++ Source or Header  |  1993-02-02  |  14KB  |  435 lines

  1. /*---------------------------------------------------*
  2.   $Id: req.c,v 1.6 92/11/03 17:16:31 tf Exp $
  3.   dcmp_Request()  a quick requster hack for dcmp.c,v
  4.   This code has been created in haste. So be careful!
  5.  *---------------------------------------------------*/
  6.  
  7. #include <exec/types.h>
  8. #include <intuition/intuition.h>
  9. #include <intuition/intuitionbase.h>
  10. #include <graphics/gfx.h>
  11. #include <graphics/gfxbase.h>
  12. #include <graphics/rastport.h>
  13. #include <stdio.h>
  14.  
  15. #ifndef AUTOSCROLL
  16. #define AUTOSCROLL 0x4000  /* screen is to autoscoll (V36+) */
  17. #endif
  18.  
  19. static char rcs_id[] = "$Id: req.c,v 1.6 92/11/03 17:16:31 tf Exp $";
  20.  
  21. /*
  22.  * Compile with -D xxxx, where xxxx can be one of those: (default: all of them ;)
  23.  *
  24.  * #define INFOBOX      * an infobox has no visible window border
  25.  * #define NICEBORDER   * alternative border for the INFOBOX
  26.  * #define NICEOPEN     * open windows via NiceOpenWindow()
  27.  * #define MAGICTEXT    * Text() odd lines top-down, even lines bottom-up
  28.  */
  29.  
  30. #define DETAILPEN  (0x0000)  /* compatible Intuition rendering pens */
  31. #define BLOCKPEN   (0x0001)  /* compatible Intuition rendering pens */
  32. #define TEXTPEN    (0x0002)  /* text on background */
  33. #define SHINEPEN   (0x0002)  /* bright edge on 3D objects */
  34. #define SHADOWPEN  (0x0001)  /* dark edge on 3D objects */
  35. #define BACKFILL   (0x0003)  /* window background */
  36.  
  37. #ifdef NICEOPEN
  38. extern struct Window *NiceOpenWindow(struct NewWindow *);
  39. extern void NiceCloseWindow(struct Window *);
  40. #endif
  41.  
  42. UBYTE *ReqWindowTitle= (UBYTE *)"dcmp Request";
  43. struct Screen *ReqScreen= (struct Screen *)NULL;
  44.  
  45. struct TextAttr ReqTextAttr= {
  46.   (STRPTR) "topaz.font",  /* ta_Name  */
  47.   8,                      /* ta_YSize */
  48.   FS_NORMAL,              /* ta_Style */
  49.   FPF_ROMFONT             /* ta_Flags */
  50. };
  51.  
  52. struct IntuiText ReqGadgetText[2]= {
  53.   { TEXTPEN,BACKFILL,JAM2,4+4,2,&ReqTextAttr,NULL,NULL },
  54.   { TEXTPEN,BACKFILL,JAM2,4+4,2,&ReqTextAttr,NULL,NULL }
  55. };
  56.  
  57. SHORT ReqBorderPairs0[2][] = {
  58.  { 0,0, 0,11, 1,11, 1,0, 86,0 },
  59.  { 1,11, 86,11, 86,1, 87,0, 87,11 }
  60. };
  61.  
  62. SHORT ReqBorderPairs1[2][] = {
  63.  { 0,0, 0,11, 1,11, 1,0, 86,0 },
  64.  { 1,11, 86,11, 86,1, 87,0, 87,11 }
  65. };
  66.  
  67. struct Border ReqBorder0[] = {
  68.   { 0,0,2,0,JAM1,5,(SHORT *)ReqBorderPairs0[0],&ReqBorder0[1] },
  69.   { 0,0,1,0,JAM1,5,(SHORT *)ReqBorderPairs0[1],NULL }
  70. };
  71.  
  72. struct Border ReqBorder1[] = {
  73.   { 0,0,2,0,JAM1,5,(SHORT *)ReqBorderPairs1[0],&ReqBorder1[1] },
  74.   { 0,0,1,0,JAM1,5,(SHORT *)ReqBorderPairs1[1],NULL }
  75. };
  76.  
  77. struct Gadget ReqGadget[2]= {
  78.   { NULL,                       /* NextGadget */
  79.     0,0,0,12,                   /* LeftEdge, TopEdge, Width, Height */
  80.     GADGHCOMP,                  /* Flags */
  81.     GADGIMMEDIATE|RELVERIFY,    /* Activation */
  82.     BOOLGADGET,                 /* GadgetType */
  83.     &ReqBorder0[0],NULL,        /* GadgetRender, SelectRender */
  84.     &ReqGadgetText[0],          /* GadgetText */
  85.     NULL,NULL,                  /* MutualExclude, SpecialInfo */
  86.     1L,NULL                     /* GadgetID, UserData */
  87.   },
  88.   { NULL,                       /* NextGadget */
  89.     0,0,0,12,                   /* LeftEdge, TopEdge, Width, Height */
  90.     GADGHCOMP,                  /* Flags */
  91.     GADGIMMEDIATE|RELVERIFY,    /* Activation */
  92.     BOOLGADGET,                 /* GadgetType */
  93.     &ReqBorder1[0],NULL,        /* GadgetRender, SelectRender */
  94.     &ReqGadgetText[1],          /* GadgetText */
  95.     NULL,NULL,                  /* MutualExclude, SpecialInfo */
  96.     0L,NULL                     /* GadgetID, UserData */
  97.   }
  98. };
  99.  
  100. struct NewWindow ReqNewWindow= { 
  101.   50,50,80,40,                  /* LeftEdge, TopEdge, Width, Height */
  102.   DETAILPEN,BLOCKPEN,           /* DetailPen, BlockPen */
  103.   CLOSEWINDOW|GADGETUP|RAWKEY,  /* IDCMPFlags */
  104.   RMBTRAP|ACTIVATE,             /* Flags */
  105.   NULL,NULL,                    /* FirstGadget, CheckMark */
  106.   NULL,NULL,NULL,               /* Title, Screen, BitMap */
  107.   0,0,0,0,                      /* MinWidth, MinHeight, MaxWidth, MaxHeight */
  108.   WBENCHSCREEN                  /* Type */
  109. };
  110.  
  111. long dcmp_Request(text, pos, neg)
  112. char *text, *pos, *neg;
  113. { long whichwitch=0; /* return code */
  114.   BOOL done= FALSE;
  115.   int ReqTextLines[30];
  116.   int i, t, m, c, y;
  117.  
  118.   /*
  119.    * If you're already using some of these pointers, then don't forget to
  120.    * declare them locally (or as static), because otherwise the global ones
  121.    * will be used!  Note also that this could crash the system because
  122.    * dcmp_Request() closes it's stuff then using the global vectors !
  123.    */
  124.  
  125.   struct IntuitionBase *IntuitionBase;
  126.   struct GfxBase       *GfxBase;
  127.   struct TextFont      *TextFont;
  128.   struct Screen        *Screen;
  129.   struct Window        *ReqWindow;
  130.   struct RastPort      *RastPort;
  131.   struct IntuiMessage  *IntuiMessage;
  132.  
  133.   if(!text) return(-1L); /* just to be sure */
  134.  
  135.   IntuitionBase= (struct IntuitionBase *)OpenLibrary("intuition.library",LIBRARY_VERSION);
  136.   if(!IntuitionBase)
  137.     return(-1L);
  138.   GfxBase= (struct GfxBase *)OpenLibrary("graphics.library",LIBRARY_VERSION);
  139.   if(!GfxBase)
  140.   { CloseLibrary(IntuitionBase);
  141.     return(-1L);
  142.   }
  143.   TextFont= (struct TextFont *)OpenFont(&ReqTextAttr);
  144.   if(!TextFont)
  145.   { CloseLibrary(GfxBase);
  146.     CloseLibrary(IntuitionBase);
  147.     return(-1L);
  148.   }
  149.  
  150.   m=0; /* length (#of chars) in longest text line */
  151.  
  152.   for(i=0,t=0; i<30 && !done; i++)
  153.   { c=0; /* char counter (this line) */
  154.     while(text[t]!='\0' && text[t]!='\n') { t++; c++; }
  155.     ReqTextLines[i]= c;
  156.     if(text[t]=='\0') done= TRUE;
  157.     else t++;
  158.     if(c>m) m=c;
  159.   }
  160.   if(i<29) ReqTextLines[i]= (-1);
  161.  
  162.   ReqNewWindow.Width= 20+ m * TextFont->tf_XSize;
  163.   ReqNewWindow.Height= 30+ i * (1+ TextFont->tf_YSize);
  164.  
  165.   if(pos && *pos)
  166.   {
  167.     ReqGadget[0].LeftEdge= 10;
  168.  
  169. #ifdef NICEBORDER
  170.     ReqGadget[0].TopEdge= ReqNewWindow.Height- 17;
  171. #else
  172.     ReqGadget[0].TopEdge= ReqNewWindow.Height- 15;
  173. #endif
  174.  
  175.     ReqGadget[0].Width= 2* ReqGadgetText[0].LeftEdge
  176.                         + strlen(pos) * TextFont->tf_XSize;
  177.  
  178.     ReqGadgetText[0].IText= pos;
  179.  
  180.     ReqBorderPairs0[0][8]= ReqBorderPairs0[1][2]
  181.                          = ReqBorderPairs0[1][4] = ReqGadget[0].Width -2;
  182.     ReqBorderPairs0[1][6]= ReqBorderPairs0[1][8] = ReqGadget[0].Width -1;
  183.  
  184.     ReqNewWindow.FirstGadget= &ReqGadget[0];
  185.   }
  186.  
  187.   if(neg && *neg)
  188.   {
  189.     ReqGadget[1].Width= 2* ReqGadgetText[1].LeftEdge
  190.                         + strlen(neg) * TextFont->tf_XSize;
  191.  
  192.     ReqGadget[1].LeftEdge= ReqNewWindow.Width- ReqGadget[1].Width- 10;
  193.  
  194. #ifdef NICEBORDER
  195.     ReqGadget[1].TopEdge= ReqNewWindow.Height- 17;
  196. #else
  197.     ReqGadget[1].TopEdge= ReqNewWindow.Height- 15;
  198. #endif
  199.  
  200.     ReqGadgetText[1].IText= neg;
  201.  
  202.     ReqBorderPairs1[0][8]= ReqBorderPairs1[1][2]
  203.                          = ReqBorderPairs1[1][4] = ReqGadget[1].Width -2;
  204.     ReqBorderPairs1[1][6]= ReqBorderPairs1[1][8] = ReqGadget[1].Width -1;
  205.  
  206.     if(pos && *pos) ReqGadget[0].NextGadget= &ReqGadget[1];
  207.     else ReqNewWindow.FirstGadget= &ReqGadget[1];
  208.   }
  209.  
  210.   /* calculate window's minimum width (as if there were no text) */
  211.  
  212.   m=  20 + ReqGadget[0].Width + ReqGadget[1].Width + 8;
  213.  
  214.   if(m < 83) m= 83; /* absolute minimum width: 83 */
  215.   if(ReqNewWindow.Width < m)
  216.   { ReqNewWindow.Width= m;
  217.     if(neg && *neg)
  218.       ReqGadget[1].LeftEdge= ReqNewWindow.Width- ReqGadget[1].Width- 10;
  219.   }
  220.  
  221.   if(ReqScreen != NULL) Screen= ReqScreen;
  222.  
  223.   /* Find the Screen on which we're going to pop up. */
  224.    
  225.   else
  226.   { ULONG lock= LockIBase(NULL);
  227.     Screen= IntuitionBase->ActiveScreen;
  228.     UnlockIBase(lock);
  229.     if(!Screen || ReqNewWindow.Width  > Screen->Width
  230.                || ReqNewWindow.Height > Screen->Height )
  231.     { lock= LockIBase(NULL);
  232.       Screen= IntuitionBase->FirstScreen;
  233.       UnlockIBase(lock);
  234.       while(Screen && (Screen->Flags & WBENCHSCREEN) != WBENCHSCREEN)
  235.         Screen= Screen->NextScreen;
  236.       if(!Screen || ReqNewWindow.Width  > Screen->Width
  237.                  || ReqNewWindow.Height > Screen->Height )
  238.       { CloseFont(TextFont);
  239.         CloseLibrary(GfxBase);
  240.         CloseLibrary(IntuitionBase);
  241.         return(-1L);
  242.       }
  243.     }
  244.   }
  245.   ReqNewWindow.Screen= Screen;
  246.   ReqNewWindow.Type= Screen->Flags & SCREENTYPE;
  247.  
  248.   /*
  249.    * If we're to open up on an AUTOSCROLL screen it would be very annoying
  250.    * for the user to search for our requester... In this case we'll try to
  251.    * center our window under the mouse:
  252.    */
  253.  
  254.   if((Screen->Flags & AUTOSCROLL) == AUTOSCROLL)
  255.   { ReqNewWindow.LeftEdge= Screen->MouseX - ReqNewWindow.Width/2;
  256.     if(ReqNewWindow.LeftEdge < 0) ReqNewWindow.LeftEdge= 0;
  257.     if(ReqNewWindow.LeftEdge + ReqNewWindow.Width > Screen->Width)
  258.       ReqNewWindow.LeftEdge= Screen->Width - ReqNewWindow.Width;
  259.  
  260.     ReqNewWindow.TopEdge= Screen->MouseY - ReqNewWindow.Height/2;
  261.     if(ReqNewWindow.TopEdge < 0) ReqNewWindow.TopEdge= 0;
  262.     if(ReqNewWindow.TopEdge + ReqNewWindow.Height > Screen->Height)
  263.       ReqNewWindow.TopEdge= Screen->Height - ReqNewWindow.Height;
  264.   }
  265.   else /* center our window on this screen */
  266.   { ReqNewWindow.LeftEdge= (Screen->Width- ReqNewWindow.Width)/2;
  267.     ReqNewWindow.TopEdge= (Screen->Height- ReqNewWindow.Height)/2;
  268.   }
  269.  
  270. #ifdef INFOBOX
  271.  
  272.   ReqNewWindow.Flags |= BORDERLESS;
  273.  
  274. #else /* => we are to have a visible window border */
  275.  
  276.   ReqNewWindow.Title= ReqWindowTitle;
  277.   ReqNewWindow.Flags |= WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG;
  278.  
  279. #endif
  280.  
  281. #ifdef NICEOPEN
  282.   ReqWindow= (struct Window *)NiceOpenWindow(&ReqNewWindow);
  283. #else
  284.   ReqWindow= (struct Window *)OpenWindow(&ReqNewWindow);
  285. #endif
  286.  
  287.   if(!ReqWindow)
  288.   { CloseFont(TextFont);
  289.     CloseLibrary(GfxBase);
  290.     CloseLibrary(IntuitionBase);
  291.     return(-1L);
  292.   }
  293.   RastPort= ReqWindow->RPort;
  294.  
  295.   SetAPen(RastPort,BACKFILL);
  296.  
  297. #ifdef INFOBOX
  298.  
  299.   RectFill(RastPort, 0, 0, ReqNewWindow.Width, ReqNewWindow.Height);
  300.  
  301. #ifdef NICEBORDER
  302.  
  303.   SetAPen(RastPort,SHINEPEN);
  304.   Move(RastPort,ReqNewWindow.Width-2,0);
  305.   Draw(RastPort,0,0);
  306.   Draw(RastPort,0,ReqNewWindow.Height-1);
  307.   SetAPen(RastPort,SHADOWPEN);
  308.   Move(RastPort,1,ReqNewWindow.Height-1);
  309.   Draw(RastPort,ReqNewWindow.Width-1,ReqNewWindow.Height-1);
  310.   Draw(RastPort,ReqNewWindow.Width-1,0);
  311.  
  312.   SetAPen(RastPort,SHADOWPEN);
  313.   Move(RastPort,ReqNewWindow.Width-5,1);
  314.   Draw(RastPort,3,1);
  315.   Draw(RastPort,3,ReqNewWindow.Height-2);
  316.   SetAPen(RastPort,SHINEPEN);
  317.   Move(RastPort,4,ReqNewWindow.Height-2);
  318.   Draw(RastPort,ReqNewWindow.Width-4,ReqNewWindow.Height-2);
  319.   Draw(RastPort,ReqNewWindow.Width-4,0);
  320.   y= 5; /* y-position of the first text line */
  321.  
  322. #else
  323.  
  324.   SetAPen(RastPort,SHINEPEN);
  325.   Move(RastPort,ReqNewWindow.Width-1,0);
  326.   Draw(RastPort,0,0);
  327.   Draw(RastPort,0,ReqNewWindow.Height-1);
  328.   Move(RastPort,1,0);
  329.   Draw(RastPort,1,ReqNewWindow.Height-2);
  330.  
  331.   SetAPen(RastPort,SHADOWPEN);
  332.   Move(RastPort,1,ReqNewWindow.Height-1);
  333.   Draw(RastPort,ReqNewWindow.Width-1,ReqNewWindow.Height-1);
  334.   Draw(RastPort,ReqNewWindow.Width-1,0);
  335.   Move(RastPort,ReqNewWindow.Width-2,ReqNewWindow.Height-1);
  336.   Draw(RastPort,ReqNewWindow.Width-2,1);
  337.   y= 6; /* y-position of the first text line */
  338.  
  339. #endif
  340.  
  341. #else
  342.  
  343.   RectFill(RastPort, 4, 11, ReqNewWindow.Width-5, ReqNewWindow.Height-3);
  344.   y= 11;
  345.  
  346. #endif
  347.  
  348.   if(ReqNewWindow.FirstGadget) /* we just removed it/them from view */
  349.     RefreshGList(ReqNewWindow.FirstGadget, ReqWindow, NULL, -1L);
  350.  
  351.   SetAPen(RastPort,TEXTPEN);
  352.   SetBPen(RastPort,BACKFILL);
  353.   SetFont(RastPort,TextFont);
  354.  
  355. #ifdef MAGICTEXT
  356.  
  357.   /* Attention: hacky code! */
  358.  
  359.   for(m=0; m<30 && ReqTextLines[m]>=0; m++); --m; /* get #of lines */
  360.   t= (m>0 && m%2)?(m):(m-1); /* skip last line if #of lines even */
  361.   { int d=strlen(text)-ReqTextLines[t]; /* first character, last line */
  362.     if((m%2)==0) d-= 1+ReqTextLines[m]; /* skip last (even) line */
  363.     y+= (1+ TextFont->tf_YSize);
  364.     for(i=0, c=0; i<=m; i+=2, t-=2)
  365.     { Move(RastPort, 10, y+ i*(1+ TextFont->tf_YSize));
  366.       Text(RastPort, &text[c], ReqTextLines[i]);
  367.       c+= 1+ ReqTextLines[i];   /* skip `\n' character */
  368.       c+= 1+ ReqTextLines[i+1]; /* skip next (odd) line */
  369.       WaitTOF();
  370.       if(t>0)
  371.       { Move(RastPort, 10, y+ t*(1+ TextFont->tf_YSize));
  372.         Text(RastPort, &text[d], ReqTextLines[t]);
  373.         d-= 1+ ReqTextLines[t-1]; /* skip `\n' character */
  374.         d-= 1+ ReqTextLines[t-2]; /* skip previous (even) line */
  375.         WaitTOF();
  376.       }
  377.     }
  378.   }
  379.  
  380. #else
  381.  
  382.   for(i=0, c=0; i<30 && ReqTextLines[i]>=0; i++)
  383.   { y+= (1+ TextFont->tf_YSize);
  384.     Move(RastPort, 10,y);
  385.     Text(RastPort, &text[c], ReqTextLines[i]);
  386.     c+= 1+ ReqTextLines[i]; /* skip `\n' character */
  387.   }
  388.  
  389. #endif
  390.  
  391.   done= FALSE;
  392.   while(!done)
  393.   { ULONG class;
  394.     USHORT code; /* rawkey code */
  395.     struct Gadget *address;
  396.     Wait(1L<<ReqWindow->UserPort->mp_SigBit);
  397.     while(IntuiMessage= (struct IntuiMessage *)GetMsg(ReqWindow->UserPort))
  398.     { class   = IntuiMessage->Class;
  399.       code    = IntuiMessage->Code;
  400.       address = (struct Gadget *)IntuiMessage->IAddress;
  401.       ReplyMsg(IntuiMessage);
  402.       switch(class)
  403.       { case GADGETUP:
  404.           whichwitch= address->GadgetID;
  405.         case CLOSEWINDOW:
  406.           done= TRUE;
  407.           break;
  408.         case RAWKEY: /* evaluate rawkey code! no conversion (yet) */
  409.         { switch(code)
  410.           { case 0x43: case 0x44: case 0x15: case 0x31:
  411.               whichwitch= 1L;                    /* ENTER, RETURN, Y, Z */
  412.               done= TRUE;
  413.               break;
  414.             case 0x45: case 0x36: case 0x13:   /* ESC, N, R */
  415.               whichwitch= 0L;
  416.               done= TRUE;
  417.               break;
  418.           }
  419.         }
  420.       }
  421.     }
  422.   }
  423.  
  424. #ifdef NICEOPEN
  425.   NiceCloseWindow(ReqWindow);
  426. #else
  427.   CloseWindow(ReqWindow);
  428. #endif
  429.  
  430.   CloseFont(TextFont);
  431.   CloseLibrary(GfxBase);
  432.   CloseLibrary(IntuitionBase);
  433.   return(whichwitch);
  434. }
  435.