home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1820.lha / XDME / win.c < prev    next >
C/C++ Source or Header  |  1993-03-09  |  27KB  |  1,213 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     win.c
  5.  
  6.     DESCRIPTION
  7.     Everything for windows and GUI
  8.  
  9.     NOTES
  10.  
  11.     BUGS
  12.  
  13.     TODO
  14.  
  15.     EXAMPLES
  16.  
  17.     SEE ALSO
  18.  
  19.     INDEX
  20.  
  21.     HISTORY
  22.     14. Nov 1992    ada created
  23.  
  24. ******************************************************************************/
  25.  
  26. /**************************************
  27.         Includes
  28. **************************************/
  29. #include "defs.h"
  30. #include <graphics/text.h>
  31. #include <intuition/classusr.h>
  32. #include <intuition/imageclass.h>
  33. #include <intuition/classes.h>
  34. #include <intuition/icclass.h>
  35.  
  36.  
  37. /**************************************
  38.         Globale Variable
  39. **************************************/
  40. Prototype void          activate_arrows   (Bool);
  41. Prototype void          do_iconify        (void);
  42. Prototype void          iconify        (void);
  43. Prototype void          uniconify        (void);
  44. Prototype void          do_newwindow        (void);
  45. Prototype void          do_openwindow     (void);
  46. Prototype struct Window * TOpenWindow        (struct NewWindow *);
  47. Prototype struct Window * opensharedwindow  (struct NewWindow *);
  48. Prototype void          closesharedwindow (struct Window *);
  49. Prototype int          getyn         (char *, char *, char *, ...);
  50. Prototype void          title         (char *);
  51. Prototype void          window_title        (void);
  52. Prototype void          set_window_params (void);
  53. Prototype void          do_resize        (void);
  54. Prototype char        * geoskip        (char *, int *, int *);
  55. Prototype void          prop_adj        (void);
  56. Prototype struct PropGadget * add_prop        (struct Window *);
  57. Prototype void          free_prop        (struct PropGadget *);
  58. Prototype void          rest_prop        (ED *);
  59. Prototype ULONG       new_top        (void);
  60. Prototype void          GeometryToNW        (char *, struct NewWindow *);
  61. Prototype void          do_title        (void);
  62. Prototype void          error         (char *, ...);
  63. Prototype void          warn            (char *, ...);
  64. Prototype void          do_setgeometry    (void);
  65.  
  66.  
  67. /**************************************
  68.       Interne Defines & Strukturen
  69. **************************************/
  70. #define IDCMPFLAGS   (IDCMP_CLOSEWINDOW |\
  71.               IDCMP_NEWSIZE |\
  72.               IDCMP_RAWKEY |\
  73.               IDCMP_MOUSEBUTTONS |\
  74.               IDCMP_ACTIVEWINDOW |\
  75.               IDCMP_MOUSEMOVE |\
  76.               IDCMP_MENUPICK |\
  77.               IDCMP_GADGETUP |\
  78.               IDCMP_GADGETDOWN |\
  79.               IDCMP_REFRESHWINDOW)
  80.  
  81. #define WINDOWFLAGS  (WFLG_ACTIVATE |\
  82.               WFLG_SIZEGADGET |\
  83.               WFLG_DRAGBAR |\
  84.               WFLG_DEPTHGADGET |\
  85.               WFLG_CLOSEGADGET)
  86.  
  87. #define ICONIFYFLAGS (WFLG_DRAGBAR |\
  88.               WFLG_RMBTRAP |\
  89.               WFLG_DEPTHGADGET |\
  90.               WFLG_NOCAREREFRESH)
  91.  
  92. struct NewWindow Nw =
  93. {
  94.    0, 1, 0  , 0  , 0, 0,  /*  width, height filled in by program */
  95.    IDCMPFLAGS, WINDOWFLAGS,
  96.    NULL, NULL, (UBYTE *)"",
  97.    NULL, NULL,
  98.    100, 50, (USHORT)-1, (USHORT)-1,
  99.    WBENCHSCREEN
  100. };
  101.  
  102.  
  103. struct PropGadget
  104. {
  105.     struct Gadget scroller;
  106.     struct Gadget up;
  107.     struct Gadget down;
  108. #ifdef NOTYET
  109.     struct Gadget iconify;
  110. #endif
  111.     struct PropInfo pinfo;
  112.     struct Image    simage;
  113.     struct Image  * upimage;
  114.     struct Image  * downimage;
  115. #ifdef NOTYET
  116.     struct Image  * iconifyimage;
  117. #endif
  118. };
  119.  
  120.  
  121. const struct PropGadget gadgetdefaults =
  122. {
  123.     {    /* PropGadget */
  124.     NULL,
  125.     -13,0, 10,0,
  126.     GFLG_RELRIGHT|GFLG_RELHEIGHT,
  127.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE|GACT_FOLLOWMOUSE,
  128.     GTYP_PROPGADGET,
  129.     NULL, NULL, NULL, NULL, NULL,
  130.     0, NULL
  131.     },
  132.     {    /* Up-Image */
  133.     NULL,
  134.     -17,-31, 18,11,
  135.     GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  136.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
  137.     GTYP_BOOLGADGET,
  138.     NULL, NULL, NULL, NULL, NULL,
  139.     1, NULL
  140.     },
  141.     {    /* Down-Gadget */
  142.     NULL,
  143.     -17,-20, 18,11,
  144.     GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  145.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
  146.     GTYP_BOOLGADGET,
  147.     NULL, NULL, NULL, NULL, NULL,
  148.     2, NULL
  149.     },
  150. #ifdef NOTYET
  151.     {    /* Zoom-Gadget */
  152.     NULL,
  153.     0,0, 0,0,
  154.     GFLG_RELRIGHT|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  155.     GACT_TOPBORDER|GACT_RELVERIFY,
  156.     GTYP_BOOLGADGET,
  157.     NULL, NULL, NULL, NULL, NULL,
  158.     3, NULL
  159.     },
  160. #endif
  161.     {    /* PropInfo */
  162.     AUTOKNOB|FREEVERT|PROPNEWLOOK|PROPBORDERLESS,
  163.     MAXPOT, MAXPOT,
  164.     MAXBODY, MAXBODY,
  165.     },
  166. };
  167.  
  168.  
  169. /**************************************
  170.         Interne Variable
  171. **************************************/
  172. static ushort    WIN_MINWIDTH,        /* min. sizes for a window */
  173.         WIN_MINHEIGHT;
  174.  
  175.  
  176. /**************************************
  177.        Interne Prototypes
  178. **************************************/
  179. static void StripIntuiMessages (struct MsgPort *,struct Window *);
  180.  
  181.  
  182. void do_iconify (void)
  183. {
  184.     text_sync ();
  185.  
  186.     if (!globalflags.Comlinemode)
  187.     iconify ();
  188. } /* do_iconify */
  189.  
  190.  
  191. /* New iconify() routine by fgk. */
  192.  
  193. void iconify (void)
  194. {
  195.     WIN        * newwin;
  196.     ED           * ep      = Ep;
  197.     WIN        * win     = ep->win;
  198.     struct IntuiText itxt;        /* To find width of prop fonts */
  199.  
  200.     itxt.ITextFont = Ep->win->WScreen->Font;    /* Init */
  201.     itxt.NextText  = NULL;
  202.  
  203.     if (!ep->iconmode)
  204.     {
  205.     ep->config.winx      = win->LeftEdge;
  206.     ep->config.winy      = win->TopEdge;
  207.     ep->config.winwidth  = win->Width;
  208.     ep->config.winheight = win->Height;
  209.  
  210.     if(Ep->win->WScreen->Font != NULL)
  211.         Nw.Height = Ep->win->WScreen->Font->ta_YSize + 3;    /* height */
  212.     else
  213.         Nw.Height = GfxBase->DefaultFont->tf_YSize + 3;
  214.  
  215.     itxt.IText = ep->name;
  216.  
  217.     /* pretending spaces are always 8 */
  218.     Nw.Width  = 60 + IntuiTextLength(&itxt);          /* width */
  219.  
  220.     Nw.LeftEdge = ep->config.iwinx;
  221.     Nw.TopEdge  = ep->config.iwiny;
  222.  
  223.     if (Nw.LeftEdge + Nw.Width > win->WScreen->Width)   /* keep in bounds */
  224.         Nw.LeftEdge = win->WScreen->Width - Nw.Width;
  225.  
  226.     if (Nw.TopEdge + Nw.Height > win->WScreen->Height)
  227.         Nw.TopEdge = win->WScreen->Height - Nw.Height;
  228.  
  229.     Nw.Title = ep->wtitle;
  230.     Nw.Flags = ICONIFYFLAGS;
  231.  
  232.     if (!ep->modified)
  233.     {     /* no CLOSE */
  234.         Nw.Flags |= WFLG_CLOSEGADGET;
  235.     }
  236.  
  237.     Nw.DetailPen = TEXT_BPEN;
  238.     Nw.BlockPen  = TEXT_FPEN;
  239.  
  240. #ifdef NOTDEF
  241.     if (win->Flags & WFLG_WINDOWACTIVE)      /*  KTS */
  242.         Nw.Flags |= WFLG_ACTIVATE;
  243. #endif
  244.  
  245.     sprintf (ep->wtitle, "%s", ep->name);
  246.  
  247.     if (newwin = opensharedwindow (&Nw))
  248.     {
  249.         Nw.BlockPen  = (unsigned char)-1;
  250.         ep->iconmode = 1;
  251.         ep->win     = newwin;
  252.  
  253.         if (ep->propgad)
  254.         {
  255.         struct PropGadget * pg = ep->propgad;
  256.  
  257.         RemoveGadget (win, &pg->scroller);
  258.         RemoveGadget (win, &pg->up);
  259.         RemoveGadget (win, &pg->down);
  260.         }
  261.  
  262.         /* Maybe I shouldn't close the window BEFORE I remove the
  263.            gadgets :-/ */
  264.         closesharedwindow (win);
  265.     }
  266.  
  267.     Nw.Flags = WINDOWFLAGS;
  268.     }
  269. } /* iconify */
  270.  
  271.  
  272. void uniconify (void)
  273. {
  274.     ED    * ep = Ep;
  275.     WIN * win = ep->win;
  276.     WIN * newwin;
  277.     RP    * rp;
  278.  
  279.     if (ep->iconmode)
  280.     {
  281.     ep->config.iwinx    = win->LeftEdge;
  282.     ep->config.iwiny    = win->TopEdge;
  283.     Nw.LeftEdge  = ep->config.winx;
  284.     Nw.TopEdge   = ep->config.winy;
  285.     Nw.Width     = ep->config.winwidth;
  286.     Nw.Height    = ep->config.winheight;
  287.     Nw.Title     = ep->wtitle;
  288.     Nw.DetailPen = TEXT_BPEN;
  289.     Nw.BlockPen  = TEXT_FPEN;
  290.  
  291.     if (newwin = opensharedwindow (&Nw))
  292.     {
  293.         closesharedwindow (win);
  294.  
  295.         win = ep->win = newwin;
  296.         rp    = win->RPort;
  297.  
  298.         if (ep->font)
  299.         SetFont (rp, ep->font);
  300.  
  301.         set_window_params ();
  302.         rest_prop (ep);
  303.  
  304.         MShowTitle     = 0;
  305.         ep->iconmode = FALSE;
  306.  
  307.         text_adjust (TRUE);
  308.  
  309.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  310.         window_title ();
  311.     }
  312.     }
  313. } /* uniconify */
  314.  
  315.  
  316. void do_newwindow (void)
  317. {
  318.     WIN * win;
  319.  
  320.     if (Ep)
  321.     text_sync ();
  322.  
  323.     if (text_init (Ep, NULL, &Nw))
  324.     {
  325.     Nw.Title = Ep->wtitle;
  326.  
  327.     if (win = opensharedwindow (&Nw))
  328.     {
  329.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  330.  
  331.         Ep->win = win;
  332.         set_window_params ();
  333.         Ep->propgad = add_prop (win);
  334.  
  335.         text_load ();
  336.     } else
  337.     {
  338.         text_uninit ();
  339.     } /* if opensharedwindow */
  340.     } /* if text_init */
  341. } /* do_newwindow */
  342.  
  343.  
  344. /*
  345.  *  openwindow with geometry specification.  Negative number specify
  346.  *  relative-right / relative-left (leftedge & topedge), or relative-width /
  347.  *  relative height (width & height).
  348.  *
  349.  *    <leftedge><topedge><width><height>
  350.  *
  351.  *  Example:    +10+10-20-20    Open window centered on screen 10 pixels
  352.  *                from the border on all sides.
  353.  */
  354.  
  355. void do_openwindow (void)
  356. {
  357.     WIN *win;
  358.  
  359.     if (Ep)
  360.     text_sync ();
  361.  
  362.     if (text_init (Ep, NULL, &Nw))
  363.     {
  364.     GeometryToNW (av[1], &Nw);
  365.  
  366.     Nw.Title = Ep->wtitle;
  367.  
  368.     if (win = opensharedwindow (&Nw))
  369.     {
  370.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  371.  
  372.         Ep->win = win;
  373.         set_window_params ();
  374.         Ep->propgad = add_prop (win);
  375.  
  376.         text_load ();
  377.     } else
  378.     {
  379.         text_uninit ();
  380.     } /* if opensharedwindow */
  381.     } /* if text_init */
  382. } /* do_openwindow */
  383.  
  384.  
  385. WIN * TOpenWindow (struct NewWindow * nw)
  386. {
  387.     WIN * win;
  388.     struct Screen * PubScreen = NULL;
  389.  
  390.     /* get WB or any screen */
  391.     PubScreen = LockPubScreen (XDMEArgs.publicscreenname);
  392.  
  393.     if (XDMEArgs.publicscreenname)
  394.     {
  395.     nw->Screen = PubScreen;     /* Try your luck on a pubscreen */
  396.     nw->Type   = PUBLICSCREEN;
  397.     } else
  398.     {
  399.     nw->Screen = NULL;
  400.     nw->Type   = WBENCHSCREEN;
  401.     }
  402.  
  403.     if (PubScreen)
  404.     {
  405.     nw->MinWidth = PubScreen->WBorLeft + 13 /* PubScreen->WBorRight */ +
  406.         4 * GfxBase->DefaultFont->tf_XSize;
  407.     nw->MinHeight = PubScreen->WBorTop + PubScreen->Font->ta_YSize * 5 +
  408.         1 + PubScreen->WBorBottom;
  409.     } else
  410.     {
  411.     nw->MinWidth  = 100;
  412.     nw->MinHeight = 50;
  413.     }
  414.  
  415.     while ((win = OpenWindowTags (nw, WA_RptQueue, 1, TAG_DONE)) == NULL)
  416.     {
  417.     if (nw->Width < nw->MinWidth || nw->Height < nw->MinHeight)
  418.         break;
  419.  
  420.     if (PubScreen)
  421.     {
  422.         nw->Width  -= GfxBase->DefaultFont->tf_XSize;
  423.         nw->Height -= GfxBase->DefaultFont->tf_YSize;
  424.     } else
  425.     {
  426.         nw->Width -= 10;
  427.         nw->Height-= 10;
  428.     }
  429.     } /* while OpenWindow */
  430.  
  431.     if (PubScreen)
  432.     UnlockPubScreen (XDMEArgs.publicscreenname, PubScreen);
  433.  
  434.     return (win);
  435. } /* TOpenWindow */
  436.  
  437.  
  438. WIN * opensharedwindow (struct NewWindow *nw)
  439. {
  440.     WIN * win;
  441.  
  442.     if (Sharedport)
  443.     nw->IDCMPFlags = 0L;
  444.     else
  445.     nw->IDCMPFlags = IDCMPFLAGS;
  446.  
  447.     win = TOpenWindow (nw);
  448.  
  449.     if (win)
  450.     {
  451.     long xend = win->Width - win->BorderRight - 1;
  452.     long yend = win->Height- win->BorderBottom - 1;
  453.  
  454.     if (Sharedport)
  455.     {
  456.         win->UserPort = Sharedport;
  457.         ModifyIDCMP (win, IDCMPFLAGS);
  458.     } else
  459.     {
  460.         Sharedport = win->UserPort;
  461.     }
  462.  
  463.     if (xend > win->BorderLeft && yend > win->BorderTop)
  464.     {
  465.         SetAPen (win->RPort, nw->DetailPen);
  466.         RectFill (win->RPort, win->BorderLeft, win->BorderTop, xend, yend);
  467.         SetAPen (win->RPort, nw->BlockPen);
  468.     }
  469.     }
  470.  
  471.     return (win);
  472. } /* opensharedwindow */
  473.  
  474.  
  475. /* the following function straight from RKM by TJM */
  476.  
  477. static void StripIntuiMessages (struct MsgPort *mp, struct Window *win)
  478. {
  479.     IMESS *msg, *succ;
  480.  
  481.     msg = (IMESS *)mp->mp_MsgList.lh_Head;
  482.  
  483.     while (succ = (IMESS *)msg->ExecMessage.mn_Node.ln_Succ)
  484.     {
  485.     if (msg->IDCMPWindow == win)
  486.     {
  487.         Remove ((struct Node *)msg);
  488.         ReplyMsg ((struct Message *)msg);
  489.     }
  490.  
  491.     msg = succ;
  492.     }
  493. } /* StripIntuiMessages */
  494.  
  495.  
  496. /* modifed TJM to close win's immediately using CloseWindowSafely from RKM */
  497. void closesharedwindow (WIN * win)
  498. {
  499.     if (win)
  500.     {
  501.     SetWindowTitles (win, "", (char *)-1);
  502.     ClearMenuStrip (win);
  503.  
  504.     Forbid ();
  505.  
  506.     StripIntuiMessages (win->UserPort,win);
  507.  
  508.     win->UserPort = NULL;
  509.     ModifyIDCMP (win,0);
  510.  
  511.     Permit ();
  512.  
  513.     CloseWindow (win);
  514.     }
  515. } /* closesharedwindow */
  516.  
  517.  
  518. int getyn (char * title, char * text, char * gads, ...)
  519. {
  520.     va_list va;
  521.     int     result;
  522.     static struct EasyStruct es =
  523.     {
  524.     sizeof (struct EasyStruct),
  525.     0L, 0, 0, 0
  526.     };
  527.  
  528.     va_start (va, gads);
  529.  
  530.     es.es_Title        = title;
  531.     es.es_TextFormat   = text;
  532.     es.es_GadgetFormat = gads;
  533.  
  534.     result = EasyRequestArgs (Ep->win, &es, NULL, va);
  535.  
  536.     va_end (va);
  537.  
  538.     return (result);
  539. } /* getyn */
  540.  
  541.  
  542. void title (char * buf)
  543. {
  544.     if (globalflags.Showtitle != 0 && !Ep->iconmode)
  545.     { /* PATCH_NULL */
  546.     SetWindowTitles (Ep->win, buf, (char *)-1);
  547.     MShowTitle = 3;
  548.     } /* if showtitle */
  549. } /* title */
  550.  
  551.  
  552. void window_title (void)
  553. {
  554.     if (globalflags.memoryfail)
  555.     {
  556.     title(" -- NO MEMORY -- ");
  557.     globalflags.memoryfail = 0;
  558.     text_redisplay ();
  559.     }
  560.  
  561.     if (globalflags.MForceTitle)
  562.     {
  563.     MShowTitle = 0;
  564.     globalflags.MForceTitle = 0;
  565.     }
  566.  
  567.     if (Ep->iconmode)
  568.     return;
  569.  
  570.     if (MShowTitle)
  571.     {
  572.     MShowTitle --;
  573.     } else
  574.     {
  575.     int    len;
  576.     int    maxlen;
  577.     short  width;
  578.     FONT * oldfont;
  579.     ED   * ep    = Ep;
  580.     WIN  * win   = ep->win;
  581.     RP   * rp    = win->RPort;
  582.     ubyte  c;
  583.     struct TextExtent bounds;
  584.  
  585.     len = text_colno ();
  586.     if (!(c = Current[len]) )
  587.         c = ' ';
  588.  
  589.     sprintf (ep->wtitle, "%4ld/%-4ld %3ld %02x %c %s",
  590.         text_lineno (),
  591.         text_lines (),
  592.         len+1,
  593.         c,
  594.         (ep->modified ? '*' : ' '),
  595.         text_name ()
  596.     );
  597.  
  598.     if (!text_imode ())
  599.         strcat (ep->wtitle, " Ovr");
  600.  
  601.     len = strlen (ep->wtitle);
  602.  
  603.     if (len < Columns && Columns < 128)
  604.     {
  605.         setmem (ep->wtitle+len, Columns - len + 1, ' ');
  606.         ep->wtitle[Columns + 1] = 0;
  607.     }
  608.  
  609.     /*
  610.      *  Update title
  611.      */
  612.  
  613.     oldfont = win->RPort->Font;
  614.     SetFont (rp, win->WScreen->RastPort.Font);
  615.  
  616.     win->Title = ep->wtitle;
  617.  
  618.     SetAPen (rp, TEXT_FPEN);
  619.     SetBPen (rp, TITLE_BPEN);
  620.     SetDrMd (rp, JAM2);
  621.     SetWrMsk (rp, -1);
  622.  
  623.     width = win->Width - 96;
  624.  
  625.     maxlen = TextFit (rp, ep->wtitle, len, &bounds, NULL,
  626.             1L, width, rp->Font->tf_YSize);
  627.  
  628.     if (len < maxlen)
  629.         len = maxlen;
  630.  
  631.     /* write new text */
  632.     Move (rp, 30, rp->Font->tf_Baseline+1);
  633.     Text (rp, ep->wtitle, maxlen);      /* No flash */
  634.  
  635.     /* clear to eol */
  636.     width = win->Width - 66;
  637.  
  638.     if (rp->cp_x < width)
  639.         EraseRect (rp, rp->cp_x, 1, width, rp->Font->tf_YSize);
  640.  
  641.     SetAPen (rp, TEXT_FPEN);
  642.     SetBPen (rp, TEXT_BPEN);
  643.     SetFont (rp, oldfont);
  644.     }
  645. } /* window_title */
  646.  
  647.  
  648. void set_window_params (void)
  649. {
  650.     ED    * ep = Ep;
  651.     WIN * win = ep->win;
  652.     RP    * rp = win->RPort;
  653.     short t;
  654.     short x;
  655.  
  656.     /* Set Character-Size */
  657.     Xsize = rp->Font->tf_XSize;
  658.     Ysize = rp->Font->tf_YSize + LineDistance;
  659.  
  660.     /* Set Borders */
  661.     Xbase = win->BorderLeft;
  662.     Ybase = win->BorderTop;
  663.  
  664.     /* Find Width/Height */
  665.     Xpixs   = win->Width - win->BorderRight - Xbase;
  666.     Ypixs   = win->Height- win->BorderBottom- Ybase;
  667.  
  668.     /* Find Width/Height in Characters */
  669.     Columns = Xpixs / Xsize;
  670.     Lines    = Ypixs / Ysize;
  671.  
  672.     /* Now Calculate Xpixs/Ypixs */
  673.     Xpixs = Xbase + Columns * Xsize - 1;
  674.     Ypixs = Ybase + Lines    * Ysize - 1;
  675.  
  676.     /* Set Base for Text() */
  677.     XTbase  =  Xbase;
  678.     YTbase  =  Ybase + rp->Font->tf_Baseline + (LineDistance + 1)/2;
  679.  
  680.     /* Set Pens */
  681.     SetAPen(rp, TEXT_FPEN);
  682.     SetBPen(rp, TEXT_BPEN);
  683.  
  684.     /* Initialize Arrays of X/Y-Coords for faster rendering */
  685.     for (t=0, x=0; t<MAXLINELEN; t++, x += Xsize)
  686.     ColumnPos[t] = x;
  687.  
  688.     for (t=0, x=0; t<MAXROWS; t++, x += Ysize)
  689.     RowPos[t] = x;
  690. } /* set_window_params */
  691.  
  692.  
  693. /* resize cols rows */
  694.  
  695. void do_resize (void)
  696. {
  697.     WIN * win     = Ep->win;
  698.     int   cols     = atoi (av[1]);
  699.     int   rows     = atoi (av[2]);
  700.     short width  = (cols * Xsize) + win->BorderLeft +
  701.            win->BorderRight;
  702.     short height = (rows * Ysize) + win->BorderTop +
  703.            win->BorderBottom;
  704.  
  705.     if (cols < 2 || rows < 1)
  706.     {
  707.     error ("resize:\nCannot make window this small.\n"
  708.            "Window must have at least 2 columns and 1 row !");
  709.     } else if (width > win->WScreen->Width - win->LeftEdge ||
  710.         height > win->WScreen->Height - win->TopEdge)
  711.         {
  712.     error ("resize:\nwindow too big (move it to\n"
  713.            "upper left corner and retry)");
  714.     } else
  715.     {
  716.     SizeWindow (win, width - win->Width, height - win->Height);
  717.     Delay (5);    /* wait 0.1 seconds for OS to resize */
  718.     }
  719. } /* do_resize */
  720.  
  721.  
  722. /* Convert geometry to nw params. */
  723.  
  724. char * geoskip (char * ptr, int * pval, int * psgn)
  725. {
  726.     ptr = skip_whitespace (ptr);
  727.  
  728.     if (*ptr == '-')
  729.     *psgn = -1;
  730.     else
  731.     *psgn = 1;
  732.  
  733.     if (*ptr == '-' || *ptr == '+')
  734.     ptr ++;
  735.  
  736.     *pval = strtol (ptr, &ptr, 0);
  737.  
  738.     return (ptr);
  739. } /* geoskip */
  740.  
  741.  
  742. /* Convert GEO-String to NewWindow-structure */
  743.  
  744. void GeometryToNW (char * geo, struct NewWindow *nw)
  745. {
  746.     int       n;
  747.     int       sign;
  748.     struct Screen scr;
  749.  
  750.     GetScreenData (&scr, sizeof (scr), WBENCHSCREEN, NULL);
  751.  
  752.     if (*geo)
  753.     {
  754.     geo = geoskip (geo, &n, &sign);
  755.     if (sign > 0)
  756.         nw->LeftEdge = n;
  757.     else
  758.         nw->LeftEdge = scr.Width - n;
  759.     }
  760.  
  761.     if (*geo)
  762.     {
  763.     geo = geoskip (geo, &n, &sign);
  764.     if (sign > 0)
  765.         nw->TopEdge = n;
  766.     else
  767.         nw->TopEdge = scr.Height - n;
  768.     }
  769.  
  770.     if (*geo)
  771.     {
  772.     geo = geoskip (geo, &n, &sign);
  773.     if (sign > 0)
  774.         nw->Width = n;
  775.     else
  776.         nw->Width = scr.Width - nw->LeftEdge - n;
  777.     }
  778.  
  779.     if (*geo)
  780.     {
  781.     geo = geoskip (geo, &n, &sign);
  782.     if (sign > 0)
  783.         nw->Height = n;
  784.     else
  785.         nw->Height = scr.Height - nw->TopEdge - n;
  786.     }
  787. } /* GeometryToNW */
  788.  
  789.  
  790. /* prop gadget stuff (TJM) */
  791.  
  792. void rest_prop (ED * ep)
  793. {
  794.     if (ep->propgad)
  795.     {
  796.     struct PropGadget * pg = ep->propgad;
  797.  
  798.     AddGadget (ep->win, &pg->scroller, -1);
  799.     AddGadget (ep->win, &pg->up, -1);
  800.     AddGadget (ep->win, &pg->down, -1);
  801.  
  802.     RefreshGList (&pg->scroller, ep->win, NULL, 3);
  803.     }
  804. } /* rest_prop */
  805.  
  806.  
  807. struct PropGadget * add_prop (struct Window * win)
  808. {
  809.     struct PropGadget * pg;
  810.     struct DrawInfo   * mydrawinfo;
  811.     struct Image      * dummy;
  812.     struct TagItem    taglist[4] =
  813.     {
  814.     SYSIA_Which, NULL,
  815.     SYSIA_DrawInfo, NULL,
  816.     };
  817.     USHORT width, size_height,
  818.        depth_width, depth_height,
  819.        height;
  820.  
  821.     /* Get memory */
  822.     if (!(pg = AllocMem (sizeof(struct PropGadget), 0)))
  823.     return NULL;
  824.  
  825.     /* copy default flags/modes/etc. */
  826.     movmem (&gadgetdefaults, pg, sizeof(struct PropGadget));
  827.  
  828.     /* find out sizes */
  829.     mydrawinfo = GetScreenDrawInfo (win->WScreen);
  830.  
  831.     taglist[0].ti_Data = DEPTHIMAGE;
  832.     taglist[1].ti_Data = (ULONG)mydrawinfo;
  833.     taglist[2].ti_Tag  = IA_Height;    /* the depth-gadget needs a height */
  834.     taglist[2].ti_Data = win->BorderTop;
  835.     taglist[3].ti_Tag  = TAG_END;
  836.  
  837.     /* get size of depth-gadget */
  838.     if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  839.     {
  840.     FreeMem (pg, sizeof (struct PropGadget));
  841.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  842.     return (NULL);
  843.     }
  844.  
  845.     depth_width  = dummy->Width;
  846.     depth_height = dummy->Height;
  847.  
  848.     /* we don't need the image anymore */
  849.     DisposeObject (dummy);
  850.  
  851. #ifdef NOTYET
  852.     /* Get the ZOOMIMAGE here because we need the height */
  853.     taglist[0].ti_Data = ZOOMIMAGE;
  854.  
  855.     if (!(pg->iconifyimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  856.     {
  857.     FreeMem (pg, sizeof (struct PropGadget));
  858.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  859.     DisposeObject (pg->upimage);
  860.     DisposeObject (pg->downimage);
  861.     return (NULL);
  862.     }
  863.  
  864.     pg->iconify.GadgetRender = pg->iconify.SelectRender = (APTR)pg->iconifyimage;
  865. #endif
  866.  
  867.     taglist[0].ti_Data = SIZEIMAGE;
  868.     taglist[2].ti_Tag  = TAG_END;
  869.  
  870.     /* get size of size-gadget */
  871.     if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  872.     {
  873.     FreeMem (pg, sizeof (struct PropGadget));
  874.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  875.     return (NULL);
  876.     }
  877.  
  878.     width    = dummy->Width;     /* width of up/down-gadgets */
  879.     size_height = dummy->Height;    /* bottom offset */
  880.  
  881.     /* we don't need the image anymore */
  882.     DisposeObject (dummy);
  883.  
  884.     taglist[0].ti_Data = UPIMAGE;
  885.  
  886.     if (!(pg->upimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  887.     {
  888.     FreeMem (pg, sizeof (struct PropGadget));
  889.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  890.     return (NULL);
  891.     }
  892.  
  893.     pg->up.GadgetRender = pg->up.SelectRender = (APTR)pg->upimage;
  894.  
  895.     height = pg->upimage->Height;
  896.  
  897.     taglist[0].ti_Data = DOWNIMAGE;
  898.  
  899.     if (!(pg->downimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  900.     {
  901.     FreeMem (pg, sizeof (struct PropGadget));
  902.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  903.     DisposeObject (pg->upimage);
  904.     return (NULL);
  905.     }
  906.  
  907.     pg->down.GadgetRender = pg->down.SelectRender = (APTR)pg->downimage;
  908.  
  909.     /* Release drawinfo */
  910.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  911.  
  912.     /* Now init all sizes/positions */
  913.     pg->scroller.TopEdge       = depth_height + 1;
  914.     pg->scroller.Height        = -(depth_height + size_height + 2*height + 2);
  915.     pg->up.LeftEdge  = pg->down.LeftEdge = -(width - 1);
  916.     pg->scroller.LeftEdge         = -(width - 4);
  917.     pg->down.TopEdge =               -(size_height + height - 1);
  918.     pg->up.TopEdge   =               pg->down.TopEdge - height;
  919.     pg->up.Width     = pg->down.Width     = width;
  920.     pg->scroller.Width             = width - 6;
  921.     pg->up.Height    = pg->down.Height     = height;
  922. #ifdef NOTYET
  923.     pg->iconify.Width             = pg->iconifyimage->Width;
  924.     pg->iconify.Height             = pg->iconifyimage->Height;
  925.     pg->iconify.LeftEdge         = -(depth_width + pg->iconify.Width);
  926. #endif
  927.  
  928.     /* Other fields */
  929.     pg->scroller.GadgetRender = (APTR)&pg->simage;
  930.     pg->scroller.SpecialInfo  = (APTR)&pg->pinfo;
  931.  
  932.     /* Link gadgets */
  933.     pg->scroller.NextGadget = &pg->up;
  934.     pg->up.NextGadget        = &pg->down;
  935.  
  936.     /* and add them to the window */
  937.     AddGList (win, &pg->scroller, -1, -1, NULL);
  938.     RefreshGList (&pg->scroller, win, NULL, 3);
  939.  
  940.     noadj = 0;        /* allow scroller refreshing */
  941.  
  942.     /* return field */
  943.     return (pg);
  944. } /* add_prop */
  945.  
  946.  
  947. void free_prop (struct PropGadget * pg)
  948. {
  949.     if (pg)
  950.     {
  951.     /* Free elements */
  952.     DisposeObject (pg->upimage);
  953.     DisposeObject (pg->downimage);
  954. #ifdef NOTYET
  955.     DisposeObject (pg->iconifyimage);
  956. #endif
  957.  
  958.     /* Free struct */
  959.     FreeMem (pg, sizeof (struct PropGadget));
  960.     }
  961. } /* free_prop */
  962.  
  963.  
  964. void prop_adj (void)
  965. {
  966.     ULONG VertBody, VertPot;
  967.  
  968.      /* block adjustment when already set by prop gad */
  969.     if (!Ep->propgad || noadj || Ep->iconmode)
  970.     return;
  971.  
  972.     /* If there are less lines than the window has, the scroller has
  973.        full size */
  974.     if (Ep->lines <= Lines)
  975.     {
  976.     VertPot  = 0;
  977.     VertBody = MAXBODY;
  978.     } else
  979.     {
  980.     ULONG overlap = Lines - (Lines * PageJump) / 100;
  981.     ULONG total;
  982.  
  983.     /* If we have more lines visible than the text actually has (ie.
  984.        there are empty lines visible) the total number of lines is
  985.        (topline + Lines) and the position is at its maximum. Else, the
  986.        number of lines is the length of the text and the position is
  987.        (toppos / invisible lines) */
  988.  
  989.     if (Ep->topline + Lines > Ep->lines)
  990.     {
  991.         total = Ep->topline + Lines;
  992.  
  993.         VertPot  = MAXPOT;
  994.     } else
  995.     {
  996.         total = Ep->lines;
  997.  
  998.         VertPot  = (Ep->topline * MAXPOT) / (total - Lines);
  999.     }
  1000.  
  1001.     /* The body-size is (number of lines for jump-scroll / all other
  1002.        lines */
  1003.     VertBody = ((Lines - overlap) * MAXBODY) / (total - overlap);
  1004.     }
  1005.  
  1006.     /* set it */
  1007.     NewModifyProp (Ep->propgad, Ep->win, NULL,
  1008.     ((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
  1009.     MAXPOT, VertPot,
  1010.     MAXBODY, VertBody,
  1011.     1
  1012.     );
  1013. } /* prop_adj */
  1014.  
  1015.  
  1016. ULONG new_top (void)
  1017. {
  1018.     ULONG top;
  1019.  
  1020.     if (Ep->lines <= Lines)
  1021.     {
  1022.     top = 0;
  1023.     } else
  1024.     {
  1025.     ULONG total;
  1026.  
  1027.     if (Ep->topline + Lines > Ep->lines)
  1028.         total = Ep->topline;
  1029.     else
  1030.         total = Ep->lines - Lines;
  1031.  
  1032.     top = ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot *
  1033.         total / MAXPOT;
  1034.  
  1035.     /* we may have to adjust the body-size (the user already adjust the
  1036.        position) */
  1037.     if (Ep->topline + Lines > Ep->lines)
  1038.     {
  1039.         ULONG VertBody;
  1040.         ULONG overlap = Lines - (Lines * PageJump) / 100;
  1041.  
  1042.         VertBody = ((Lines - overlap) * MAXBODY) /
  1043.                (Ep->topline + Lines - overlap);
  1044.  
  1045.         NewModifyProp (Ep->propgad, Ep->win, NULL,
  1046.         ((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
  1047.         MAXPOT, ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot,
  1048.         MAXBODY, VertBody,
  1049.         1
  1050.         );
  1051.     }
  1052.     }
  1053.  
  1054.     return (top);
  1055. } /* new_top */
  1056.  
  1057.  
  1058. void do_title (void)
  1059. {
  1060.     static char buffer[256];
  1061.  
  1062.     strncpy ((char *)buffer, (char *)av[1], 255);
  1063.     buffer[255] = 0;
  1064.  
  1065.     title ((char *)buffer);
  1066. } /* do_title */
  1067.  
  1068.  
  1069. void error (char * fmt, ...)
  1070. {
  1071.     va_list va;
  1072.     static struct EasyStruct es =
  1073.     {
  1074.     sizeof (struct EasyStruct),
  1075.     NULL,
  1076.     "XDME Error",
  1077.     NULL,
  1078.     "Ok"
  1079.     };
  1080.  
  1081.     va_start (va, fmt);
  1082.  
  1083.     globalflags.Abortcommand = 1;
  1084.  
  1085.     if (globalflags.NoRequest) {            /* PATCH_NULL [25 Jan 1993] : line added */
  1086.     char * ptr;                /* PATCH_NULL [25 Jan 1993] : line added */
  1087.  
  1088.     vsprintf (tmp_buffer, fmt, va);     /* PATCH_NULL [25 Jan 1993] : line added */
  1089.     ptr = tmp_buffer;            /* PATCH_NULL [25 Jan 1993] : line added */
  1090.  
  1091.     while (*ptr) {                      /* PATCH_NULL [25 Jan 1993] : line added */
  1092.         if (*ptr == '\n') *ptr = ' ';   /* PATCH_NULL [25 Jan 1993] : line added */
  1093.         ptr ++;                /* PATCH_NULL [25 Jan 1993] : line added */
  1094.     } /* while */                /* PATCH_NULL [25 Jan 1993] : line added */
  1095.  
  1096.     title (tmp_buffer);                 /* PATCH_NULL [25 Jan 1993] : line added */
  1097.  
  1098.     } else {                    /* PATCH_NULL [25 Jan 1993] : line added */
  1099.  
  1100.     es.es_TextFormat = fmt;
  1101.  
  1102.     EasyRequestArgs ((Ep ? Ep->win : NULL), &es, NULL, va);
  1103.  
  1104.     } /* if (not) noRequest */              /* PATCH_NULL [25 Jan 1993] : line added */
  1105.  
  1106.     va_end (va);
  1107. } /* error */
  1108.  
  1109.  
  1110. void warn (char * fmt, ...)
  1111. {
  1112.     va_list va;
  1113.  
  1114.     va_start (va, fmt);
  1115.  
  1116.     vsprintf (tmp_buffer, fmt, va);
  1117.  
  1118.     title (tmp_buffer);
  1119.  
  1120.     va_end (va);
  1121. } /* warn */
  1122.  
  1123.  
  1124. /*
  1125.     Changes the window-size and position. If the position is negative,
  1126.     it's calculated as offset from the right/bottom border. If
  1127.     width/height are negative, they are relative to the screen's
  1128.     width/height. If they are 0, they are not changed.
  1129. */
  1130.  
  1131. void do_setgeometry (void)      /* av[1..4]: X Y Width Height */
  1132. {
  1133.     static const char error_text[] =
  1134.     ":\n"
  1135.     "Cannot set window to\n"
  1136.     "(%ld/%ld), W:%ld, H:%ld\n"
  1137.     "because that's ";
  1138.     WORD top, left, width, height;
  1139.     SCREEN * screen;
  1140.     char * error_ptr;
  1141.     long   minsize = 0;
  1142.  
  1143.     left   = strtol (av[1], NULL, 0);
  1144.     top    = strtol (av[2], NULL, 0);
  1145.     width  = strtol (av[3], NULL, 0);
  1146.     height = strtol (av[4], NULL, 0);
  1147.  
  1148.     screen = Ep->win->WScreen;
  1149.  
  1150.     if (left < 0)
  1151.     left += screen->Width;
  1152.     if (top < 0)
  1153.     top += screen->Height;
  1154.     if (width < 0)
  1155.     width += screen->Width + 1;
  1156.     if (height < 0)
  1157.     height += screen->Height + 1;
  1158.  
  1159.     if (!width || Ep->iconmode)
  1160.     width = Ep->win->Width;
  1161.     if (!height || Ep->iconmode)
  1162.     height = Ep->win->Height;
  1163.  
  1164.     /* if the left/top is not ok, or we are not in iconmode AND the
  1165.        width/height is wrong ... */
  1166.     if (left < 0)
  1167.     error_ptr = "left edge negative";
  1168.     else if (top < 0)
  1169.     error_ptr = "top edge negative";
  1170.     else if (left > screen->Width)
  1171.     error_ptr = "left edge too big";
  1172.     else if (top > screen->Height)
  1173.     error_ptr = "top edge too big";
  1174.     else if (!Ep->iconmode)
  1175.     {
  1176.     if (width < Nw.MinWidth)
  1177.     {
  1178.         error_ptr = "width too narrow\n(The minimal width is ";
  1179.         minsize = Nw.MinWidth;
  1180.     } else if (height < Nw.MinHeight)
  1181.     {
  1182.         error_ptr = "height too low\n(The minimal height is ";
  1183.         minsize = Nw.MinHeight;
  1184.     } else if (left + width > screen->Width)
  1185.         error_ptr = "right edge too big";
  1186.     else if (top + height > screen->Height)
  1187.         error_ptr = "bottom edge too big";
  1188.     }
  1189.  
  1190.     if (error_ptr)
  1191.     {
  1192.     if (minsize != 0)
  1193.     {
  1194.         error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s%d).",
  1195.             error_text, av[0], left, top, width, height, error_ptr,
  1196.             minsize);
  1197.     } else
  1198.     {
  1199.         error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s.",
  1200.             error_text, av[0], left, top, width, height, error_ptr);
  1201.     }
  1202.     } else
  1203.     {
  1204.     ChangeWindowBox (Ep->win, left, top, width, height);
  1205.     Delay (5);
  1206.     }
  1207. } /* do_setgeometry */
  1208.  
  1209.  
  1210. /******************************************************************************
  1211. *****  ENDE win.c
  1212. ******************************************************************************/
  1213.