4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
47 #include <sys/types.h>
48 #include "curses_inc.h"
50 #ifdef _VR2_COMPAT_CODE
52 #endif /* _VR2_COMPAT_CODE */
54 /* 1200 is put at the 0th location since 0 is probably a mistake. */
55 static long baud_convert
[] = {
56 1200, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
57 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,
58 115200, 153600, 230400, 307200, 460800
61 static char isfilter
= 0;
62 static int _chk_trm(void);
63 static void _forget(void);
66 * newscreen sets up a terminal and returns a pointer to the terminal
67 * structure or NULL in case of an error. The parameters are:
69 * lsize, csize, tabsize: physical sizes
70 * infptr, outfptr: input and output stdio stream file pointers
74 newscreen(char *type
, int lsize
, int csize
, int tabsize
,
75 FILE *outfptr
, FILE *infptr
)
77 int old_lines
= LINES
, old_cols
= COLS
, retcode
;
81 WINDOW
*old_curscr
= curscr
;
83 TERMINAL
*old_term
= cur_term
;
87 outf
= fopen("trace", "w");
92 setbuf(outf
, (char *)NULL
);
96 fprintf(outf
, "NEWTERM(type=%s, outfptr=%x %d, infptr=%x %d) "
97 "isatty(2) %d, getenv %s\n", type
, outfptr
,
98 fileno(outfptr
), infptr
, fileno(infptr
), isatty(2),
103 /* read in terminfo file */
105 if (setupterm(type
, fileno(outfptr
), &retcode
) != 0)
108 /* the max length of a multi-byte character */
109 _csmax
= (cswidth
[0] > cswidth
[1]+1 ?
110 (cswidth
[0] > cswidth
[2]+1 ? cswidth
[0] : cswidth
[2]+1) :
111 (cswidth
[1] > cswidth
[2] ? cswidth
[1]+1 : cswidth
[2]+1));
114 /* the max length of a multi-column character */
115 _scrmax
= _curs_scrwidth
[0] > _curs_scrwidth
[1] ?
116 (_curs_scrwidth
[0] > _curs_scrwidth
[2] ? _curs_scrwidth
[0] :
117 _curs_scrwidth
[2]) : (_curs_scrwidth
[1] > _curs_scrwidth
[2] ?
118 _curs_scrwidth
[1] : _curs_scrwidth
[2]);
119 /* true multi-byte/multi-column case */
120 _mbtrue
= (_csmax
> 1 || _scrmax
> 1);
122 if ((curs_errno
= _chk_trm()) != -1) {
123 (void) strcpy(curs_parm_err
, cur_term
->_termname
);
127 /* use calloc because almost everything needs to be zero */
128 if ((SP
= (SCREEN
*) calloc(1, sizeof (SCREEN
))) == NULL
)
131 SP
->term_file
= outfptr
;
132 SP
->input_file
= infptr
;
135 * The default is echo, for upward compatibility, but we do
136 * all echoing in curses to avoid problems with the tty driver
137 * echoing things during critical sections.
142 /* set some fields for cur_term structure */
144 (void) typeahead(fileno(infptr
));
145 (void) tinputfd(fileno(infptr
));
148 * We use LINES instead of the SP variable and a local variable because
149 * slk_init and rip_init update the LINES value and application code
150 * may look at the value of LINES in the function called by rip_init.
154 LINES
= SP
->lsize
= lsize
> 0 ? lsize
: lines
;
156 /* force the output to be buffered */
158 (void) setvbuf(outfptr
, (char *)NULL
, _IOFBF
, 0);
160 if ((sobuf
= malloc(BUFSIZ
)) == NULL
) {
161 curs_errno
= CURS_BAD_MALLOC
;
163 strcpy(curs_parm_err
, "newscreen");
166 setbuf(outfptr
, sobuf
);
170 SP
->baud
= baud_convert
[_BRS(PROGTTYS
)];
172 SP
->baud
= baud_convert
[_BR(PROGTTY
)];
175 /* figure out how much each terminal capability costs */
178 /* initialize the array of alternate characters */
183 /* set tty settings to something reasonable for us */
185 PROGTTYS
.c_lflag
&= ~ECHO
;
186 PROGTTYS
.c_lflag
|= ISIG
;
187 PROGTTYS
.c_oflag
&= ~(OCRNL
|ONLCR
); /* why would anyone set OCRNL? */
189 PROGTTY
.sg_flags
&= ~(RAW
|ECHO
|CRMOD
);
195 COLS
= SP
->csize
= csize
> 0 ? csize
: columns
;
197 tabsize
= (init_tabs
== -1) ? 8 : init_tabs
;
199 SP
->tsize
= (short)tabsize
;
202 fprintf(outf
, "LINES = %d, COLS = %d\n", LINES
, COLS
);
205 if ((curscr
= SP
->cur_scr
= newwin(LINES
, COLS
, 0, 0)) == NULL
)
209 #ifdef _VR2_COMPAT_CODE
211 #endif /* _VR2_COMPAT_CODE */
212 curscr
->_sync
= TRUE
;
215 * This will tell _quick_echo(if it's ever called), whether
216 * _quick_echo should let wrefresh handle everything.
219 if (ceol_standout_glitch
|| (magic_cookie_glitch
>= 0) ||
220 tilde_glitch
|| (transparent_underline
&& erase_overstrike
)) {
221 curscr
->_flags
|= _CANT_BE_IMMED
;
223 if (!(SP
->virt_scr
= newwin(LINES
, COLS
, 0, 0)))
225 _virtscr
= SP
->virt_scr
;
227 SP
->virt_scr
->_clear
= FALSE
;
229 /* video mark map for cookie terminals */
231 if (ceol_standout_glitch
|| (magic_cookie_glitch
>= 0)) {
235 if ((marks
= (char **)calloc((unsigned)LINES
,
236 sizeof (char *))) == NULL
)
239 nc
= (COLS
/ BITSPERBYTE
) + (COLS
% BITSPERBYTE
? 1 : 0);
240 if ((*marks
= (char *)calloc((unsigned)nc
* LINES
,
241 sizeof (char))) == NULL
)
243 for (i
= LINES
- 1; i
-- > 0; ++marks
)
244 *(marks
+ 1) = *marks
+ nc
;
247 /* hash tables for lines */
248 if ((SP
->cur_hash
= (int *)calloc((unsigned)2 * LINES
,
249 sizeof (int))) == NULL
)
251 SP
->virt_hash
= SP
->cur_hash
+ LINES
;
253 /* adjust the screen size if soft labels and/or ripoffline are used */
259 if ((SP
->std_scr
= newwin(LINES
, COLS
, 0, 0)) == NULL
) {
260 /* free all the storage allocated above and return NULL */
269 curs_errno
= CURS_BAD_MALLOC
;
271 strcpy(curs_parm_err
, "newscreen");
280 fprintf(outf
, "SP %x, stdscr %x, curscr %x\n",
281 SP
, SP
->std_scr
, curscr
);
284 if (((SP
->imode
= (enter_insert_mode
&& exit_insert_mode
)) != 0) &&
285 ((SP
->dmode
= (enter_delete_mode
&& exit_delete_mode
)) != 0)) {
286 if (strcmp(enter_insert_mode
, enter_delete_mode
) == 0)
287 SP
->sid_equal
= TRUE
;
288 if (strcmp(exit_insert_mode
, exit_delete_mode
) == 0)
289 SP
->eid_equal
= TRUE
;
291 SP
->ichok
= (SP
->imode
|| insert_character
|| parm_ich
);
292 SP
->dchok
= (delete_character
|| parm_dch
);
294 stdscr
= SP
->std_scr
;
301 * check if terminal have capabilities to do basic cursor movements and
307 short error_num
= -1;
310 fprintf(outf
, "chk_trm().\n");
314 error_num
= CURS_UNKNOWN
;
318 /* Only need to move left or right on current line */
319 if (!(cursor_left
|| carriage_return
||
320 column_address
|| parm_left_cursor
)) {
324 if ((hard_copy
|| over_strike
) ||
325 /* some way to move up, down, left */
326 (!(cursor_address
) &&
327 (!((cursor_up
|| cursor_home
) && cursor_down
&&
328 (cursor_left
|| carriage_return
)))) ||
331 error_num
= CURS_STUPID
;
346 * if (for some reason) user assumes that terminal has only one line,
347 * disable all capabilities that deal with non-horizontal cursor movement
352 row_address
= cursor_address
= clear_screen
= parm_down_cursor
=
353 cursor_up
= cursor_down
= NULL
;
354 cursor_home
= carriage_return
;