* New alpha version 2.24.1
[alpine.git] / alpine / osdep / termout.unx.c
blobd906511eb01423a1fd8bfefdfd0ef8acbeb23750
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: termout.unx.c 955 2008-03-06 23:52:36Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2008 University of Washington
8 * Copyright 2013-2021 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
18 #include <system.h>
19 #include <general.h>
21 #include "../../c-client/mail.h" /* for MAILSTREAM and friends */
22 #include "../../c-client/osdep.h"
23 #include "../../c-client/rfc822.h" /* for soutr_t and such */
24 #include "../../c-client/misc.h" /* for cpystr proto */
25 #include "../../c-client/utf8.h" /* for CHARSET and such*/
26 #include "../../c-client/imap4r1.h"
28 #include "../../pith/osdep/color.h"
30 #include "../../pith/debug.h"
31 #include "../../pith/conf.h"
32 #include "../../pith/newmail.h"
33 #include "../../pith/charconv/utf8.h"
35 #include "../../pico/estruct.h"
36 #include "../../pico/pico.h"
37 #include "../../pico/edef.h"
38 #include "../../pico/efunc.h"
39 #include "../../pico/osdep/color.h"
41 #include "../status.h"
42 #include "../keymenu.h"
43 #include "../titlebar.h"
45 #include "termout.gen.h"
46 #include "termout.unx.h"
49 /*======================================================================
50 Routines for painting the screen
51 - figure out what the terminal type is
52 - deal with screen size changes
53 - save special output sequences
54 - the usual screen clearing, cursor addressing and scrolling
57 This library gives programs the ability to easily access the
58 termcap information and write screen oriented and raw input
59 programs. The routines can be called as needed, except that
60 to use the cursor / screen routines there must be a call to
61 InitScreen() first. The 'Raw' input routine can be used
62 independently, however. (Elm comment)
64 Not sure what the original source of this code was. It got to be
65 here as part of ELM. It has been changed significantly from the
66 ELM version to be more robust in the face of inconsistent terminal
67 autowrap behaviour. Also, the unused functions were removed, it was
68 made to pay attention to the window size, and some code was made nicer
69 (in my opinion anyways). It also outputs the terminal initialization
70 strings and provides for minimal scrolling and detects terminals
71 with out enough capabilities. (Pine comment, 1990)
74 This code used to pay attention to the "am" auto margin and "xn"
75 new line glitch fields, but they were so often incorrect because many
76 terminals can be configured to do either that we've taken it out. It
77 now assumes it doesn't know where the cursor is after outputting in the
78 80th column.
82 static int _lines, _columns;
86 * Internal prototypes
88 static int outchar(int);
89 static void moveabsolute(int, int);
90 static void CursorUp(int);
91 static void CursorDown(int);
92 static void CursorLeft(int);
93 static void CursorRight(int);
96 extern char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
97 *_setinverse, *_clearinverse,
98 *_cleartoeoln, *_cleartoeos,
99 *_startinsert, *_endinsert, *_insertchar, *_deletechar,
100 *_deleteline, *_insertline,
101 *_scrollregion, *_scrollup, *_scrolldown,
102 *_termcap_init, *_termcap_end;
103 extern char term_name[];
104 extern int _tlines, _tcolumns, _bce;
106 static enum {NoScroll,UseScrollRegion,InsertDelete} _scrollmode;
108 extern int tputs(char *, int, int (*)(int));
109 extern char *tgoto(char *, int, int);
113 /*----------------------------------------------------------------------
114 Initialize the screen for output, set terminal type, etc
116 Args: tt -- Pointer to variable to store the tty output structure.
118 Result: terminal size is discovered and set in pine state
119 termcap entry is fetched and stored
120 make sure terminal has adequate capabilities
121 evaluate scrolling situation
122 returns status of indicating the state of the screen/termcap entry
124 Returns:
125 -1 indicating no terminal name associated with this shell,
126 -2..-n No termcap for this terminal type known
127 -3 Can't open termcap file
128 -4 Terminal not powerful enough - missing clear to eoln or screen
129 or cursor motion
130 ----*/
132 config_screen(struct ttyo **tt)
134 struct ttyo *ttyo;
135 int err;
137 ttyo = (struct ttyo *)fs_get(sizeof (struct ttyo));
139 _line = 0; /* where are we right now?? */
140 _col = 0; /* assume zero, zero... */
143 * This is an ugly hack to let vtterminalinfo know it's being called
144 * from pine.
146 Pmaster = (PICO *)1;
147 if((err = vtterminalinfo(F_ON(F_TCAP_WINS, ps_global))) != 0)
148 return(err);
150 Pmaster = NULL;
152 if(_tlines <= 0)
153 _lines = DEFAULT_LINES_ON_TERMINAL;
154 else
155 _lines = _tlines;
157 if(_tcolumns <= 0)
158 _columns = DEFAULT_COLUMNS_ON_TERMINAL;
159 else
160 _columns = _tcolumns;
162 get_windsize(ttyo);
164 ttyo->header_rows = 2;
165 ttyo->footer_rows = 3;
167 /*---- Make sure this terminal has the capability.
168 All we need is cursor address, clear line, and
169 reverse video.
170 ---*/
171 if(_moveto == NULL || _cleartoeoln == NULL ||
172 _setinverse == NULL || _clearinverse == NULL) {
173 return(-4);
176 dprint((1, "Terminal type: %s\n", term_name ? term_name : "?"));
178 /*------ Figure out scrolling mode -----*/
179 if(_scrollregion != NULL && _scrollregion[0] != '\0' &&
180 _scrollup != NULL && _scrollup[0] != '\0'){
181 _scrollmode = UseScrollRegion;
182 } else if(_insertline != NULL && _insertline[0] != '\0' &&
183 _deleteline != NULL && _deleteline[0] != '\0') {
184 _scrollmode = InsertDelete;
185 } else {
186 _scrollmode = NoScroll;
188 dprint((7, "Scroll mode: %s\n",
189 _scrollmode==NoScroll ? "No Scroll" :
190 _scrollmode==InsertDelete ? "InsertDelete" : "Scroll Regions"));
192 if (!_left) {
193 _left = "\b";
196 *tt = ttyo;
198 return(0);
203 /*----------------------------------------------------------------------
204 Initialize the screen with the termcap string
205 ----*/
206 void
207 init_screen(void)
209 if(_termcap_init) /* init using termcap's rule */
210 tputs(_termcap_init, 1, outchar);
212 /* and make sure there are no scrolling surprises! */
213 BeginScroll(0, ps_global->ttyo->screen_rows - 1);
215 pico_toggle_color(0);
216 switch(ps_global->color_style){
217 case COL_NONE:
218 case COL_TERMDEF:
219 pico_set_color_options(pico_trans_color() ? COLOR_TRANS_OPT : 0);
220 break;
221 case COL_ANSI8:
222 pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT);
223 break;
224 case COL_ANSI16:
225 pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT);
226 break;
227 case COL_ANSI256:
228 pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT);
229 break;
232 if(ps_global->color_style != COL_NONE)
233 pico_toggle_color(1);
235 /* set colors */
236 if(pico_usingcolor()){
237 if(ps_global->VAR_NORM_FORE_COLOR)
238 pico_nfcolor(ps_global->VAR_NORM_FORE_COLOR);
240 if(ps_global->VAR_NORM_BACK_COLOR)
241 pico_nbcolor(ps_global->VAR_NORM_BACK_COLOR);
243 if(ps_global->VAR_REV_FORE_COLOR)
244 pico_rfcolor(ps_global->VAR_REV_FORE_COLOR);
246 if(ps_global->VAR_REV_BACK_COLOR)
247 pico_rbcolor(ps_global->VAR_REV_BACK_COLOR);
249 pico_set_normal_color();
252 /* and make sure icon text starts out consistent */
253 icon_text(NULL, IT_NEWMAIL);
254 fflush(stdout);
260 /*----------------------------------------------------------------------
261 Get the current window size
263 Args: ttyo -- pointer to structure to store window size in
265 NOTE: we don't override the given values unless we know better
266 ----*/
268 get_windsize(struct ttyo *ttyo)
270 #if defined(SIGWINCH) && defined(TIOCGWINSZ)
271 struct winsize win;
274 * Get the window size from the tty driver. If we can't fish it from
275 * stdout (pine's output is directed someplace else), try stdin (which
276 * *must* be associated with the terminal; see init_tty_driver)...
278 if(ioctl(1, TIOCGWINSZ, &win) >= 0 /* 1 is stdout */
279 || ioctl(0, TIOCGWINSZ, &win) >= 0){ /* 0 is stdin */
280 if(win.ws_row)
281 _lines = MIN(win.ws_row, MAX_SCREEN_ROWS);
283 if(win.ws_col)
284 _columns = MIN(win.ws_col, MAX_SCREEN_COLS);
286 dprint((2, "new win size -----<%d %d>------\n",
287 _lines, _columns));
289 else{
290 /* Depending on the OS, the ioctl() may have failed because
291 of a 0 rows, 0 columns setting. That happens on DYNIX/ptx 1.3
292 (with a kernel patch that happens to involve the negotiation
293 of window size in the telnet streams module.) In this case
294 the error is EINVARG. Leave the default settings. */
295 dprint((1, "ioctl(TIOCWINSZ) failed :%s\n",
296 error_description(errno)));
298 #endif
300 ttyo->screen_cols = MIN(_columns, MAX_SCREEN_COLS);
301 ttyo->screen_rows = MIN(_lines, MAX_SCREEN_ROWS);
302 return(0);
306 /*----------------------------------------------------------------------
307 End use of the screen.
308 Print status message, if any.
309 Flush status messages.
310 ----*/
311 void
312 end_screen(char *message, int exit_val)
314 int footer_rows_was_one = 0;
316 if(!panicking()){
318 dprint((9, "end_screen called\n"));
320 if(FOOTER_ROWS(ps_global) == 1){
321 footer_rows_was_one++;
322 FOOTER_ROWS(ps_global) = 3;
323 mark_status_unknown();
326 flush_status_messages(exit_val ? 0 : 1);
327 blank_keymenu(_lines - 2, 0);
328 MoveCursor(_lines - 2, 0);
331 /* unset colors */
332 if(pico_usingcolor())
333 pico_endcolor();
335 if(_termcap_end != NULL)
336 tputs(_termcap_end, 1, outchar);
338 if(!panicking()){
340 if(message){
341 printf("%s\r\n", message);
344 if(F_ON(F_ENABLE_XTERM_NEWMAIL, ps_global) && getenv("DISPLAY"))
345 icon_text("xterm", IT_NEWMAIL);
347 fflush(stdout);
349 if(footer_rows_was_one){
350 FOOTER_ROWS(ps_global) = 1;
351 mark_status_unknown();
358 /*----------------------------------------------------------------------
359 Clear the terminal screen
361 Result: The screen is cleared
362 internal cursor position set to 0,0
363 ----*/
364 void
365 ClearScreen(void)
367 _line = 0; /* clear leaves us at top... */
368 _col = 0;
370 if(ps_global->in_init_seq)
371 return;
373 mark_status_unknown();
374 mark_keymenu_dirty();
375 mark_titlebar_dirty();
378 * If the terminal doesn't have back color erase, then we have to
379 * erase manually to preserve the background color.
381 if(pico_usingcolor() && (!_bce || !_clearscreen)){
382 ClearLines(0, _lines-1);
383 MoveCursor(0, 0);
385 else if(_clearscreen){
386 tputs(_clearscreen, 1, outchar);
387 moveabsolute(0, 0); /* some clearscreens don't move correctly */
392 /*----------------------------------------------------------------------
393 Internal move cursor to absolute position
395 Args: col -- column to move cursor to
396 row -- row to move cursor to
398 Result: cursor is moved (variables, not updates)
399 ----*/
401 static void
402 moveabsolute(int col, int row)
405 char *stuff, *tgoto();
407 stuff = tgoto(_moveto, col, row);
408 tputs(stuff, 1, outchar);
412 /*----------------------------------------------------------------------
413 Move the cursor to the row and column number
414 Args: row number
415 column number
417 Result: Cursor moves
418 internal position updated
419 ----*/
420 void
421 MoveCursor(int row, int col)
423 /** move cursor to the specified row column on the screen.
424 0,0 is the top left! **/
426 int scrollafter = 0;
428 /* we don't want to change "rows" or we'll mangle scrolling... */
430 if(ps_global->in_init_seq)
431 return;
433 if (col < 0)
434 col = 0;
435 if (col >= ps_global->ttyo->screen_cols)
436 col = ps_global->ttyo->screen_cols - 1;
437 if (row < 0)
438 row = 0;
439 if (row > ps_global->ttyo->screen_rows) {
440 if (col == 0)
441 scrollafter = row - ps_global->ttyo->screen_rows;
442 row = ps_global->ttyo->screen_rows;
445 if (!_moveto)
446 return;
448 if (_col >= ps_global->ttyo->screen_cols)
449 _col = ps_global->ttyo->screen_cols - 1;
451 if (row == _line) {
452 if (col == _col)
453 return; /* already there! */
455 else if (abs(col - _col) < 5) { /* within 5 spaces... */
456 if (col > _col && _right)
457 CursorRight(col - _col);
458 else if (col < _col && _left)
459 CursorLeft(_col - col);
460 else
461 moveabsolute(col, row);
463 else /* move along to the new x,y loc */
464 moveabsolute(col, row);
466 else if (col == _col && abs(row - _line) < 5) {
467 if (row < _line && _up)
468 CursorUp(_line - row);
469 else if (_line > row && _down)
470 CursorDown(row - _line);
471 else
472 moveabsolute(col, row);
474 else if (_line == row-1 && col == 0) {
475 putchar('\n'); /* that's */
476 putchar('\r'); /* easy! */
478 else
479 moveabsolute(col, row);
481 _line = row; /* to ensure we're really there... */
482 _col = col;
484 if (scrollafter) {
485 while (scrollafter--) {
486 putchar('\n');
487 putchar('\r');
492 return;
497 /*----------------------------------------------------------------------
498 Newline, move the cursor to the start of next line
500 Result: Cursor moves
501 ----*/
502 void
503 NewLine(void)
505 /** move the cursor to the beginning of the next line **/
507 Writechar('\n', 0);
508 Writechar('\r', 0);
513 /*----------------------------------------------------------------------
514 Move cursor up n lines with terminal escape sequence
516 Args: n -- number of lines to go up
518 Result: cursor moves,
519 internal position updated
521 Only for ttyout use; not outside callers
522 ----*/
523 static void
524 CursorUp(int n)
526 /** move the cursor up 'n' lines **/
527 /** Calling function must check that _up is not null before calling **/
529 _line = (_line-n > 0? _line - n: 0); /* up 'n' lines... */
531 while (n-- > 0)
532 tputs(_up, 1, outchar);
537 /*----------------------------------------------------------------------
538 Move cursor down n lines with terminal escape sequence
540 Arg: n -- number of lines to go down
542 Result: cursor moves,
543 internal position updated
545 Only for ttyout use; not outside callers
546 ----*/
547 static void
548 CursorDown(int n)
550 /** move the cursor down 'n' lines **/
551 /** Caller must check that _down is not null before calling **/
553 _line = (_line+n < ps_global->ttyo->screen_rows ? _line + n
554 : ps_global->ttyo->screen_rows);
555 /* down 'n' lines... */
557 while (n-- > 0)
558 tputs(_down, 1, outchar);
563 /*----------------------------------------------------------------------
564 Move cursor left n lines with terminal escape sequence
566 Args: n -- number of lines to go left
568 Result: cursor moves,
569 internal position updated
571 Only for ttyout use; not outside callers
572 ----*/
573 static void
574 CursorLeft(int n)
576 /** move the cursor 'n' characters to the left **/
577 /** Caller must check that _left is not null before calling **/
579 _col = (_col - n> 0? _col - n: 0); /* left 'n' chars... */
581 while (n-- > 0)
582 tputs(_left, 1, outchar);
586 /*----------------------------------------------------------------------
587 Move cursor right n lines with terminal escape sequence
589 Args: number of lines to go right
591 Result: cursor moves,
592 internal position updated
594 Only for ttyout use; not outside callers
595 ----*/
596 static void
597 CursorRight(int n)
599 /** move the cursor 'n' characters to the right (nondestructive) **/
600 /** Caller must check that _right is not null before calling **/
602 _col = (_col+n < ps_global->ttyo->screen_cols? _col + n :
603 ps_global->ttyo->screen_cols); /* right 'n' chars... */
605 while (n-- > 0)
606 tputs(_right, 1, outchar);
611 /*----------------------------------------------------------------------
612 Go into scrolling mode, that is set scrolling region if applicable
614 Args: top -- top line of region to scroll
615 bottom -- bottom line of region to scroll
616 (These are zero-origin numbers)
618 Result: either set scrolling region or
619 save values for later scrolling
620 returns -1 if we can't scroll
622 Unfortunately this seems to leave the cursor in an unpredictable place
623 at least the manuals don't say where, so we force it here.
624 -----*/
625 static int __t, __b;
628 BeginScroll(int top, int bottom)
630 char *stuff;
632 if(_scrollmode == NoScroll)
633 return(-1);
635 __t = top;
636 __b = bottom;
637 if(_scrollmode == UseScrollRegion){
638 stuff = tgoto(_scrollregion, bottom, top);
639 tputs(stuff, 1, outchar);
640 /*-- a location very far away to force a cursor address --*/
641 _line = FARAWAY;
642 _col = FARAWAY;
644 return(0);
649 /*----------------------------------------------------------------------
650 End scrolling -- clear scrolling regions if necessary
652 Result: Clear scrolling region on terminal
653 -----*/
654 void
655 EndScroll(void)
657 if(_scrollmode == UseScrollRegion && _scrollregion != NULL){
658 /* Use tgoto even though we're not cursor addressing because
659 the format of the capability is the same.
661 char *stuff = tgoto(_scrollregion, ps_global->ttyo->screen_rows -1, 0);
662 tputs(stuff, 1, outchar);
663 /*-- a location very far away to force a cursor address --*/
664 _line = FARAWAY;
665 _col = FARAWAY;
670 /* ----------------------------------------------------------------------
671 Scroll the screen using insert/delete or scrolling regions
673 Args: lines -- number of lines to scroll, positive forward
675 Result: Screen scrolls
676 returns 0 if scroll successful, -1 if not
678 positive lines goes forward (new lines come in at bottom
679 Leaves cursor at the place to insert put new text
681 0,0 is the upper left
682 -----*/
684 ScrollRegion(int lines)
686 int l;
688 if(lines == 0)
689 return(0);
691 if(_scrollmode == UseScrollRegion) {
692 if(lines > 0) {
693 MoveCursor(__b, 0);
694 for(l = lines ; l > 0 ; l--)
695 tputs((_scrolldown == NULL || _scrolldown[0] =='\0') ? "\n" :
696 _scrolldown, 1, outchar);
697 } else {
698 MoveCursor(__t, 0);
699 for(l = -lines; l > 0; l--)
700 tputs(_scrollup, 1, outchar);
702 } else if(_scrollmode == InsertDelete) {
703 if(lines > 0) {
704 MoveCursor(__t, 0);
705 for(l = lines; l > 0; l--)
706 tputs(_deleteline, 1, outchar);
707 MoveCursor(__b, 0);
708 for(l = lines; l > 0; l--)
709 tputs(_insertline, 1, outchar);
710 } else {
711 for(l = -lines; l > 0; l--) {
712 MoveCursor(__b, 0);
713 tputs(_deleteline, 1, outchar);
714 MoveCursor(__t, 0);
715 tputs(_insertline, 1, outchar);
718 } else {
719 return(-1);
721 fflush(stdout);
722 return(0);
726 void
727 Writewchar(UCS ucs)
729 if(ps_global->in_init_seq /* silent */
730 || (F_ON(F_BLANK_KEYMENU, ps_global) /* or bottom, */
731 /* right cell */
732 && _line + 1 == ps_global->ttyo->screen_rows
733 && _col + 1 == ps_global->ttyo->screen_cols))
734 return;
737 if(ucs == LINE_FEED || ucs == RETURN || ucs == BACKSPACE || ucs == BELL || ucs == TAB){
738 switch(ucs){
739 case LINE_FEED:
740 /*-- Don't have to watch out for auto wrap or newline glitch
741 because we never let it happen. See below
742 ---*/
743 putchar('\n');
744 _line = MIN(_line+1,ps_global->ttyo->screen_rows);
745 break;
747 case RETURN : /* move to column 0 */
748 putchar('\r');
749 _col = 0;
750 break;
752 case BACKSPACE : /* move back a space if not in column 0 */
753 if(_col != 0) {
754 putchar('\b');
755 _col--;
756 } /* else BACKSPACE does nothing */
758 break;
760 case BELL : /* ring the bell but don't advance _col */
761 putchar((int) ucs);
762 break;
764 case TAB : /* if a tab, output it */
765 do /* BUG? ignores tty driver's spacing */
766 putchar(' ');
767 /* fix from Eduardo Chappa, have to increment _col once more */
768 while(_col < ps_global->ttyo->screen_cols
769 && ((++_col)&0x07) != 0);
770 break;
773 else{
774 unsigned char obuf[MAX(MB_LEN_MAX,32)];
775 int i, width = 0, outchars = 0, printable_ascii = 0;
777 if(ucs < 0x80 && isprint((unsigned char) ucs)){
778 printable_ascii++; /* efficiency shortcut */
779 width = 1;
781 else
782 width = wcellwidth(ucs);
784 if(width < 0){
786 * This happens when we have a Unicode character that
787 * we aren't able to print in our locale. For example,
788 * if the locale is setup with the terminal
789 * expecting ISO-8859-1 characters then there are
790 * lots of Unicode characters that can't be printed.
791 * Print a '?' instead.
793 width = 1;
794 obuf[outchars++] = '?';
796 else if(_col + width > ps_global->ttyo->screen_cols){
798 * Hopefully this won't happen. The
799 * character overflows the right edge because it
800 * is a double wide and we're in last column.
801 * Fill with spaces instead and toss the
802 * character.
804 * Put a > in the right column to show we tried to write
805 * past the end.
807 while(outchars < ps_global->ttyo->screen_cols - _col - 1)
808 obuf[outchars++] = ' ';
810 obuf[outchars++] = '>';
813 * In case last time through wrote in the last column and
814 * caused an autowrap, reposition cursor.
816 if(_col >= ps_global->ttyo->screen_cols)
817 moveabsolute(ps_global->ttyo->screen_cols-1, _line);
819 else{
821 * Convert the ucs into the multibyte
822 * character that corresponds to the
823 * ucs in the users locale.
825 if(printable_ascii)
826 obuf[outchars++] = (unsigned char) ucs;
827 else{
828 outchars = wtomb((char *) obuf, ucs);
829 if(outchars < 0){
830 width = 1;
831 obuf[0] = '?';
832 outchars = 1;
837 _col += width;
838 for(i = 0; i < outchars; i++)
839 putchar(obuf[i]);
843 * We used to wrap by moving to the next line and making _col = 0
844 * when we went past the end. We don't believe that this is useful
845 * anymore. If we wrap it is unintentional. Instead, stay at the
846 * end of the line. We need to be a little careful because we're
847 * moving to a different place than _col is set to, but since _col
848 * is off the right edge, it should be ok.
850 if(_col >= ps_global->ttyo->screen_cols) {
851 _col = ps_global->ttyo->screen_cols;
852 moveabsolute(ps_global->ttyo->screen_cols-1, _line);
857 void
858 Write_to_screen(char *string) /* UNIX */
861 while(*string)
862 Writechar((unsigned char) *string++, 0);
866 /*----------------------------------------------------------------------
867 Write no more than n chars of string to screen at current cursor position
869 Args: string -- string to be output
870 n -- number of chars to output
872 Result: String written to the screen
873 ----*/
874 void
875 Write_to_screen_n(char *string, int n) /* UNIX */
879 while(n-- && *string)
880 Writechar((unsigned char) *string++, 0);
884 /*----------------------------------------------------------------------
885 Clear screen to end of line on current line
887 Result: Line is cleared
888 ----*/
889 void
890 CleartoEOLN(void)
892 int c, starting_col, starting_line;
893 char *last_bg_color;
896 * If the terminal doesn't have back color erase, then we have to
897 * erase manually to preserve the background color.
899 if(pico_usingcolor() && (!_bce || !_cleartoeoln)){
900 starting_col = _col;
901 starting_line = _line;
902 last_bg_color = pico_get_last_bg_color();
903 pico_set_nbg_color();
904 for(c = _col; c < _columns; c++)
905 Writechar(' ', 0);
907 MoveCursor(starting_line, starting_col);
908 if(last_bg_color){
909 (void)pico_set_bg_color(last_bg_color);
910 fs_give((void **)&last_bg_color);
913 else if(_cleartoeoln)
914 tputs(_cleartoeoln, 1, outchar);
919 /*----------------------------------------------------------------------
920 Clear screen to end of screen from current point
922 Result: screen is cleared
923 ----*/
924 void
925 CleartoEOS(void)
927 int starting_col, starting_line;
930 * If the terminal doesn't have back color erase, then we have to
931 * erase manually to preserve the background color.
933 if(pico_usingcolor() && (!_bce || !_cleartoeos)){
934 starting_col = _col;
935 starting_line = _line;
936 CleartoEOLN();
937 ClearLines(_line+1, _lines-1);
938 MoveCursor(starting_line, starting_col);
940 else if(_cleartoeos)
941 tputs(_cleartoeos, 1, outchar);
946 /*----------------------------------------------------------------------
947 function to output character used by termcap
949 Args: c -- character to output
951 Result: character output to screen via stdio
952 ----*/
954 outchar(int c)
956 /** output the given character. From tputs... **/
957 /** Note: this CANNOT be a macro! **/
959 return(putc((unsigned char)c, stdout));
964 /*----------------------------------------------------------------------
965 function to output string such that it becomes icon text
967 Args: s -- string to write
969 Result: string indicated become our "icon" text
970 ----*/
971 void
972 icon_text(char *s, int type)
974 static enum {ukn, yes, no} xterm;
975 char *str, *converted, *use_this;
977 if(xterm == ukn)
978 xterm = (getenv("DISPLAY") != NULL) ? yes : no;
980 if(F_ON(F_ENABLE_XTERM_NEWMAIL,ps_global) && xterm == yes){
981 fputs("\033]0;", stdout);
983 str = s ? s : ps_global->pine_name;
984 converted = convert_to_locale(str);
985 use_this = converted ? converted : str;
987 fputs(use_this, stdout);
989 fputs("\007", stdout);
990 fputs("\033]1;", stdout);
992 fputs(use_this, stdout);
994 fputs("\007", stdout);
995 fflush(stdout);
997 if(converted)
998 fs_give((void **) &converted);