d80fa0cf4e633f9f1d42601a0a946938d3d8ef24
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / pdcurses / initscr.c
1 /* Public Domain Curses */
2
3 #include <curspriv.h>
4
5 RCSID("$Id: initscr.c,v 1.114 2008/07/13 16:08:18 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9   Name:                                                         initscr
10
11   Synopsis:
12         WINDOW *initscr(void);
13         WINDOW *Xinitscr(int argc, char *argv[]);
14         int endwin(void);
15         bool isendwin(void);
16         SCREEN *newterm(const char *type, FILE *outfd, FILE *infd);
17         SCREEN *set_term(SCREEN *new);
18         void delscreen(SCREEN *sp);
19
20         int resize_term(int nlines, int ncols);
21         bool is_termresized(void);
22         const char *curses_version(void);
23
24   Description:
25         initscr() should be the first curses routine called.  It will 
26         initialize all curses data structures, and arrange that the 
27         first call to refresh() will clear the screen.  In case of 
28         error, initscr() will write a message to standard error and end 
29         the program.
30
31         endwin() should be called before exiting or escaping from curses 
32         mode temporarily.  It will restore tty modes, move the cursor to 
33         the lower left corner of the screen and reset the terminal into 
34         the proper non-visual mode.  To resume curses after a temporary 
35         escape, call refresh() or doupdate().
36
37         isendwin() returns TRUE if endwin() has been called without a 
38         subsequent refresh, unless SP is NULL.
39
40         In some implementations of curses, newterm() allows the use of 
41         multiple terminals. Here, it's just an alternative interface for 
42         initscr(). It always returns SP, or NULL.
43
44         delscreen() frees the memory allocated by newterm() or
45         initscr(), since it's not freed by endwin(). This function is
46         usually not needed. In PDCurses, the parameter must be the
47         value of SP, and delscreen() sets SP to NULL.
48
49         set_term() does nothing meaningful in PDCurses, but is included 
50         for compatibility with other curses implementations.
51
52         resize_term() is effectively two functions: When called with 
53         nonzero values for nlines and ncols, it attempts to resize the 
54         screen to the given size. When called with (0, 0), it merely 
55         adjusts the internal structures to match the current size after 
56         the screen is resized by the user. On the currently supported 
57         platforms, this functionality is mutually exclusive: X11 allows 
58         user resizing, while DOS, OS/2 and Win32 allow programmatic 
59         resizing. If you want to support user resizing, you should check 
60         for getch() returning KEY_RESIZE, and/or call is_termresized() 
61         at appropriate times; if either condition occurs, call 
62         resize_term(0, 0). Then, with either user or programmatic 
63         resizing, you'll have to resize any windows you've created, as 
64         appropriate; resize_term() only handles stdscr and curscr.
65
66         is_termresized() returns TRUE if the curses screen has been
67         resized by the user, and a call to resize_term() is needed. 
68         Checking for KEY_RESIZE is generally preferable, unless you're 
69         not handling the keyboard.
70
71         curses_version() returns a string describing the version of 
72         PDCurses.
73
74   Return Value:
75         All functions return NULL on error, except endwin(), which
76         returns ERR on error.
77
78   Portability                                X/Open    BSD    SYS V
79         initscr                                 Y       Y       Y
80         endwin                                  Y       Y       Y
81         isendwin                                Y       -      3.0
82         newterm                                 Y       -       Y
83         set_term                                Y       -       Y
84         delscreen                               Y       -      4.0
85         resize_term                             -       -       -
86         is_termresized                          -       -       -
87         curses_version                          -       -       -
88
89 **man-end****************************************************************/
90
91 #include <stdlib.h>
92
93 char ttytype[128];
94
95 const char *_curses_notice = "PDCurses 3.4 - Public Domain 2008";
96
97 SCREEN *SP = (SCREEN*)NULL;           /* curses variables */
98 WINDOW *curscr = (WINDOW *)NULL;      /* the current screen image */
99 WINDOW *stdscr = (WINDOW *)NULL;      /* the default screen window */
100 WINDOW *pdc_lastscr = (WINDOW *)NULL; /* the last screen image */
101
102 int LINES = 0;                        /* current terminal height */
103 int COLS = 0;                         /* current terminal width */
104 int TABSIZE = 8;
105
106 MOUSE_STATUS Mouse_status, pdc_mouse_status;
107
108 extern RIPPEDOFFLINE linesripped[5];
109 extern char linesrippedoff;
110
111 WINDOW *Xinitscr(int argc, char *argv[])
112 {
113     int i;
114
115     PDC_LOG(("Xinitscr() - called\n"));
116
117     if (SP && SP->alive)
118         return NULL;
119
120     if (PDC_scr_open(argc, argv) == ERR)
121     {
122         fprintf(stderr, "initscr(): Unable to create SP\n");
123         exit(8);
124     }
125
126     SP->autocr = TRUE;       /* cr -> lf by default */
127     SP->raw_out = FALSE;     /* tty I/O modes */
128     SP->raw_inp = FALSE;     /* tty I/O modes */
129     SP->cbreak = TRUE;
130     SP->save_key_modifiers = FALSE;
131     SP->return_key_modifiers = FALSE;
132     SP->echo = TRUE;
133     SP->visibility = 1;
134     SP->resized = FALSE;
135     SP->_trap_mbe = 0L;
136     SP->_map_mbe_to_key = 0L;
137     SP->linesrippedoff = 0;
138     SP->linesrippedoffontop = 0;
139     SP->delaytenths = 0;
140     SP->line_color = -1;
141
142     SP->orig_cursor = PDC_get_cursor_mode();
143
144     LINES = SP->lines;
145     COLS = SP->cols;
146
147     if (LINES < 2 || COLS < 2)
148     {
149         fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n",
150                 LINES, COLS);
151         exit(4);
152     }
153
154     if ((curscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)NULL)
155     {
156         fprintf(stderr, "initscr(): Unable to create curscr.\n");
157         exit(2);
158     }
159
160     if ((pdc_lastscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)NULL)
161     {
162         fprintf(stderr, "initscr(): Unable to create pdc_lastscr.\n");
163         exit(2);
164     }
165
166     wattrset(pdc_lastscr, (chtype)(-1));
167     werase(pdc_lastscr);
168
169     PDC_slk_initialize();
170     LINES -= SP->slklines;
171
172     /* We have to sort out ripped off lines here, and reduce the height 
173        of stdscr by the number of lines ripped off */
174
175     for (i = 0; i < linesrippedoff; i++)
176     {
177         if (linesripped[i].line < 0)
178             (*linesripped[i].init)(newwin(1, COLS, LINES - 1, 0), COLS);
179         else
180             (*linesripped[i].init)(newwin(1, COLS,
181                                    SP->linesrippedoffontop++, 0), COLS);
182
183         SP->linesrippedoff++;
184         LINES--;
185     }
186
187     linesrippedoff = 0;
188
189     if (!(stdscr = newwin(LINES, COLS, SP->linesrippedoffontop, 0)))
190     {
191         fprintf(stderr, "initscr(): Unable to create stdscr.\n");
192         exit(1);
193     }
194
195     wclrtobot(stdscr);
196
197     /* If preserving the existing screen, don't allow a screen clear */
198
199     if (SP->_preserve)
200     {
201         untouchwin(curscr);
202         untouchwin(stdscr);
203         stdscr->_clear = FALSE;
204         curscr->_clear = FALSE;
205     }
206     else
207         curscr->_clear = TRUE;
208
209     PDC_init_atrtab();  /* set up default colors */
210
211     MOUSE_X_POS = MOUSE_Y_POS = -1;
212     BUTTON_STATUS(1) = BUTTON_RELEASED;
213     BUTTON_STATUS(2) = BUTTON_RELEASED;
214     BUTTON_STATUS(3) = BUTTON_RELEASED;
215     Mouse_status.changes = 0;
216
217     SP->alive = TRUE;
218
219     def_shell_mode();
220
221     sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname());
222
223     return stdscr;
224 }
225
226 WINDOW *initscr(void)
227 {
228     PDC_LOG(("initscr() - called\n"));
229
230     return Xinitscr(0, NULL);
231 }
232
233 int endwin(void)
234 {
235     PDC_LOG(("endwin() - called\n"));
236
237     /* Allow temporary exit from curses using endwin() */
238
239     def_prog_mode();
240     PDC_scr_close();
241
242     SP->alive = FALSE;
243
244     return OK;
245 }
246
247 bool isendwin(void)
248 {
249     PDC_LOG(("isendwin() - called\n"));
250     
251     return SP ? !(SP->alive) : FALSE;
252 }
253
254 SCREEN *newterm(const char *type, FILE *outfd, FILE *infd)
255 {
256     PDC_LOG(("newterm() - called\n"));
257
258     return Xinitscr(0, NULL) ? SP : NULL;
259 }
260
261 SCREEN *set_term(SCREEN *new)
262 {
263     PDC_LOG(("set_term() - called\n"));
264
265     /* We only support one screen */
266
267     return (new == SP) ? SP : NULL;
268 }
269
270 void delscreen(SCREEN *sp)
271 {
272     PDC_LOG(("delscreen() - called\n"));
273
274     if (sp != SP)
275         return;
276
277     PDC_slk_free();     /* free the soft label keys, if needed */
278
279     delwin(stdscr);
280     delwin(curscr);
281     delwin(pdc_lastscr);
282     stdscr = (WINDOW *)NULL;
283     curscr = (WINDOW *)NULL;
284     pdc_lastscr = (WINDOW *)NULL;
285
286     SP->alive = FALSE;
287
288     PDC_scr_free();     /* free SP and pdc_atrtab */
289
290     SP = (SCREEN *)NULL;
291 }
292
293 int resize_term(int nlines, int ncols)
294 {
295     PDC_LOG(("resize_term() - called: nlines %d\n", nlines));
296
297     if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR)
298         return ERR;
299
300     SP->lines = PDC_get_rows();
301     LINES = SP->lines - SP->linesrippedoff - SP->slklines;
302     SP->cols = COLS = PDC_get_columns();
303
304     if (wresize(curscr, SP->lines, SP->cols) == ERR ||
305         wresize(stdscr, LINES, COLS) == ERR ||
306         wresize(pdc_lastscr, SP->lines, SP->cols) == ERR)
307         return ERR;
308
309     werase(pdc_lastscr);
310     curscr->_clear = TRUE;
311
312     if (SP->slk_winptr)
313     {
314         if (wresize(SP->slk_winptr, SP->slklines, COLS) == ERR)
315             return ERR;
316
317         wmove(SP->slk_winptr, 0, 0);
318         wclrtobot(SP->slk_winptr);
319         PDC_slk_initialize();
320         slk_noutrefresh();
321     }
322
323     touchwin(stdscr);
324     wnoutrefresh(stdscr);
325
326     return OK;
327 }
328
329 bool is_termresized(void)
330 {
331     PDC_LOG(("is_termresized() - called\n"));
332
333     return SP->resized;
334 }
335
336 const char *curses_version(void)
337 {
338     return _curses_notice;
339 }