xref: /aosp_15_r20/external/coreboot/payloads/libpayload/curses/PDCurses/pdcurses/initscr.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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 #ifndef XCURSES
112 static
113 #endif
Xinitscr(int argc,char * argv[])114 WINDOW *Xinitscr(int argc, char *argv[])
115 {
116     int i;
117 
118     PDC_LOG(("Xinitscr() - called\n"));
119 
120     if (SP && SP->alive)
121         return NULL;
122 
123     if (PDC_scr_open(argc, argv) == ERR)
124     {
125         fprintf(stderr, "initscr(): Unable to create SP\n");
126         exit(8);
127     }
128 
129     SP->autocr = TRUE;       /* cr -> lf by default */
130     SP->raw_out = FALSE;     /* tty I/O modes */
131     SP->raw_inp = FALSE;     /* tty I/O modes */
132     SP->cbreak = TRUE;
133     SP->save_key_modifiers = FALSE;
134     SP->return_key_modifiers = FALSE;
135     SP->echo = TRUE;
136     SP->visibility = 1;
137     SP->resized = FALSE;
138     SP->_trap_mbe = 0L;
139     SP->_map_mbe_to_key = 0L;
140     SP->linesrippedoff = 0;
141     SP->linesrippedoffontop = 0;
142     SP->delaytenths = 0;
143     SP->line_color = -1;
144 
145     SP->orig_cursor = PDC_get_cursor_mode();
146 
147     LINES = SP->lines;
148     COLS = SP->cols;
149 
150     if (LINES < 2 || COLS < 2)
151     {
152         fprintf(stderr, "initscr(): LINES=%d COLS=%d: too small.\n",
153                 LINES, COLS);
154         exit(4);
155     }
156 
157     if ((curscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)NULL)
158     {
159         fprintf(stderr, "initscr(): Unable to create curscr.\n");
160         exit(2);
161     }
162 
163     if ((pdc_lastscr = newwin(LINES, COLS, 0, 0)) == (WINDOW *)NULL)
164     {
165         fprintf(stderr, "initscr(): Unable to create pdc_lastscr.\n");
166         exit(2);
167     }
168 
169     wattrset(pdc_lastscr, (chtype)(-1));
170     werase(pdc_lastscr);
171 
172     PDC_slk_initialize();
173     LINES -= SP->slklines;
174 
175     /* We have to sort out ripped off lines here, and reduce the height
176        of stdscr by the number of lines ripped off */
177 
178     for (i = 0; i < linesrippedoff; i++)
179     {
180         if (linesripped[i].line < 0)
181             (*linesripped[i].init)(newwin(1, COLS, LINES - 1, 0), COLS);
182         else
183             (*linesripped[i].init)(newwin(1, COLS,
184                                    SP->linesrippedoffontop++, 0), COLS);
185 
186         SP->linesrippedoff++;
187         LINES--;
188     }
189 
190     linesrippedoff = 0;
191 
192     if (!(stdscr = newwin(LINES, COLS, SP->linesrippedoffontop, 0)))
193     {
194         fprintf(stderr, "initscr(): Unable to create stdscr.\n");
195         exit(1);
196     }
197 
198     wclrtobot(stdscr);
199 
200     /* If preserving the existing screen, don't allow a screen clear */
201 
202     if (SP->_preserve)
203     {
204         untouchwin(curscr);
205         untouchwin(stdscr);
206         stdscr->_clear = FALSE;
207         curscr->_clear = FALSE;
208     }
209     else
210         curscr->_clear = TRUE;
211 
212     PDC_init_atrtab();  /* set up default colors */
213 
214     MOUSE_X_POS = MOUSE_Y_POS = -1;
215     BUTTON_STATUS(1) = BUTTON_RELEASED;
216     BUTTON_STATUS(2) = BUTTON_RELEASED;
217     BUTTON_STATUS(3) = BUTTON_RELEASED;
218     Mouse_status.changes = 0;
219 
220     SP->alive = TRUE;
221 
222     def_shell_mode();
223 
224     sprintf(ttytype, "pdcurses|PDCurses for %s", PDC_sysname());
225 
226     return stdscr;
227 }
228 
initscr(void)229 WINDOW *initscr(void)
230 {
231     PDC_LOG(("initscr() - called\n"));
232 
233     return Xinitscr(0, NULL);
234 }
235 
endwin(void)236 int endwin(void)
237 {
238     PDC_LOG(("endwin() - called\n"));
239 
240     /* Allow temporary exit from curses using endwin() */
241 
242     def_prog_mode();
243     PDC_scr_close();
244 
245     SP->alive = FALSE;
246 
247     return OK;
248 }
249 
isendwin(void)250 bool isendwin(void)
251 {
252     PDC_LOG(("isendwin() - called\n"));
253 
254     return SP ? !(SP->alive) : FALSE;
255 }
256 
newterm(const char * type,FILE * outfd,FILE * infd)257 SCREEN *newterm(const char *type, FILE *outfd, FILE *infd)
258 {
259     PDC_LOG(("newterm() - called\n"));
260 
261     return Xinitscr(0, NULL) ? SP : NULL;
262 }
263 
set_term(SCREEN * new)264 SCREEN *set_term(SCREEN *new)
265 {
266     PDC_LOG(("set_term() - called\n"));
267 
268     /* We only support one screen */
269 
270     return (new == SP) ? SP : NULL;
271 }
272 
delscreen(SCREEN * sp)273 void delscreen(SCREEN *sp)
274 {
275     PDC_LOG(("delscreen() - called\n"));
276 
277     if (sp != SP)
278         return;
279 
280     PDC_slk_free();     /* free the soft label keys, if needed */
281 
282     delwin(stdscr);
283     delwin(curscr);
284     delwin(pdc_lastscr);
285     stdscr = (WINDOW *)NULL;
286     curscr = (WINDOW *)NULL;
287     pdc_lastscr = (WINDOW *)NULL;
288 
289     SP->alive = FALSE;
290 
291     PDC_scr_free();     /* free SP and pdc_atrtab */
292 
293     SP = (SCREEN *)NULL;
294 }
295 
resize_term(int nlines,int ncols)296 int resize_term(int nlines, int ncols)
297 {
298     PDC_LOG(("resize_term() - called: nlines %d\n", nlines));
299 
300     if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR)
301         return ERR;
302 
303     SP->lines = PDC_get_rows();
304     LINES = SP->lines - SP->linesrippedoff - SP->slklines;
305     SP->cols = COLS = PDC_get_columns();
306 
307     if (wresize(curscr, SP->lines, SP->cols) == ERR ||
308         wresize(stdscr, LINES, COLS) == ERR ||
309         wresize(pdc_lastscr, SP->lines, SP->cols) == ERR)
310         return ERR;
311 
312     werase(pdc_lastscr);
313     curscr->_clear = TRUE;
314 
315     if (SP->slk_winptr)
316     {
317         if (wresize(SP->slk_winptr, SP->slklines, COLS) == ERR)
318             return ERR;
319 
320         wmove(SP->slk_winptr, 0, 0);
321         wclrtobot(SP->slk_winptr);
322         PDC_slk_initialize();
323         slk_noutrefresh();
324     }
325 
326     touchwin(stdscr);
327     wnoutrefresh(stdscr);
328 
329     return OK;
330 }
331 
is_termresized(void)332 bool is_termresized(void)
333 {
334     PDC_LOG(("is_termresized() - called\n"));
335 
336     return SP->resized;
337 }
338 
curses_version(void)339 const char *curses_version(void)
340 {
341     return _curses_notice;
342 }
343