]> code.citadel.org Git - citadel.git/blob - citadel/textclient/screen.c
Implemented a nice way to do a status line that clings to the top of the screen witho...
[citadel.git] / citadel / textclient / screen.c
1 /*
2  * Screen output handling
3  */
4
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <signal.h>
9 #include <string.h>
10 #include <stdarg.h>
11 #include <sys/types.h>
12 #include "sysdep.h"
13 #ifndef HAVE_SNPRINTF
14 #include "snprintf.h"
15 #endif
16 #include <libcitadel.h>
17 #include "citadel.h"
18 #include "citadel_ipc.h"
19 #include "citadel_decls.h"
20 #include "commands.h"
21 #include "screen.h"
22
23 char arg_screen;
24
25 /* the default paginator prompt will be replaced by the server's prompt when we learn it */
26 char *moreprompt = " -- more -- ";
27
28 extern int screenheight;
29 extern int screenwidth;
30 int lines_printed = 0;
31 int cols_printed = 0;
32
33 extern int rc_ansi_color;
34 extern int rc_prompt_control;
35 extern void check_screen_dims(void);
36
37 void do_keepalive(void);
38
39 /*
40  * Initialize the screen
41  */
42 void screen_new(void)
43 {
44         send_ansi_detect();
45         look_for_ansi();
46         cls(0);
47         color(DIM_WHITE);
48 }
49
50
51
52 /*
53  * Beep.
54  */
55 void ctdl_beep(void) {
56         putc(7, stdout);
57 }
58         
59
60
61
62 /*
63  * scr_printf() outputs to the terminal
64  */
65 int scr_printf(char *fmt, ...)
66 {
67         static char outbuf[4096];       /* static for performance -- not re-entrant -- change if needed */
68         va_list ap;
69         register int retval;
70         int i, len;
71
72         va_start(ap, fmt);
73         retval = vsnprintf(outbuf, sizeof outbuf, fmt, ap);
74         va_end(ap);
75
76         len = strlen(outbuf);
77         for (i=0; i<len; ++i) {
78                 scr_putc(outbuf[i]);
79         }
80         return retval;
81 }
82
83
84 /*
85  * Read one character from the terminal
86  */
87 int scr_getc(int delay)
88 {
89         unsigned char buf;
90
91         scr_flush();
92
93         buf = '\0';
94         if (!read (0, &buf, 1))
95                 logoff(NULL, 3);
96
97         lines_printed = 0;
98         return buf;
99 }
100
101 /*
102  * Issue the paginator prompt (more / hit any key to continue)
103  */
104 void hit_any_key(void) {
105         int a, b;
106
107         color(COLOR_PUSH);
108         color(DIM_RED);
109         scr_printf("%s\r", moreprompt);
110         color(COLOR_POP);
111         b=inkey();
112         for (a=0; a<screenwidth; ++a) {
113                 scr_putc(' ');
114         }
115         scr_printf("\r");
116
117         if ( (rc_prompt_control == 1) || ((rc_prompt_control == 3) && (userflags & US_PROMPTCTL)) ) {
118                 if (b == 'q' || b == 'Q' || b == 's' || b == 'S') {
119                         b = STOP_KEY;
120                 }
121                 if (b == 'n' || b == 'N') {
122                         b = NEXT_KEY;
123                 }
124         }
125
126         if (b==NEXT_KEY) sigcaught = SIGINT;
127         if (b==STOP_KEY) sigcaught = SIGQUIT;
128 }
129
130
131 /*
132  * Output one character to the terminal
133  */
134 int scr_putc(int c)
135 {
136         /* handle tabs normally */
137         if (c == '\t') {
138                 do {
139                         scr_putc(' ');
140                 } while ((cols_printed % 8) != 0);
141                 return(c);
142         }
143
144         /* Output the character... */
145         if (putc(c, stdout) == EOF) {
146                 logoff(NULL, 3);
147         }
148
149         if (c == '\n') {
150                 ++lines_printed;
151                 cols_printed = 0;
152         }
153         else if (c == '\r') {
154                 cols_printed = 0;
155         }
156         else if (isprint(c)) {
157                 ++cols_printed;
158                 if ((screenwidth > 0) && (cols_printed > screenwidth)) {
159                         ++lines_printed;
160                         cols_printed = 0;
161                 }
162         }
163
164         if ((screenheight > 0) && (lines_printed > (screenheight-2))) { /* -3 if we add status line */
165                 lines_printed = 0;
166                 hit_any_key();
167                 lines_printed = 0;
168                 cols_printed = 0;
169         }
170
171         return c;
172 }
173
174 /*
175 char status_line[1024] =
176         " This is the status line, status line, status line, this is "
177         "the status line, all day long. *****************************"
178         "************************************************************"
179         "************************************************************"
180         "************************************************************"
181         "************************************************************"
182         "************************************************************"
183         "************************************************************"
184         "************************************************************"
185         "************************************************************"
186         "************************************************************"
187         "************************************************************"
188         "************************************************************"
189         "************************************************************"
190         "************************************************************"
191         "************************************************************"
192         "************************************************************";
193 */
194
195 void scr_flush(void)
196 {
197         /*
198         if ((enable_color) && (screenwidth > 0)) {
199                 printf("\033[s\033[1;1H\033[K\033[7m");
200                 fwrite(status_line, screenwidth, 1, stdout);
201                 printf("\033[27m\033[u");
202         }
203         */
204         fflush(stdout);
205 }
206
207
208 static volatile int caught_sigwinch = 0;
209
210
211 /*
212  * scr_winch() handles window size changes from SIGWINCH
213  * resizes all our windows for us
214  */
215 RETSIGTYPE scr_winch(int signum)
216 {
217         /* if we receive this signal, we must be running
218          * in a terminal that supports resizing.
219          */
220         have_xterm = 1;
221         caught_sigwinch = 1;
222         check_screen_dims();
223         signal(SIGWINCH, scr_winch);
224 }