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