home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / cbw / part04 / dline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-16  |  6.8 KB  |  348 lines

  1. /*
  2.  * Library of display line routines.
  3.  *
  4.  * Robert W. Baldwin, December 1984.
  5.  */
  6.  
  7. #include    <stdio.h>
  8. #include    "window.h"
  9. #include    "specs.h"
  10.  
  11.  
  12. /* After clrdline is called the routines assume that there is
  13.  * a null character terminating the string at index w->wwidth.
  14.  * That is, the length of the display string is always equal
  15.  * the the (fixed) width of the line.
  16.  * The dl_length field behaves like the apparent string length.
  17.  * It is the column location of the last non-blank character.
  18.  * That is, an all blank line has a length of zero.
  19.  */
  20.  
  21. /* INTERNAL PROCEDURES */
  22.  
  23. /* Set the range of positions between firstcol and lastcol (inclusive) to
  24.  * the given string.  The string is padded on the right with spaces
  25.  * or truncated to make it fill the interval.
  26.  */
  27. setarange(line, str, firstcol, lastcol)
  28. displine    *line;
  29. char        *str;
  30. int            firstcol, lastcol;
  31. {
  32.     int        i;
  33.  
  34.     line->dl_length = 0;
  35.     for (i = firstcol-1 ; i < lastcol ; i++)  {
  36.         if (*str == 0)  break;
  37.         if (*str != ' ')  line->dl_length = i+1;
  38.         line->dl_chars[i] = *str++;
  39.         }
  40.  
  41.     for ( ; i < lastcol ; i++)  {
  42.         line->dl_chars[i] = ' ';
  43.         }
  44.  
  45.     line->dl_chars[i] = '\000';
  46. }
  47.  
  48.  
  49.  
  50. /* PUBLIC PROCEDURES */
  51.  
  52.  
  53.  
  54. /* Set the line from column, col, onward to the given string,
  55.  * padding with blanks if needed.  Note col = 1, set the whole line.
  56.  * This cannot be used to initialize a display line.  It does not
  57.  * set the character preceeding col.
  58.  */
  59. setnadline(line, str, col)
  60. displine    *line;
  61. char        *str;
  62. int            col;
  63. {
  64.     setarange(line, str, col, line->wwidth);
  65. }
  66.  
  67.  
  68. /* Blank out all the characters in a displine.
  69.  */
  70. clrdline(line)
  71. displine    *line;
  72. {
  73.     line->dl_length = 0;
  74.     setarange(line, "", 1, line->wwidth);
  75. }
  76.  
  77.  
  78. /* Set the entire displine to the given string, padding with blanks.
  79.  * This fills in the null termination, so it can be used to initialize
  80.  * a display line.
  81.  */
  82. setadline(line, str)
  83. displine    *line;
  84. char        *str;
  85. {
  86.     line->dl_length = 0;
  87.     setarange(line, str, 1, line->wwidth);
  88. }
  89.  
  90.  
  91. /* Set characters in the given range to the string, truncating 
  92.  * if necessary.  Do not pad with blanks, just avoid overflowing
  93.  * the range.
  94.  */
  95. setrange(line, str, firstcol, lastcol)
  96. displine    *line;
  97. char        *str;
  98. int            firstcol, lastcol;        /* Inclusive interval. */
  99. {
  100.     int        i;
  101.     int        newlength;
  102.  
  103.     newlength = 0;
  104.     for (i = firstcol-1 ; i < lastcol ; i++)  {
  105.         if (*str == 0)  return;
  106.         if (*str != ' ')  newlength = i+1;
  107.         line->dl_chars[i] = *str++;
  108.         }
  109.  
  110.     if (newlength > line->dl_length)  line->dl_length = newlength; 
  111. }
  112.  
  113.  
  114.  
  115. /* Starting at column, col, set the characters in the display line, line,
  116.  * to the given string, str.
  117.  * This differs from setnadline because it does not pad the line with blanks.
  118.  * Overflows are avoided by truncation.
  119.  * Note that col is a one-based position, not zero-based as strings are.
  120.  * This cannot be used to initialize a line, since it does not set the
  121.  * characters before column col.
  122.  */
  123. setndline(line, str, col)
  124. displine    *line;
  125. char        *str;
  126. int            col;
  127. {
  128.     setrange(line, str, col, line->wwidth);
  129. }
  130.  
  131.  
  132. /* Set the variable part of the line (between min and max_col) to
  133.  * the given string.  Pad with blanks.
  134.  */
  135. dlsetvar(line, str)
  136. displine    *line;
  137. char        *str;
  138. {
  139.     setarange(line, str, line->dl_min_col, line->dl_max_col);
  140. }
  141.  
  142.  
  143.  
  144. /* Fill the given buffer from the given range of column positions.
  145.  * Trailing blanks are not removed.
  146.  */
  147. getrange(line, buf, firstcol, lastcol)
  148. displine    *line;
  149. char        *buf;
  150. int            firstcol, lastcol;
  151. {
  152.     int        i;
  153.  
  154.     for (i = firstcol-1 ; i < lastcol ; i++)  {
  155.         *buf++ = line->dl_chars[i];
  156.         }
  157.     *buf = '\000';
  158. }
  159.  
  160.  
  161. /* Fill the given character buffer with a null terminated string
  162.  * corresponding to the part of the dline between the min and max
  163.  * column positions.  Trailing blanks are not removed.
  164.  */
  165. dlgetvar(line, buf)
  166. displine    *line;
  167. char        *buf;
  168. {
  169.     getrange(line, buf, line->dl_min_col, line->dl_max_col);
  170. }
  171.  
  172.  
  173.  
  174. /* EDITING PROCEDURES */
  175.  
  176.  
  177. /* Insert the given character at the current cursor position.
  178.  * Do nothing if the line would become too long.
  179.  * Do nothing if the character is not printable.
  180.  * The cursor moves to the right one column, provided it doesn't
  181.  * move past dl_max_col.
  182.  */
  183. dlinsert(line, k)
  184. displine    *line;
  185. key            k;
  186. {
  187.     char    restbuf[MAXWIDTH+1];        /* Char from cursor to end. */
  188.     char    insbuf[2];                    /* Char to insert. */
  189.  
  190.     if (line->dl_length >= line->wwidth)  return;
  191.     if (!printable(k))  return;
  192.  
  193.     getrange(line, restbuf, line->wcur_col, line->wwidth);
  194.  
  195.     insbuf[0] = k;
  196.     insbuf[1] = '\000';
  197.     setrange(line, insbuf, line->wcur_col, line->wcur_col);
  198.  
  199.     setrange(line, restbuf, line->wcur_col+1, line->wwidth);
  200.  
  201.     dlright(line);
  202. }
  203.  
  204.  
  205. /* Delete the character at the current cursor position and
  206.  * shuffle down the rest of the line.
  207.  * The cursor doesn't move.
  208.  * The non-blank length is correctly maintained.
  209.  */
  210. dldelete(line)
  211. displine    *line;
  212. {
  213.     char    *p;
  214.     char    linebuf[MAXWIDTH+1];        /* Rebuild whole line here. */
  215.  
  216.     getrange(line, linebuf, 1, line->wcur_col-1);
  217.  
  218.     for (p = linebuf ; *p != '\000' ; p++);    /* p pts to end of line. */
  219.     getrange(line, p, line->wcur_col+1, line->wwidth);
  220.     
  221.     setadline(line, linebuf);
  222. }
  223.  
  224.  
  225. /* Move the cursor right within min and max column.
  226.  */
  227. dlright(line)
  228. displine    *line;
  229. {
  230.     if (line->wcur_col+1 <= line->dl_max_col)
  231.         line->wcur_col++;
  232. }
  233.  
  234.  
  235. /* Move the cursor left within min and max column.
  236.  */
  237. dlleft(line)
  238. displine    *line;
  239. {
  240.     if (line->wcur_col-1 >= line->dl_min_col)
  241.         line->wcur_col--;
  242. }
  243.  
  244.  
  245.  
  246. /* DISPLAY UPDATING PROCEDURES */
  247.  
  248.  
  249. /* Redraw routine for a display line.
  250.  */
  251. wl_dldraw(dline)
  252. displine    *dline;
  253. {
  254.     int        oldcolumn;
  255.  
  256.     oldcolumn = dline->wcur_col;
  257.  
  258.     wl_setcur(dline, 1, 1);
  259.     plstring(dline->dl_chars);
  260.     wl_setcur(dline, 1, oldcolumn);
  261. }
  262.  
  263.  
  264. /* Insert a character an redisplay the line.
  265.  */
  266. wl_dlinsert(line, k)
  267. displine    *line;
  268. key            k;
  269. {
  270.     dlinsert(line, k);
  271.     wl_dldraw(line);
  272. }
  273.  
  274.  
  275. /* Delete the current character an redisplay the line.
  276.  */
  277. wl_dlfdel(line, k)
  278. displine    *line;
  279. key            k;
  280. {
  281.     dldelete(line, k);
  282.     wl_dldraw(line);
  283. }
  284.  
  285.  
  286. /* Delete the previous character an redisplay the line.
  287.  * The cursor moves backwards one position.
  288.  */
  289. wl_dlbdel(line, k)
  290. displine    *line;
  291. key            k;
  292. {
  293.     if (line->wcur_col == line->dl_min_col)  return;
  294.  
  295.     dlleft(line);
  296.     dldelete(line, k);
  297.     wl_dldraw(line);
  298. }
  299.  
  300.  
  301. /* Move cursor right and update display.
  302.  */
  303. wl_dlright(line)
  304. displine    *line;
  305. {
  306.     dlright(line);
  307.     wl_rcursor(line);
  308. }
  309.  
  310.  
  311. /* Move cursor left and update display.
  312.  */
  313. wl_dlleft(line)
  314. displine    *line;
  315. {
  316.     dlleft(line);
  317.     wl_rcursor(line);
  318. }
  319.  
  320.  
  321. /* Clear the variable part of the display line and update the display.
  322.  */
  323. wl_dlclr(line)
  324. displine    *line;
  325. {
  326.     dlsetvar(line, "");
  327.     line->wcur_col = line->dl_min_col;
  328.     wl_dldraw(line);
  329. }
  330.  
  331.  
  332. /* Scan for the first argument place holder, '%',
  333.  * position the cursor there, and delete it.
  334.  * Do nothing if the line doesn't contain a '%'.
  335.  */
  336. wl_nxtarg(line)
  337. displine    *line;
  338. {
  339.     int        i;
  340.  
  341.     for (i = line->dl_min_col-1 ; i < line->dl_max_col ; i++) {
  342.         if (line->dl_chars[i] != '%') continue;
  343.         wl_setcur(line, 1, i+1);
  344.         wl_dlfdel(line);
  345.         break;
  346.         }
  347. }
  348.