4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 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
45 #include <sys/types.h>
46 #include "curses_inc.h"
48 #ifdef _VR2_COMPAT_CODE
50 #endif /* _VR2_COMPAT_CODE */
52 /* 1200 is put at the 0th location since 0 is probably a mistake. */
53 static long baud_convert
[] = {
54 1200, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
55 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,
56 115200, 153600, 230400, 307200, 460800, 921600
59 static char isfilter
= 0;
60 static int _chk_trm(void);
61 static void _forget(void);
64 * newscreen sets up a terminal and returns a pointer to the terminal
65 * structure or NULL in case of an error. The parameters are:
67 * lsize, csize, tabsize: physical sizes
68 * infptr, outfptr: input and output stdio stream file pointers
72 newscreen(char *type
, int lsize
, int csize
, int tabsize
,
73 FILE *outfptr
, FILE *infptr
)
75 int old_lines
= LINES
, old_cols
= COLS
, retcode
;
79 WINDOW
*old_curscr
= curscr
;
81 TERMINAL
*old_term
= cur_term
;
85 outf
= fopen("trace", "w");
90 setbuf(outf
, (char *)NULL
);
94 fprintf(outf
, "NEWTERM(type=%s, outfptr=%x %d, infptr=%x %d) "
95 "isatty(2) %d, getenv %s\n", type
, outfptr
,
96 fileno(outfptr
), infptr
, fileno(infptr
), isatty(2),
101 /* read in terminfo file */
103 if (setupterm(type
, fileno(outfptr
), &retcode
) != 0)
106 /* the max length of a multi-byte character */
107 _csmax
= (cswidth
[0] > cswidth
[1]+1 ?
108 (cswidth
[0] > cswidth
[2]+1 ? cswidth
[0] : cswidth
[2]+1) :
109 (cswidth
[1] > cswidth
[2] ? cswidth
[1]+1 : cswidth
[2]+1));
112 /* the max length of a multi-column character */
113 _scrmax
= _curs_scrwidth
[0] > _curs_scrwidth
[1] ?
114 (_curs_scrwidth
[0] > _curs_scrwidth
[2] ? _curs_scrwidth
[0] :
115 _curs_scrwidth
[2]) : (_curs_scrwidth
[1] > _curs_scrwidth
[2] ?
116 _curs_scrwidth
[1] : _curs_scrwidth
[2]);
117 /* true multi-byte/multi-column case */
118 _mbtrue
= (_csmax
> 1 || _scrmax
> 1);
120 if ((curs_errno
= _chk_trm()) != -1) {
121 (void) strcpy(curs_parm_err
, cur_term
->_termname
);
125 /* use calloc because almost everything needs to be zero */
126 if ((SP
= (SCREEN
*) calloc(1, sizeof (SCREEN
))) == NULL
)
129 SP
->term_file
= outfptr
;
130 SP
->input_file
= infptr
;
133 * The default is echo, for upward compatibility, but we do
134 * all echoing in curses to avoid problems with the tty driver
135 * echoing things during critical sections.
140 /* set some fields for cur_term structure */
142 (void) typeahead(fileno(infptr
));
143 (void) tinputfd(fileno(infptr
));
146 * We use LINES instead of the SP variable and a local variable because
147 * slk_init and rip_init update the LINES value and application code
148 * may look at the value of LINES in the function called by rip_init.
152 LINES
= SP
->lsize
= lsize
> 0 ? lsize
: lines
;
154 /* force the output to be buffered */
156 (void) setvbuf(outfptr
, (char *)NULL
, _IOFBF
, 0);
158 if ((sobuf
= malloc(BUFSIZ
)) == NULL
) {
159 curs_errno
= CURS_BAD_MALLOC
;
161 strcpy(curs_parm_err
, "newscreen");
164 setbuf(outfptr
, sobuf
);
168 SP
->baud
= baud_convert
[_BRS(PROGTTYS
)];
170 SP
->baud
= baud_convert
[_BR(PROGTTY
)];
173 /* figure out how much each terminal capability costs */
176 /* initialize the array of alternate characters */
181 /* set tty settings to something reasonable for us */
183 PROGTTYS
.c_lflag
&= ~ECHO
;
184 PROGTTYS
.c_lflag
|= ISIG
;
185 PROGTTYS
.c_oflag
&= ~(OCRNL
|ONLCR
); /* why would anyone set OCRNL? */
187 PROGTTY
.sg_flags
&= ~(RAW
|ECHO
|CRMOD
);
193 COLS
= SP
->csize
= csize
> 0 ? csize
: columns
;
195 tabsize
= (init_tabs
== -1) ? 8 : init_tabs
;
197 SP
->tsize
= (short)tabsize
;
200 fprintf(outf
, "LINES = %d, COLS = %d\n", LINES
, COLS
);
203 if ((curscr
= SP
->cur_scr
= newwin(LINES
, COLS
, 0, 0)) == NULL
)
207 #ifdef _VR2_COMPAT_CODE
209 #endif /* _VR2_COMPAT_CODE */
210 curscr
->_sync
= TRUE
;
213 * This will tell _quick_echo(if it's ever called), whether
214 * _quick_echo should let wrefresh handle everything.
217 if (ceol_standout_glitch
|| (magic_cookie_glitch
>= 0) ||
218 tilde_glitch
|| (transparent_underline
&& erase_overstrike
)) {
219 curscr
->_flags
|= _CANT_BE_IMMED
;
221 if (!(SP
->virt_scr
= newwin(LINES
, COLS
, 0, 0)))
223 _virtscr
= SP
->virt_scr
;
225 SP
->virt_scr
->_clear
= FALSE
;
227 /* video mark map for cookie terminals */
229 if (ceol_standout_glitch
|| (magic_cookie_glitch
>= 0)) {
233 if ((marks
= (char **)calloc((unsigned)LINES
,
234 sizeof (char *))) == NULL
)
237 nc
= (COLS
/ BITSPERBYTE
) + (COLS
% BITSPERBYTE
? 1 : 0);
238 if ((*marks
= (char *)calloc((unsigned)nc
* LINES
,
239 sizeof (char))) == NULL
)
241 for (i
= LINES
- 1; i
-- > 0; ++marks
)
242 *(marks
+ 1) = *marks
+ nc
;
245 /* hash tables for lines */
246 if ((SP
->cur_hash
= (int *)calloc((unsigned)2 * LINES
,
247 sizeof (int))) == NULL
)
249 SP
->virt_hash
= SP
->cur_hash
+ LINES
;
251 /* adjust the screen size if soft labels and/or ripoffline are used */
257 if ((SP
->std_scr
= newwin(LINES
, COLS
, 0, 0)) == NULL
) {
258 /* free all the storage allocated above and return NULL */
267 curs_errno
= CURS_BAD_MALLOC
;
269 strcpy(curs_parm_err
, "newscreen");
278 fprintf(outf
, "SP %x, stdscr %x, curscr %x\n",
279 SP
, SP
->std_scr
, curscr
);
282 if (((SP
->imode
= (enter_insert_mode
&& exit_insert_mode
)) != 0) &&
283 ((SP
->dmode
= (enter_delete_mode
&& exit_delete_mode
)) != 0)) {
284 if (strcmp(enter_insert_mode
, enter_delete_mode
) == 0)
285 SP
->sid_equal
= TRUE
;
286 if (strcmp(exit_insert_mode
, exit_delete_mode
) == 0)
287 SP
->eid_equal
= TRUE
;
289 SP
->ichok
= (SP
->imode
|| insert_character
|| parm_ich
);
290 SP
->dchok
= (delete_character
|| parm_dch
);
292 stdscr
= SP
->std_scr
;
299 * check if terminal have capabilities to do basic cursor movements and
305 short error_num
= -1;
308 fprintf(outf
, "chk_trm().\n");
312 error_num
= CURS_UNKNOWN
;
316 /* Only need to move left or right on current line */
317 if (!(cursor_left
|| carriage_return
||
318 column_address
|| parm_left_cursor
)) {
322 if ((hard_copy
|| over_strike
) ||
323 /* some way to move up, down, left */
324 (!(cursor_address
) &&
325 (!((cursor_up
|| cursor_home
) && cursor_down
&&
326 (cursor_left
|| carriage_return
)))) ||
329 error_num
= CURS_STUPID
;
344 * if (for some reason) user assumes that terminal has only one line,
345 * disable all capabilities that deal with non-horizontal cursor movement
350 row_address
= cursor_address
= clear_screen
= parm_down_cursor
=
351 cursor_up
= cursor_down
= NULL
;
352 cursor_home
= carriage_return
;