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

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     $Id: text.c 1.4 1994/09/09 12:31:30 digulla Exp digulla $
  5.  
  6.     HISTORY
  7.     04. Oct 1992    ada created
  8.     $Log: text.c $
  9.  * Revision 1.4  1994/09/09  12:31:30  digulla
  10.  * added new style Prototypes, DEFCMD and DEFHELP
  11.  *
  12.  * Revision 1.3  1994/08/30  11:03:38  digulla
  13.  * used BLOCK_MASK instead of ALL_MASK
  14.  *
  15.  * Revision 1.2  1994/08/19  14:06:00  digulla
  16.  * set all masks to ALL_MASK (SetWrMsk())
  17.  * removed dead assignments
  18.  *
  19.  * Revision 1.1  1994/08/13  16:37:39  digulla
  20.  * Initial revision
  21.  *
  22.  
  23. ******************************************************************************/
  24.  
  25. /**************************************
  26.         Includes
  27. **************************************/
  28. #include "defs.h"
  29.  
  30.  
  31. /**************************************
  32.         Globale Variable
  33. **************************************/
  34.  
  35.  
  36. /**************************************
  37.       Interne Defines & Strukturen
  38. **************************************/
  39.  
  40.  
  41. /**************************************
  42.         Interne Variable
  43. **************************************/
  44.  
  45. struct HNode *TextRoot = NULL;
  46. struct List  *pDBase   = NULL;
  47.  
  48. /**************************************
  49.        Interne Prototypes
  50. **************************************/
  51.  
  52.  
  53. /*****************************************************************************
  54.  
  55.     NAME
  56.     uninit_init
  57.  
  58.     PARAMETER
  59.     ED * ep;
  60.  
  61.     RETURN
  62.     ED * new_ep;
  63.  
  64.     DESCRIPTION
  65.     Resets an editor-struct.
  66.  
  67. ******************************************************************************/
  68.  
  69. Prototype ED * uninit_init (ED * ep);
  70.  
  71. ED * uninit_init (ED * ep)
  72. {
  73.     FONT      * font;
  74.     BPTR        lock   = DupLock (ep->dirlock);
  75.     WIN       * win;
  76.     struct Gadget * gadg;
  77.     int         bufsiz = CONFIG_SIZE;
  78.     char      * buf    = malloc (bufsiz);
  79.  
  80.     /* get buffer for config */
  81.     if (!buf)
  82.     {
  83.     nomemory ();
  84.  
  85. DEFMESSAGE( _out_of_memory, "Out of memory !" )
  86.     warn (_out_of_memory);
  87.  
  88.     return (NULL);
  89.     }
  90.  
  91.     movmem (&ep->beginconfig, buf, bufsiz);
  92.  
  93.     /* remember window, font and gadget */
  94.     win     = ep->win;
  95.     font    = ep->font;
  96.     gadg    = ep->propgad;
  97.     ep->font    = NULL;
  98.  
  99.     /* throw anything away */
  100.     text_uninit ();
  101.  
  102.     /* init editor */
  103.     text_init (Ep, NULL, NULL);
  104.  
  105.     /* switch to new one */
  106.     ep = Ep;
  107.  
  108.     /* close font if there is one */
  109.     if (ep->font)
  110.     CloseFont (ep->font);
  111.  
  112.     /* reset window */
  113.     ep->win  = win;
  114.  
  115.     /* set new font */
  116.     if (ep->font = font)
  117.     {
  118.     SetFont (ep->win->RPort, font);
  119.     set_window_params ();
  120.     }
  121.  
  122.     /* set gadget */
  123.     ep->propgad = gadg;
  124.  
  125.     /* copy config back */
  126.     movmem (buf, &ep->beginconfig, bufsiz);
  127.  
  128.     /* no modifications. Set cursor to beginning */
  129.     SETF_MODIFIED (ep, 0);
  130.     ep->line     = ep->topline = 0;
  131.  
  132.     /* create new lock */
  133.     UnLock (ep->dirlock);
  134.     ep->dirlock = (long)lock;
  135.  
  136.     /* free buffer */
  137.     free (buf);
  138.  
  139.     return (ep);
  140. } /* uninit_init */
  141.  
  142.  
  143. /*****************************************************************************
  144.  
  145.     NAME
  146.     setpen
  147.  
  148.     PARAMETER
  149.     Line line, Column column
  150.  
  151.     RETURN
  152.     same as is_inblock()
  153.  
  154.     DESCRIPTION
  155.     Chooses the correct pen (color) for the given position.
  156.  
  157. ******************************************************************************/
  158.  
  159. /* Return: Same as is_inblock() ! */
  160. Prototype int setpen (Line line, Column column);
  161.  
  162. int setpen (Line line, Column column)
  163. {
  164.     ED    * ep   = Ep;
  165.     RP    * rp   = ep->win->RPort;
  166.     WORD  test;
  167.  
  168.     test = is_inblock (line, column);
  169.  
  170.     if (test & BP_INSIDE)
  171.     {
  172.     SetAPen (rp,  BLOCK_FPEN(ep));
  173.     SetBPen (rp,  BLOCK_BPEN(ep));
  174.     SetWrMsk (rp, BLOCK_MASK(ep));
  175.     } else
  176.     {
  177.     SetAPen (rp,  TEXT_FPEN(ep));
  178.     SetBPen (rp,  TEXT_BPEN(ep));
  179.     SetWrMsk (rp, TEXT_MASK(ep));
  180.     }
  181.  
  182.     return (test);
  183. } /* setpen */
  184.  
  185.  
  186. /*****************************************************************************
  187.  
  188.     NAME
  189.  
  190.     PARAMETER
  191.  
  192.     RETURN
  193.  
  194.     DESCRIPTION
  195.  
  196. ******************************************************************************/
  197.  
  198. Prototype WORD inversemode (int n);
  199.  
  200. WORD inversemode (int n)
  201. {
  202.     RP    * rp = Ep->win->RPort;
  203.     WORD  test;
  204.     UBYTE fgpen;
  205.     UBYTE bgpen;
  206.  
  207.     test = setpen (Ep->line, Ep->column);
  208.  
  209.     if (n)
  210.     {
  211.     fgpen = ~rp->FgPen;
  212.     bgpen = ~rp->BgPen;
  213.  
  214.     SetAPen (rp, bgpen);
  215.     SetBPen (rp, fgpen);
  216.     SetDrMd (rp, JAM2|INVERSVID);
  217.     } else
  218.     SetDrMd (rp, JAM2);
  219.  
  220.     SetWrMsk (rp, ALL_MASK);
  221.  
  222.     return ((WORD)(test & BP_INSIDE));
  223. } /* inversemode */
  224.  
  225.  
  226. /*****************************************************************************
  227.  
  228.     NAME
  229.  
  230.     PARAMETER
  231.  
  232.     RETURN
  233.  
  234.     DESCRIPTION
  235.  
  236. ******************************************************************************/
  237.  
  238. Prototype int text_init (ED * oldep, WIN * win, struct NewWindow * nw);
  239.  
  240. int text_init (ED * oldep, WIN * win, struct NewWindow * nw)
  241. {
  242.     ED * ep;
  243.  
  244.     if (!(ep = (ED *)allocb (sizeof(ED))) )
  245.     return (0);
  246.  
  247.     setmem (ep, sizeof(ED), 0);
  248.     ep->win = win;
  249.  
  250.     if (oldep)
  251.     {
  252.     ep->dirlock = (long)DupLock (oldep->dirlock);
  253.  
  254.     movmem (&oldep->beginconfig, &ep->beginconfig, CONFIG_SIZE);
  255.  
  256.     if (oldep->font)
  257.     {
  258.         ep->font = oldep->font;
  259.         ep->font->tf_Accessors ++;
  260.  
  261.         if (win)
  262.         SetFont (win->RPort, ep->font);
  263.     }
  264.  
  265.     /* change oldep to "last editor" to have the iconified window
  266.        positioned right */
  267.     oldep = GetTail ((LIST *)&DBase);
  268.  
  269.     if (GETF_ICONMODE(oldep))
  270.     {
  271.         ep->config.iwinx = oldep->win->LeftEdge;
  272.         ep->config.iwiny = oldep->win->TopEdge;
  273.     } else
  274.     {
  275.         ep->config.iwinx = oldep->config.iwinx;
  276.         ep->config.iwiny = oldep->config.iwiny;
  277.     }
  278.  
  279.     ep->config.iwinx += TextLength (oldep->win->RPort, oldep->name,
  280.                 strlen (oldep->name)) + 60;
  281.  
  282.     if (ep->config.iwinx > oldep->win->WScreen->Width)
  283.     {
  284.         ep->config.iwinx = 0;
  285.  
  286.         if(Ep->win->WScreen->Font != NULL)
  287.         /* height */
  288.         ep->config.iwiny += oldep->win->WScreen->Font->ta_YSize + 3;
  289.         else
  290.         ep->config.iwiny += GfxBase->DefaultFont->tf_YSize + 3;
  291.     }
  292.     }
  293.     else
  294.     {
  295.     PROC * proc = (PROC *)FindTask (NULL);
  296.  
  297.     ep->dirlock = (long)DupLock (proc->pr_CurrentDir);
  298.  
  299.     loadconfig (ep);
  300.     }
  301.  
  302.     ep->lines      = 1;
  303.     ep->maxlines  = 32;
  304.     ep->list      = (UBYTE **)alloclptr (ep->maxlines);
  305.     SETLINE(ep,0,allocline (1));
  306.  
  307.     Current[0] = Clen = 0;
  308.  
  309. DEFMESSAGE( __unnamed, "unnamed" )
  310.     strcpy ((char *)ep->name, __unnamed);
  311.  
  312.     ep->node.Name  = ep->name;
  313.     ep->node.Flags = HLF_SYSNODE /* | HLF_TREE */;
  314.     ep->node.Parent= TextRoot;
  315.     HL_LockSubs (TextRoot);
  316.     AddTail ((LIST *)&DBase, (NODE *)ep);
  317.     HL_UnlockSubs (TextRoot);
  318.     //HL_Init (&ep->Node, ep->Name, TextRoot, HLF_SYSNODE);
  319.  
  320.     ep->keytable  = currenthash ();
  321.     ep->menustrip = currentmenu ();
  322.  
  323.     Ep = ep;    /* no switch_ed() here ! */
  324.  
  325.     strcpy (ep->wtitle, "  OK  ");
  326.  
  327.     if (win)
  328.     text_cursor (1);
  329.  
  330.     if (nw)
  331.     {
  332.     if (!GETF_ICONMODE(ep) && ep->win)
  333.     {
  334.         nw->LeftEdge = ep->win->LeftEdge;
  335.         nw->TopEdge  = ep->win->TopEdge;
  336.         nw->Width     = ep->win->Width;
  337.         nw->Height     = ep->win->Height;
  338.     } else
  339.     {
  340.         if (ep->config.winwidth && ep->config.winheight)
  341.         {
  342.         nw->LeftEdge = ep->config.winx;
  343.         nw->TopEdge  = ep->config.winy;
  344.         nw->Width    = ep->config.winwidth;
  345.         nw->Height   = ep->config.winheight;
  346.         } else
  347.         {
  348.         nw->LeftEdge = 0;
  349.         nw->TopEdge  = 0;
  350.         nw->Width    = 640;
  351.         nw->Height   = 200;
  352.         }
  353.     }
  354.  
  355.     nw->DetailPen = TEXT_BPEN(ep);
  356.     nw->BlockPen  = TEXT_FPEN(ep);
  357.     }
  358.  
  359.     return (1);
  360. } /* text_init */
  361.  
  362.  
  363. /*****************************************************************************
  364.  
  365.     NAME
  366.     text_switch
  367.  
  368.     PARAMETER
  369.     WIN * win;        The window to switch to.
  370.  
  371.     RETURN
  372.     BOOL found;        Was the change successful ?
  373.  
  374.     DESCRIPTION
  375.     Searches for the specified window and makes the editor with that
  376.     window active.
  377.  
  378. ******************************************************************************/
  379.  
  380. Prototype BOOL text_switch (WIN * win);
  381.  
  382. BOOL text_switch (WIN * win)
  383. {
  384.     ED * ep;
  385.  
  386.     /* look for that window */
  387.  
  388.     for (ep=(ED *)GetHead(&DBase); ep; ep=(ED *)GetSucc((struct Node *)ep))
  389.     {
  390.     if (ep->win == win)
  391.         break;
  392.     }
  393.  
  394.     return (switch_ed (ep));
  395. } /* text_switch */
  396.  
  397.  
  398. /*****************************************************************************
  399.  
  400.     NAME
  401.     text_sync
  402.  
  403.     PARAMETER
  404.     void
  405.  
  406.     RETURN
  407.     BOOL redraw;        Did text_sync() a screen-refresh ?
  408.  
  409.     DESCRIPTION
  410.     copy current line to list of lines and say, if screen-update
  411.     is neccessary. Furthermore, Current is filled with spaces upto
  412.     the current column.
  413.  
  414. ******************************************************************************/
  415.  
  416. Prototype BOOL text_sync (void);
  417.  
  418. BOOL text_sync (void)
  419. {
  420.     ED      * ep       = Ep;
  421. //    char    redraw = 0;
  422.     WORD    len;
  423.     UBYTE * ptr;
  424.     UBYTE * line;
  425.  
  426.     /* remove trailing spaces */
  427.     len = strlen ((char *)Current)-1;
  428.     ptr = Current + len;
  429.  
  430.     if (!GETF_SLINE (ep)) /* preserve line length in shortline mode */
  431.     {
  432.     while (len && *ptr == ' ')
  433.     {
  434.         len --;
  435.         ptr --;
  436.     }
  437.  
  438.     if (*ptr == ' ')
  439.         *ptr = 0;
  440.     else
  441.     {
  442.         ptr[1] = 0;
  443.         len ++;
  444.     }
  445.     }
  446.     else        /* BUGFIX 25-09-94 */
  447.     ++len;        /* BUGFIX 25-09-94 */
  448.  
  449.     /* Line length */
  450.     Clen = len;
  451.  
  452.     if (!GETF_COMLINEMODE(Ep))
  453.     {
  454.     WORD  len_in_blocks, clen_in_blocks;
  455.  
  456.     line = GETTEXT(ep,ep->line);
  457.     len = strlen ((char *)line);
  458.  
  459.     /* Find out how many blocks (*8) we use and how many we need */
  460.     len_in_blocks  =  (len + 8) & ~7;
  461.     clen_in_blocks = (Clen + 8) & ~7;
  462.  
  463.     /* This was highly wasting memory. OS is always padding Alloc's
  464.        to 8 Bytes. If the length of the line is still within one
  465.        block but has changed we freed and allocated new memory.
  466.        This guranteed to fragment memory.
  467.  
  468.        Just use the old version and edit some large text. Use avail,
  469.        save & reload text and "avail" again. The you'll see what I mean.
  470.        This is fixed now. */
  471.  
  472.     /* I must not use strcpy() if the line was empty since empty
  473.        lines are handled differently, i.e. they use static memory.
  474.        Only allocate new, if the line was empty or if the size in
  475.        blocks has changed, i.e. we need one more or less block of
  476.        memory (see AllocMem() in Amiga-ROM-Kernel-Ref.-Manual about
  477.        blocks). */
  478.     if ((!len && Clen) || len_in_blocks != clen_in_blocks)
  479.     {
  480.         if (ptr = allocline(Clen+1))
  481.         {
  482.  
  483. #ifdef DEBUG_MEM_H
  484.     printf ("Allocated at %08x\n", ptr);
  485. #endif
  486.  
  487.         SETF_MODIFIED(ep,1);
  488.         SETF_OVERIDE(ep,0);
  489.  
  490.         freeline (line);
  491.         SETLINE(ep,ep->line,(LINE)ptr);
  492.  
  493.         strcpy ((char *)ptr, (char *)Current);
  494.         } else
  495.         {
  496.         nomemory ();
  497.         strcpy ((char *)Current, (char *)line);
  498.         }
  499.     } else
  500.     { /* Within one block ... */
  501.         UBYTE * ptr1, * ptr2;
  502.  
  503.         ptr1 = line;
  504.         ptr2 = Current;
  505.  
  506.         /* We need not to copy stuff that's equal ! */
  507.         while (*ptr1 == *ptr2)
  508.         {
  509.         if (!*ptr1)
  510.             break;
  511.  
  512.         ptr1 ++;
  513.         ptr2 ++;
  514.         }
  515.  
  516.         if (*ptr1 != *ptr2)
  517.         {
  518.         SETF_MODIFIED(ep,1);
  519.         SETF_OVERIDE(ep,0);
  520.  
  521. /*printf ("Lines \nOld `%s'\nNew `%s'\ndiffer at\n%s\n%s", line, Current, ptr1, ptr2); */
  522.  
  523.         strcpy ((char *)ptr1, (char *)ptr2);
  524. /*printf ("New Line `%s'\n", line);*/
  525.         } /* Any changes ? */
  526.     } /* Old block length != new block length */
  527.     } /* if (!Comlinemode) */
  528.  
  529. error:
  530.     return ((BOOL)text_adjust (FALSE));
  531. } /* text_sync */
  532.  
  533.  
  534. /*****************************************************************************
  535.  
  536.     NAME
  537.     text_adjust
  538.  
  539.     PARAMETER
  540.     BOOL force;        TRUE: Redraw screen even if the cursor
  541.                       is visible.
  542.                 FALSE: Draw only, if cursor is not visible.
  543.  
  544.     RETURN
  545.     BOOL did_redraw;
  546.  
  547.     DESCRIPTION
  548.     Make sure the current cursor position is visible.
  549.  
  550. ******************************************************************************/
  551.  
  552. Prototype BOOL text_adjust (BOOL force);
  553.  
  554. BOOL text_adjust (BOOL force)
  555. {
  556.     if (!Nsu)
  557.     {
  558.     if (Ep->column - Ep->topcolumn >= Columns || Ep->column < Ep->topcolumn)
  559.     {
  560.         force = 1;
  561.  
  562.         Ep->topcolumn = Ep->column - (Columns>>1);
  563.  
  564.         if (Ep->topcolumn < 0)
  565.         Ep->topcolumn = 0;
  566.     }
  567.  
  568.     if (Ep->line - Ep->topline >= Lines || Ep->line < Ep->topline)
  569.     {
  570.         force = 1;
  571.  
  572.         Ep->topline = Ep->line - (Lines>>1);
  573.  
  574.         if (Ep->topline < 0)
  575.         Ep->topline = 0;
  576.     }
  577.  
  578.     /* need I redraw ?? */
  579.     if (force)
  580.         text_redisplay ();
  581.     }
  582.  
  583.     /* pad line with spaces upto cursor */
  584.     while (Ep->column > Clen)
  585.     Current[Clen++] = ' ';
  586.  
  587.     Current[Clen] = '\0';
  588.  
  589.     return (force);
  590. } /* text_adjust */
  591.  
  592.  
  593. /*****************************************************************************
  594.  
  595.     NAME
  596.     text_load
  597.  
  598.     PARAMETER
  599.     void
  600.  
  601.     RETURN
  602.     void
  603.  
  604.     DESCRIPTION
  605.     Load current line into Current. Current is padded with spaces
  606.     if the cursor is to the left.
  607.  
  608. ******************************************************************************/
  609.  
  610. Prototype void text_load (void);
  611.  
  612. void text_load (void)
  613. {
  614.     if (GETF_COMLINEMODE(Ep))
  615.     return;
  616.  
  617.     strcpy ((char *)Current, GETTEXT(Ep,Ep->line));
  618.  
  619.     Clen = strlen ((char *)Current);
  620.  
  621.     if (GETF_SLINE(Ep) && (Ep->column > Clen))
  622.     Ep->column = Clen;
  623.  
  624.     while (Ep->column > Clen)
  625.     Current[Clen++] = ' ';
  626.  
  627.     Current[Clen] = '\0';
  628. } /* text_load */
  629.  
  630.  
  631. Prototype int text_colno (void);
  632.  
  633. int text_colno (void)
  634. {
  635.     return((int)Ep->column);
  636. } /* text_colno */
  637.  
  638.  
  639. Prototype int text_lineno (void);
  640.  
  641. int text_lineno (void)
  642. {
  643.     return((int)Ep->line+1);
  644. } /* text_lineno */
  645.  
  646.  
  647. Prototype int text_lines (void);
  648.  
  649. int text_lines (void)
  650. {
  651.     return((int)Ep->lines);
  652. } /* text_lines */
  653.  
  654.  
  655. Prototype int text_cols (void);
  656.  
  657. int text_cols (void)
  658. {
  659.     return((int)Clen);
  660. } /* text_cols */
  661.  
  662.  
  663. Prototype int text_imode (void);
  664.  
  665. int text_imode (void)
  666. {
  667.     return ((int)GETF_INSERTMODE(Ep));
  668. } /* text_imode */
  669.  
  670.  
  671. Prototype int text_tabsize (void);
  672.  
  673. int text_tabsize (void)
  674. {
  675.     return((int)Ep->config.tabstop);
  676. } /* text_tabsize */
  677.  
  678.  
  679. Prototype UBYTE * text_name (void);
  680.  
  681. UBYTE * text_name (void)
  682. {
  683.     return(Ep->name);
  684. } /* text_name */
  685.  
  686.  
  687. /*****************************************************************************
  688.  
  689.     NAME
  690.  
  691.     PARAMETER
  692.  
  693.     RETURN
  694.  
  695.     DESCRIPTION
  696.  
  697. ******************************************************************************/
  698.  
  699. Prototype void text_uninit (void);
  700.  
  701. void text_uninit (void)
  702. {
  703.     ED * ep = Ep;
  704.  
  705.     if (ep)
  706.     {
  707.     markerkill  (ep);
  708.     check_stack (ep);
  709.     VSTK_CloseProject (ep); /* PATCH_NULL 10 Nov 1994 - added */
  710.  
  711.  
  712.     freelist (ep->list, ep->lines);
  713.     FreeMem (ep->list, ep->maxlines * sizeof(LINE));
  714.  
  715.     DelAllVarsFromTree((void **)&ep->textvars); /* PATCH_NULL: local vars have to be freed */
  716.  
  717.     if (ActualBlock.ep == ep)
  718.         unblock ();
  719.  
  720.     HL_LockSubs (TextRoot);
  721.     Remove ((NODE *)ep);
  722.     HL_UnlockSubs (TextRoot);
  723.     //HL_Uninit (&ep->Node);
  724.  
  725.     if (ep->font)
  726.     {
  727.         SetFont (ep->win->RPort, ep->win->WScreen->RastPort.Font);
  728.         CloseFont (ep->font);
  729.     }
  730.  
  731.     UnLock (ep->dirlock);
  732.     FreeMem (ep, sizeof(ED));
  733.  
  734.     if (ep = (ED *)GetHead (&DBase))
  735.     {
  736.         Ep = NULL;
  737.  
  738.         switch_ed (ep);
  739.  
  740.         text_load ();
  741.     } else
  742.         Ep = NULL;
  743.     }
  744. } /* text_uninit */
  745.  
  746.  
  747. /*****************************************************************************
  748.  
  749.     NAME
  750.  
  751.     PARAMETER
  752.  
  753.     RETURN
  754.  
  755.     DESCRIPTION
  756.  
  757. ******************************************************************************/
  758.  
  759. Prototype void text_cursor (int n);
  760.  
  761. void text_cursor (int n)
  762. {
  763.     ED    * ep   = Ep;
  764.     RP    * rp   = ep->win->RPort;
  765.  
  766.     if (GETF_ICONMODE(Ep) || Nsu)
  767.     return;
  768.  
  769.     movetocursor ();
  770.     inversemode (n);
  771.  
  772.     if (Current[ep->column])
  773.     {
  774.     Text (rp, Current + ep->column, 1);
  775.     } else
  776.     {
  777.     Text (rp, (STRPTR)" ", 1);
  778.     }
  779.  
  780.     if (n && GETF_FOLLOWCURSOR(Ep))
  781.     do_makecursorvisible ();
  782.  
  783.     inversemode (0);
  784.  
  785. } /* text_cursor */
  786.  
  787.  
  788. /*****************************************************************************
  789.  
  790.     NAME
  791.  
  792.     PARAMETER
  793.  
  794.     RETURN
  795.  
  796.     DESCRIPTION
  797.  
  798. ******************************************************************************/
  799.  
  800. Prototype void text_position (int col, int row);
  801.  
  802. void text_position (int col, int row)
  803. {
  804.     ED    * ep     = Ep;
  805.     WORD  column,
  806.       line;
  807.  
  808.     text_sync ();
  809.  
  810.     column = ep->topcolumn + col;
  811.  
  812.     if (column > MAXLINELEN-1)
  813.     column = MAXLINELEN-1;
  814.  
  815.     if (column < 0)
  816.     column = 0;
  817.  
  818.     line = ep->topline + row;
  819.  
  820.     if (line >= ep->lines)
  821.     line = ep->lines - 1;
  822.  
  823.     if (line < 0)
  824.     line = 0;
  825.  
  826.     ep->column = column;
  827.     ep->line = line;
  828.  
  829.     text_load ();
  830.     text_adjust (FALSE);
  831. } /* text_position */
  832.  
  833.  
  834. /*****************************************************************************
  835.  
  836.     NAME
  837.     text_displayseg
  838.  
  839.     PARAMETER
  840.     int start;
  841.     int lines;
  842.  
  843.     RETURN
  844.     void
  845.  
  846.     DESCRIPTION
  847.  
  848. ******************************************************************************/
  849.  
  850. Prototype void text_displayseg (int start, int lines);
  851.  
  852. void text_displayseg (int start, int lines)
  853. {
  854.     ED * ep = Ep;
  855.  
  856.     if (Nsu || GETF_ICONMODE(ep)) return;
  857.  
  858.     if (GETF_COMLINEMODE(Ep))
  859.     {
  860.     text_redraw_cmdline ();
  861.     } else
  862.     {
  863.     Line   start_line;
  864.  
  865.     start_line = start + ep->topline;
  866.  
  867.     redraw_block (TRUE, start_line, ep->topcolumn,
  868.             start_line + lines-1, ep->topcolumn + Columns-1);
  869.  
  870.     prop_adj ();
  871.     } /* !Comlinemode */
  872. } /* text_displayseg */
  873.  
  874.  
  875. /*****************************************************************************
  876.  
  877.     NAME
  878.     text_redraw_cmdline
  879.  
  880.     PARAMETER
  881.     void
  882.  
  883.     RETURN
  884.     void
  885.  
  886.     DESCRIPTION
  887.  
  888. ******************************************************************************/
  889.  
  890. Prototype void text_redraw_cmdline (void);
  891.  
  892. void text_redraw_cmdline (void)
  893. {
  894.     RP * rp = Ep->win->RPort;
  895.     int  len;
  896.     int  topline = Ep->line - Ep->topline;
  897.  
  898.     /* Clear back */
  899.     SetAPen  (rp, TEXT_BPEN(Ep));
  900.     SetWrMsk (rp, BLOCK_MASK(Ep));
  901.     RectFill (rp, Xbase, ROW(topline), Xpixs, Ypixs);
  902.  
  903.     /* Write text */
  904.     SetAPen (rp, TEXT_FPEN(Ep));
  905.     SetBPen (rp, TEXT_BPEN(Ep));
  906.  
  907.     len = Clen - Ep->topcolumn;
  908.  
  909.     if (len > 0)
  910.     {
  911.     Move (rp, XTbase, ROWT(topline));
  912.     Text (rp, Current + Ep->topcolumn, (len > Columns) ? Columns : len);
  913.     }
  914.  
  915.     SetWrMsk (rp, ALL_MASK);
  916. } /* text_redraw_cmdline */
  917.  
  918.  
  919. /*****************************************************************************
  920.  
  921.     NAME
  922.     do_redisplay
  923.  
  924.     PARAMETER
  925.     void
  926.  
  927.     RETURN
  928.        void
  929.  
  930.     DESCRIPTION
  931.  
  932. ******************************************************************************/
  933.  
  934. /*DEFHELP #cmd win,misc REDISPLAY - force XDME to redraw the text */
  935.  
  936. DEFUSERCMD("redisplay", 0, CF_VWM, void, do_redisplay, (void),)
  937. {
  938.     text_adjust (TRUE);
  939. } /* do_redisplay */
  940.  
  941.  
  942. /*****************************************************************************
  943.  
  944.     NAME
  945.     text_redisplay
  946.  
  947.     PARAMETER
  948.     void
  949.  
  950.     RETURN
  951.     void
  952.  
  953.     DESCRIPTION
  954.  
  955. ******************************************************************************/
  956.  
  957. Prototype void text_redisplay (void);
  958.  
  959. void text_redisplay (void)
  960. {
  961.     ED * ep = Ep;
  962.     RP * rp = ep->win->RPort;
  963.  
  964.     if (!Nsu)
  965.     {
  966.     if (!GETF_COMLINEMODE(Ep))
  967.     {
  968.         SetAPen (rp, TEXT_BPEN(ep));
  969.         SetWrMsk (rp, ALL_MASK);
  970.  
  971.         RectFill (rp, Xbase, Ybase, Xpixs, Ypixs);
  972.     }
  973.  
  974.     text_displayseg (0, Lines);
  975.     }
  976. } /* text_redisplay */
  977.  
  978.  
  979. /*****************************************************************************
  980.  
  981.     NAME
  982.     text_redisplaycurrline
  983.  
  984.     PARAMETER
  985.     void
  986.  
  987.     RETURN
  988.     void
  989.  
  990.     DESCRIPTION
  991.     Redrenders the current line.
  992.  
  993. ******************************************************************************/
  994.  
  995. Prototype void text_redisplaycurrline (void);
  996.  
  997. void text_redisplaycurrline (void)
  998. {
  999.     ED * ep  = Ep;
  1000.     RP * rp  = ep->win->RPort;
  1001.     int  row = ep->line - ep->topline;
  1002.  
  1003.     if (!Nsu)
  1004.     {
  1005.     if (GETF_COMLINEMODE(Ep))
  1006.     {
  1007.         text_displayseg (0, Lines);
  1008.     } else {
  1009.         SetAPen (rp, TEXT_BPEN(ep));
  1010.         SetWrMsk (rp, ALL_MASK);
  1011.         RectFill (rp, Xbase, ROW(row), Xpixs, ROW(row+1)-1);
  1012.  
  1013.         redraw_block (TRUE, ep->line, ep->topcolumn, ep->line,
  1014.             ep->topcolumn + Columns - 1);
  1015.     }
  1016.     }
  1017. } /* text_redisplaycurrline */
  1018.  
  1019.  
  1020. /*****************************************************************************
  1021.  
  1022.     NAME
  1023.     text_write
  1024.  
  1025.     PARAMETER
  1026.     UBYTE * str;
  1027.  
  1028.     RETURN
  1029.     void
  1030.  
  1031.     DESCRIPTION
  1032.     Inserts the string str into the text.
  1033.  
  1034. ******************************************************************************/
  1035.  
  1036. Prototype void text_write (UBYTE * str);
  1037.  
  1038. void text_write (UBYTE * str)
  1039. {
  1040.     WORD  len = strlen ((char *)str);
  1041.     WORD  i;
  1042.     ED    * ep  = Ep;
  1043.     RP    * rp  = ep->win->RPort;
  1044.  
  1045.     if (Clen + len >= MAXLINELEN-1)
  1046.     {
  1047.     text_sync ();
  1048.     text_load ();
  1049.     }
  1050.  
  1051.     if (!GETF_INSERTMODE(ep))
  1052.     {
  1053.     UWORD line, column_start, column_end;
  1054.  
  1055.     if (ep->column + len >= MAXLINELEN-1)
  1056.         goto fail;
  1057.  
  1058.     movmem (str, Current + ep->column, len);
  1059.  
  1060.     /* clear area */
  1061.     line = ep->line - ep->topline;
  1062.     column_start = ep->column - ep->topcolumn;
  1063.     column_end = column_start + len;
  1064.  
  1065.     /* only draw, if we need to (otherwise the screen is refreshed !) */
  1066.     if (column_end < Columns)
  1067.     {
  1068.         SetAPen (rp, TEXT_BPEN(ep));
  1069.         SetWrMsk (rp, TEXT_MASK(ep));       /* don't write over block */
  1070.  
  1071.         /* clear area */
  1072.         RectFill (rp, COL(column_start), ROW(line),
  1073.             COL(column_end)-1, ROW(line+1)-1);
  1074.  
  1075.         /* refresh block */
  1076.         redraw_block (TRUE, ep->line, ep->column, ep->line,
  1077.                 ep->column + len - 1);
  1078.  
  1079.         setpen (ep->line, ep->column);
  1080.     }
  1081.  
  1082.     if (ep->column + len >= Clen)
  1083.         Clen = ep->column + len;
  1084.  
  1085.     Current[Clen] = 0;
  1086.     } else
  1087.     {
  1088.     if (Clen + len >= MAXLINELEN-1)
  1089.         goto fail;
  1090.  
  1091.     movmem (Current + ep->column, Current + ep->column + len,
  1092.         Clen+1-ep->column);
  1093.     movmem (str, Current + ep->column, len);
  1094.     Clen += len;
  1095.  
  1096.     if (len < Columns - (ep->column - ep->topcolumn))
  1097.     {
  1098.         i = ep->line - ep->topline;
  1099.  
  1100.         setpen (ep->line, ep->column);
  1101.  
  1102.         ScrollRaster (rp, -len * Xsize, 0 ,
  1103.         COL(ep->column - ep->topcolumn),
  1104.         ROW(i),
  1105.         Xpixs,
  1106.         ROW(i + 1) - 1);
  1107.  
  1108.         if (Ep->win->WLayer->Flags & LAYERREFRESH)
  1109.         OptimizedRefresh (Ep);
  1110.     }
  1111.  
  1112.     /* update block */
  1113.     if (ActualBlock.type == BT_NORMAL &&
  1114.         (is_inblock (ep->line, ep->column) & BP_INSIDE))
  1115.         set_block_end (NO_CHANGE, ActualBlock.end_column + len);
  1116.     }
  1117.  
  1118.     i = ep->column;
  1119.     redraw_lineseg (Current, ROWT(ep->line - ep->topline), i, i+len);
  1120.  
  1121.     ep->column += len;
  1122.  
  1123.     if (ep->column - ep->topcolumn >= Columns)
  1124.     {
  1125.     text_sync ();
  1126.     text_adjust (FALSE);
  1127.     }
  1128.  
  1129. fail:
  1130.     if (!GETF_COMLINEMODE(ep))
  1131.     {
  1132.     if (GETF_WORDWRAP(ep))
  1133.         do_reformat(0);
  1134.     else if (GETF_AUTOSPLIT(ep))
  1135.     {
  1136.         WORD  thislen;        /* Length of this line */
  1137. //          WORD  nextlen;          /* Length of next line */
  1138.         WORD  wordlen;        /* Length of word */
  1139.         char * ptr;
  1140.  
  1141.         /* Check if we have to break */
  1142.         thislen = strlen ((char *)Current);
  1143.  
  1144.         if (thislen > ep->config.margin && ep->column == thislen)
  1145.         {
  1146.         /* Well, lets start.
  1147.            This algorithm is very simple for now. It does work only,
  1148.            when the cursor is the end of the line and copies the last
  1149.            word in the next line.
  1150.         */
  1151.         wordlen = thislen - 1;
  1152.         ptr = (char *)Current + wordlen;
  1153.  
  1154.         while (*ptr != ' ' && wordlen)
  1155.         {
  1156.             ptr --;
  1157.             wordlen --;
  1158.         }
  1159.  
  1160.         /* If we found a space, we are 1 char wrong */
  1161.         if (wordlen)
  1162.         {
  1163.             /* ptr ++ dead assign */
  1164.             wordlen ++;
  1165.         }
  1166.  
  1167.         /* Calc. length of last word */
  1168.         wordlen = thislen - wordlen;
  1169.  
  1170.         /* Do nothing if this word won't fit in the next line */
  1171.         if (wordlen < ep->config.margin)
  1172.         {
  1173.             /* Set cursor at the beginning of the word,
  1174.                split line there, go down and go to last
  1175.                char in this line. */
  1176.             ep->column -= wordlen;
  1177.             do_split ();
  1178.             do_down ();
  1179.             do_lastcolumn ();
  1180.         } /* if does word fit */
  1181.         } /* if "Do we have to split ?" */
  1182.     } /* if Autosplit */
  1183.     } /* if !Comlinemode */
  1184.  
  1185.     SetWrMsk (rp, ALL_MASK);
  1186. } /* text_write */
  1187.  
  1188.  
  1189. /*****************************************************************************
  1190.  
  1191.     NAME
  1192.     text_redrawblock
  1193.  
  1194.     PARAMETER
  1195.     BOOL on;    Turn block on (TRUE) or off (FALSE)
  1196.  
  1197.     RETURN
  1198.     void
  1199.  
  1200.     DESCRIPTION
  1201.     Redraw the block.
  1202.  
  1203. ******************************************************************************/
  1204.  
  1205. Prototype void text_redrawblock (BOOL on);
  1206.  
  1207. void text_redrawblock (BOOL on)
  1208. {
  1209.     ED * saveed = NULL;
  1210.  
  1211.     /* if there is a block that belongs to an editor */
  1212.  
  1213.     if (ActualBlock.ep)
  1214.     {
  1215.     /* change the actual editor, if the editor the block is in and the
  1216.        actual one are not the same */
  1217.  
  1218.     if (ActualBlock.ep != Ep)
  1219.     {
  1220.         saveed = Ep;
  1221.         switch_ed (ActualBlock.ep);
  1222.     }
  1223.  
  1224.     /* redraw the block */
  1225.  
  1226.     displayblock (on);
  1227.  
  1228.     /* if we changed the editor, undo it */
  1229.  
  1230.     if (saveed)
  1231.         switch_ed (saveed);
  1232.     } else if (!on)
  1233.     {
  1234.     /* if we want to turn the block off, do it here */
  1235.  
  1236.     unblock ();
  1237.     }
  1238. } /* text_redrawblock */
  1239.  
  1240.  
  1241. /*****************************************************************************
  1242.  
  1243.     NAME
  1244.     redraw_text
  1245.  
  1246.     PARAMETER
  1247.     Line start_line;    Line to start with
  1248.     Line end_line;        Line to end in (not included)
  1249.  
  1250.     RETURN
  1251.     void
  1252.  
  1253.     DESCRIPTION
  1254.     Redraws some lines of text. Only the start-line is included in the
  1255.     update.
  1256.  
  1257. ******************************************************************************/
  1258.  
  1259. Prototype void redraw_text (Line start_line, Line end_line);
  1260.  
  1261. void redraw_text (Line start_line, Line end_line)
  1262. {
  1263.     if (start_line < Ep->topline)
  1264.     start_line = Ep->topline;
  1265.  
  1266.     if (end_line > Ep->topline + Lines)
  1267.     end_line = Ep->topline + Lines;
  1268.     if (end_line > Ep->lines)
  1269.     end_line = Ep->lines;
  1270.  
  1271.     for ( ; start_line < end_line; start_line ++)
  1272.     redraw_textline (Ep, start_line);
  1273. } /* redraw_text */
  1274.  
  1275.  
  1276. /*****************************************************************************
  1277.  
  1278.     NAME
  1279.     redraw_textline
  1280.  
  1281.     PARAMETER
  1282.     Line line;
  1283.  
  1284.     RETURN
  1285.     void
  1286.  
  1287.     DESCRIPTION
  1288.     Redraws one complete lines of text.
  1289.  
  1290.     NOTES
  1291.     - line must be a valid line from the text.
  1292.     - THIS IS A MACRO !
  1293.  
  1294. ******************************************************************************/
  1295.  
  1296.  
  1297. /*****************************************************************************
  1298.  
  1299.     NAME
  1300.     redraw_textlineseg
  1301.  
  1302.     PARAMETER
  1303.     Line   line;        The line
  1304.     Column start_column;    The column to start in
  1305.     Column end_column;    The column to end with (not included)
  1306.  
  1307.     RETURN
  1308.     void
  1309.  
  1310.     DESCRIPTION
  1311.     Redraws part of a lines in the text. We redraw all text between
  1312.     start_column and end_column including only the former.
  1313.  
  1314.     NOTE
  1315.     If used to update text that traverses a block-border, the colors
  1316.     of the drawn text will be wrong.
  1317.  
  1318. ******************************************************************************/
  1319.  
  1320. Prototype void redraw_textlineseg (Line line, Column start_column, Column end_column);
  1321.  
  1322. void redraw_textlineseg (Line line, Column start_column, Column end_column)
  1323. {
  1324.     setpen (line, start_column);
  1325.  
  1326.     if (line == Ep->line)
  1327.     redraw_lineseg (Current, ROWT(line - Ep->topline),
  1328.         start_column, end_column);
  1329.     else
  1330.     redraw_lineseg (GETTEXT(Ep,line), ROWT(line - Ep->topline),
  1331.         start_column, end_column);
  1332. } /* redraw_textlineseg */
  1333.  
  1334.  
  1335. /*****************************************************************************
  1336.  
  1337.     NAME
  1338.     redraw_lineseg
  1339.  
  1340.     PARAMETER
  1341.     UBYTE * text;        The contents of the line
  1342.     UWORD  y;           y-position to draw at
  1343.     Column    start_column;    The column to start in
  1344.     Column    end_column;    The column to end with (not included)
  1345.  
  1346.     RETURN
  1347.     void
  1348.  
  1349.     DESCRIPTION
  1350.     Redraws part of a lines in the text. We redraw all text between
  1351.     start_column and end_column including only the former.
  1352.  
  1353. ******************************************************************************/
  1354.  
  1355. Prototype void redraw_lineseg (UBYTE * text, UWORD y, Column start_column, Column end_column);
  1356.  
  1357. void redraw_lineseg (UBYTE * text, UWORD y, Column start_column, Column end_column)
  1358. {
  1359.     RP *   rp         = Ep->win->RPort;
  1360.     int    len;
  1361.  
  1362.     if (Nsu) return;
  1363.  
  1364.     /* start-column visible ? */
  1365.  
  1366.     if (start_column < Ep->topcolumn)
  1367.     start_column = Ep->topcolumn;
  1368.  
  1369.     /* end-column visible ? */
  1370.  
  1371.     if (end_column > Ep->topcolumn + Columns)
  1372.     end_column = Ep->topcolumn + Columns;
  1373.  
  1374.     /* outside screen ? */
  1375.  
  1376.     if (start_column > end_column)
  1377.     return;
  1378.  
  1379.     /* get length of line beyond the start-column */
  1380.  
  1381.     len = strlen (text);
  1382.  
  1383.     if (len > end_column)
  1384.     len = end_column;
  1385.  
  1386.     len -= start_column;
  1387.  
  1388.     /* if there is still text ... */
  1389.  
  1390.     if (len > 0)
  1391.     {
  1392.     /* get contents of line at offset */
  1393.     text += start_column;
  1394.  
  1395.     while (*text == ' ' && len)
  1396.     {
  1397.         text ++;
  1398.         len --;
  1399.         start_column ++;
  1400.     }
  1401.  
  1402.     /* draw any text that is still to draw */
  1403.  
  1404.     if (len)
  1405.     {
  1406.         /* set gfxcursor */
  1407.  
  1408.         Move (rp, COLT(start_column - Ep->topcolumn), y);
  1409.  
  1410.         /* draw text */
  1411.  
  1412.         Text (rp, text, len);
  1413.     }
  1414.     }
  1415. } /* redraw_lineseg */
  1416.  
  1417.  
  1418. /******************************************************************************
  1419. *****  ENDE text.c
  1420. ******************************************************************************/
  1421.  
  1422. DEFAUTOINIT( text_initialize )
  1423. {
  1424.     extern void* HL_InstSubs(void*);
  1425.     TextRoot = HL_SystemList("*Texts*");
  1426.     pDBase   = HL_InstSubs(TextRoot);
  1427. }
  1428.