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