home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / text / jed / src / jed.lha / housekeeping.c < prev    next >
C/C++ Source or Header  |  1992-11-02  |  11KB  |  389 lines

  1.  
  2. /*
  3.  * HOUSEKEEPING.C
  4.  * (c) 1992 J.Harper
  5.  */
  6.  
  7. #include "jed.h"
  8. #include "jed_protos.h"
  9.  
  10. Prototype   VOID    keepposaddx        (WORD);
  11. Prototype   VOID    keeppossubx        (WORD);
  12. Prototype   VOID    keepposaddy        (LONG);
  13. Prototype   VOID    keeppossuby        (LONG);
  14. Prototype   VOID    keeppossplity    (VOID);
  15. Prototype   VOID    keepposjoiny    (VOID);
  16. Prototype   VOID    resyncx        (VOID);
  17. Prototype   VOID    resyncy        (VOID);
  18. Prototype   VOID    resyncxy        (VOID);
  19. Prototype   VOID    resetallviews    (TX *);
  20. Local        VOID    scrollvwup        (VOID);
  21. Local        VOID    scrollvwdn        (VOID);
  22.  
  23. /*
  24.  * The next few routines deal with updating the various references to
  25.  * coordinates throughout the views after chunks have been deleted and
  26.  * inserted.
  27.  */
  28. VOID
  29. keepposaddx(WORD addx)
  30. {
  31.     TX *tx = CurrVW->vw_Tx;
  32.     VW *thisvw;
  33.     MARK *thismark;
  34.     WORD xpos = CurrVW->vw_CursorPos.pos_Col;
  35.     LONG ypos = CurrVW->vw_CursorPos.pos_Line;
  36.  
  37. #define upd(x,y) if((y == ypos) && (x >= xpos)) x += addx
  38.  
  39.     for(thisvw = (VW *)tx->tx_Views.mlh_Head; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  40.     {
  41.     upd(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  42.     upd(thisvw->vw_AutoMark.pos_Col, thisvw->vw_AutoMark.pos_Line);
  43.     upd(thisvw->vw_Block[0].pos_Col, thisvw->vw_Block[0].pos_Line);
  44.     upd(thisvw->vw_Block[1].pos_Col, thisvw->vw_Block[1].pos_Line);
  45.     }
  46.     for(thismark = (MARK *)tx->tx_Marks.mlh_Head; thismark->mk_Node.mln_Succ; thismark = (MARK *)thismark->mk_Node.mln_Succ)
  47.     {
  48.     upd(thismark->mk_Pos.pos_Col, thismark->mk_Pos.pos_Line);
  49.     }
  50.  
  51. #undef upd(x,y)
  52. }
  53.  
  54. VOID
  55. keeppossubx(WORD subx)
  56. {
  57.     TX *tx = CurrVW->vw_Tx;
  58.     VW *thisvw;
  59.     MARK *thismark;
  60.     WORD xpos = CurrVW->vw_CursorPos.pos_Col;
  61.     LONG ypos = CurrVW->vw_CursorPos.pos_Line;
  62.  
  63. #define upd(x,y) if((y == ypos) && (x >= xpos)) { if((x -= subx) < xpos) x = xpos; }
  64.  
  65.     for(thisvw = (VW *)tx->tx_Views.mlh_Head; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  66.     {
  67.     upd(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  68.     upd(thisvw->vw_AutoMark.pos_Col, thisvw->vw_AutoMark.pos_Line);
  69.     upd(thisvw->vw_Block[0].pos_Col, thisvw->vw_Block[0].pos_Line);
  70.     upd(thisvw->vw_Block[1].pos_Col, thisvw->vw_Block[1].pos_Line);
  71.     }
  72.     for(thismark = (MARK *)tx->tx_Marks.mlh_Head; thismark->mk_Node.mln_Succ; thismark = (MARK *)thismark->mk_Node.mln_Succ)
  73.     {
  74.     upd(thismark->mk_Pos.pos_Col, thismark->mk_Pos.pos_Line);
  75.     }
  76.  
  77. #undef upd(x,y)
  78. }
  79.  
  80. /*
  81.  * Whole lines only please
  82.  */
  83. VOID
  84. keepposaddy(LONG addy)
  85. {
  86.     TX *tx = CurrVW->vw_Tx;
  87.     VW *thisvw;
  88.     MARK *thismark;
  89.     LONG ypos = CurrVW->vw_CursorPos.pos_Line;
  90.  
  91. #define upd(y) if(y >= ypos) y += addy
  92.  
  93.     for(thisvw = (VW *)tx->tx_Views.mlh_Head; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  94.     {
  95.     upd(thisvw->vw_CursorPos.pos_Line);
  96.     upd(thisvw->vw_AutoMark.pos_Line);
  97.     upd(thisvw->vw_Block[0].pos_Line);
  98.     upd(thisvw->vw_Block[1].pos_Line);
  99.     if(thisvw != CurrVW)
  100.     {
  101.         upd(thisvw->vw_StartLine);
  102.     }
  103.     }
  104.     for(thismark = (MARK *)tx->tx_Marks.mlh_Head; thismark->mk_Node.mln_Succ; thismark = (MARK *)thismark->mk_Node.mln_Succ)
  105.     {
  106.     upd(thismark->mk_Pos.pos_Line);
  107.     }
  108.  
  109. #undef upd(y)
  110. }
  111.  
  112. /*
  113.  * Whole lines only please
  114.  */
  115. VOID
  116. keeppossuby(LONG suby)
  117. {
  118.     TX *tx = CurrVW->vw_Tx;
  119.     VW *thisvw;
  120.     MARK *thismark;
  121.     LONG ypos = CurrVW->vw_CursorPos.pos_Line;
  122.  
  123. #define upd(y) if(y > ypos) { if((y -= suby) < ypos) y = ypos; }
  124. #define upd2(x,y) if(y >= ypos) { if((y -= suby) < ypos) {y = ypos; x = 0; }}
  125.  
  126.     for(thisvw = (VW *)tx->tx_Views.mlh_Head; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  127.     {
  128.     upd2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  129.     upd2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_AutoMark.pos_Line);
  130.     upd2(thisvw->vw_Block[0].pos_Col, thisvw->vw_Block[0].pos_Line);
  131.     upd2(thisvw->vw_Block[1].pos_Col, thisvw->vw_Block[1].pos_Line);
  132.     if(thisvw != CurrVW)
  133.     {
  134.         upd(thisvw->vw_StartLine);
  135.     }
  136.     }
  137.     for(thismark = (MARK *)tx->tx_Marks.mlh_Head; thismark->mk_Node.mln_Succ; thismark = (MARK *)thismark->mk_Node.mln_Succ)
  138.     {
  139.     upd2(thismark->mk_Pos.pos_Col, thismark->mk_Pos.pos_Line);
  140.     }
  141.  
  142. #undef upd(y)
  143. #undef upd2(x,y)
  144. }
  145.  
  146. /*
  147.  * Use when splitting a line into 2, cursor should be at position of split
  148.  */
  149. VOID
  150. keeppossplity(VOID)
  151. {
  152.     TX *tx = CurrVW->vw_Tx;
  153.     VW *thisvw;
  154.     MARK *thismark;
  155.     WORD xpos = CurrVW->vw_CursorPos.pos_Col;
  156.     LONG ypos = CurrVW->vw_CursorPos.pos_Line;
  157.  
  158. #define upd(y) if(y > ypos) y++
  159. #define upd2(x,y) if((y == ypos) && (x >= xpos)) { x -= xpos; y++; } else if(y > ypos) y++
  160.  
  161.     for(thisvw = (VW *)tx->tx_Views.mlh_Head; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  162.     {
  163.     upd2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  164.     upd2(thisvw->vw_AutoMark.pos_Col, thisvw->vw_AutoMark.pos_Line);
  165.     upd2(thisvw->vw_Block[0].pos_Col, thisvw->vw_Block[0].pos_Line);
  166.     upd2(thisvw->vw_Block[1].pos_Col, thisvw->vw_Block[1].pos_Line);
  167.     if(thisvw != CurrVW)
  168.     {
  169.         upd(thisvw->vw_StartLine);
  170.     }
  171.     }
  172.     for(thismark = (MARK *)tx->tx_Marks.mlh_Head; thismark->mk_Node.mln_Succ; thismark = (MARK *)thismark->mk_Node.mln_Succ)
  173.     {
  174.     upd2(thismark->mk_Pos.pos_Col, thismark->mk_Pos.pos_Line);
  175.     }
  176.  
  177. #undef upd(y)
  178. #undef upd2(x,y)
  179. }
  180.  
  181. /*
  182.  * Use when compacting 2 adjacent lines into one
  183.  */
  184. VOID
  185. keepposjoiny(VOID)
  186. {
  187.     VW *thisvw = CurrVW;
  188.     TX *tx = thisvw->vw_Tx;
  189.     MARK *thismark;
  190.     LONG ypos = thisvw->vw_CursorPos.pos_Line;
  191.     WORD xpos = thisvw->vw_CursorPos.pos_Col;
  192.  
  193. #define upd(y) if(y > ypos) y--
  194. #define upd2(x,y) if(y > ypos) { if(y == ypos + 1) x += xpos; y--; }
  195.  
  196.     for(thisvw = (VW *)tx->tx_Views.mlh_Head; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  197.     {
  198.     upd2(thisvw->vw_CursorPos.pos_Col, thisvw->vw_CursorPos.pos_Line);
  199.     upd2(thisvw->vw_AutoMark.pos_Col, thisvw->vw_AutoMark.pos_Line);
  200.     upd2(thisvw->vw_Block[0].pos_Col, thisvw->vw_Block[0].pos_Line);
  201.     upd2(thisvw->vw_Block[1].pos_Col, thisvw->vw_Block[1].pos_Line);
  202.     if(thisvw != CurrVW)
  203.     {
  204.         upd(thisvw->vw_StartLine);
  205.     }
  206.     }
  207.     for(thismark = (MARK *)tx->tx_Marks.mlh_Head; thismark->mk_Node.mln_Succ; thismark = (MARK *)thismark->mk_Node.mln_Succ)
  208.     {
  209.     upd2(thismark->mk_Pos.pos_Col, thismark->mk_Pos.pos_Line);
  210.     }
  211.  
  212. #undef upd(y)
  213. #undef upd2(x,y)
  214. }
  215.  
  216. /*
  217.  * These routines are called to recalculate the cursor's position on the
  218.  * screen, they handle all scrolling (vertical and horizontal)
  219.  *
  220.  * refresh() should be called after any of these functions.
  221.  */
  222. VOID
  223. resyncx(VOID)
  224. {
  225.     VW *vw = CurrVW;
  226.  
  227.     while((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) >= vw->vw_MaxX)
  228.     {
  229.     vw->vw_StartCol += vw->vw_XStep;
  230.     vw->vw_RefreshType |= RFF_ALL;
  231.     }
  232.     while(vw->vw_CursorPos.pos_Col < vw->vw_StartCol)
  233.     {
  234.     vw->vw_StartCol -= vw->vw_XStep;
  235.     if(vw->vw_StartCol < 0)
  236.         vw->vw_StartCol = 0;
  237.     vw->vw_RefreshType |= RFF_ALL;
  238.     }
  239. }
  240.  
  241. VOID
  242. resyncy(VOID)
  243. {
  244.     VW *vw = CurrVW;
  245.     WORD y = vw->vw_CursorPos.pos_Line - vw->vw_StartLine;
  246.  
  247.     if(y < 0)
  248.     {
  249.     if((y == -1) && (!(vw->vw_RefreshType & RFF_ALL)) && (!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
  250.     {
  251.         LINE *newline = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
  252.         scrollvwdn();
  253.         pentoline(0);
  254.         drawline(newline, vw->vw_CursorPos.pos_Line);
  255.     }
  256.     else
  257.         vw->vw_RefreshType |= RFF_ALL;
  258.     vw->vw_StartLine = vw->vw_CursorPos.pos_Line;
  259.     }
  260.     else if(y >= vw->vw_MaxY)
  261.     {
  262.     if((y == vw->vw_MaxY) && (!(vw->vw_RefreshType & RFF_ALL)) && (!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
  263.     {
  264.         LINE *newline = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
  265.         scrollvwup();
  266.         pentoline(vw->vw_MaxY - 1);
  267.         drawline(newline, vw->vw_CursorPos.pos_Line);
  268.     }
  269.     else
  270.         vw->vw_RefreshType |= RFF_ALL;
  271.     vw->vw_StartLine = vw->vw_CursorPos.pos_Line - vw->vw_MaxY + 1;
  272.     }
  273. }
  274.  
  275. VOID
  276. resyncxy(VOID)
  277. {
  278.     VW *vw = CurrVW;
  279.     WORD y = vw->vw_CursorPos.pos_Line - vw->vw_StartLine;
  280.  
  281.     while((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) >= vw->vw_MaxX)
  282.     {
  283.     vw->vw_StartCol += vw->vw_XStep;
  284.     vw->vw_RefreshType |= RFF_ALL;
  285.     }
  286.     while(vw->vw_CursorPos.pos_Col < vw->vw_StartCol)
  287.     {
  288.     vw->vw_StartCol -= vw->vw_XStep;
  289.     if(vw->vw_StartCol < 0)
  290.         vw->vw_StartCol = 0;
  291.     vw->vw_RefreshType |= RFF_ALL;
  292.     }
  293.     if(y < 0)
  294.     {
  295.     if((y == -1) && (!(vw->vw_RefreshType & RFF_ALL)) && (!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
  296.     {
  297.         LINE *newline = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
  298.         scrollvwdn();
  299.         pentoline(0);
  300.         drawline(newline, vw->vw_CursorPos.pos_Line);
  301.     }
  302.     else
  303.         vw->vw_RefreshType |= RFF_ALL;
  304.     vw->vw_StartLine = vw->vw_CursorPos.pos_Line;
  305.     }
  306.     else if(y >= vw->vw_MaxY)
  307.     {
  308.     if((y == vw->vw_MaxY) && (!(vw->vw_RefreshType & RFF_ALL)) && (!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
  309.     {
  310.         LINE *newline = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
  311.         scrollvwup();
  312.         pentoline(vw->vw_MaxY - 1);
  313.         drawline(newline, vw->vw_CursorPos.pos_Line);
  314.     }
  315.     else
  316.         vw->vw_RefreshType |= RFF_ALL;
  317.     vw->vw_StartLine = vw->vw_CursorPos.pos_Line - vw->vw_MaxY + 1;
  318.     }
  319. }
  320.  
  321. /*
  322.  * This makes all views of this file have their cursor at the top of the
  323.  * file, it also refreshes each view.
  324.  */
  325. VOID
  326. resetallviews(TX *tx)
  327. {
  328.     VW *thisvw;
  329.     VW *currvw = CurrVW;
  330.     for(thisvw = (VW *)tx->tx_Views.mlh_Head; thisvw->vw_Node.mln_Succ; thisvw = (VW *)thisvw->vw_Node.mln_Succ)
  331.     {
  332.     thisvw->vw_CursorPos.pos_Col = 0;
  333.     thisvw->vw_CursorPos.pos_Line = 0;
  334.     thisvw->vw_StartCol = 0;
  335.     thisvw->vw_StartLine = 0;
  336.     thisvw->vw_AutoMark.pos_Col = 0;
  337.     thisvw->vw_AutoMark.pos_Line = 0;
  338.     thisvw->vw_BlockStatus = -1;
  339.     thisvw->vw_RefreshType |= RFF_ALL;
  340.     thisvw->vw_NonStdTitle = FALSE;
  341.     CurrVW = thisvw;
  342.     stdtitle();
  343.     }
  344.     CurrVW = currvw;
  345.     refreshallviews(tx);
  346. }
  347.  
  348. /*
  349.  * Scrolls the view one line,
  350.  * if there is no block markings on this page a new BitMap is faked --
  351.  * with a depth of 1, this (almost) doubles scrolling speed, thanks to
  352.  * Adriaan van den Brand for this cool idea.
  353.  */
  354. VOID
  355. scrollvwup(VOID)
  356. {
  357.     VW *vw = CurrVW;
  358.     struct RastPort *rp = vw->vw_Rp;
  359.     if(ScrollHack)
  360.     {
  361.     struct BitMap *oldbm = rp->BitMap;
  362.     struct BitMap newbm = *oldbm;
  363.     newbm.Depth = pageinblock() ? 2 : 1;
  364.     rp->BitMap = &newbm;
  365.     ScrollRaster(rp, 0, vw->vw_FontY, vw->vw_XStartPix, vw->vw_YStartPix, vw->vw_XEndPix, vw->vw_YStartPix + (vw->vw_MaxY * vw->vw_FontY) - 1);
  366.     rp->BitMap = oldbm;
  367.     }
  368.     else
  369.     ScrollRaster(rp, 0, vw->vw_FontY, vw->vw_XStartPix, vw->vw_YStartPix, vw->vw_XEndPix, vw->vw_YStartPix + (vw->vw_MaxY * vw->vw_FontY) - 1);
  370. }
  371. VOID
  372. scrollvwdn(VOID)
  373. {
  374.     VW *vw = CurrVW;
  375.     struct RastPort *rp = vw->vw_Rp;
  376.     if(ScrollHack)
  377.     {
  378.     struct BitMap *oldbm = rp->BitMap;
  379.     struct BitMap newbm = *oldbm;
  380.     newbm.Depth = pageinblock() ? 2 : 1;
  381.     rp->BitMap = &newbm;
  382.     ScrollRaster(rp, 0, -vw->vw_FontY, vw->vw_XStartPix, vw->vw_YStartPix, vw->vw_XEndPix, vw->vw_YStartPix + (vw->vw_MaxY * vw->vw_FontY) - 1);
  383.     rp->BitMap = oldbm;
  384.     }
  385.     else
  386.     ScrollRaster(rp, 0, -vw->vw_FontY, vw->vw_XStartPix, vw->vw_YStartPix, vw->vw_XEndPix, vw->vw_YStartPix + (vw->vw_MaxY * vw->vw_FontY) - 1);
  387. }
  388.  
  389.