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