home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 531.lha / Less_v1.4Z / src.LZH / src / output.c < prev    next >
C/C++ Source or Header  |  1991-07-03  |  9KB  |  362 lines

  1. /*
  2.  * High level routines dealing with the output to the screen.
  3.  */
  4.  
  5. #ifdef AMIGA
  6. /* Compile with -HPreHeader.q to get "less.h"! */
  7. #else
  8. #include "less.h"
  9. #endif
  10.  
  11.  
  12. public int errmsgs;     /* Count of messages displayed by error() */
  13.  
  14. extern int sigs;
  15. extern int sc_width, sc_height;
  16. extern int ul_width, ue_width;
  17. extern int so_width, se_width;
  18. extern int bo_width, be_width;
  19. #ifdef AMIGA
  20. extern int it_width, ie_width;
  21. extern int nv_width, ne_width;
  22. extern int nrow;  /* vertical screen size */
  23. #endif
  24. #ifdef EIGHTBIT
  25. extern int bs_mode;
  26. #endif
  27. extern int tabstop;
  28. extern int twiddle;
  29. extern int any_display;
  30. extern char *line;
  31. extern char *first_cmd;
  32.  
  33. /*
  34.  * Display the line which is in the line buffer.
  35.  */
  36. #ifdef __STDC__
  37. void put_line (void)
  38. #else
  39.         public void
  40. put_line()
  41. #endif
  42. {
  43. #ifdef AMIGA
  44.         register unsigned char *p;
  45. #else
  46.         register char *p;
  47. #endif
  48.         register int c;
  49.         register int column;
  50.         extern int auto_wrap, ignaw;
  51.  
  52.         if (sigs)
  53.                 /*
  54.                  * Don't output if a signal is pending.
  55.                  */
  56.                 return;
  57.  
  58.         if (line == NULL)
  59.                 line = (twiddle) ? "~" : "";
  60.  
  61.         column = 0;
  62. #ifdef AMIGA
  63.         for (p = (unsigned char *)line;  *p != '\0';  p++)
  64. #else
  65.         for (p = line;  *p != '\0';  p++)
  66. #endif
  67.         {
  68.                 switch (c = *p)
  69.                 {
  70.                 case UL_CHAR:
  71.                         ul_enter();
  72.                         column += ul_width;
  73.                         break;
  74.                 case UE_CHAR:
  75.                         ul_exit();
  76.                         column += ue_width;
  77.                         break;
  78.                 case BO_CHAR:
  79.                         bo_enter();
  80.                         column += bo_width;
  81.                         break;
  82.                 case BE_CHAR:
  83.                         bo_exit();
  84.                         column += be_width;
  85.                         break;
  86. #ifdef AMIGA
  87.                 case IT_CHAR:
  88.                         it_enter();
  89.                         column += it_width;
  90.                         break;
  91.                 case IE_CHAR:
  92.                         it_exit();
  93.                         column += ie_width;
  94.                         break;
  95.                 case NV_CHAR:
  96.                         nv_enter();
  97.                         column += nv_width;
  98.                         break;
  99.                 case NE_CHAR:
  100.                         nv_exit();
  101.                         column += ne_width;
  102.                         break;
  103. #endif
  104.                 case '\t':
  105.                         do
  106.                         {
  107.                                 putchr(' ');
  108.                                 column++;
  109.                         } while ((column % tabstop) != 0);
  110.                         break;
  111.                 case '\b':
  112. #ifdef EIGHTBIT
  113.                         if (bs_mode == BS_CONTROL)
  114.                         {
  115.                                 putchr('^');
  116.                                 putchr(carat_char(c));
  117.                                 column += 2;
  118.                                 break;
  119.                         }
  120. #endif
  121.                         putbs();
  122.                         column--;
  123.                         break;
  124.                 default:
  125. #ifdef EIGHTBIT
  126.                                 /* Control characters are still control
  127.                                  * characters.  Replace them with some-
  128.                                  * thing printable.
  129.                                  */
  130.                         if (control_char(c))
  131.                         {
  132.                                 putchr('^');
  133.                                 putchr(carat_char(c));
  134.                                 column += 2;
  135.                         }
  136. #else
  137.                         if (c & 0200)
  138.                         {
  139.                                 /*
  140.                                  * Control characters arrive here as the
  141.                                  * normal character [carat_char(c)] with
  142.                                  * the 0200 bit set.  See pappend().
  143.                                  */
  144.                                 putchr('^');
  145.                                 putchr(c & 0177);
  146.                                 column += 2;
  147.                         }
  148. #endif
  149.                         else
  150.                         {
  151.                                 putchr(c);
  152.                                 column++;
  153.                         }
  154.                 }
  155.         }
  156.         if (column < sc_width || !auto_wrap || ignaw)
  157.                 putchr('\n');
  158. }
  159.  
  160. /*
  161.  * Is a given character a "control" character?
  162.  * {{ ASCII DEPENDENT }}
  163.  */
  164. #ifdef __STDC__
  165. int control_char (int c)
  166. #else
  167.         public int
  168. control_char(c)
  169.         int c;
  170. #endif
  171. {
  172. #ifdef EIGHTBIT
  173.         /* SAS says 0xff is a control character, for some reason */
  174.         return iscntrl(c) && c != 0xff;
  175. #else
  176.         return ( c < ' ' || c == '\177' );
  177. #endif
  178. }
  179.  
  180. /*
  181.  * Return the printable character used to identify a control character
  182.  * (printed after a carat; e.g. '\3' => "^C").
  183.  * {{ ASCII DEPENDENT }}
  184.  */
  185. #ifdef __STDC__
  186. int carat_char (int c)
  187. #else
  188.         public int
  189. carat_char(c)
  190.         int c;
  191. #endif
  192. {
  193.         return ((c == '\177') ? '?' : (c | 0100));
  194. }
  195.  
  196.  
  197. static char obuf[1024];
  198. static char *ob = obuf;
  199.  
  200. /*
  201.  * Flush buffered output.
  202.  */
  203. #ifdef __STDC__
  204. void flush (void)
  205. #else
  206.         public void
  207. flush()
  208. #endif
  209. {
  210. #ifdef AMIGA
  211.         ttwrite ( obuf, (long) (ob-obuf));
  212. #else
  213.         write(1, obuf, ob-obuf);
  214. #endif
  215.         ob = obuf;
  216. }
  217.  
  218. /*
  219.  * Discard buffered output.
  220.  */
  221. #ifdef __STDC__
  222. void dropout (void)
  223. #else
  224.         public void
  225. dropout()
  226. #endif
  227. {
  228.         ob = obuf;
  229. }
  230.  
  231. /*
  232.  * Output a character.
  233.  */
  234. #ifdef __STDC__
  235. void putchr (int c)
  236. #else
  237.         public void
  238. putchr(c)
  239.         int c;
  240. #endif
  241. {
  242.         if (ob >= &obuf[sizeof(obuf)])
  243.                 flush();
  244.         *ob++ = c;
  245. }
  246.  
  247. /*
  248.  * Output a string.
  249.  */
  250. #ifdef __STDC__
  251. void putstr (register char *s)
  252. #else
  253.         public void
  254. putstr(s)
  255.         register char *s;
  256. #endif
  257. {
  258.         while (*s != '\0')
  259.                 putchr(*s++);
  260. }
  261.  
  262. /*
  263.  * Output a message in the lower left corner of the screen
  264.  * and wait for carriage return.
  265.  */
  266.  
  267. static char return_to_continue[] = "  (press RETURN)";
  268.  
  269. #ifdef __STDC__
  270. void error (char *s)
  271. #else
  272.         public void
  273. error(s)
  274.         char *s;
  275. #endif
  276. {
  277.         register int c;
  278.         static char buf[2];
  279.  
  280.         errmsgs++;
  281. #ifdef AMIGA
  282.         /* nrow tells us if the window has been opened yet.
  283.            any_display tells us if we have initialized reading a file yet.
  284.            If either of these are false, trying to write to the screen
  285.            now will cause trouble, either immediately or when we try to
  286.            regenerate a non-existant display.
  287.         */
  288.         if ( nrow < 2 || !any_display )
  289. #else
  290.         if (!any_display)
  291. #endif
  292.         {
  293.                 /*
  294.                  * Nothing has been displayed yet.
  295.                  * Output this message on error output (file
  296.                  * descriptor 2) and don't wait for a keystroke
  297.                  * to continue.
  298.                  *
  299.                  * This has the desirable effect of producing all
  300.                  * error messages on error output if standard output
  301.                  * is directed to a file.  It also does the same if
  302.                  * we never produce any real output; for example, if
  303.                  * the input file(s) cannot be opened.  If we do
  304.                  * eventually produce output, code in edit() makes
  305.                  * sure these messages can be seen before they are
  306.                  * overwritten or scrolled away.
  307.                  */
  308. #ifdef AMIGA
  309.                 /* If the window is too small, s may be NULL on Amiga */
  310.                 if ( s )
  311.                     MyRequester( s );
  312.                 else
  313.                     MyRequester ( "Error" );
  314. #else
  315.                 write(2, s, strlen(s));
  316.                 write(2, "\n", 1);
  317. #endif
  318.                 return;
  319.         }
  320.  
  321.         lower_left();
  322.         clear_eol();
  323.         so_enter();
  324. #ifdef AMIGA
  325.         if ( s )
  326. #endif
  327.         putstr(s);
  328.         putstr(return_to_continue);
  329.         so_exit();
  330.  
  331. #if ONLY_RETURN
  332.         while ((c = getchr()) != '\n' && c != '\r')
  333.                 bell();
  334. #else
  335.         c = getchr();
  336.         if (c != '\n' && c != '\r' && c != ' ')
  337.         {
  338.                 buf[0] = c;
  339.                 first_cmd = buf;
  340.         }
  341. #endif
  342.         lower_left();
  343.  
  344. #ifdef AMIGA
  345.         if ( s &&
  346.                 strlen(s) + sizeof(return_to_continue) +
  347.                 so_width + se_width + 1 > sc_width
  348.                 )
  349. #else
  350.         if (strlen(s) + sizeof(return_to_continue) +
  351.                 so_width + se_width + 1 > sc_width)
  352. #endif
  353.                 /*
  354.                  * Printing the message has probably scrolled the screen.
  355.                  * {{ Unless the terminal doesn't have auto margins,
  356.                  *    in which case we just hammered on the right margin. }}
  357.                  */
  358.                 repaint();
  359.  
  360.         flush();
  361. }
  362.