]> code.citadel.org Git - citadel.git/blob - citadel/screen.c
- fixes for building without OpenSSL
[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 HAVE_VW_PRINTW
17 #define _vwprintw vw_printw
18 #else
19 /* Ancient curses implementations, this needs testing. Anybody got XENIX? */
20 #define _vwprintw vwprintw
21 #endif
22 #ifndef HAVE_SNPRINTF
23 #include "snprintf.h"
24 #endif
25 #include "citadel.h"
26 #include "commands.h"
27 #include "screen.h"
28
29 #ifdef HAVE_CURSES_H
30 static SCREEN *myscreen = NULL;
31 static WINDOW *mainwindow = NULL;
32 static WINDOW *statuswindow = NULL;
33
34 char rc_screen;
35 char arg_screen;
36
37 extern int screenheight;
38 extern int screenwidth;
39 extern int rc_ansi_color;
40 extern void check_screen_dims(void);
41 #endif
42
43 void do_keepalive(void);
44
45
46 /*
47  * status_line() is a convenience function for writing a "typical"
48  * status line to the window.
49  */
50 void status_line(const char *humannode, const char *bbs_city,
51                  const char *room_name, int secure, int newmailcount)
52 {
53 #ifdef HAVE_CURSES_H
54         if (statuswindow) {
55                 if (secure) {
56                         sln_printf("Encrypted ");
57                         waddch(statuswindow, ACS_VLINE);
58                         waddch(statuswindow, ' ');
59                 }
60                 if (room_name)
61                         sln_printf("%s on ", room_name);
62                 if (humannode)
63                         sln_printf("%s ", humannode);
64                 if (newmailcount > -1) {
65                         waddch(statuswindow, ACS_VLINE);
66                         sln_printf(" Mail: %d new ", newmailcount);
67                 }
68                 sln_printf("\n");
69         }
70 #endif /* HAVE_CURSES_H */
71 }
72
73
74 /*
75  * Initialize the screen.  If newterm() fails, myscreen will be NULL and
76  * further handlers will assume we should be in line mode.
77  */
78 void screen_new(void)
79 {
80 #ifdef HAVE_CURSES_H
81         if (arg_screen != RC_NO && rc_screen != RC_NO)
82                 myscreen = newterm(NULL, stdout, stdin);
83         if (myscreen) {
84                 cbreak();
85                 noecho();
86                 nonl();
87                 intrflush(stdscr, FALSE);
88                 keypad(stdscr, TRUE);
89                 /* Setup all our colors */
90                 start_color();
91                 if (rc_ansi_color)
92                         enable_color = 1;
93                 init_pair(1+DIM_BLACK, COLOR_BLACK, COLOR_BLACK);
94                 init_pair(1+DIM_RED, COLOR_RED, COLOR_BLACK);
95                 init_pair(1+DIM_GREEN, COLOR_GREEN, COLOR_BLACK);
96                 init_pair(1+DIM_YELLOW, COLOR_YELLOW, COLOR_BLACK);
97                 init_pair(1+DIM_BLUE, COLOR_BLUE, COLOR_BLACK);
98                 init_pair(1+DIM_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
99                 init_pair(1+DIM_CYAN, COLOR_CYAN, COLOR_BLACK);
100                 init_pair(1+DIM_WHITE, COLOR_WHITE, COLOR_BLACK);
101                 init_pair(17, COLOR_WHITE, COLOR_BLUE);
102         } else
103 #endif /* HAVE_CURSES_H */
104         {
105                 send_ansi_detect();
106                 look_for_ansi();
107                 cls(0);
108                 color(1+DIM_WHITE);
109         }
110         screen_set();
111         windows_new();
112 }
113
114
115 /*
116  * Kill the screen completely (used at exit).  It is safe to call this
117  * function more than once.
118  */
119 void screen_delete(void)
120 {
121         windows_delete();
122         screen_reset();
123 #ifdef HAVE_CURSES_H
124         if (myscreen)
125                 delscreen(myscreen);
126         myscreen = NULL;
127 #endif
128 }
129
130
131 /*
132  * Set screen/IO parameters, e.g. at start of program or return from external
133  * program run.
134  */
135 int screen_set(void)
136 {
137 #ifdef HAVE_CURSES_H
138         if (myscreen) {
139                 set_term(myscreen);
140                 wrefresh(curscr);
141                 return 1;
142         }
143 #endif /* HAVE_CURSES_H */
144         return 0;
145 }
146
147
148 /*
149  * Reset screen/IO parameters, e.g. at exit or fork of external program.
150  */
151 int screen_reset(void)
152 {
153 #ifdef HAVE_CURSES_H
154         if (myscreen) {
155                 endwin();
156                 return 1;
157         }
158 #endif /* HAVE_CURSES_H */
159         return 0;
160 }
161
162
163 /*
164  * scr_printf() outputs to the main window (or screen if not in curses)
165  */
166 int scr_printf(char *fmt, ...)
167 {
168         va_list ap;
169         register int retval;
170
171         va_start(ap, fmt);
172 #ifdef HAVE_CURSES_H
173         if (mainwindow) {
174                 retval = _vwprintw(mainwindow, fmt, ap);
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 #ifdef HAVE_CURSES_H
213         static char buf[4096];
214 #endif
215
216         va_start(ap, fmt);
217 #ifdef HAVE_CURSES_H
218         if (statuswindow) {
219                 register char *i;
220                 
221                 retval = vsnprintf(buf, 4096, fmt, ap);
222                 for (i = buf; *i; i++) {
223                         if (*i == '\r' || *i == '\n')
224                                 wclrtoeol(statuswindow);
225                         sln_putc(*i);
226                         if (*i == '\r' || *i == '\n') {
227                                 wrefresh(statuswindow);
228                                 mvwinch(statuswindow, 0, 0);
229                         }
230                 }
231         } else
232 #endif
233                 retval = vprintf(fmt, ap);
234         va_end(ap);
235         return retval;
236 }
237
238
239 /*
240  * sln_printf_if() outputs to status window, no output if not in curses
241  */
242 int sln_printf_if(char *fmt, ...)
243 {
244         register int retval = 1;
245 #ifdef HAVE_CURSES_H
246         static char buf[4096];
247         va_list ap;
248
249         va_start(ap, fmt);
250         if (statuswindow) {
251                 register char *i;
252                 
253                 retval = vsnprintf(buf, 4096, fmt, ap);
254                 for (i = buf; *i; i++) {
255                         if (*i == '\r' || *i == '\n')
256                                 wclrtoeol(statuswindow);
257                         sln_putc(*i);
258                         if (*i == '\r' || *i == '\n') {
259                                 wrefresh(statuswindow);
260                                 mvwinch(statuswindow, 0, 0);
261                         }
262                 }
263         }
264         va_end(ap);
265 #endif
266         return retval;
267 }
268
269
270 int scr_getc(void)
271 {
272   char buf;
273 #ifdef HAVE_CURSES_H
274         if (mainwindow)
275                 return wgetch(mainwindow);
276 #endif
277   buf = '\0';
278   read (0, &buf, 1);
279         return buf;
280 }
281
282 int scr_blockread(void)
283   {
284     int a = 0;
285 #ifdef HAVE_CURSES_H
286     wtimeout(mainwindow, S_KEEPALIVE); 
287     while (1)
288       {
289         do_keepalive();
290         a = wgetch(mainwindow); /* will block for food */
291         if (a != ERR)
292           break;
293         /* a = scr_getc(); */
294       }
295 #endif
296     return a;
297   }
298
299 /*
300  * scr_putc() outputs a single character
301  */
302 int scr_putc(int c)
303 {
304 #ifdef HAVE_CURSES_H
305         if (mainwindow)
306                 return ((waddch(mainwindow, c) == OK) ? c : EOF);
307 #endif
308         return putc(c, stdout);
309 }
310
311
312 int sln_putc(int c)
313 {
314 #ifdef HAVE_CURSES_H
315         if (statuswindow)
316                 return ((waddch(statuswindow, c) == OK) ? c : EOF);
317 #endif
318         return putc(c, stdout);
319 }
320
321
322 int sln_putc_if(int c)
323 {
324 #ifdef HAVE_CURSES_H
325         if (statuswindow)
326                 return ((waddch(statuswindow, c) == OK) ? c : EOF);
327 #endif
328         return 1;
329 }
330
331
332 /*
333  * scr_color() sets the window color for mainwindow
334  */
335 int scr_color(int colornum)
336 {
337 #ifdef HAVE_CURSES_H
338         if (mainwindow) {
339 #ifdef HAVE_WCOLOR_SET
340                 wcolor_set(mainwindow, 1 + (colornum & 7), NULL);
341 #endif
342                 if (colornum & 8) {
343                         wattron(mainwindow, A_BOLD);
344                 } else {
345                         wattroff(mainwindow, A_BOLD);
346                 }
347                 return 1;
348         }
349 #endif
350         return 0;
351 }
352
353
354 void scr_flush(void)
355 {
356 #ifdef HAVE_CURSES_H
357         if (mainwindow)
358                 wrefresh(mainwindow);
359         else
360 #endif
361                 fflush(stdout);
362 }
363
364
365 void err_flush(void)
366 {
367 #ifdef HAVE_CURSES_H
368         if (mainwindow)         /* FIXME: error status window needed */
369                 wrefresh(mainwindow);
370         else
371 #endif
372                 fflush(stderr);
373 }
374
375
376 void sln_flush(void)
377 {
378 #ifdef HAVE_CURSES_H
379         if (statuswindow)
380                 wrefresh(statuswindow);
381         else
382 #endif
383                 fflush(stdout);
384 }
385
386
387 int scr_set_windowsize(void)
388 {
389 #ifdef HAVE_CURSES_H
390         int y, x;
391
392         if (mainwindow) {
393                 getmaxyx(mainwindow, y, x);
394                 screenheight = y;
395                 screenwidth = x;
396                 return 1;
397         }
398 #endif /* HAVE_CURSES_H */
399         return 0;
400 }
401
402
403 /*
404  * scr_winch() handles window size changes from SIGWINCH
405  * resizes all our windows for us
406  */
407 RETSIGTYPE scr_winch(void)
408 {
409 #ifdef HAVE_CURSES_H
410         /* FIXME: not implemented */
411 #endif
412         check_screen_dims();
413 }
414
415
416 /*
417  * Initialize the window(s) we will be using.
418  */
419 void windows_new(void)
420 {
421 #ifdef HAVE_CURSES_H
422         register int x, y;
423
424         if (myscreen) {
425                 getmaxyx(stdscr, y, x);
426                 mainwindow = newwin(y - 1, x, 0, 0);
427                 screenwidth = x;
428                 screenheight = y - 1;
429                 immedok(mainwindow, FALSE);
430                 leaveok(mainwindow, FALSE);
431                 scrollok(mainwindow, TRUE);
432                 statuswindow = newwin(1, x, y - 1, 0);
433                 wbkgdset(statuswindow, COLOR_PAIR(17));
434                 werase(statuswindow);
435                 immedok(statuswindow, FALSE);
436                 leaveok(statuswindow, FALSE);
437                 scrollok(statuswindow, FALSE);
438                 wrefresh(statuswindow);
439         }
440 #else /* HAVE_CURSES_H */
441
442 #endif /* HAVE_CURSES_H */
443 }
444
445
446 /*
447  * Deinitialize the window(s) we were using (at exit).
448  */
449 void windows_delete(void)
450 {
451 #ifdef HAVE_CURSES_H
452         if (mainwindow)
453                 delwin(mainwindow);
454         mainwindow = NULL;
455         if (statuswindow)
456                 delwin(statuswindow);
457         statuswindow = NULL;
458 #else /* HAVE_CURSES_H */
459
460 #endif /* HAVE_CURSES_H */
461 }