#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "curses_inc.h"
#ifdef _VR2_COMPAT_CODE
extern char _endwin;
#endif
static long baud_convert[] = {
1200, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,
115200, 153600, 230400, 307200, 460800, 921600,
1000000, 1152000, 1500000, 2000000, 2500000,
3000000, 3500000, 4000000
};
static char isfilter = 0;
static int _chk_trm(void);
static void _forget(void);
SCREEN *
newscreen(char *type, int lsize, int csize, int tabsize,
FILE *outfptr, FILE *infptr)
{
int old_lines = LINES, old_cols = COLS, retcode;
#ifndef _IOFBF
char *sobuf;
#endif
WINDOW *old_curscr = curscr;
SCREEN *old = SP;
TERMINAL *old_term = cur_term;
#ifdef DEBUG
if (outf == NULL) {
outf = fopen("trace", "w");
if (outf == NULL) {
perror("trace");
exit(-1);
}
setbuf(outf, (char *)NULL);
}
if (outf)
fprintf(outf, "NEWTERM(type=%s, outfptr=%x %d, infptr=%x %d) "
"isatty(2) %d, getenv %s\n", type, outfptr,
fileno(outfptr), infptr, fileno(infptr), isatty(2),
getenv("TERM"));
#endif
if (setupterm(type, fileno(outfptr), &retcode) != 0)
goto err2;
_csmax = (cswidth[0] > cswidth[1]+1 ?
(cswidth[0] > cswidth[2]+1 ? cswidth[0] : cswidth[2]+1) :
(cswidth[1] > cswidth[2] ? cswidth[1]+1 : cswidth[2]+1));
if (_csmax > CSMAX)
goto err2;
_scrmax = _curs_scrwidth[0] > _curs_scrwidth[1] ?
(_curs_scrwidth[0] > _curs_scrwidth[2] ? _curs_scrwidth[0] :
_curs_scrwidth[2]) : (_curs_scrwidth[1] > _curs_scrwidth[2] ?
_curs_scrwidth[1] : _curs_scrwidth[2]);
_mbtrue = (_csmax > 1 || _scrmax > 1);
if ((curs_errno = _chk_trm()) != -1) {
(void) strcpy(curs_parm_err, cur_term->_termname);
goto err2;
}
if ((SP = (SCREEN *) calloc(1, sizeof (SCREEN))) == NULL)
goto err1;
SP->term_file = outfptr;
SP->input_file = infptr;
SP->fl_echoit = 1;
(void) typeahead(fileno(infptr));
(void) tinputfd(fileno(infptr));
LINES = SP->lsize = lsize > 0 ? lsize : lines;
#ifdef _IOFBF
(void) setvbuf(outfptr, (char *)NULL, _IOFBF, 0);
#else
if ((sobuf = malloc(BUFSIZ)) == NULL) {
curs_errno = CURS_BAD_MALLOC;
#ifdef DEBUG
strcpy(curs_parm_err, "newscreen");
#endif
}
setbuf(outfptr, sobuf);
#endif
#ifdef SYSV
SP->baud = baud_convert[_BRS(PROGTTYS)];
#else
SP->baud = baud_convert[_BR(PROGTTY)];
#endif
_init_costs();
(void) init_acs();
SP->tcap = cur_term;
#ifdef SYSV
PROGTTYS.c_lflag &= ~ECHO;
PROGTTYS.c_lflag |= ISIG;
PROGTTYS.c_oflag &= ~(OCRNL|ONLCR);
#else
PROGTTY.sg_flags &= ~(RAW|ECHO|CRMOD);
#endif
(void) cbreak();
COLS = SP->csize = csize > 0 ? csize : columns;
if (tabsize == 0)
tabsize = (init_tabs == -1) ? 8 : init_tabs;
SP->tsize = (short)tabsize;
#ifdef DEBUG
if (outf)
fprintf(outf, "LINES = %d, COLS = %d\n", LINES, COLS);
#endif
if ((curscr = SP->cur_scr = newwin(LINES, COLS, 0, 0)) == NULL)
goto err;
SP->fl_endwin = 2;
#ifdef _VR2_COMPAT_CODE
_endwin = FALSE;
#endif
curscr->_sync = TRUE;
if (ceol_standout_glitch || (magic_cookie_glitch >= 0) ||
tilde_glitch || (transparent_underline && erase_overstrike)) {
curscr->_flags |= _CANT_BE_IMMED;
}
if (!(SP->virt_scr = newwin(LINES, COLS, 0, 0)))
goto err;
_virtscr = SP->virt_scr;
SP->virt_scr->_clear = FALSE;
if (ceol_standout_glitch || (magic_cookie_glitch >= 0)) {
int i, nc;
char **marks;
if ((marks = (char **)calloc((unsigned)LINES,
sizeof (char *))) == NULL)
goto err;
SP->_mks = marks;
nc = (COLS / BITSPERBYTE) + (COLS % BITSPERBYTE ? 1 : 0);
if ((*marks = (char *)calloc((unsigned)nc * LINES,
sizeof (char))) == NULL)
goto err;
for (i = LINES - 1; i-- > 0; ++marks)
*(marks + 1) = *marks + nc;
}
if ((SP->cur_hash = (int *)calloc((unsigned)2 * LINES,
sizeof (int))) == NULL)
goto err;
SP->virt_hash = SP->cur_hash + LINES;
if (_slk_init)
(*_slk_init)();
if (_rip_init)
(*_rip_init)();
if ((SP->std_scr = newwin(LINES, COLS, 0, 0)) == NULL) {
err:
delscreen(SP);
COLS = old_cols;
curscr = old_curscr;
LINES = old_lines;
err1:
SP = old;
curs_errno = CURS_BAD_MALLOC;
#ifdef DEBUG
strcpy(curs_parm_err, "newscreen");
#endif
err2:
cur_term = old_term;
return (NULL);
}
#ifdef DEBUG
if (outf)
fprintf(outf, "SP %x, stdscr %x, curscr %x\n",
SP, SP->std_scr, curscr);
#endif
if (((SP->imode = (enter_insert_mode && exit_insert_mode)) != 0) &&
((SP->dmode = (enter_delete_mode && exit_delete_mode)) != 0)) {
if (strcmp(enter_insert_mode, enter_delete_mode) == 0)
SP->sid_equal = TRUE;
if (strcmp(exit_insert_mode, exit_delete_mode) == 0)
SP->eid_equal = TRUE;
}
SP->ichok = (SP->imode || insert_character || parm_ich);
SP->dchok = (delete_character || parm_dch);
stdscr = SP->std_scr;
TABSIZE = SP->tsize;
return (SP);
}
static int
_chk_trm(void)
{
short error_num = -1;
#ifdef DEBUG
if (outf)
fprintf(outf, "chk_trm().\n");
#endif
if (generic_type)
error_num = CURS_UNKNOWN;
else {
if (isfilter) {
_forget();
if (!(cursor_left || carriage_return ||
column_address || parm_left_cursor)) {
goto out_stupid;
}
} else {
if ((hard_copy || over_strike) ||
(!(cursor_address) &&
(!((cursor_up || cursor_home) && cursor_down &&
(cursor_left || carriage_return)))) ||
(!clear_screen)) {
out_stupid:
error_num = CURS_STUPID;
}
}
}
return (error_num);
}
int
filter(void)
{
isfilter = 1;
return (OK);
}
static void
_forget(void)
{
row_address = cursor_address = clear_screen = parm_down_cursor =
cursor_up = cursor_down = NULL;
cursor_home = carriage_return;
lines = 1;
}