home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Src / win.c < prev   
Encoding:
C/C++ Source or Header  |  1994-12-06  |  35.2 KB  |  1,557 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     $Id: win.c 1.6 1994/09/14 20:43:56 digulla Exp digulla $
  5.  
  6.     DESCRIPTION
  7.     Everything for windows and GUI
  8.  
  9.     HISTORY
  10.     14. Nov 1992    ada created
  11.     $Log: win.c $
  12.  * Revision 1.6  1994/09/14  20:43:56  digulla
  13.  * added flag for insertmode to format_string()
  14.  *
  15.  * Revision 1.5  1994/09/09  12:31:30  digulla
  16.  * added new style Prototypes, DEFCMD and DEFHELP
  17.  * added function format_string()
  18.  * made window_title() and iconify() use format_string()
  19.  * added commands to set the pattern for the title and the icon
  20.  *
  21.  * Revision 1.4  1994/08/30  11:03:38  digulla
  22.  * adjusted position of Zoom gadget again (and checked it this time)
  23.  *
  24.  * Revision 1.3  1994/08/19  14:03:35  digulla
  25.  * XDME now listens to IDCMP_INACTIVEWINDOW, too
  26.  * Fixed flicker in window_title
  27.  * removed dead assignments
  28.  * adjusted position of Zoom gadget
  29.  * fixed show_log
  30.  *
  31.  * Revision 1.2  1994/08/13  16:36:50  digulla
  32.  * added lines++ to showlog
  33.  *
  34.  * Revision 1.1  1994/08/09  23:35:26  digulla
  35.  * Initial revision
  36.  *
  37.  
  38. ******************************************************************************/
  39.  
  40. /**************************************
  41.         Includes
  42. **************************************/
  43. #include "defs.h"
  44. #include <graphics/text.h>
  45. #include <intuition/classusr.h>
  46. #include <intuition/imageclass.h>
  47. #include <intuition/classes.h>
  48. #include <intuition/icclass.h>
  49. #define MYDEBUG 1
  50. #include "debug.h"
  51.  
  52.  
  53. /**************************************
  54.         Globale Variable
  55. **************************************/
  56.  
  57.  
  58. /**************************************
  59.       Interne Defines & Strukturen
  60. **************************************/
  61. #define IDCMPFLAGS   (IDCMP_CLOSEWINDOW |\
  62.               IDCMP_NEWSIZE |\
  63.               IDCMP_RAWKEY |\
  64.               IDCMP_MOUSEBUTTONS |\
  65.               IDCMP_ACTIVEWINDOW |\
  66.               IDCMP_INACTIVEWINDOW |\
  67.               IDCMP_MOUSEMOVE |\
  68.               IDCMP_MENUPICK |\
  69.               IDCMP_GADGETUP |\
  70.               IDCMP_GADGETDOWN |\
  71.               IDCMP_REFRESHWINDOW)
  72.  
  73. #define WINDOWFLAGS  (WFLG_ACTIVATE |\
  74.               WFLG_SIZEGADGET |\
  75.               WFLG_DRAGBAR |\
  76.               WFLG_DEPTHGADGET |\
  77.               WFLG_CLOSEGADGET |\
  78.               WFLG_SIMPLE_REFRESH)
  79.  
  80. #define ICONIFYFLAGS (WFLG_DRAGBAR |\
  81.               WFLG_RMBTRAP |\
  82.               WFLG_DEPTHGADGET |\
  83.               WFLG_SIMPLE_REFRESH)
  84.  
  85.  
  86.  
  87. struct NewWindow Nw =
  88. {
  89.    0, 1, 0  , 0  , 0, 0,  /*  width, height filled in by program */
  90.    IDCMPFLAGS, WINDOWFLAGS,
  91.    NULL, NULL, (UBYTE *)"",
  92.    NULL, NULL,
  93.    100, 50, (UWORD)-1, (UWORD)-1,
  94.    WBENCHSCREEN
  95. };
  96.  
  97. #define NUM_GADS    4
  98.  
  99. struct PropGadget
  100. {
  101.     struct Gadget   scroller;
  102.     struct Gadget   up;
  103.     struct Gadget   down;
  104. #ifdef NOT_DEF
  105.     struct Gadget   depth;
  106. #endif
  107.     struct Gadget   iconify;
  108.     struct PropInfo pinfo;        /* PropInfo for scroller */
  109.     struct Image    simage;        /* image for scroller */
  110.     struct Image  * upimage;
  111.     struct Image  * downimage;
  112. #ifdef NOT_DEF
  113.     struct Image  * depthimage;
  114. #endif
  115.     struct Image  * iconifyimage;
  116. };
  117.  
  118.  
  119. const struct PropGadget gadgetdefaults =
  120. {
  121.     {    /* PropGadget */
  122.     NULL,
  123.     0,0, 0,0,
  124.     GFLG_RELRIGHT|GFLG_RELHEIGHT,
  125.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE|GACT_FOLLOWMOUSE,
  126.     GTYP_PROPGADGET,
  127.     NULL, NULL, NULL, NULL, NULL,
  128.     0, NULL
  129.     },
  130.     {    /* Up-Image */
  131.     NULL,
  132.     0,0, 0,0,
  133.     GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  134.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
  135.     GTYP_BOOLGADGET,
  136.     NULL, NULL, NULL, NULL, NULL,
  137.     1, NULL
  138.     },
  139.     {    /* Down-Gadget */
  140.     NULL,
  141.     0,0, 0,0,
  142.     GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  143.     GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
  144.     GTYP_BOOLGADGET,
  145.     NULL, NULL, NULL, NULL, NULL,
  146.     2, NULL
  147.     },
  148. #ifdef NOT_DEF
  149.     {    /* Depth-Gadget */
  150.     NULL,
  151.     0,0, 0,0,
  152.     GFLG_RELRIGHT|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  153.     GACT_TOPBORDER|GACT_RELVERIFY,
  154.     GTYP_BOOLGADGET,
  155.     NULL, NULL, NULL, NULL, NULL,
  156.     3, NULL
  157.     },
  158. #endif
  159.     {    /* Zoom-Gadget */
  160.     NULL,
  161.     0,0, 0,0,
  162.     GFLG_RELRIGHT|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
  163.     GACT_TOPBORDER|GACT_RELVERIFY,
  164.     GTYP_BOOLGADGET,
  165.     NULL, NULL, NULL, NULL, NULL,
  166.     4, NULL
  167.     },
  168.     {    /* PropInfo */
  169.     AUTOKNOB|FREEVERT|PROPNEWLOOK|PROPBORDERLESS,
  170.     MAXPOT, MAXPOT,
  171.     MAXBODY, MAXBODY,
  172.     },
  173. };
  174.  
  175.  
  176. /**************************************
  177.         Interne Variable
  178. **************************************/
  179. static UWORD    WIN_MINWIDTH,        /* min. sizes for a window */
  180.         WIN_MINHEIGHT;
  181.  
  182. #define MAX_LOG     10
  183. static char * log_messages[MAX_LOG];
  184. static USHORT numlogs = 0;
  185.  
  186.  
  187. /**************************************
  188.        Interne Prototypes
  189. **************************************/
  190. static void log (char *);
  191. static void StripIntuiMessages (struct MsgPort *,struct Window *);
  192.  
  193.  
  194. /*DEFHELP #cmd win ICONIFY - iconify the window */
  195.  
  196. DEFUSERCMD("iconify", 0, CF_VWM|CF_ICO, void, do_iconify, (void),)
  197. {
  198.     text_sync ();
  199.  
  200.     if (!GETF_COMLINEMODE(Ep))
  201.     iconify ();
  202. } /* do_iconify */
  203.  
  204.  
  205. /*DEFHELP #cmd prefs,win SETDEFICONTITLE string - Sets the pattern for the window-title when iconifed */
  206.  
  207. static char * default_icontitle = "%f";
  208.  
  209. Prototype char icontitle_pattern[];
  210. char icontitle_pattern[80] = "%f";
  211.  
  212. DEFUSERCMD("setdeficontitle", 1, CF_VWM|CF_ICO|CF_COK, void, do_setdeficontitle, (void),)
  213. {
  214.     if (!*av[1])
  215.     strcpy (icontitle_pattern, default_icontitle);
  216.     else
  217.     {
  218.     strncpy (icontitle_pattern, av[1], sizeof (icontitle_pattern));
  219.     icontitle_pattern[sizeof (icontitle_pattern)-1] = 0;
  220.     }
  221. } /* do_setdeftitle */
  222.  
  223.  
  224. /* New iconify() routine by fgk. */
  225. Prototype void iconify (void);
  226.  
  227. void iconify (void)
  228. {
  229.     WIN        * newwin;
  230.     ED           * ep      = Ep;
  231.     WIN        * win     = ep->win;
  232.     struct IntuiText itxt;        /* To find width of prop fonts */
  233.  
  234.     itxt.ITextFont = Ep->win->WScreen->Font;    /* Init */
  235.     itxt.NextText  = NULL;
  236.  
  237.     if (!GETF_ICONMODE(ep))
  238.     {
  239.     ep->config.winx      = win->LeftEdge;
  240.     ep->config.winy      = win->TopEdge;
  241.     ep->config.winwidth  = win->Width;
  242.     ep->config.winheight = win->Height;
  243.  
  244.     if(Ep->win->WScreen->Font != NULL)
  245.         Nw.Height = Ep->win->WScreen->Font->ta_YSize + 3;    /* height */
  246.     else
  247.         Nw.Height = GfxBase->DefaultFont->tf_YSize + 3;
  248.  
  249.     format_string (ep->wtitle, icontitle_pattern);
  250.     itxt.IText = ep->wtitle;
  251.  
  252.     /* pretending spaces are always 8 */
  253.     Nw.Width  = 60 + IntuiTextLength(&itxt);          /* width */
  254.  
  255.     Nw.LeftEdge = ep->config.iwinx;
  256.     Nw.TopEdge  = ep->config.iwiny;
  257.  
  258.     if (Nw.LeftEdge + Nw.Width > win->WScreen->Width)   /* keep in bounds */
  259.         Nw.LeftEdge = win->WScreen->Width - Nw.Width;
  260.  
  261.     if (Nw.TopEdge + Nw.Height > win->WScreen->Height)
  262.         Nw.TopEdge = win->WScreen->Height - Nw.Height;
  263.  
  264.     Nw.Title = ep->wtitle;
  265.     Nw.Flags = ICONIFYFLAGS;
  266.  
  267.     if (!GETF_MODIFIED(ep))
  268.     {     /* no CLOSE */
  269.         Nw.Flags |= WFLG_CLOSEGADGET;
  270.     }
  271.  
  272.     Nw.DetailPen = TEXT_BPEN(ep);
  273.     Nw.BlockPen  = TEXT_FPEN(ep);
  274.  
  275.     if (GETF_ICONACTIVE(ep) && win->Flags & WFLG_WINDOWACTIVE)      /*  KTS */
  276.         Nw.Flags |= WFLG_ACTIVATE;
  277.  
  278.     if (newwin = opensharedwindow (&Nw))
  279.     {
  280.         Nw.BlockPen  = (unsigned char)-1;
  281.  
  282.         rem_prop (ep);
  283.         closesharedwindow (win);
  284.         SETF_ICONMODE(ep,1);
  285.  
  286.         ep->win     = newwin;
  287.     }
  288.     else
  289.         window_title (); /* undo effects of format_string() */
  290.     }
  291. } /* iconify */
  292.  
  293.  
  294. /*DEFHELP #cmd win UNICONIFY - uniconify the window */
  295.  
  296. DEFUSERCMD("uniconify", 0, CF_VWM|CF_ICO, void, uniconify, (void),)
  297. {
  298.     ED    * ep = Ep;
  299.     WIN * win = ep->win;
  300.     WIN * newwin;
  301.     RP    * rp;
  302.  
  303.     if (GETF_ICONMODE(ep))
  304.     {
  305.     ep->config.iwinx = win->LeftEdge;
  306.     ep->config.iwiny = win->TopEdge;
  307.     Nw.LeftEdge     = ep->config.winx;
  308.     Nw.TopEdge     = ep->config.winy;
  309.     Nw.Width     = ep->config.winwidth;
  310.     Nw.Height     = ep->config.winheight;
  311.     Nw.Title     = ep->wtitle;
  312.     Nw.Flags     = WINDOWFLAGS;
  313.     Nw.DetailPen     = TEXT_BPEN(ep);
  314.     Nw.BlockPen     = TEXT_FPEN(ep);
  315.  
  316.     if (newwin = opensharedwindow (&Nw))
  317.     {
  318.         closesharedwindow (win);
  319.  
  320.         win = ep->win = newwin;
  321.         rp    = win->RPort;
  322.  
  323.         if (ep->font)
  324.         SetFont (rp, ep->font);
  325.  
  326.         set_window_params ();
  327.         rest_prop (ep);
  328.  
  329.         MShowTitle     = 0;
  330.         SETF_ICONMODE (ep, FALSE);
  331.  
  332.         text_adjust (TRUE);
  333.  
  334.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  335.         window_title ();
  336.     }
  337.     }
  338. } /* uniconify */
  339.  
  340.  
  341. /*DEFHELP #cmd win NEWWINDOW - open new window using default window parameters */
  342.  
  343. DEFUSERCMD("newwindow", 0, CF_VWM|CF_ICO, void, do_newwindow, (void),)
  344. {
  345.     WIN * win;
  346.  
  347.     if (Ep)
  348.     text_sync ();
  349.  
  350.     if (text_init (Ep, NULL, &Nw))
  351.     {
  352.     Nw.Title = Ep->wtitle;
  353.     Nw.Flags = WINDOWFLAGS;
  354.  
  355.     if (win = opensharedwindow (&Nw))
  356.     {
  357.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  358.  
  359.         Ep->win = win;
  360.         set_window_params ();
  361.         Ep->propgad = (struct Gadget *)add_prop (win);
  362.  
  363.         text_load ();
  364.     }
  365.     else
  366.     {
  367.         text_uninit ();
  368.     } /* if opensharedwindow */
  369.     } /* if text_init */
  370. } /* do_newwindow */
  371.  
  372.  
  373. /*
  374.  *  openwindow with geometry specification.  Negative number specify
  375.  *  relative-right / relative-left (leftedge & topedge), or relative-width /
  376.  *  relative height (width & height).
  377.  *
  378.  *    <leftedge><topedge><width><height>
  379.  *
  380.  *  Example:    +10+10-20-20    Open window centered on screen 10 pixels
  381.  *                from the border on all sides.
  382.  */
  383.  
  384. /*DEFHELP #cmd win OPENWINDOW geo -open new window using specified geometry. */
  385.  
  386. DEFUSERCMD("openwindow", 1, CF_VWM|CF_ICO, void, do_openwindow, (void),)
  387. {
  388.     WIN *win;
  389.  
  390.     if (Ep)
  391.     text_sync ();
  392.  
  393.     if (text_init (Ep, NULL, &Nw))
  394.     {
  395.     GeometryToNW (av[1], &Nw);
  396.  
  397.     Nw.Title = Ep->wtitle;
  398.     Nw.Flags = WINDOWFLAGS;
  399.  
  400.     if (win = opensharedwindow (&Nw))
  401.     {
  402.         menu_strip (currentmenu(),win);   /* PATCH_NULL [13 Jan 1993] : added currentmenu(), */
  403.  
  404.         Ep->win = win;
  405.         set_window_params ();
  406.         Ep->propgad = (struct Gadget *)add_prop (win);
  407.  
  408.         text_load ();
  409.     }
  410.     else
  411.     {
  412.         text_uninit ();
  413.     } /* if opensharedwindow */
  414.     } /* if text_init */
  415. } /* do_openwindow */
  416.  
  417.  
  418. Prototype WIN * TOpenWindow (struct NewWindow * nw);
  419.  
  420. WIN * TOpenWindow (struct NewWindow * nw)
  421. {
  422.     WIN * win;
  423.     struct Screen * PubScreen;
  424.  
  425.     /* get WB or any screen */
  426.     PubScreen = LockPubScreen (XDMEArgs.publicscreenname);
  427.  
  428.     if (PubScreen)
  429.     {
  430.     nw->MinWidth = PubScreen->WBorLeft + PubScreen->WBorRight +
  431.         4 * GfxBase->DefaultFont->tf_XSize;
  432.     nw->MinHeight = PubScreen->WBorTop + PubScreen->Font->ta_YSize * 5 +
  433.         1 + PubScreen->WBorBottom;
  434.     }
  435.     else
  436.     {
  437.     nw->MinWidth  = 100;
  438.     nw->MinHeight = 50;
  439.     }
  440.  
  441.     win = OpenWindowTags (nw,
  442.         WA_RptQueue, 1,
  443.         WA_PubScreen, PubScreen,
  444.         WA_AutoAdjust, TRUE,
  445.         TAG_DONE);
  446.  
  447.     if (PubScreen)
  448.     UnlockPubScreen (XDMEArgs.publicscreenname, PubScreen);
  449.  
  450.     return (win);
  451. } /* TOpenWindow */
  452.  
  453.  
  454. Prototype WIN * opensharedwindow (struct NewWindow *nw);
  455.  
  456. WIN * opensharedwindow (struct NewWindow *nw)
  457. {
  458.     WIN * win;
  459.  
  460.     if (Sharedport)
  461.     nw->IDCMPFlags = 0L;
  462.     else
  463.     nw->IDCMPFlags = IDCMPFLAGS;
  464.  
  465.     win = TOpenWindow (nw);
  466.  
  467.     if (win)
  468.     {
  469.     long xend = win->Width - win->BorderRight - 1;
  470.     long yend = win->Height- win->BorderBottom - 1;
  471.  
  472.     if (Sharedport)
  473.     {
  474.         win->UserPort = Sharedport;
  475.         ModifyIDCMP (win, IDCMPFLAGS);
  476.     } else
  477.     {
  478.         Sharedport = win->UserPort;
  479.     }
  480.  
  481.     if (xend > win->BorderLeft && yend > win->BorderTop)
  482.     {
  483.         SetAPen (win->RPort, nw->DetailPen);
  484.         RectFill (win->RPort, win->BorderLeft, win->BorderTop, xend, yend);
  485.         SetAPen (win->RPort, nw->BlockPen);
  486.     }
  487.     }
  488.  
  489.     return (win);
  490. } /* opensharedwindow */
  491.  
  492.  
  493. /* the following function straight from RKM by TJM */
  494.  
  495. static void StripIntuiMessages (struct MsgPort *mp, struct Window *win)
  496. {
  497.     IMESS *msg, *succ;
  498.  
  499.     msg = (IMESS *)mp->mp_MsgList.lh_Head;
  500.  
  501.     while (succ = (IMESS *)msg->ExecMessage.mn_Node.ln_Succ)
  502.     {
  503.     if (msg->IDCMPWindow == win)
  504.     {
  505.         Remove ((struct Node *)msg);
  506.         ReplyMsg ((struct Message *)msg);
  507.     }
  508.  
  509.     msg = succ;
  510.     }
  511. } /* StripIntuiMessages */
  512.  
  513.  
  514. /* modifed TJM to close win's immediately using CloseWindowSafely from RKM */
  515. Prototype void closesharedwindow (WIN * win);
  516.  
  517. void closesharedwindow (WIN * win)
  518. {
  519.     if (win)
  520.     {
  521.     SetWindowTitles (win, "", (char *)-1);
  522.     ClearMenuStrip (win);
  523.  
  524.     Forbid ();
  525.  
  526.     StripIntuiMessages (win->UserPort,win);
  527.  
  528.     win->UserPort = NULL;
  529.     ModifyIDCMP (win,0);
  530.  
  531.     Permit ();
  532.  
  533.     CloseWindow (win);
  534.     }
  535. } /* closesharedwindow */
  536.  
  537.  
  538. Prototype int getyn (char * title, char * text, char * gads, ...);
  539.  
  540. int getyn (char * title, char * text, char * gads, ...)
  541. {
  542.     va_list va;
  543.     int     result;
  544.     static struct EasyStruct es =
  545.     {
  546.     sizeof (struct EasyStruct),
  547.     0L, 0, 0, 0
  548.     };
  549.  
  550.     va_start (va, gads);
  551.  
  552.     es.es_Title        = title;
  553.     es.es_TextFormat   = text;
  554.     es.es_GadgetFormat = gads;
  555.  
  556.     result = EasyRequestArgs (Ep->win, &es, NULL, va);
  557.  
  558.     va_end (va);
  559.  
  560.     return (result);
  561. } /* getyn */
  562.  
  563.  
  564. Prototype void show_title (char *);
  565.  
  566. void show_title (char * title)
  567. {
  568.     if (GETF_SHOWTITLE(Ep) && !GETF_ICONMODE(Ep))
  569.     {
  570.     SetWindowTitles (Ep->win, title, (char *)-1);
  571.     MShowTitle = 3;
  572.     } /* if showtitle */
  573. } /* show_title */
  574.  
  575.  
  576. Prototype void title (char * fmt, ...);
  577.  
  578. void title (char * fmt, ...)
  579. {
  580.     va_list va;
  581.  
  582.     va_start (va, fmt);
  583.  
  584.     vsprintf (tmp_buffer, fmt, va);
  585.     strtrans (tmp_buffer, "\n\t", "  ");
  586.  
  587.     show_title (tmp_buffer);
  588. } /* title */
  589.  
  590.  
  591. /*DEFHELP #cmd prefs,win SETDEFTITLE string - Sets the pattern for the window-title. */
  592.  
  593. #define DEFAULT_TITLE        "%l/%L %c %C %m %f %i"
  594.  
  595. static char * default_title = DEFAULT_TITLE;
  596. Prototype char title_pattern[];
  597. char title_pattern[30] = DEFAULT_TITLE;
  598.  
  599. DEFUSERCMD("setdeftitle", 1, CF_VWM|CF_ICO|CF_COK, void, do_setdeftitle, (void),)
  600. {
  601.     if (!*av[1])
  602.     strcpy (title_pattern, default_title);
  603.     else
  604.     {
  605.     strncpy (title_pattern, av[1], sizeof (title_pattern));
  606.     title_pattern[sizeof (title_pattern)-1] = 0;
  607.     }
  608.  
  609.     window_title ();
  610. } /* do_setdeftitle */
  611.  
  612.  
  613. /*DEFLONG #long SETDEFTITLE,SETDEFICONTITLE
  614.  
  615. This command allows to specify a pattern from which XDME will built a
  616. string and display it at the appropriate position. The string can contain
  617. any characters (like in @{B}printf()@{UB}). The following characters are replaced by
  618. a special string, however:
  619.  
  620.     Sequence    Replacement
  621.  
  622.        @{B}%%@{UB}         A single @{B}%@{UB} in the resulting string
  623.        @{B}%l@{UB}         the current line
  624.        @{B}%L@{UB}         the number of lines
  625.        @{B}%c@{UB}         the current column
  626.        @{B}%C@{UB}         the code of the character under the cursor in hex
  627.        @{B}%m@{UB}         modified flag (either @{B}@{UB}- or @{B}*@{UB})
  628.        @{B}%f@{UB}         the current filename
  629.        @{B}%p@{UB}         the last 20 characters of the current path
  630.        @{B}%b@{UB}         the actual blocktype (@{B}L@{UB} for line, @{B}N@{UB} for character oriented
  631.             and @{B}V@{UB} for vertical
  632.  
  633. The defaults for XDME's title are: @{B}%l/%L %C %c %m %f %i@{UB}
  634. The defaults for XDME's icon are: @{B}%f@{UB}
  635. */
  636.  
  637. Prototype void format_string (char * dest, const char * fmt);
  638.  
  639. void format_string (char * dest, const char * fmt)
  640. {
  641.     static BPTR lock;
  642.     static char path[32];
  643.  
  644.     while (*fmt)
  645.     {
  646.     if (*fmt == '%')
  647.     {
  648.         fmt ++;
  649.  
  650.         switch (*fmt)
  651.         {
  652.         case '%':
  653.         *dest ++ = '%';
  654.         break;
  655.  
  656.         case 'l': /* current line */
  657.         sprintf (dest, "%4ld", Ep->line+1);
  658.         dest += strlen (dest);
  659.         break;
  660.  
  661.         case 'L': /* number of lines */
  662.         sprintf (dest, "%4ld", Ep->lines);
  663.         dest += strlen (dest);
  664.         break;
  665.  
  666.         case 'c': /* current column */
  667.         sprintf (dest, "%3ld", Ep->column+1);
  668.         dest += strlen (dest);
  669.         break;
  670.  
  671.         case 'C': /* current character */
  672.         sprintf (dest, "%02x", Ep->column >= Clen ? ' ' : Current[Ep->column]);
  673.         dest += strlen (dest);
  674.         break;
  675.  
  676.         case 'm': /* modified ? */
  677.         *dest ++ = GETF_MODIFIED(Ep) ? '*' : '-';
  678.         break;
  679.  
  680.         case 'f': /* filename */
  681.         strcpy (dest, Ep->name);
  682.         dest += strlen (dest);
  683.         break;
  684.  
  685.         case 'b': { /* block-type */
  686.         extern UWORD block_type;
  687.         *dest ++ = *(" LNV" + block_type);
  688.         break; }
  689.  
  690.         case 'i': /* insertmode */
  691.         if (!GETF_INSERTMODE(Ep))
  692.         {
  693.             strcpy (dest, "Ovr");
  694.             dest += 3;
  695.         }
  696.  
  697.         break;
  698.  
  699.         case 'p': /* path */
  700.         /* just do this, if we don't have the path already */
  701.         if (Ep->dirlock != lock)
  702.         {
  703.             int len;
  704.             char buffer[256];
  705.  
  706.             /* put path into a separate buffer so we can cut it
  707.                later */
  708.             getpathto (Ep->dirlock, NULL, buffer);
  709.  
  710.             /* cut path to max. 24 chars */
  711.             len = strlen (buffer);
  712.             if (len > 20)
  713.             {
  714.             len -= 20;
  715.             strcpy (path, "...");
  716.             }
  717.             else
  718.             {
  719.             *path = 0;
  720.             len = 0;
  721.             }
  722.  
  723.             strcat (path, buffer+len);
  724.             lock = Ep->dirlock;
  725.         }
  726.  
  727.         strcpy (dest, path);
  728.  
  729.         dest += strlen (dest);
  730.         break;
  731.         }
  732.  
  733.         fmt ++;
  734.     }
  735.     else
  736.         *dest ++ = *fmt ++;
  737.     }
  738.  
  739.     *dest = 0;
  740. } /* format_string */
  741.  
  742.  
  743. Prototype void window_title (void);
  744.  
  745. void window_title (void)
  746. {
  747.     if (GETF_MEMORYFAIL(Ep))
  748.     {
  749.     title(" -- NO MEMORY -- ");
  750.     SETF_MEMORYFAIL(Ep,0);
  751.     text_redisplay ();
  752.     }
  753.  
  754.     if (GETF_MFORCETITLE(Ep))
  755.     {
  756.     MShowTitle = 0;
  757.     SETF_MFORCETITLE(Ep,0);
  758.     }
  759.  
  760.     if (GETF_ICONMODE(Ep))
  761.     return;
  762.  
  763.     if (MShowTitle)
  764.     {
  765.     MShowTitle --;
  766.     }
  767.     else
  768.     {
  769.     int    len;
  770.     int    maxlen;
  771.     WORD   width;
  772.     FONT * oldfont;
  773.     ED   * ep    = Ep;
  774.     WIN  * win   = ep->win;
  775.     RP   * rp    = win->RPort;
  776.     struct TextExtent bounds;
  777.  
  778.     format_string (ep->wtitle, title_pattern);
  779.  
  780.     len = strlen (ep->wtitle);
  781.  
  782.     if (len < Columns && Columns < sizeof (ep->wtitle))
  783.     {
  784.         setmem (ep->wtitle+len, Columns - len + 1, ' ');
  785.         ep->wtitle[Columns + 1] = 0;
  786.     }
  787.  
  788.     /*
  789.      *  Update title
  790.      */
  791.  
  792.     if (GETF_WINDOWTITLES(Ep))                            /* PATCH_NULL 16-08-94 */
  793.         SetWindowTitles(ep->win, ep->wtitle, (char *)-1); /* PATCH_NULL 16-08-94 */
  794.     else                              /* PATCH_NULL 16-08-94 */
  795.     {
  796.         oldfont = win->RPort->Font;
  797.         SetFont (rp, win->WScreen->RastPort.Font);
  798.  
  799.         win->Title = ep->wtitle;
  800.  
  801.         SetAPen (rp, TITLE_FPEN(ep));
  802.         SetBPen (rp, TITLE_BPEN(ep));
  803.         SetDrMd (rp, JAM2);
  804.         SetWrMsk (rp, ALL_MASK);
  805.  
  806.         width = win->Width - 96;
  807.  
  808.         maxlen = TextFit (rp, ep->wtitle, len, &bounds, NULL,
  809.             1L, width, rp->Font->tf_YSize);
  810.  
  811.         /* write new text */
  812.         /* SetWindowTitles(ep->win, ep->wtitle, (char *)-1); / * PATCH_NULL each time the window was deactivated, parts of the title went away */
  813.         Move (rp, 30, rp->Font->tf_Baseline+1);
  814.         Text (rp, ep->wtitle, maxlen);      /* No flash */
  815.  
  816.         /* clear to eol */
  817.         width = win->Width - 66;
  818.  
  819.         if (rp->cp_x < width) {
  820.  
  821.     /* >>> PATCH_NULL 28-07-94 - Patch to clear the Title in a right manner */
  822.         if (win->Flags & WFLG_WINDOWACTIVE) {
  823.             SetAPen(rp, 3);
  824.         } else {
  825.             SetAPen(rp, 0);
  826.         }
  827.         RectFill (rp, rp->cp_x, 1, width, rp->Font->tf_YSize);
  828.     /* <<< PATCH_NULL 28-07-94 - this patch works only w/ 4-color WB */
  829.         } /* if */
  830.  
  831.         SetAPen (rp, TEXT_FPEN(ep));
  832.         SetBPen (rp, TEXT_BPEN(ep));
  833.         SetFont (rp, oldfont);
  834.     } /* if */
  835.     }
  836. } /* window_title */
  837.  
  838.  
  839. Prototype void set_window_params (void);
  840.  
  841. void set_window_params (void)
  842. {
  843.     ED    * ep = Ep;
  844.     WIN * win = ep->win;
  845.     RP    * rp = win->RPort;
  846.     WORD  t;
  847.     WORD  x;
  848.  
  849.     /* Set Character-Size */
  850.     Xsize = rp->Font->tf_XSize;
  851.     Ysize = rp->Font->tf_YSize + LineDistance;
  852.  
  853.     /* Set Borders */
  854.     Xbase = win->BorderLeft;
  855.     Ybase = win->BorderTop;
  856.  
  857.     /* Find Width/Height */
  858.     Xpixs   = win->Width - win->BorderRight - Xbase;
  859.     Ypixs   = win->Height- win->BorderBottom- Ybase;
  860.  
  861.     /* Find Width/Height in Characters */
  862.     Columns = Xpixs / Xsize;
  863.     Lines    = Ypixs / Ysize;
  864.  
  865.     /* Now Calculate Xpixs/Ypixs */
  866.     Xpixs = Xbase + Columns * Xsize - 1;
  867.     Ypixs = Ybase + Lines    * Ysize - 1;
  868.  
  869.     /* Set Base for Text() */
  870.     XTbase  =  Xbase;
  871.     YTbase  =  Ybase + rp->Font->tf_Baseline + (LineDistance + 1)/2;
  872.  
  873.     /* Set Pens */
  874.     SetAPen(rp, TEXT_FPEN(Ep));
  875.     SetBPen(rp, TEXT_BPEN(Ep));
  876.  
  877.     /* Initialize Arrays of X/Y-Coords for faster rendering */
  878.     if (ColumnPos[1] != Xsize)
  879.     for (t=0, x=0; t<MAXLINELEN; t++, x += Xsize)
  880.         ColumnPos[t] = x;
  881.  
  882.     if (RowPos[1] != Ysize)
  883.     for (t=0, x=0; t<MAXROWS; t++, x += Ysize)
  884.         RowPos[t] = x;
  885. } /* set_window_params */
  886.  
  887.  
  888. /*DEFHELP #cmd prefs,win RESIZE cols rows -Resize current window. E.G: (@{B}resize 70 23@{UB}) */
  889.  
  890. DEFUSERCMD("resize", 2, CF_VWM, void, do_resize, (void),)
  891. {
  892.     WIN * win     = Ep->win;
  893.     int   cols     = atoi (av[1]);
  894.     int   rows     = atoi (av[2]);
  895.     WORD  width  = (cols * Xsize) + win->BorderLeft +
  896.            win->BorderRight;
  897.     WORD  height = (rows * Ysize) + win->BorderTop +
  898.            win->BorderBottom;
  899.  
  900.     if (cols < 2 || rows < 1)
  901.     {
  902.     error ("resize:\nCannot make window this small.\n"
  903.            "Window must have at least 2 columns and 1 row !");
  904.     } else if (width > win->WScreen->Width - win->LeftEdge ||
  905.         height > win->WScreen->Height - win->TopEdge)
  906.         {
  907.     error ("resize:\nwindow too big (move it to\n"
  908.            "upper left corner and retry)");
  909.     } else
  910.     {
  911.     SizeWindow (win, width - win->Width, height - win->Height);
  912.     Delay (5);    /* wait 0.1 seconds for OS to resize */
  913.     }
  914. } /* do_resize */
  915.  
  916.  
  917. /* Convert geometry to nw params. */
  918.  
  919. Prototype char * geoskip (char * ptr, int * pval, int * psgn);
  920.  
  921. char * geoskip (char * ptr, int * pval, int * psgn)
  922. {
  923.     ptr = skip_whitespace (ptr);
  924.  
  925.     if (*ptr == '-')
  926.     *psgn = -1;
  927.     else
  928.     *psgn = 1;
  929.  
  930.     if (*ptr == '-' || *ptr == '+')
  931.     ptr ++;
  932.  
  933.     *pval = strtol (ptr, &ptr, 0);
  934.  
  935.     return (ptr);
  936. } /* geoskip */
  937.  
  938.  
  939. /* Convert GEO-String to NewWindow-structure */
  940.  
  941. Prototype void GeometryToNW (char * geo, struct NewWindow *nw);
  942.  
  943. void GeometryToNW (char * geo, struct NewWindow *nw)
  944. {
  945.     int       n;
  946.     int       sign;
  947.     struct Screen scr;
  948.  
  949.     GetScreenData (&scr, sizeof (scr), WBENCHSCREEN, NULL);
  950.  
  951.     if (*geo)
  952.     {
  953.     geo = geoskip (geo, &n, &sign);
  954.     if (sign > 0)
  955.         nw->LeftEdge = n;
  956.     else
  957.         nw->LeftEdge = scr.Width - n;
  958.     }
  959.  
  960.     if (*geo)
  961.     {
  962.     geo = geoskip (geo, &n, &sign);
  963.     if (sign > 0)
  964.         nw->TopEdge = n;
  965.     else
  966.         nw->TopEdge = scr.Height - n;
  967.     }
  968.  
  969.     if (*geo)
  970.     {
  971.     geo = geoskip (geo, &n, &sign);
  972.     if (sign > 0)
  973.         nw->Width = n;
  974.     else
  975.         nw->Width = scr.Width - nw->LeftEdge - n;
  976.     }
  977.  
  978.     if (*geo)
  979.     {
  980.     geoskip (geo, &n, &sign);
  981.  
  982.     if (sign > 0)
  983.         nw->Height = n;
  984.     else
  985.         nw->Height = scr.Height - nw->TopEdge - n;
  986.     }
  987. } /* GeometryToNW */
  988.  
  989.  
  990. /* prop gadget stuff (TJM) */
  991.  
  992. Prototype void rest_prop (ED * ep);
  993.  
  994. void rest_prop (ED * ep)
  995. {
  996.     if (ep->propgad)
  997.     {
  998.     struct PropGadget * pg = (struct PropGadget *)ep->propgad;
  999.  
  1000.     AddGList (ep->win, &pg->scroller, 0, NUM_GADS, NULL);
  1001.     RefreshGList (&pg->scroller, ep->win, NULL, NUM_GADS);
  1002.     }
  1003. } /* rest_prop */
  1004.  
  1005.  
  1006. Prototype void rem_prop (ED * ep);
  1007.  
  1008. void rem_prop (ED * ep)
  1009. {
  1010.     if (ep->propgad)
  1011.     {
  1012.     struct PropGadget * pg = (struct PropGadget *)ep->propgad;
  1013.  
  1014.     RemoveGList (ep->win, &pg->scroller, NUM_GADS);
  1015.     }
  1016. } /* rest_prop */
  1017.  
  1018.  
  1019. Prototype struct PropGadget * add_prop (struct Window * win);
  1020.  
  1021. struct PropGadget * add_prop (struct Window * win)
  1022. {
  1023.     struct PropGadget * pg;
  1024.     struct DrawInfo   * mydrawinfo;
  1025.     struct Image      * dummy;
  1026.     struct TagItem    taglist[5] =
  1027.     {
  1028.     SYSIA_Which, NULL,
  1029.     SYSIA_DrawInfo, NULL,
  1030.     SYSIA_Size, 0,
  1031.     };
  1032.     UWORD  height, size,
  1033.        size_width, size_height,
  1034.        depth_width, depth_height;
  1035.  
  1036.     /* Get memory */
  1037.     if (!(pg = AllocMem (sizeof(struct PropGadget), 0)))
  1038.     return NULL;
  1039.  
  1040.     /* copy default flags/modes/etc. */
  1041.     movmem (&gadgetdefaults, pg, sizeof(struct PropGadget));
  1042.  
  1043.     /* find out sizes */
  1044.     mydrawinfo = GetScreenDrawInfo (win->WScreen);
  1045.  
  1046.     if (win->WScreen->ViewPort.Modes & HIRES)
  1047.     {
  1048.     size = SYSISIZE_MEDRES;
  1049.  
  1050.     /* Don't use HIRES, since that will produce too large images */
  1051.     /* if (win->WScreen->ViewPort.Modes & LACE)
  1052.         size = SYSISIZE_HIRES;
  1053.     else */
  1054.     }
  1055.     else
  1056.     size = SYSISIZE_LOWRES;
  1057.  
  1058.     taglist[0].ti_Data = DEPTHIMAGE;
  1059.     taglist[1].ti_Data = (ULONG)mydrawinfo;
  1060.     taglist[2].ti_Data = size;
  1061.     taglist[3].ti_Tag  = IA_Height;    /* the depth-gadget needs a height */
  1062.     taglist[3].ti_Data = win->BorderTop;
  1063.     taglist[4].ti_Tag  = TAG_END;
  1064.  
  1065.     /* get size of depth-gadget */
  1066.     if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  1067.     {
  1068. oom:
  1069.     FreeMem (pg, sizeof (struct PropGadget));
  1070.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  1071.     return (NULL);
  1072.     }
  1073.  
  1074.     depth_width  = dummy->Width;
  1075.     depth_height = dummy->Height;
  1076.  
  1077. #ifdef NOT_DEF
  1078.     pg->depth.GadgetRender = pg->depth.SelectRender = (APTR)pg->depthimage;
  1079. #else
  1080.     DisposeObject (dummy);
  1081. #endif
  1082.  
  1083.     /* Get the ZOOMIMAGE here because we need the height */
  1084.     taglist[0].ti_Data = ZOOMIMAGE;
  1085.  
  1086.     if (!(pg->iconifyimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  1087.     goto oom;
  1088.  
  1089.     pg->iconify.GadgetRender = pg->iconify.SelectRender = (APTR)pg->iconifyimage;
  1090.  
  1091.     taglist[0].ti_Data = SIZEIMAGE;
  1092.     taglist[3].ti_Tag  = TAG_END;
  1093.  
  1094.     /* get size of size-gadget */
  1095.     if (!(dummy = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  1096.     {
  1097.     DisposeObject (pg->iconifyimage);
  1098.     goto oom;
  1099.     }
  1100.  
  1101.     size_width    = dummy->Width;     /* width of up/down-gadgets */
  1102.     size_height = dummy->Height;    /* bottom offset */
  1103.  
  1104.     /* we don't need the image anymore */
  1105.     DisposeObject (dummy);
  1106.  
  1107.     taglist[0].ti_Data = UPIMAGE;
  1108.  
  1109.     if (!(pg->upimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  1110.     {
  1111.     DisposeObject (pg->iconifyimage);
  1112.     goto oom;
  1113.     }
  1114.  
  1115.     pg->up.GadgetRender = pg->up.SelectRender = (APTR)pg->upimage;
  1116.  
  1117.     height = pg->upimage->Height;
  1118.  
  1119.     taglist[0].ti_Data = DOWNIMAGE;
  1120.  
  1121.     if (!(pg->downimage = (struct Image *)NewObjectA (NULL, "sysiclass", taglist)) )
  1122.     {
  1123.     DisposeObject (pg->iconifyimage);
  1124.     DisposeObject (pg->upimage);
  1125.     goto oom;
  1126.     }
  1127.  
  1128.     pg->down.GadgetRender = pg->down.SelectRender = (APTR)pg->downimage;
  1129.  
  1130.     /* Release drawinfo */
  1131.     FreeScreenDrawInfo (win->WScreen, mydrawinfo);
  1132.  
  1133.     /* Now init all sizes/positions */
  1134.     pg->scroller.TopEdge    = depth_height + 1;
  1135.     pg->scroller.Height     = -(depth_height + size_height + 2*height + 2);
  1136.     pg->up.LeftEdge =
  1137.     pg->down.LeftEdge   = -(size_width - 1);
  1138.     pg->scroller.LeftEdge   = -(size_width - 4);
  1139.     pg->down.TopEdge        = -(size_height + height - 1);
  1140.     pg->up.TopEdge        = pg->down.TopEdge - height;
  1141.     pg->up.Width =
  1142.     pg->down.Width        = size_width;
  1143.     pg->scroller.Width        = size_width - 6;
  1144.     pg->up.Height =
  1145.     pg->down.Height     = height;
  1146. #ifdef NOT_DEF
  1147.     pg->depth.Width        = pg->depthimage->Width;
  1148.     pg->depth.Height        = pg->depthimage->Height;
  1149.     pg->depth.LeftEdge        = -(pg->depth.Width - 1);
  1150. #endif
  1151.     pg->iconify.Width        = pg->iconifyimage->Width;
  1152.     pg->iconify.Height        = pg->iconifyimage->Height;
  1153.     pg->iconify.LeftEdge    = -(depth_width + pg->iconify.Width - 3);
  1154.  
  1155.     /* Other fields */
  1156.     pg->scroller.GadgetRender = (APTR)&pg->simage;
  1157.     pg->scroller.SpecialInfo  = (APTR)&pg->pinfo;
  1158.  
  1159.     /* Link gadgets */
  1160.     pg->scroller.NextGadget = &pg->up;
  1161.     pg->up.NextGadget        = &pg->down;
  1162.     pg->down.NextGadget     = &pg->iconify;
  1163.     /* pg->depth.NextGadget    = &pg->iconify; */
  1164.  
  1165.     /* and add them to the window */
  1166.     AddGList (win, &pg->scroller, 0, NUM_GADS, NULL);
  1167.     RefreshGList (&pg->scroller, win, NULL, NUM_GADS);
  1168.  
  1169.     noadj = 0;        /* allow scroller refreshing */
  1170.  
  1171.     /* return field */
  1172.     return (pg);
  1173. } /* add_prop */
  1174.  
  1175.  
  1176. Prototype void free_prop (struct PropGadget * pg);
  1177.  
  1178. void free_prop (struct PropGadget * pg)
  1179. {
  1180.     if (pg)
  1181.     {
  1182.     /* Free elements */
  1183.     DisposeObject (pg->upimage);
  1184.     DisposeObject (pg->downimage);
  1185.     /* DisposeObject (pg->depthimage); */
  1186.     DisposeObject (pg->iconifyimage);
  1187.  
  1188.     /* Free struct */
  1189.     FreeMem (pg, sizeof (struct PropGadget));
  1190.     }
  1191. } /* free_prop */
  1192.  
  1193.  
  1194. Prototype void prop_adj (void);
  1195.  
  1196. void prop_adj (void)
  1197. {
  1198.     ULONG VertBody, VertPot;
  1199.  
  1200.      /* block adjustment when already set by prop gad */
  1201.     if (!Ep->propgad || noadj || GETF_ICONMODE(Ep))
  1202.     return;
  1203.  
  1204.     /* If there are less lines than the window has, the scroller has
  1205.        full size */
  1206.     if (Ep->lines <= Lines)
  1207.     {
  1208.     VertPot  = 0;
  1209.     VertBody = MAXBODY;
  1210.     } else
  1211.     {
  1212.     ULONG overlap = Lines - (Lines * PageJump) / 100;
  1213.     ULONG total;
  1214.  
  1215.     /* If we have more lines visible than the text actually has (ie.
  1216.        there are empty lines visible) the total number of lines is
  1217.        (topline + Lines) and the position is at its maximum. Else, the
  1218.        number of lines is the length of the text and the position is
  1219.        (toppos / invisible lines) */
  1220.  
  1221.     if (Ep->topline + Lines > Ep->lines)
  1222.     {
  1223.         total = Ep->topline + Lines;
  1224.  
  1225.         VertPot  = MAXPOT;
  1226.     } else
  1227.     {
  1228.         total = Ep->lines;
  1229.  
  1230.         VertPot  = (Ep->topline * MAXPOT) / (total - Lines);
  1231.     }
  1232.  
  1233.     /* The body-size is (number of lines for jump-scroll / all other
  1234.        lines */
  1235.     VertBody = ((Lines - overlap) * MAXBODY) / (total - overlap);
  1236.     }
  1237.  
  1238.     /* set it */
  1239.     NewModifyProp (Ep->propgad, Ep->win, NULL,
  1240.     ((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
  1241.     MAXPOT, VertPot,
  1242.     MAXBODY, VertBody,
  1243.     1
  1244.     );
  1245. } /* prop_adj */
  1246.  
  1247.  
  1248. Prototype ULONG new_top (void);
  1249.  
  1250. ULONG new_top (void)
  1251. {
  1252.     ULONG top;
  1253.  
  1254.     if (Ep->lines <= Lines)
  1255.     {
  1256.     top = 0;
  1257.     } else
  1258.     {
  1259.     ULONG total;
  1260.  
  1261.     if (Ep->topline + Lines > Ep->lines)
  1262.         total = Ep->topline;
  1263.     else
  1264.         total = Ep->lines - Lines;
  1265.  
  1266.     top = ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot *
  1267.         total / MAXPOT;
  1268.  
  1269.     /* we may have to adjust the body-size (the user already adjust the
  1270.        position) */
  1271.     if (Ep->topline + Lines > Ep->lines)
  1272.     {
  1273.         ULONG VertBody;
  1274.         ULONG overlap = Lines - (Lines * PageJump) / 100;
  1275.  
  1276.         VertBody = ((Lines - overlap) * MAXBODY) /
  1277.                (Ep->topline + Lines - overlap);
  1278.  
  1279.         NewModifyProp (Ep->propgad, Ep->win, NULL,
  1280.         ((struct PropInfo *)Ep->propgad->SpecialInfo)->Flags,
  1281.         MAXPOT, ((struct PropInfo *)Ep->propgad->SpecialInfo)->VertPot,
  1282.         MAXBODY, VertBody,
  1283.         1
  1284.         );
  1285.     }
  1286.     }
  1287.  
  1288.     return (top);
  1289. } /* new_top */
  1290.  
  1291.  
  1292. /*DEFHELP #cmd prefs,win TITLE title - set window title manually */
  1293.  
  1294. DEFUSERCMD("title", 1, CF_VWM|CF_ICO, void, do_title, (void),)
  1295. {
  1296.     static char buffer[256];
  1297.  
  1298.     strncpy ((char *)buffer, (char *)av[1], sizeof (buffer)-1);
  1299.     buffer[sizeof (buffer)-1] = 0;
  1300.  
  1301.     show_title ((char *)buffer);
  1302. } /* do_title */
  1303.  
  1304.  
  1305. /*DEFHELP #cmd win SHOWLOG - XDME collects all warnings internally. These can now be showed again with this command. */
  1306.  
  1307. DEFUSERCMD("showlog", 0, CF_VWM|CF_ICO|CF_COK, void, do_showlog, (void),)
  1308. {
  1309.     ED * ep = Ep;
  1310.     int t;
  1311.     UBYTE * ptr;
  1312.  
  1313.     /* Neues Fenster auf */
  1314.     do_newwindow ();
  1315.  
  1316.     /* Nur wenn das ging ... */
  1317.     if (ep != Ep)
  1318.     {
  1319.     for (t=0; t<numlogs; Ep->lines = ++t)
  1320.     {
  1321.         if ( !makeroom(8) || !(ptr = allocline (strlen (log_messages[t]) + 1)) )
  1322.         break;
  1323.  
  1324.         strcpy (ptr, log_messages[t]);
  1325.  
  1326.         SETLINE(Ep,t,ptr);
  1327.     }
  1328.  
  1329.     if (numlogs)
  1330.         strcpy (Current, log_messages[0]);
  1331.  
  1332.     Clen = strlen (Current);
  1333.  
  1334.     text_redisplay ();
  1335.     SETF_VIEWMODE(ep,1);
  1336.     }
  1337. } /* do_showlog */
  1338.  
  1339.  
  1340. static void log (char * text)
  1341. {
  1342.     /* Wenn schon alle Slots voll sind, Platz schaffen */
  1343.     if (numlogs == MAX_LOG)
  1344.     {
  1345.     /* Erste message freigeben */
  1346.     free (log_messages[0]);
  1347.  
  1348.     /* Rest nach vorne schieben */
  1349.     movmem (&log_messages[1], &log_messages[0],
  1350.                         sizeof(char *) * (MAX_LOG - 1));
  1351.  
  1352.     /* Anzahl anpassen */
  1353.     numlogs --;
  1354.     }
  1355.  
  1356.     /* Wenn neuer log angefügt werden konnte, anzahl erhöhen */
  1357.     if (log_messages[numlogs] = strdup (text))
  1358.     numlogs ++;
  1359.  
  1360. } /* log */
  1361.  
  1362.  
  1363. Prototype void error (char * fmt, ...);
  1364.  
  1365. void error (char * fmt, ...)
  1366. {
  1367.     va_list va;
  1368.     static struct EasyStruct es =
  1369.     {
  1370.     sizeof (struct EasyStruct),
  1371.     NULL,
  1372.     "XDME Error",
  1373.     NULL,
  1374.     "Ok"
  1375.     };
  1376.  
  1377.     va_start (va, fmt);
  1378.  
  1379.     SETF_ABORTCOMMAND(Ep,1);
  1380.  
  1381.     if (GETF_NOREQUEST(Ep))
  1382.     {
  1383.     char * ptr;                /* PATCH_NULL [25 Jan 1993] : line added */
  1384.  
  1385.     vsprintf (tmp_buffer, fmt, va);     /* PATCH_NULL [25 Jan 1993] : line added */
  1386.     ptr = tmp_buffer;            /* PATCH_NULL [25 Jan 1993] : line added */
  1387.  
  1388.     while (*ptr) {                      /* PATCH_NULL [25 Jan 1993] : line added */
  1389.         if (*ptr == '\n') *ptr = ' ';   /* PATCH_NULL [25 Jan 1993] : line added */
  1390.         ptr ++;                /* PATCH_NULL [25 Jan 1993] : line added */
  1391.     } /* while */                /* PATCH_NULL [25 Jan 1993] : line added */
  1392.  
  1393.     show_title (tmp_buffer);            /* PATCH_NULL [25 Jan 1993] : line added */
  1394.     log (tmp_buffer);
  1395.     }
  1396.     else
  1397.     {
  1398.     es.es_TextFormat = fmt;
  1399.  
  1400.     EasyRequestArgs ((Ep ? Ep->win : NULL), &es, NULL, va);
  1401.  
  1402.     } /* if (not) noRequest */              /* PATCH_NULL [25 Jan 1993] : line added */
  1403.  
  1404.     va_end (va);
  1405.  
  1406. #ifdef PATCH_COMMANDSHELL
  1407.     if (CMDSH_Active && CMDSH_ErrorsOut) { /* PATCH_NULL 21-09-94 : added */
  1408.     va_start (va, fmt);
  1409.     CMDSH_Print(fmt, (ULONG *)va);
  1410.     va_end (va);
  1411.     } /* if */
  1412. #endif
  1413. } /* error */
  1414.  
  1415.  
  1416. Prototype void warn (char * fmt, ...);
  1417.  
  1418. void warn (char * fmt, ...)
  1419. {
  1420.     va_list va;
  1421.  
  1422.     va_start (va, fmt);
  1423.  
  1424.     vsprintf (tmp_buffer, fmt, va);
  1425.     strtrans (tmp_buffer, "\n\t", "  ");
  1426.  
  1427.     show_title (tmp_buffer);
  1428.     log (tmp_buffer);
  1429.  
  1430.     va_end (va);
  1431.  
  1432. #ifdef PATCH_COMMANDSHELL
  1433.     if (CMDSH_Active && CMDSH_WarningsOut) { /* PATCH_NULL 21-09-94 : added */
  1434.     va_start (va, fmt);
  1435.     CMDSH_Print(fmt, (ULONG *)va);
  1436.     va_end (va);
  1437.     } /* if */
  1438. #endif
  1439. } /* warn */
  1440.  
  1441.  
  1442. /*
  1443.     Changes the window-size and position. If the position is negative,
  1444.     it's calculated as offset from the right/bottom border. If
  1445.     width/height are negative, they are relative to the screen's
  1446.     width/height. If they are 0, they are not changed.
  1447. */
  1448.  
  1449. /*DEFHELP #cmd win SETGEOMETRY x y width height - Set x/y position and width/height of XDME's window. */
  1450.  
  1451. DEFUSERCMD("setgeometry", 4, CF_VWM, void, do_setgeometry, (void),)
  1452. {
  1453.     static const char error_text[] =
  1454.     ":\n"
  1455.     "Cannot set window to\n";
  1456.     WORD top, left, width, height;
  1457.     SCREEN * screen;
  1458.     char * error_ptr = NULL;
  1459.     long   minsize = 0;
  1460.  
  1461.     left   = strtol (av[1], NULL, 0);
  1462.     top    = strtol (av[2], NULL, 0);
  1463.     width  = strtol (av[3], NULL, 0);
  1464.     height = strtol (av[4], NULL, 0);
  1465.  
  1466.     screen = Ep->win->WScreen;
  1467.  
  1468.     if (left < 0)
  1469.     left += screen->Width;
  1470.     if (top < 0)
  1471.     top += screen->Height;
  1472.     if (width < 0)
  1473.     width += screen->Width + 1;
  1474.     if (height < 0)
  1475.     height += screen->Height + 1;
  1476.  
  1477.     if (!width || GETF_ICONMODE(Ep))
  1478.     width = Ep->win->Width;
  1479.     if (!height || GETF_ICONMODE(Ep))
  1480.     height = Ep->win->Height;
  1481.  
  1482.     /* if the left/top is not ok, or we are not in iconmode AND the
  1483.        width/height is wrong ... */
  1484.     if (left < 0)
  1485.     error_ptr = "left edge negative";
  1486.     else if (top < 0)
  1487.     error_ptr = "top edge negative";
  1488.     else if (left > screen->Width)
  1489.     error_ptr = "left edge too big";
  1490.     else if (top > screen->Height)
  1491.     error_ptr = "top edge too big";
  1492.     else if (!GETF_ICONMODE(Ep))
  1493.     {
  1494.     if (width < Nw.MinWidth)
  1495.     {
  1496.         error_ptr = "width is too narrow\n(The minimal width is ";
  1497.         minsize = Nw.MinWidth;
  1498.     } else if (height < Nw.MinHeight)
  1499.     {
  1500.         error_ptr = "height is too low\n(The minimal height is ";
  1501.         minsize = Nw.MinHeight;
  1502.     } else if (left + width > screen->Width)
  1503.         error_ptr = "right edge is too big";
  1504.     else if (top + height > screen->Height)
  1505.         error_ptr = "bottom edge is too big";
  1506.     }
  1507.  
  1508.     if (error_ptr)
  1509.     {
  1510.     if (minsize != 0)
  1511.     {
  1512.         error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s%ld).",
  1513.             av[0], error_text, left, top, width, height, error_ptr,
  1514.             minsize);
  1515.     } else
  1516.     {
  1517.         error ("%s%s(%ld/%ld), W:%ld, H:%ld\nbecause the %s.",
  1518.             error_text, av[0], left, top, width, height, error_ptr);
  1519.     }
  1520.     } else
  1521.     {
  1522.     ChangeWindowBox (Ep->win, left, top, width, height);
  1523.     Delay (5);
  1524.     }
  1525. } /* do_setgeometry */
  1526.  
  1527.  
  1528. /*DEFHELP #cmd win TOBACK - Move active window to back */
  1529.  
  1530. DEFUSERCMD("toback", 0, CF_VWM|CF_COK|CF_ICO, void, do_toback, (void),)
  1531. {
  1532.     WindowToBack (Ep->win);
  1533. } /* do_toback */
  1534.  
  1535.  
  1536. /*DEFHELP #cmd win TOFRONT - Move active window to front */
  1537.  
  1538. DEFUSERCMD("tofront", 0, CF_VWM|CF_COK|CF_ICO, void, do_tofront, (void),)
  1539. {
  1540.     WindowToFront (Ep->win);
  1541. } /* do_tofront */
  1542.  
  1543. /*DEFHELP #cmd win ACTIVATEWINDOW - Make the active Textwindow active for Intuition */
  1544.  
  1545. DEFUSERCMD("ActivateWindow", 0, CF_VWM|CF_COK|CF_ICO, void, do_axtivatewindow, (void),)
  1546. {
  1547.     ActivateWindow (Ep->win);
  1548.     if (GETF_ACTIVATETOFRONT(Ep))
  1549.     WindowToFront (Ep->win);
  1550. } /* do_tofront */
  1551.  
  1552.  
  1553.  
  1554. /******************************************************************************
  1555. *****  ENDE win.c
  1556. ******************************************************************************/
  1557.