|
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 } |