home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / text / jed / src / jed.lha / windows.c < prev   
C/C++ Source or Header  |  1993-01-15  |  20KB  |  950 lines

  1.  
  2. /*
  3.  * WINDOWS.C
  4.  * (c) 1992-3 J.Harper
  5.  */
  6.  
  7. #include "jed.h"
  8. #include "revision.h"
  9. #include "jed_protos.h"
  10.  
  11. Prototype   VALUE * cmd_newfile        (LONG, VALUE *);
  12. Prototype   BOOL    newfile        (STRPTR);
  13. Prototype   VALUE * cmd_newview        (LONG, VALUE *);
  14. Prototype   BOOL    newview        (VOID);
  15. Prototype   VALUE * cmd_close        (LONG, VALUE *);
  16. Prototype   VOID    killwindow        (VOID);
  17. Prototype   VALUE * cmd_sleep        (LONG, VALUE *);
  18. Prototype   VALUE * cmd_unsleep        (LONG, VALUE *);
  19. Prototype   BOOL    unsleep        (VOID);
  20. Prototype   VALUE * cmd_dlock        (LONG, VALUE *);
  21. Local        TX *    newtx        (VOID);
  22. Local        VOID    killtx        (TX *);
  23. Local        VW *    newvw        (TX *, struct Window *, VW *);
  24. Local        VOID    killvw        (VW *);
  25. Prototype   WORD    numtxs        (VOID);
  26. Prototype   WORD    numviews        (TX *);
  27. Prototype   VOID    updatedimensions    (VW *);
  28. Local struct Window *newwindow        (UWORD *, STRPTR);
  29. Local        VOID    CloseSharedWindow    (struct Window *);
  30. Local        VOID    StripIntuiMessages    (struct MsgPort *, struct Window *);
  31. Prototype   struct IntuiMessage *GetWinIMsg(struct Window *);
  32. Prototype   VALUE * cmd_nextwind    (LONG, VALUE *);
  33. Prototype   VALUE * cmd_prevwind    (LONG, VALUE *);
  34. Prototype   VALUE * cmd_activatefile    (LONG, VALUE *);
  35. Prototype   BOOL    activatefile    (STRPTR);
  36. Prototype   VOID    settitle        (STRPTR);
  37. Prototype   VOID    settitlefmt        (STRPTR, ULONG, ...);
  38. Prototype   VALUE * cmd_settitle    (LONG, VALUE *);
  39. Prototype   VOID    notitle        (VOID);
  40. Prototype   VOID    stdtitle        (VOID);
  41. Prototype   VOID    resettitle        (VOID);
  42. Prototype   LONG    ezreq        (STRPTR, STRPTR, LONG, ...);
  43. Prototype   VALUE * cmd_req        (LONG, VALUE *);
  44. Prototype   BOOL    setfont        (VW *);
  45. Prototype   VALUE * cmd_rename        (LONG, VALUE *);
  46. Prototype   VALUE * cmd_changes        (LONG, VALUE *);
  47. Prototype   VALUE * cmd_position    (LONG, VALUE *);
  48. Prototype   VOID    resetslptxtitles    (TX *);
  49.  
  50. Prototype   struct MinList TXList;
  51. Prototype   VW          *CurrVW;
  52. Prototype   WORD       NumWindows;
  53.  
  54. struct MinList TXList;
  55. VW          *CurrVW;
  56. WORD           NumWindows;
  57.  
  58. #define IDCMP (IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE \
  59.     | IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_RAWKEY \
  60.     | IDCMP_ACTIVEWINDOW)
  61.  
  62. #define SIDCMP (IDCMP_MOUSEBUTTONS | IDCMP_CLOSEWINDOW \
  63.     | IDCMP_RAWKEY)
  64.  
  65. #define WFLAGS (WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET \
  66.     | WFLG_SIZEGADGET | WFLG_REPORTMOUSE | WFLG_ACTIVATE \
  67.     | WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH)
  68.  
  69. #define SWFLAGS (WFLG_DRAGBAR | WFLG_CLOSEGADGET | WFLG_ACTIVATE \
  70.     | WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH | WFLG_RMBTRAP)
  71.  
  72. Local const UBYTE ScreenTitle[] = VERSSTRING " (" __DATE__ ") Copyright © J.Harper";
  73. Local struct MsgPort *SharedPort;
  74.  
  75. /*
  76.  * (newfile `fileName')
  77.  */
  78. VALUE *
  79. cmd_newfile(LONG argc, VALUE *argv)
  80. {
  81.     if(TPLATE1(VTF_STRING))
  82.     {
  83.     BOOL rc = newfile(ARG1.val_Value.String);
  84.     setnumres(rc);
  85.     if(!rc)
  86.         settitle(NoMemMsg);
  87.     }
  88.     return(&RES);
  89. }
  90.  
  91. BOOL
  92. newfile(STRPTR fileName)
  93. {
  94.     TX *tx;
  95.     VW *oldvw = CurrVW;
  96.     struct Window *wd;
  97.  
  98.     if(oldvw)
  99.     {
  100.     if(oldvw->vw_Sleeping)
  101.         wd = newwindow(oldvw->vw_OldDimensions, oldvw->vw_Prefs.prf_ScreenName);
  102.     else
  103.         wd = newwindow(&oldvw->vw_Window->LeftEdge, oldvw->vw_Prefs.prf_ScreenName);
  104.     }
  105.     else
  106.     wd = newwindow(DefDims, DefPrefs.prf_ScreenName);
  107.     if(wd)
  108.     {
  109.     NumWindows++;
  110.     setmenu(wd);
  111.     if(tx = newtx())
  112.     {
  113.         if(oldvw)
  114.         cursor(ON);
  115.         if(CurrVW = newvw(tx, wd, oldvw))
  116.         {
  117.         if(readtx(tx, fileName, CurrVW->vw_Prefs.prf_DiskTab))
  118.         {
  119.             setupfileprefs(tx);
  120.             CurrVW->vw_RefreshType = RFF_ALL;
  121.             stdtitle();
  122.             return(TRUE);
  123.         }
  124.         killvw(CurrVW);
  125.         }
  126.         CurrVW = oldvw;
  127.         if(oldvw)
  128.         cursor(OFF);
  129.         killtx(tx);
  130.     }
  131.     CloseSharedWindow(wd);
  132.     }
  133.     return(FALSE);
  134. }
  135.  
  136. /*
  137.  * (newview)
  138.  */
  139. VALUE *
  140. cmd_newview(LONG argc, VALUE *argv)
  141. {
  142.     BOOL rc = newview();
  143.     setnumres(rc);
  144.     if(!rc)
  145.     settitle(NoMemMsg);
  146.     return(&RES);
  147. }
  148.  
  149. BOOL
  150. newview(VOID)
  151. {
  152.     struct Window *wd;
  153.     TX *tx;
  154.     VW *oldvw = CurrVW;
  155.  
  156.     if(oldvw->vw_Sleeping)
  157.     wd = newwindow(oldvw->vw_OldDimensions, oldvw->vw_Prefs.prf_ScreenName);
  158.     else
  159.     wd = newwindow(&oldvw->vw_Window->LeftEdge, oldvw->vw_Prefs.prf_ScreenName);
  160.     if(wd)
  161.     {
  162.     NumWindows++;
  163.     setmenu(wd);
  164.     cursor(ON);
  165.     if(CurrVW = newvw(oldvw->vw_Tx, wd, oldvw));
  166.     {
  167.         CurrVW->vw_RefreshType = RFF_ALL;
  168.         cursor(ON);
  169.         stdtitle();
  170.         return(TRUE);
  171.     }
  172.     CurrVW = oldvw;
  173.     cursor(OFF);
  174.     CloseSharedWindow(wd);
  175.     }
  176.     return(FALSE);
  177. }
  178.  
  179. /*
  180.  * (close)
  181.  */
  182. VALUE *
  183. cmd_close(LONG argc, VALUE *argv)
  184. {
  185.     TX *tx = CurrVW->vw_Tx;
  186.     if((numviews(tx) > 1) || (!tx->tx_Changes) || (ezreq("OK to lose %ld changes\nto file %s", "Yeah|Cancel", tx->tx_Changes, tx->tx_TitleName)))
  187.     {
  188.     killwindow();
  189.     setnumres(TRUE);
  190.     }
  191.     else
  192.     setnumres(FALSE);
  193.     return(&RES);
  194. }
  195.  
  196. VOID
  197. killwindow(VOID)
  198. {
  199.     VW *vw = CurrVW;
  200.     TX *tx = vw->vw_Tx;
  201.  
  202.     setdefprefs(vw);
  203.     notitle();
  204.     CloseSharedWindow(vw->vw_Window);
  205.     killvw(vw);
  206.     if(IsMListEmpty(tx->tx_Views))
  207.     {
  208.     killtx(tx);
  209.     if(IsMListEmpty(TXList))
  210.         CurrVW = NULL;
  211.     else
  212.         CurrVW = (VW *)((TX *)TXList.mlh_Head)->tx_Views.mlh_Head;
  213.     }
  214.     else
  215.     CurrVW = (VW *)tx->tx_Views.mlh_Head;
  216.     if(CurrVW)
  217.     {
  218.     CurrVW->vw_DeferRefresh++;
  219.     cursor(OFF);
  220.     }
  221. }
  222.  
  223. /*
  224.  * Sleeps the window.
  225.  */
  226. VALUE *
  227. cmd_sleep(LONG argc, VALUE *argv)
  228. {
  229.     VW *vw = CurrVW;
  230.     if(!vw->vw_Sleeping)
  231.     {
  232.     struct Window *swin;
  233.     if(swin = OpenWindowTags(NULL,
  234.         WA_Left, 0,
  235.         WA_Top, 0,
  236.         WA_Width, 150,
  237.         WA_Height, vw->vw_Window->BorderTop,
  238.         WA_IDCMP, 0,
  239.         WA_Flags, SWFLAGS,
  240.         WA_Title, vw->vw_Tx->tx_TitleName,
  241.         WA_ScreenTitle, ScreenTitle,
  242.         WA_AutoAdjust, TRUE,
  243.         WA_PubScreenName, vw->vw_Prefs.prf_ScreenName,
  244.         WA_PubScreenFallBack, TRUE,
  245.         TAG_END))
  246.     {
  247.         swin->UserPort = SharedPort;
  248.         ModifyIDCMP(swin, SIDCMP);
  249.  
  250.         vw->vw_OldDimensions[0] = vw->vw_Window->LeftEdge;
  251.         vw->vw_OldDimensions[1] = vw->vw_Window->TopEdge;
  252.         vw->vw_OldDimensions[2] = vw->vw_Window->Width;
  253.         vw->vw_OldDimensions[3] = vw->vw_Window->Height;
  254.  
  255.         clearmenu(vw->vw_Window);
  256.         Forbid();
  257.         StripIntuiMessages(vw->vw_Window->UserPort, vw->vw_Window);
  258.         vw->vw_Window->UserPort = NULL;
  259.         ModifyIDCMP(vw->vw_Window, 0L);
  260.         Permit();
  261.         CloseWindow(vw->vw_Window);
  262.  
  263.         vw->vw_Window = swin;
  264.         vw->vw_Rp = swin->RPort;
  265.         vw->vw_Sleeping = TRUE;
  266.         swin->UserData = (BYTE *)vw;
  267.         setnumres(TRUE);
  268.     }
  269.     else
  270.     {
  271.         settitle("error: can't open window to sleep in");
  272.         setnumres(FALSE);
  273.     }
  274.     }
  275.     return(&RES);
  276. }
  277.  
  278. VALUE *
  279. cmd_unsleep(LONG argc, VALUE *argv)
  280. {
  281.     if(CurrVW->vw_Sleeping)
  282.     {
  283.     setnumres(unsleep());
  284.     }
  285.     return(&RES);
  286. }
  287.  
  288. BOOL
  289. unsleep(VOID)
  290. {
  291.     VW *vw = CurrVW;
  292.     BOOL rc = TRUE;
  293.     if(vw->vw_Sleeping)
  294.     {
  295.     struct Window *nwin;
  296.  
  297.     if(nwin = newwindow(vw->vw_OldDimensions, vw->vw_Prefs.prf_ScreenName))
  298.     {
  299.         setmenu(nwin);
  300.  
  301.         Forbid();
  302.         StripIntuiMessages(vw->vw_Window->UserPort, vw->vw_Window);
  303.         vw->vw_Window->UserPort = NULL;
  304.         ModifyIDCMP(vw->vw_Window, 0L);
  305.         Permit();
  306.         CloseWindow(vw->vw_Window);
  307.  
  308.         vw->vw_Window = nwin;
  309.         vw->vw_Rp = nwin->RPort;
  310.         vw->vw_Sleeping = FALSE;
  311.         nwin->UserData = (BYTE *)vw;
  312.         SetFont(vw->vw_Rp, vw->vw_Font);
  313.         updatedimensions(vw);
  314.         vw->vw_RefreshType = RFF_ALL;
  315.     }
  316.     else
  317.         rc = FALSE;
  318.     }
  319.     return(rc);
  320. }
  321.  
  322. VALUE *
  323. cmd_dlock(LONG argc, VALUE *argv)
  324. {
  325.     if(TPLATE1(VTF_NUMBER))
  326.     {
  327.     VW *vw = CurrVW;
  328.     vw->vw_DisplayLock = ARG1.val_Value.Number;
  329.     setnumres(TRUE);
  330.     }
  331.     return(&RES);
  332. }
  333.  
  334. /*
  335.  * Creates a new TX structure
  336.  */
  337. Local TX *
  338. newtx(VOID)
  339. {
  340.     TX *tx = AllocVec(sizeof(TX), MEMF_CLEAR);
  341.     if(tx)
  342.     {
  343.     AddMTail(&TXList, &tx->tx_Node);
  344.     NewMList(&tx->tx_Views);
  345.     NewMList(&tx->tx_Marks);
  346.     return(tx);
  347.     }
  348.     return(FALSE);
  349. }
  350.  
  351. Local VOID
  352. killtx(TX *tx)
  353. {
  354.     RemoveM(&tx->tx_Node);
  355.     killlinelist(tx);
  356.     freestring(tx->tx_TitleName);
  357.     freestring(tx->tx_FileName);
  358.     FreeVec(tx);
  359. }
  360.  
  361. /*
  362.  * Creates a new VW, oldVW is used to copy prefs from, can be NULL.
  363.  */
  364. Local VW *
  365. newvw(TX *tx, struct Window *wd, VW *oldVW)
  366. {
  367.     VW *vw = AllocVec(sizeof(VW), MEMF_CLEAR);
  368.     if(vw)
  369.     {
  370.     vw->vw_Window = wd;
  371.     vw->vw_Rp = wd->RPort;
  372.     vw->vw_Tx = tx;
  373.     wd->UserData = (BYTE *)vw;
  374.     copyprefs(vw, oldVW);
  375.     if(setfont(vw))
  376.     {
  377.         updatedimensions(vw);
  378.         vw->vw_BlockStatus = -1;
  379.         AddMTail(&tx->tx_Views, &vw->vw_Node);
  380.         return(vw);
  381.     }
  382.     FreeVec(vw);
  383.     }
  384.     return(FALSE);
  385. }
  386.  
  387. Local VOID
  388. killvw(VW *vw)
  389. {
  390.     RemoveM(&vw->vw_Node);
  391.     freestring(vw->vw_LineUndo.text);
  392.     CloseFont(vw->vw_Font);
  393. #ifndef NOREGEXP
  394.     if(vw->vw_LastRE.prog)
  395.     free(vw->vw_LastRE.prog);
  396. #endif
  397.     FreeVec(vw);
  398. }
  399.  
  400. WORD
  401. numtxs(VOID)
  402. {
  403.     WORD i =0;
  404.     TX *tx = (TX *)TXList.mlh_Head;
  405.     while(tx = (TX *)tx->tx_Node.mln_Succ)
  406.     i++;
  407.     return(i);
  408. }
  409.  
  410. WORD
  411. numviews(TX *tx)
  412. {
  413.     WORD i = 0;
  414.     VW *vw = (VW *)tx->tx_Views.mlh_Head;
  415.     while(vw = (VW *)vw->vw_Node.mln_Succ)
  416.     i++;
  417.     return(i);
  418. }
  419.  
  420. VOID
  421. updatedimensions(VW *vw)
  422. {
  423.     if(!vw->vw_Sleeping)
  424.     {
  425.     struct Window *wd = vw->vw_Window;
  426.  
  427.     vw->vw_XStartPix = (UWORD)wd->BorderLeft;
  428.     vw->vw_YStartPix = (UWORD)wd->BorderTop;
  429.     vw->vw_XEndPix = wd->Width - (UWORD)wd->BorderRight - 1;
  430.     vw->vw_YEndPix = wd->Height - (UWORD)wd->BorderBottom;
  431.     vw->vw_XWidthPix = vw->vw_XEndPix - vw->vw_XStartPix;
  432.     vw->vw_YHeightPix = vw->vw_YEndPix - vw->vw_YStartPix;
  433.  
  434.     vw->vw_FontStart = vw->vw_YStartPix + vw->vw_Font->tf_Baseline;
  435.     vw->vw_FontX = vw->vw_Font->tf_XSize;
  436.     vw->vw_FontY = vw->vw_Font->tf_YSize;
  437.  
  438.     vw->vw_MaxX = (vw->vw_XWidthPix / vw->vw_FontX);
  439.     vw->vw_MaxY = (vw->vw_YHeightPix / vw->vw_FontY);
  440.     vw->vw_XStep = vw->vw_MaxX / 4;
  441.     if(!vw->vw_XStep)
  442.         vw->vw_XStep = 1;
  443.     }
  444. }
  445.  
  446. /*
  447.  * Opens an editor window. Sets up the shared IDCMP
  448.  */
  449. Local struct Window *
  450. newwindow(UWORD *dimensions, STRPTR pubName)
  451. {
  452.     struct Window *res;
  453.     res = OpenWindowTags(NULL,
  454.     WA_Left, dimensions[0],
  455.     WA_Top, dimensions[1],
  456.     WA_Width, dimensions[2],
  457.     WA_Height, dimensions[3],
  458.     WA_IDCMP, SharedPort ? 0 : IDCMP,
  459.     WA_MinWidth, 80,
  460.     WA_MinHeight, 40,
  461.     WA_MaxWidth, ~0,
  462.     WA_MaxHeight, ~0,
  463.     WA_Flags, WFLAGS,
  464.     WA_ScreenTitle, ScreenTitle,
  465.     WA_AutoAdjust, TRUE,
  466.     WA_PubScreenName, pubName,
  467.     WA_PubScreenFallBack, TRUE,
  468.     WA_RptQueue, 2,
  469.     TAG_END);
  470.     if(res)
  471.     {
  472.     if(SharedPort)
  473.     {
  474.         res->UserPort = SharedPort;
  475.         ModifyIDCMP(res, IDCMP);
  476.     }
  477.     else
  478.         SharedPort = res->UserPort;
  479.     }
  480.     return(res);
  481. }
  482.  
  483. /*
  484.  * Code to close a window who's sharing a UserPort -- taken from
  485.  * CloseWindow() autodoc.
  486.  */
  487. Local VOID
  488. CloseSharedWindow(struct Window *win)
  489. {
  490.     clearmenu(win);
  491.     if(--NumWindows)
  492.     {
  493.     Forbid();
  494.     StripIntuiMessages(win->UserPort, win);
  495.     win->UserPort = NULL;
  496.     ModifyIDCMP(win, 0L);
  497.     Permit();
  498.     }
  499.     else
  500.     SharedPort = NULL;
  501.     CloseWindow(win);
  502. }
  503.  
  504. Local VOID
  505. StripIntuiMessages(struct MsgPort *mp, struct Window *win)
  506. {
  507.     struct IntuiMessage *msg;
  508.     struct Node *succ;
  509.  
  510.     msg = (struct IntuiMessage *)mp->mp_MsgList.lh_Head;
  511.     while(succ = msg->ExecMessage.mn_Node.ln_Succ)
  512.     {
  513.     if(msg->IDCMPWindow == win)
  514.     {
  515.         Remove((struct Node *)msg);
  516.         ReplyMsg((struct Message *)msg);
  517.     }
  518.     msg = (struct IntuiMessage *)succ;
  519.     }
  520. }
  521.  
  522. /*
  523.  * Gets the next Imsg for the specified window -- this is used for event
  524.  * loops local to a single window
  525.  */
  526. struct IntuiMessage *
  527. GetWinIMsg(struct Window *win)
  528. {
  529.     struct IntuiMessage *msg;
  530.     struct Node *succ;
  531.  
  532.     Forbid();
  533.     msg = (struct IntuiMessage *)win->UserPort->mp_MsgList.lh_Head;
  534.     while(succ = msg->ExecMessage.mn_Node.ln_Succ)
  535.     {
  536.     if(msg->IDCMPWindow == win)
  537.     {
  538.         Remove((struct Node *)msg);
  539.         Permit();
  540.         return(msg);
  541.     }
  542.     msg = (struct IntuiMessage *)succ;
  543.     }
  544.     Permit();
  545.     return(FALSE);
  546. }
  547.  
  548. VALUE *
  549. cmd_nextwind(LONG argc, VALUE *argv)
  550. {
  551.     if(TPLATE1(VTF_STRING))
  552.     {
  553.     cursor(ON);
  554.     switch(toupper(*(ARG1.val_Value.String)))
  555.     {
  556.         case 'F':
  557.         TX *tx = CurrVW->vw_Tx;
  558.         tx = (TX *)tx->tx_Node.mln_Succ;
  559.         if(!tx->tx_Node.mln_Succ)
  560.             tx = (TX *)TXList.mlh_Head;
  561.         CurrVW = (VW *)tx->tx_Views.mlh_Head;
  562.         WindowToFront(CurrVW->vw_Window);
  563.         ActivateWindow(CurrVW->vw_Window);
  564.         CurrVW->vw_DeferRefresh = 1;
  565.         setnumres(TRUE);
  566.         break;
  567.         case 'V':
  568.         VW *vw = (VW *)CurrVW->vw_Node.mln_Succ;
  569.         if(!vw->vw_Node.mln_Succ)
  570.             vw = (VW *)CurrVW->vw_Tx->tx_Views.mlh_Head;
  571.         CurrVW = vw;
  572.         WindowToFront(CurrVW->vw_Window);
  573.         ActivateWindow(CurrVW->vw_Window);
  574.         CurrVW->vw_DeferRefresh = 1;
  575.         setnumres(TRUE);
  576.         break;
  577.         case 'A':
  578.         VW *vw = (VW *)CurrVW->vw_Node.mln_Succ;
  579.         if(!vw->vw_Node.mln_Succ)
  580.         {
  581.             TX *tx = (TX *)CurrVW->vw_Tx->tx_Node.mln_Succ;
  582.             if(!tx->tx_Node.mln_Succ)
  583.             tx = (TX *)TXList.mlh_Head;
  584.             CurrVW = (VW *)tx->tx_Views.mlh_Head;
  585.         }
  586.         else
  587.             CurrVW = vw;
  588.         WindowToFront(CurrVW->vw_Window);
  589.         ActivateWindow(CurrVW->vw_Window);
  590.         CurrVW->vw_DeferRefresh = 1;
  591.         setnumres(TRUE);
  592.         break;
  593.         default:
  594.         settitle(BadArgMsg);
  595.         break;
  596.     }
  597.     cursor(OFF);
  598.     }
  599.     return(&RES);
  600. }
  601.  
  602. VALUE *
  603. cmd_prevwind(LONG argc, VALUE *argv)
  604. {
  605.     if(TPLATE1(VTF_STRING))
  606.     {
  607.     cursor(ON);
  608.     switch(toupper(*ARG1.val_Value.String))
  609.     {
  610.         case 'F':
  611.         TX *tx = CurrVW->vw_Tx;
  612.         tx = (TX *)tx->tx_Node.mln_Pred;
  613.         if(!tx->tx_Node.mln_Pred)
  614.             tx = (TX *)TXList.mlh_TailPred;
  615.         CurrVW = (VW *)tx->tx_Views.mlh_TailPred;
  616.         WindowToFront(CurrVW->vw_Window);
  617.         ActivateWindow(CurrVW->vw_Window);
  618.         CurrVW->vw_DeferRefresh = 1;
  619.         setnumres(TRUE);
  620.         break;
  621.         case 'V':
  622.         VW *vw = (VW *)CurrVW->vw_Node.mln_Pred;
  623.         if(!vw->vw_Node.mln_Pred)
  624.             vw = (VW *)CurrVW->vw_Tx->tx_Views.mlh_TailPred;
  625.         CurrVW = vw;
  626.         WindowToFront(CurrVW->vw_Window);
  627.         ActivateWindow(CurrVW->vw_Window);
  628.         CurrVW->vw_DeferRefresh = 1;
  629.         setnumres(TRUE);
  630.         break;
  631.         case 'A':
  632.         VW *vw = (VW *)CurrVW->vw_Node.mln_Pred;
  633.         if(!vw->vw_Node.mln_Pred)
  634.         {
  635.             TX *tx = (TX *)CurrVW->vw_Tx->tx_Node.mln_Pred;
  636.             if(!tx->tx_Node.mln_Pred)
  637.             tx = (TX *)TXList.mlh_TailPred;
  638.             CurrVW = (VW *)tx->tx_Views.mlh_TailPred;
  639.         }
  640.         else
  641.             CurrVW = vw;
  642.         WindowToFront(CurrVW->vw_Window);
  643.         ActivateWindow(CurrVW->vw_Window);
  644.         CurrVW->vw_DeferRefresh = 1;
  645.         setnumres(TRUE);
  646.         break;
  647.         default:
  648.         settitle(BadArgMsg);
  649.         break;
  650.     }
  651.     cursor(OFF);
  652.     }
  653.     return(&RES);
  654. }
  655.  
  656. VALUE *
  657. cmd_activatefile(LONG argc, VALUE *argv)
  658. {
  659.     if(TPLATE1(VTF_STRING))
  660.     setnumres(activatefile(ARG1.val_Value.String));
  661.     return(&RES);
  662. }
  663.  
  664. BOOL
  665. activatefile(STRPTR file)
  666. {
  667.     cursor(ON);
  668.     BPTR lock1 = Lock(file, SHARED_LOCK);
  669.     if(lock1)
  670.     {
  671.     TX *thistx = TXList.mlh_Head;
  672.     while(thistx->tx_Node.mln_Succ)
  673.     {
  674.         BPTR lock2 = Lock(thistx->tx_FileName, SHARED_LOCK);
  675.         if(lock2)
  676.         {
  677.         if(SameLock(lock1, lock2) == LOCK_SAME)
  678.         {
  679.             CurrVW = (VW *)thistx->tx_Views.mlh_Head;
  680.             unsleep();
  681.             WindowToFront(CurrVW->vw_Window);
  682.             ActivateWindow(CurrVW->vw_Window);
  683.             UnLock(lock2);
  684.             UnLock(lock1);
  685.             cursor(OFF);
  686.             CurrVW->vw_DeferRefresh = 1;
  687.             return(TRUE);
  688.         }
  689.         UnLock(lock2);
  690.         }
  691.         thistx = (TX *)thistx->tx_Node.mln_Succ;
  692.     }
  693.     UnLock(lock1);
  694.     if(newfile(file))
  695.     {
  696.         cursor(OFF);
  697.         return(TRUE);
  698.     }
  699.     }
  700.     else
  701.     settitlefmt("error: unknown file %s", (LONG)file);
  702.     cursor(OFF);
  703.     return(FALSE);
  704. }
  705.  
  706. VOID
  707. settitle(STRPTR title)
  708. {
  709.     VW *vw = CurrVW;
  710.     if(!vw->vw_Sleeping)
  711.     {
  712.     freestring(vw->vw_LastTitle);
  713.     vw->vw_LastTitle = savestring(title);
  714.     SetWindowTitles(CurrVW->vw_Window, vw->vw_LastTitle, (UBYTE *)-1L);
  715.     vw->vw_NonStdTitle = TRUE;
  716.     }
  717. }
  718.  
  719. VOID
  720. settitlefmt(STRPTR fmt, ULONG arg1, ...)
  721. {
  722.     VW *vw = CurrVW;
  723.     if(!vw->vw_Sleeping)
  724.     {
  725.     UBYTE fmtbuff[256];
  726.     vsprintf(fmtbuff, fmt, &arg1);
  727.     freestring(vw->vw_LastTitle);
  728.     vw->vw_LastTitle = savestring(fmtbuff);
  729.     SetWindowTitles(vw->vw_Window, vw->vw_LastTitle, (UBYTE *)-1L);
  730.     vw->vw_NonStdTitle = TRUE;
  731.     }
  732. }
  733.  
  734. VALUE *
  735. cmd_settitle(LONG argc, VALUE *argv)
  736. {
  737.     if(TPLATE1(VTF_STRING))
  738.     {
  739.     settitle(ARG1.val_Value.String);
  740.     setnumres(TRUE);
  741.     }
  742.     return(&RES);
  743. }
  744.  
  745. VOID
  746. notitle(VOID)
  747. {
  748.     VW *vw = CurrVW;
  749.     if(!vw->vw_Sleeping)
  750.     {
  751.     freestring(vw->vw_LastTitle);
  752.     vw->vw_LastTitle = NULL;
  753.     SetWindowTitles(vw->vw_Window, NULL, (UBYTE *)-1L);
  754.     vw->vw_NonStdTitle = FALSE;
  755.     }
  756. }
  757.  
  758. VOID
  759. stdtitle(VOID)
  760. {
  761.     VW *vw = CurrVW;
  762.     if((!vw->vw_NonStdTitle) && (!vw->vw_Sleeping))
  763.     {
  764.     TX *tx = vw->vw_Tx;
  765.     UBYTE blk;
  766.     UBYTE fmtbuff[100];
  767.     if(vw->vw_BlockStatus >= 0)
  768.     {
  769.         if(!vw->vw_BlockStatus)
  770.         blk = 'B';
  771.         else
  772.         blk = 'b';
  773.     }
  774.     else
  775.         blk = 0;
  776.     freestring(vw->vw_LastTitle);
  777.     sprintf(fmtbuff, "%s%lc (%ld,%ld) %ld line(s) %lc%lc%lc%lc%ld",
  778.         (LONG)tx->tx_TitleName,
  779.         tx->tx_Changes ? (LONG)'+' : (LONG)'\0',
  780.         (LONG)vw->vw_CursorPos.pos_Col + 1,
  781.         vw->vw_CursorPos.pos_Line + 1,
  782.         tx->tx_NumLines,
  783.         blk,
  784.         vw->vw_Prefs.prf_AutoIndent ? 'A' : 0,
  785.         vw->vw_Prefs.prf_WordWrap ? 'W' : 0,
  786.         vw->vw_Prefs.prf_NoSnapshotWin ? 'N' : 0,
  787.         vw->vw_Prefs.prf_SaveTabs);
  788.     vw->vw_LastTitle = savestring(fmtbuff);
  789.     SetWindowTitles(vw->vw_Window, vw->vw_LastTitle, (UBYTE *)-1L);
  790.     }
  791. }
  792.  
  793. VOID
  794. resettitle(VOID)
  795. {
  796.     CurrVW->vw_NonStdTitle = FALSE;
  797. }
  798.  
  799. Local struct EasyStruct ezstruct =
  800. {
  801.     sizeof(struct EasyStruct),
  802.     0,
  803.     "jed request...",
  804.     NULL,
  805.     NULL,
  806. };
  807.  
  808. LONG
  809. ezreq(STRPTR bodyFmt, STRPTR gadFmt, LONG arg1, ...)
  810. {
  811.     ezstruct.es_TextFormat = bodyFmt;
  812.     ezstruct.es_GadgetFormat = gadFmt;
  813.     return(EasyRequestArgs(CurrVW->vw_Window, &ezstruct, NULL, &arg1));
  814. }
  815.  
  816. /*
  817.  * (req `bodyFmt' `gadFmt' args...)
  818.  *
  819.  * command to do a request, formatting is provided.
  820.  * result is number of gadget pressed (starting at 1 for leftmost gadget and
  821.  * incrementing by one, rightmost gadget is 0.
  822.  */
  823. VALUE *
  824. cmd_req(LONG argc, VALUE *argv)
  825. {
  826.     if(TPLATE2(VTF_STRING, VTF_STRING))
  827.     {
  828.     LONG result, i, args[20];
  829.  
  830.     ezstruct.es_TextFormat = ARG1.val_Value.String;
  831.     ezstruct.es_GadgetFormat = ARG2.val_Value.String;
  832.  
  833.     for(i = 0; (i < (argc - 2)) && (i < 20); i++)
  834.         args[i] = argv[i + 3].val_Value.Number;
  835.  
  836.     result = EasyRequestArgs(CurrVW->vw_Window, &ezstruct, NULL, args);
  837.     setnumres(result);
  838.     }
  839.     return(&RES);
  840. }
  841.  
  842. BOOL
  843. setfont(VW *vw)
  844. {
  845.     struct TextAttr ta;
  846.     struct TextFont *tf;
  847.  
  848.     ta.ta_Name = vw->vw_Prefs.prf_FontName;
  849.     ta.ta_YSize = vw->vw_Prefs.prf_FontSize;
  850.     ta.ta_Style = FS_NORMAL;
  851.     ta.ta_Flags = 0;
  852.  
  853.     if(tf = OpenDiskFont(&ta))
  854.     {
  855.     if(tf->tf_Flags & FPF_PROPORTIONAL)
  856.     {
  857.         CloseFont(tf);
  858.         return(FALSE);
  859.     }
  860.     SetFont(vw->vw_Rp, tf);
  861.     if(vw->vw_Font)
  862.         CloseFont(vw->vw_Font);
  863.     vw->vw_Font = tf;
  864.     updatedimensions(vw);
  865.     return(TRUE);
  866.     }
  867.     return(FALSE);
  868. }
  869.  
  870. VALUE *
  871. cmd_rename(LONG argc, VALUE *argv)
  872. {
  873.     if(TPLATE1(VTF_STRING))
  874.     {
  875.     TX *tx = CurrVW->vw_Tx;
  876.     STRPTR newn, newt;
  877.     BOOL rc = FALSE;
  878.     if(newn = savestring(ARG1.val_Value.String))
  879.     {
  880.         if(newt = (*ARG1.val_Value.String ? savestring(FilePart(ARG1.val_Value.String)) : savestring("Unititled")))
  881.         {
  882.         freestring(tx->tx_TitleName);
  883.         freestring(tx->tx_FileName);
  884.         tx->tx_FileName = newn;
  885.         tx->tx_TitleName = newt;
  886.         resetslptxtitles(tx);
  887.         rc = TRUE;
  888.         }
  889.     }
  890.     if(!rc)
  891.         settitle(NoMemMsg);
  892.     setnumres(rc);
  893.     }
  894.     return(&RES);
  895. }
  896.  
  897. VALUE *
  898. cmd_changes(LONG argc, VALUE *argv)
  899. {
  900.     if(TPLATE1(VTF_NUMBER))
  901.     {
  902.     TX *tx = CurrVW->vw_Tx;
  903.     setnumres(tx->tx_Changes);
  904.     tx->tx_Changes = ARG1.val_Value.Number;
  905.     }
  906.     return(&RES);
  907. }
  908.  
  909. /*
  910.  * (position left top width height)
  911.  */
  912. VALUE *
  913. cmd_position(LONG argc, VALUE *argv)
  914. {
  915.     if(TPLATE4(VTF_NUMBER, VTF_NUMBER, VTF_NUMBER, VTF_NUMBER))
  916.     {
  917.     VW *vw = CurrVW;
  918.     if(!vw->vw_Sleeping)
  919.     {
  920.         ChangeWindowBox(vw->vw_Window, ARG1.val_Value.Number, ARG2.val_Value.Number, ARG3.val_Value.Number, ARG4.val_Value.Number);
  921.         vw->vw_DeferRefresh = 1;
  922.     }
  923.     else
  924.     {
  925.         vw->vw_OldDimensions[0] = ARG1.val_Value.Number;
  926.         vw->vw_OldDimensions[1] = ARG2.val_Value.Number;
  927.         vw->vw_OldDimensions[2] = ARG3.val_Value.Number;
  928.         vw->vw_OldDimensions[3] = ARG4.val_Value.Number;
  929.     }
  930.     setnumres(TRUE);
  931.     }
  932.     return(&RES);
  933. }
  934.  
  935. /*
  936.  * Used when the name of a TX is changed. All sleeping views have their title
  937.  * display updated.
  938.  */
  939. VOID
  940. resetslptxtitles(TX *tx)
  941. {
  942.     VW *vw = (VW *)tx->tx_Views.mlh_Head;
  943.     while(vw->vw_Node.mln_Succ)
  944.     {
  945.     if(vw->vw_Sleeping)
  946.         SetWindowTitles(vw->vw_Window, tx->tx_TitleName, (UBYTE *)~0);
  947.     vw = (VW *)vw->vw_Node.mln_Succ;
  948.     }
  949. }
  950.