]> code.citadel.org Git - citadel.git/blob - citadel/textclient/screen.c
HUGE update to the way the paginator works. scr_putc() now keeps track of how many...
[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 extern int screenheight;
26 extern int screenwidth;
27 int lines_printed = 0;
28 int cols_printed = 0;
29
30 extern int rc_ansi_color;
31 extern void check_screen_dims(void);
32
33 void do_keepalive(void);
34
35 /*
36  * Initialize the screen
37  */
38 void screen_new(void)
39 {
40         send_ansi_detect();
41         look_for_ansi();
42         cls(0);
43         color(DIM_WHITE);
44 }
45
46
47
48 /*
49  * Beep.
50  */
51 void ctdl_beep(void) {
52         putc(7, stdout);
53 }
54         
55
56
57
58 /*
59  * scr_printf() outputs to the terminal
60  */
61 int scr_printf(char *fmt, ...)
62 {
63         static char outbuf[4096];       /* static for performance -- not re-entrant -- change if needed */
64         va_list ap;
65         register int retval;
66         int i, len;
67
68         va_start(ap, fmt);
69         retval = vsnprintf(outbuf, sizeof outbuf, fmt, ap);
70         va_end(ap);
71
72         len = strlen(outbuf);
73         for (i=0; i<len; ++i) {
74                 scr_putc(outbuf[i]);
75         }
76         return retval;
77 }
78
79
80 /*
81  * Read one character from the terminal
82  */
83 int scr_getc(int delay)
84 {
85         unsigned char buf;
86
87         scr_flush();
88
89         buf = '\0';
90         if (!read (0, &buf, 1))
91                 logoff(NULL, 3);
92
93         lines_printed = 0;
94         return buf;
95 }
96
97 /*
98  * Issue the paginator prompt (more / hit any key to continue)
99  */
100 void hit_any_key(void) {
101         int b;
102
103         color(COLOR_PUSH);
104         color(DIM_RED);
105         /* scr_printf("%s\r", ipc->ServInfo.moreprompt); */
106         scr_printf("<<more>>\r");       // FIXME use the prompt given by the server
107         color(COLOR_POP);
108         stty_ctdl(0);
109         b=inkey();
110         /*
111         for (a=0; !IsEmptyStr(&ipc->ServInfo.moreprompt[a]); ++a)
112                 scr_putc(' ');
113         */
114         scr_printf("        ");
115         scr_putc(13);
116         stty_ctdl(1);
117 /*
118         if ( (rc_prompt_control == 1)
119            || ((rc_prompt_control == 3) && (userflags & US_PROMPTCTL)) ) {
120                 if (b == 'q' || b == 'Q' || b == 's' || b == 'S')
121                         b = STOP_KEY;
122                 if (b == 'n' || b == 'N')
123                         b = NEXT_KEY;
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 we want to do a top status line, this is a reasonable way to do it
165         //      printf("\033[s\033[0;70H");
166         //      printf("\033[K   %d/%d  %d/%d", cols_printed, screenwidth, lines_printed, screenheight);
167         //      printf("\033[u");
168
169         if ((screenheight > 0) && (lines_printed > (screenheight-2))) {
170                 lines_printed = 0;
171                 hit_any_key();
172                 lines_printed = 0;
173                 cols_printed = 0;
174         }
175
176         return c;
177 }
178
179
180 void scr_flush(void)
181 {
182         fflush(stdout);
183 }
184
185
186 static volatile int caught_sigwinch = 0;
187
188
189 /*
190  * scr_winch() handles window size changes from SIGWINCH
191  * resizes all our windows for us
192  */
193 RETSIGTYPE scr_winch(int signum)
194 {
195         /* if we receive this signal, we must be running
196          * in a terminal that supports resizing.
197          */
198         have_xterm = 1;
199         caught_sigwinch = 1;
200         check_screen_dims();
201         signal(SIGWINCH, scr_winch);
202 }