blob: 165b7f941b2e47b402089668dce9353c95bee8d6 [file] [log] [blame]
Patrick Georgi3b77b722011-07-07 15:41:53 +02001/* Public Domain Curses */
2
3#include <curspriv.h>
4
5RCSID("$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:
Stefan Reinauere11835e2011-10-31 12:54:00 -070025 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
Patrick Georgi3b77b722011-07-07 15:41:53 +020029 the program.
30
Stefan Reinauere11835e2011-10-31 12:54:00 -070031 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
Patrick Georgi3b77b722011-07-07 15:41:53 +020035 escape, call refresh() or doupdate().
36
Stefan Reinauere11835e2011-10-31 12:54:00 -070037 isendwin() returns TRUE if endwin() has been called without a
Patrick Georgi3b77b722011-07-07 15:41:53 +020038 subsequent refresh, unless SP is NULL.
39
Stefan Reinauere11835e2011-10-31 12:54:00 -070040 In some implementations of curses, newterm() allows the use of
41 multiple terminals. Here, it's just an alternative interface for
Patrick Georgi3b77b722011-07-07 15:41:53 +020042 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
Stefan Reinauere11835e2011-10-31 12:54:00 -070049 set_term() does nothing meaningful in PDCurses, but is included
Patrick Georgi3b77b722011-07-07 15:41:53 +020050 for compatibility with other curses implementations.
51
Stefan Reinauere11835e2011-10-31 12:54:00 -070052 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
Patrick Georgi3b77b722011-07-07 15:41:53 +020064 appropriate; resize_term() only handles stdscr and curscr.
65
66 is_termresized() returns TRUE if the curses screen has been
Stefan Reinauere11835e2011-10-31 12:54:00 -070067 resized by the user, and a call to resize_term() is needed.
68 Checking for KEY_RESIZE is generally preferable, unless you're
Patrick Georgi3b77b722011-07-07 15:41:53 +020069 not handling the keyboard.
70
Stefan Reinauere11835e2011-10-31 12:54:00 -070071 curses_version() returns a string describing the version of
Patrick Georgi3b77b722011-07-07 15:41:53 +020072 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
93char ttytype[128];
94
95const char *_curses_notice = "PDCurses 3.4 - Public Domain 2008";
96
97SCREEN *SP = (SCREEN*)NULL; /* curses variables */
98WINDOW *curscr = (WINDOW *)NULL; /* the current screen image */
99WINDOW *stdscr = (WINDOW *)NULL; /* the default screen window */
100WINDOW *pdc_lastscr = (WINDOW *)NULL; /* the last screen image */
101
102int LINES = 0; /* current terminal height */
103int COLS = 0; /* current terminal width */
104int TABSIZE = 8;
105
106MOUSE_STATUS Mouse_status, pdc_mouse_status;
107
108extern RIPPEDOFFLINE linesripped[5];
109extern char linesrippedoff;
110
Stefan Reinauer0fef4fe2013-03-25 15:32:25 -0700111#ifndef XCURSES
112static
113#endif
Patrick Georgi3b77b722011-07-07 15:41:53 +0200114WINDOW *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
Stefan Reinauere11835e2011-10-31 12:54:00 -0700175 /* We have to sort out ripped off lines here, and reduce the height
Patrick Georgi3b77b722011-07-07 15:41:53 +0200176 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
229WINDOW *initscr(void)
230{
231 PDC_LOG(("initscr() - called\n"));
232
233 return Xinitscr(0, NULL);
234}
235
236int 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
250bool isendwin(void)
251{
252 PDC_LOG(("isendwin() - called\n"));
Stefan Reinauere11835e2011-10-31 12:54:00 -0700253
Patrick Georgi3b77b722011-07-07 15:41:53 +0200254 return SP ? !(SP->alive) : FALSE;
255}
256
257SCREEN *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
264SCREEN *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
273void 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
296int 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
332bool is_termresized(void)
333{
334 PDC_LOG(("is_termresized() - called\n"));
335
336 return SP->resized;
337}
338
339const char *curses_version(void)
340{
341 return _curses_notice;
342}