]> code.citadel.org Git - citadel.git/blob - citadel/screen.c
* Cosmetics for the client status line
[citadel.git] / citadel / screen.c
1 /* $Id$ */
2
3 /*
4  * Handle full-screen curses stuff
5  */
6
7 #include "sysdep.h"
8 #ifdef HAVE_CURSES_H
9 #include <curses.h>
10 #endif
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdarg.h>
14 #include <unistd.h>
15 #include <sys/types.h>
16 #ifdef VW_PRINTW_IN_CURSES
17 #define _vwprintw vw_printw
18 #else
19 /* Ancient curses implementations, this needs testing. Anybody got XENIX? */
20 #define _vwprintw vwprintw
21 #endif
22 #include "citadel.h"
23 #include "commands.h"
24 #include "screen.h"
25
26 #ifdef HAVE_CURSES_H
27 static SCREEN *myscreen = NULL;
28 static WINDOW *mainwindow = NULL;
29 static WINDOW *statuswindow = NULL;
30
31 char rc_screen;
32 char arg_screen;
33
34 extern int screenheight;
35 extern int screenwidth;
36 extern void check_screen_dims(void);
37 #endif
38
39
40 /*
41  * status_line() is a convenience function for writing a "typical"
42  * status line to the window.
43  */
44 void status_line(const char *humannode, const char *bbs_city,
45                  const char *room_name, int secure, int newmailcount)
46 {
47 #ifdef HAVE_CURSES_H
48         if (statuswindow) {
49                 if (secure)
50                         sln_printf("Secure ");
51                 else
52                         sln_printf("Not secure ");
53                 waddch(statuswindow, ACS_VLINE);
54                 waddch(statuswindow, ' ');
55                 if (humannode && bbs_city)
56                         sln_printf("%s at %s ", humannode, bbs_city);
57                 if (room_name)
58                         sln_printf("in %s ", room_name);
59                 if (newmailcount > -1) {
60                         waddch(statuswindow, ACS_VLINE);
61                         sln_printf(" %d unread mail", newmailcount);
62                 }
63                 mvwinch(statuswindow, 0, 0);
64         }
65 #endif /* HAVE_CURSES_H */
66 }
67
68
69 /*
70  * Initialize the screen.  If newterm() fails, myscreen will be NULL and
71  * further handlers will assume we should be in line mode.
72  */
73 void screen_new(void)
74 {
75 #ifdef HAVE_CURSES_H
76         if (arg_screen != RC_NO && rc_screen != RC_NO)
77                 myscreen = newterm(NULL, stdout, stdin);
78         if (myscreen) {
79                 cbreak();
80                 noecho();
81                 nonl();
82                 intrflush(stdscr, FALSE);
83                 keypad(stdscr, TRUE);
84         } else
85 #endif /* HAVE_CURSES_H */
86         {
87                 send_ansi_detect();
88                 look_for_ansi();
89                 cls(0);
90                 color(1+DIM_WHITE);
91         }
92 #ifdef HAVE_CURSES_H
93         if (myscreen) {
94                 /* Setup all our colors */
95                 start_color();
96                 init_pair(1+DIM_BLACK, COLOR_BLACK, COLOR_BLACK);
97                 init_pair(1+DIM_RED, COLOR_RED, COLOR_BLACK);
98                 init_pair(1+DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
99                 init_pair(1+DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
100                 init_pair(1+DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
101                 init_pair(1+DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
102                 init_pair(1+DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
103                 init_pair(1+DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
104                 init_pair(17, COLOR_WHITE, COLOR_BLUE);
105         }
106 #endif /* HAVE_CURSES_H */
107         screen_set();
108         windows_new();
109 }
110
111
112 /*
113  * Kill the screen completely (used at exit).  It is safe to call this
114  * function more than once.
115  */
116 void screen_delete(void)
117 {
118         windows_delete();
119         screen_reset();
120 #ifdef HAVE_CURSES_H
121         if (myscreen)
122                 delscreen(myscreen);
123         myscreen = NULL;
124 #endif
125 }
126
127
128 /*
129  * Set screen/IO parameters, e.g. at start of program or return from external
130  * program run.
131  */
132 int screen_set(void)
133 {
134 #ifdef HAVE_CURSES_H
135         if (myscreen) {
136                 set_term(myscreen);
137                 wrefresh(curscr);
138                 return 1;
139         }
140 #endif /* HAVE_CURSES_H */
141         return 0;
142 }
143
144
145 /*
146  * Reset screen/IO parameters, e.g. at exit or fork of external program.
147  */
148 int screen_reset(void)
149 {
150 #ifdef HAVE_CURSES_H
151         if (myscreen) {
152                 endwin();
153                 return 1;
154         }
155 #endif /* HAVE_CURSES_H */
156         return 0;
157 }
158
159
160 /*
161  * scr_printf() outputs to the main window (or screen if not in curses)
162  */
163 int scr_printf(char *fmt, ...)
164 {
165         va_list ap;
166         register int retval;
167
168         va_start(ap, fmt);
169 #ifdef HAVE_CURSES_H
170         if (mainwindow) {
171                 retval = _vwprintw(mainwindow, fmt, ap);
172                 /*
173                 if (fmt[strlen(fmt) - 1] == '\n')
174                         wrefresh(mainwindow);
175                 */
176         } else
177 #endif
178                 retval = vprintf(fmt, ap);
179         va_end(ap);
180         return retval;
181 }
182
183
184 /*
185  * err_printf() outputs to error status window (or stderr if not in curses)
186  */
187 int err_printf(char *fmt, ...)
188 {
189         va_list ap;
190         register int retval;
191
192         va_start(ap, fmt);
193 #ifdef HAVE_CURSES_H
194         if (mainwindow) {               /* FIXME: direct to error window */
195                 retval = _vwprintw(mainwindow, fmt, ap);
196                 if (fmt[strlen(fmt) - 1] == '\n')
197                         wrefresh(mainwindow);
198         } else
199 #endif
200                 retval = vfprintf(stderr, fmt, ap);
201         va_end(ap);
202         return retval;
203 }
204
205
206 /*
207  * sln_printf() outputs to error status window (or stderr if not in curses)
208  */
209 int sln_printf(char *fmt, ...)
210 {
211         va_list ap;
212         register int retval;
213
214         va_start(ap, fmt);
215 #ifdef HAVE_CURSES_H
216         if (statuswindow) {
217                 retval = _vwprintw(statuswindow, fmt, ap);
218                 if (fmt[strlen(fmt) - 1] == '\n')
219                         wrefresh(mainwindow);
220         } else
221 #endif
222                 retval = vprintf(fmt, ap);
223         va_end(ap);
224         return retval;
225 }
226
227
228 /*
229  * sln_printf_if() outputs to status window, no output if not in curses
230  */
231 int sln_printf_if(char *fmt, ...)
232 {
233         register int retval = 1;
234 #ifdef HAVE_CURSES_H
235         va_list ap;
236
237         va_start(ap, fmt);
238         if (statuswindow) {
239                 retval = _vwprintw(statuswindow, fmt, ap);
240                 if (fmt[strlen(fmt) - 1] == '\r' ||
241                     fmt[strlen(fmt) - 1] == '\n') {
242                         mvwinch(statuswindow, 0, 0);
243                         wrefresh(mainwindow);
244                 }
245         }
246         va_end(ap);
247 #endif
248         return retval;
249 }
250
251
252 int scr_getc(void)
253 {
254 #ifdef HAVE_CURSES_H
255         if (mainwindow)
256                 return wgetch(mainwindow);
257 #endif
258         return getchar();
259 }
260
261
262 /*
263  * scr_putc() outputs a single character
264  */
265 int scr_putc(int c)
266 {
267 #ifdef HAVE_CURSES_H
268         if (mainwindow)
269                 return ((waddch(mainwindow, c) == OK) ? c : EOF);
270 #endif
271         return putc(c, stdout);
272 }
273
274
275 /*
276  * scr_color() sets the window color for mainwindow
277  */
278 int scr_color(int colornum)
279 {
280 #ifdef HAVE_CURSES_H
281         if (mainwindow) {
282                 wcolor_set(mainwindow, 1 + (colornum & 7), NULL);
283                 if (colornum & 8) {
284                         wattron(mainwindow, A_BOLD);
285                 } else {
286                         wattroff(mainwindow, A_BOLD);
287                 }
288                 return 1;
289         }
290 #endif
291         return 0;
292 }
293
294
295 void scr_flush(void)
296 {
297 #ifdef HAVE_CURSES_H
298         if (mainwindow)
299                 wrefresh(mainwindow);
300         else
301 #endif
302                 fflush(stdout);
303 }
304
305
306 void err_flush(void)
307 {
308 #ifdef HAVE_CURSES_H
309         if (mainwindow)         /* FIXME: error status window needed */
310                 wrefresh(mainwindow);
311         else
312 #endif
313                 fflush(stderr);
314 }
315
316
317 void sln_flush(void)
318 {
319 #ifdef HAVE_CURSES_H
320         if (statuswindow)
321                 wrefresh(statuswindow);
322         else
323 #endif
324                 fflush(stdout);
325 }
326
327
328 int scr_set_windowsize(void)
329 {
330 #ifdef HAVE_CURSES_H
331         int y, x;
332
333         if (mainwindow) {
334                 getmaxyx(mainwindow, y, x);
335                 screenheight = y;
336                 screenwidth = x;
337                 return 1;
338         }
339 #endif /* HAVE_CURSES_H */
340         return 0;
341 }
342
343
344 /*
345  * scr_winch() handles window size changes from SIGWINCH
346  * resizes all our windows for us
347  */
348 RETSIGTYPE scr_winch(void)
349 {
350 #ifdef HAVE_CURSES_H
351         /* FIXME: not implemented */
352 #endif
353         check_screen_dims();
354 }
355
356
357 /*
358  * Initialize the window(s) we will be using.
359  */
360 void windows_new(void)
361 {
362 #ifdef HAVE_CURSES_H
363         register int x, y;
364
365         if (myscreen) {
366                 getmaxyx(stdscr, y, x);
367                 mainwindow = newwin(y - 1, x, 0, 0);
368                 screenwidth = x;
369                 screenheight = y - 1;
370                 immedok(mainwindow, FALSE);
371                 leaveok(mainwindow, FALSE);
372                 scrollok(mainwindow, TRUE);
373                 statuswindow = newwin(1, x, y - 1, 0);
374                 wbkgdset(statuswindow, COLOR_PAIR(17));
375                 werase(statuswindow);
376                 immedok(statuswindow, TRUE);
377                 leaveok(statuswindow, FALSE);
378                 scrollok(statuswindow, FALSE);
379                 wrefresh(statuswindow);
380         }
381 #else /* HAVE_CURSES_H */
382
383 #endif /* HAVE_CURSES_H */
384 }
385
386
387 /*
388  * Deinitialize the window(s) we were using (at exit).
389  */
390 void windows_delete(void)
391 {
392 #ifdef HAVE_CURSES_H
393         if (mainwindow)
394                 delwin(mainwindow);
395         mainwindow = NULL;
396         if (statuswindow)
397                 delwin(statuswindow);
398         statuswindow = NULL;
399 #else /* HAVE_CURSES_H */
400
401 #endif /* HAVE_CURSES_H */
402 }