pdcurses/initscr.c

changeset 97
2d43f05b284c
equal deleted inserted replaced
96:5314ebdcb38d 97:2d43f05b284c
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 }

mercurial