Commit message: ncurses 6.2 - patch 20200531

+ correct configure version-check/warnng for g++ to allow for 10.x
+ re-enable "bel" in konsole-base (report by Nia Huang)
+ add linux-s entry (patch by Alexandre Montaron).
+ drop long-obsolete convert_configure.pl
+ add test/test_parm.c, for checking tparm changes.
+ improve parameter-checking for tparm, adding function _nc_tiparm() to
  handle the most-used case, which accepts only numeric parameters
  (report/testcase by "puppet-meteor").
+ use a more conservative estimate of the buffer-size in lib_tparm.c's
  save_text() and save_number(), in case the sprintf() function
  passes-through unexpected characters from a format specifier
  (report/testcase by "puppet-meteor").
+ add a check for end-of-string in cvtchar to handle a malformed
  string in infotocap (report/testcase by "puppet-meteor").
CVE: CVE-2021-39537
CWE: CWE-787
Vulnerability description: An issue was discovered in ncurses through v6.2-1. _nc_captoinfo in captoinfo.c has a heap-based buffer overflow.

Project: ncurses

_trace_slot(SCREEN *sp, const char *tag)
{
    MEVENT *ep;

    _tracef("%s", tag);

    for (ep = FirstEV(sp); ep <= LastEV(sp); ep++)
	_tracef("mouse event queue slot %ld = %s",
		(long) IndexEV(sp, ep),
		_nc_tracemouse(sp, ep));
}

Project: ncurses

set_colors(int fg, int bg)
{
    int pair = mypair(fg, bg);
    if (pair > 0) {
	attron(COLOR_PAIR(mypair(fg, bg)));
    }
}

Project: ncurses

set_foreground_color(NCURSES_SP_DCLx int fg, NCURSES_SP_OUTC outc)
{
#ifdef USE_TERM_DRIVER
    CallDriver_3(SP_PARM, td_color, TRUE, fg, outc);
#else
    if (set_a_foreground) {
	TPUTS_TRACE("set_a_foreground");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(set_a_foreground, fg),
				1, outc);
    } else {
	TPUTS_TRACE("set_foreground");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(set_foreground, toggled_colors(fg)),
				1, outc);
    }
#endif
}

Project: ncurses

start_color(void)
{
    return NCURSES_SP_NAME(start_color) (CURRENT_SCREEN);
}

Project: ncurses

sent_string(const char *s)
{
    bool sent = FALSE;
    if (VALID_STRING(s)) {
	tputs(s, 0, out_char);
	sent = TRUE;
    }
    return sent;
}

Project: ncurses

put_translate(int c)
/* emit a comment char, translating terminfo names to termcap names */
{
    static bool in_name = FALSE;
    static size_t have, used;
    static char *namebuf, *suffix;

    if (in_name) {
	if (used + 1 >= have) {
	    have += 132;
	    if ((namebuf = typeRealloc(char, have, namebuf)) == 0)
		  failed("put_translate namebuf");
	    if ((suffix = typeRealloc(char, have, suffix)) == 0)
		  failed("put_translate suffix");
	}
	if (c == '\n' || c == '@') {
	    namebuf[used++] = '\0';
	    (void) putchar('<');
	    (void) fputs(namebuf, stdout);
	    putchar(c);
	    in_name = FALSE;
	} else if (c != '>') {
	    namebuf[used++] = (char) c;
	} else {		/* ah! candidate name! */
	    char *up;
	    NCURSES_CONST char *tp;

	    namebuf[used++] = '\0';
	    in_name = FALSE;

	    suffix[0] = '\0';
	    if ((up = strchr(namebuf, '#')) != 0
		|| (up = strchr(namebuf, '=')) != 0
		|| ((up = strchr(namebuf, '@')) != 0 && up[1] == '>')) {
		_nc_STRCPY(suffix, up, have);
		*up = '\0';
	    }

	    if ((tp = nametrans(namebuf)) != 0) {
		(void) putchar(':');
		(void) fputs(tp, stdout);
		(void) fputs(suffix, stdout);
		(void) putchar(':');
	    } else {
		/* couldn't find a translation, just dump the name */
		(void) putchar('<');
		(void) fputs(namebuf, stdout);
		(void) fputs(suffix, stdout);
		(void) putchar('>');
	    }
	}
    } else {
	used = 0;
	if (c == '<') {
	    in_name = TRUE;
	} else {
	    putchar(c);
	}
    }
}

Project: ncurses

_nc_mvcur(int yold, int xold,
	  int ynew, int xnew)
{
    return NCURSES_SP_NAME(_nc_mvcur) (CURRENT_SCREEN, yold, xold, ynew, xnew);
}

Project: ncurses

NCURSES_SP_NAME(_nc_screen_init) (NCURSES_SP_DCL0)
{
    NCURSES_SP_NAME(_nc_screen_resume) (NCURSES_SP_ARG);
}

Project: ncurses

bcd_expression(const char *str)
{
    /* leave this non-const for HPUX */
    static char fmt[] = "%%p%c%%{10}%%/%%{16}%%*%%p%c%%{10}%%m%%+";
    int len = 0;
    char ch1, ch2;

    if (sscanf(str, fmt, &ch1, &ch2) == 2
	&& isdigit(UChar(ch1))
	&& isdigit(UChar(ch2))
	&& (ch1 == ch2)) {
	len = 28;
#ifndef NDEBUG
	{
	    char buffer[80];
	    int tst;
	    _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) fmt, ch1, ch2);
	    tst = strlen(buffer) - 1;
	    assert(len == tst);
	}
#endif
    }
    return len;
}

Project: ncurses

drv_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB, int beepFlag)
{
    SCREEN *sp;
    int res = ERR;

    AssertTCB();
    SetSP();

    /* FIXME: should make sure that we are not in altchar mode */
    if (beepFlag) {
	if (bell) {
	    res = NCURSES_PUTP2("bell", bell);
	    NCURSES_SP_NAME(_nc_flush) (sp);
	} else if (flash_screen) {
	    res = NCURSES_PUTP2("flash_screen", flash_screen);
	    NCURSES_SP_NAME(_nc_flush) (sp);
	}
    } else {
	if (flash_screen) {
	    res = NCURSES_PUTP2("flash_screen", flash_screen);
	    NCURSES_SP_NAME(_nc_flush) (sp);
	} else if (bell) {
	    res = NCURSES_PUTP2("bell", bell);
	    NCURSES_SP_NAME(_nc_flush) (sp);
	}
    }
    return res;
}

Project: ncurses

doupdate(void)
{
    return TINFO_DOUPDATE(CURRENT_SCREEN);
}

Project: ncurses

default_bg(NCURSES_SP_DCL0)
{
    return SP_PARM != 0 ? SP_PARM->_default_bg : COLOR_BLACK;
}

Project: ncurses

tparm_copy_valist(TPARM_DATA * data, int use_TPARM_ARG, va_list ap)
{
    int i;

    for (i = 0; i < data->num_actual; i++) {
	if (data->p_is_s[i] != 0) {
	    char *value = va_arg(ap, char *);
	    if (value == 0)
		value = dummy;
	    data->p_is_s[i] = value;
	    data->param[i] = 0;
	} else if (use_TPARM_ARG) {
	    data->param[i] = va_arg(ap, TPARM_ARG);
	} else {
	    data->param[i] = (TPARM_ARG) va_arg(ap, int);
	}
    }
}

Project: ncurses

show_databases(const char *outdir)
{
    bool specific = (outdir != 0) || getenv("TERMINFO") != 0;
    char *result;
    const char *tried = 0;

    if (outdir == 0) {
	outdir = _nc_tic_dir(0);
    }
    if ((result = valid_db_path(outdir)) != 0) {
	printf("%s\n", result);
	free(result);
    } else {
	tried = outdir;
    }

    if ((outdir = _nc_home_terminfo())) {
	if ((result = valid_db_path(outdir)) != 0) {
	    printf("%s\n", result);
	    free(result);
	} else if (!specific) {
	    tried = outdir;
	}
    }

    /*
     * If we can write in neither location, give an error message.
     */
    if (tried) {
	fflush(stdout);
	fprintf(stderr, "%s: %s (no permission)\n", _nc_progname, tried);
	ExitProgram(EXIT_FAILURE);
    }
}

Project: ncurses

check_noaddress(TERMTYPE2 *tp, const char *why)
{
    UNEXPECTED(column_address);
    UNEXPECTED(cursor_address);
    UNEXPECTED(cursor_home);
    UNEXPECTED(cursor_mem_address);
    UNEXPECTED(cursor_to_ll);
    UNEXPECTED(row_address);
    UNEXPECTED(row_address);
}

Project: ncurses

_nc_tiparm(int expected, const char *string, ...)
{
    TPARM_DATA myData;
    va_list ap;
    char *result = NULL;

    _nc_tparm_err = 0;
#ifdef TRACE
    TPS(tname) = "_nc_tiparm";
#endif /* TRACE */

    if (tparm_setup(string, &myData) == OK
	&& myData.num_actual <= expected
	&& myData.tparm_type == 0) {

	va_start(ap, string);
	tparm_copy_valist(&myData, FALSE, ap);
	va_end(ap);

	result = tparam_internal(string, &myData);
    }
    return result;
}

Project: ncurses

drv_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB, int OnFlag)
{
    SCREEN *sp = TCB->csp;

    AssertTCB();
    if (OnFlag) {
	NCURSES_PUTP2("label_on", label_on);
    } else {
	NCURSES_PUTP2("label_off", label_off);
    }
}

Project: ncurses

default_erase(void)
{
    int result;

    if (over_strike
	&& VALID_STRING(key_backspace)
	&& strlen(key_backspace) == 1) {
	result = key_backspace[0];
    } else {
	result = CERASE;
    }

    return result;
}

Project: ncurses

ClrToEOS(NCURSES_SP_DCLx NCURSES_CH_T blank)
{
    int row, col;

    row = SP_PARM->_cursrow;
    col = SP_PARM->_curscol;

    if (row < 0)
	row = 0;
    if (col < 0)
	col = 0;

    UpdateAttrs(SP_PARM, blank);
    TPUTS_TRACE("clr_eos");
    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
			    clr_eos,
			    screen_lines(SP_PARM) - row,
			    NCURSES_SP_NAME(_nc_outch));

    while (col < screen_columns(SP_PARM))
	CurScreen(SP_PARM)->_line[row].text[col++] = blank;

    for (row++; row < screen_lines(SP_PARM); row++) {
	for (col = 0; col < screen_columns(SP_PARM); col++)
	    CurScreen(SP_PARM)->_line[row].text[col] = blank;
    }
}

Project: ncurses

initialize_mousetype(SCREEN *sp)
{
    T((T_CALLED("initialize_mousetype()")));

    /* Try gpm first, because gpm may be configured to run in xterm */
#if USE_GPM_SUPPORT
    if (allow_gpm_mouse(sp)) {
	if (!sp->_mouse_gpm_loaded) {
#ifdef HAVE_LIBDL
	    load_gpm_library(sp);
#else /* !HAVE_LIBDL */
	    sp->_mouse_gpm_found = TRUE;
	    sp->_mouse_gpm_loaded = TRUE;
#endif
	}

	/*
	 * The gpm_fd file-descriptor may be negative (xterm).  So we have to
	 * maintain our notion of whether the mouse connection is active
	 * without testing the file-descriptor.
	 */
	if (sp->_mouse_gpm_found && enable_gpm_mouse(sp, TRUE)) {
	    sp->_mouse_type = M_GPM;
	    sp->_mouse_fd = *(my_gpm_fd);
	    T(("GPM mouse_fd %d", sp->_mouse_fd));
	    returnVoid;
	}
    }
#endif /* USE_GPM_SUPPORT */

    /* OS/2 VIO */
#if USE_EMX_MOUSE
    if (!sp->_emxmouse_thread
	&& strstr(SP_TERMTYPE term_names, "xterm") == 0
	&& NonEmpty(key_mouse)) {
	int handles[2];

	if (pipe(handles) < 0) {
	    perror("mouse pipe error");
	    returnVoid;
	} else {
	    int rc;

	    if (!sp->_emxmouse_buttons[0]) {
		const char *s = getenv("MOUSE_BUTTONS_123");

		sp->_emxmouse_buttons[0] = 1;
		if (s && strlen(s) >= 3) {
		    sp->_emxmouse_buttons[1] = s[0] - '0';
		    sp->_emxmouse_buttons[2] = s[1] - '0';
		    sp->_emxmouse_buttons[3] = s[2] - '0';
		} else {
		    sp->_emxmouse_buttons[1] = 1;
		    sp->_emxmouse_buttons[2] = 3;
		    sp->_emxmouse_buttons[3] = 2;
		}
	    }
	    sp->_emxmouse_wfd = handles[1];
	    M_FD(sp) = handles[0];
	    /* Needed? */
	    setmode(handles[0], O_BINARY);
	    setmode(handles[1], O_BINARY);
	    /* Do not use CRT functions, we may single-threaded. */
	    rc = DosCreateThread((unsigned long *) &sp->_emxmouse_thread,
				 mouse_server, (long) sp, 0, 8192);
	    if (rc) {
		printf("mouse thread error %d=%#x", rc, rc);
	    } else {
		sp->_mouse_type = M_XTERM;
	    }
	    returnVoid;
	}
    }
#endif /* USE_EMX_MOUSE */

#if USE_SYSMOUSE
    {
	static char dev_tty[] = "/dev/tty";
	struct mouse_info the_mouse;
	char *the_device = 0;

	if (NC_ISATTY(sp->_ifd))
	    the_device = ttyname(sp->_ifd);
	if (the_device == 0)
	    the_device = dev_tty;

	sp->_mouse_fd = open(the_device, O_RDWR);

	if (sp->_mouse_fd >= 0) {
	    /*
	     * sysmouse does not have a usable user interface for obtaining
	     * mouse events.  The logical way to proceed (reading data on a
	     * stream) only works if one opens the device as root.  Even in
	     * that mode, careful examination shows we lose events
	     * occasionally.  The interface provided for user programs is to
	     * establish a signal handler.  really.
	     *
	     * Take over SIGUSR2 for this purpose since SIGUSR1 is more
	     * likely to be used by an application.  getch() will have to
	     * handle the misleading EINTR's.
	     */
	    signal(SIGUSR2, SIG_IGN);
	    the_mouse.operation = MOUSE_MODE;
	    the_mouse.u.mode.mode = 0;
	    the_mouse.u.mode.signal = SIGUSR2;
	    if (ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse) != -1) {
		signal(SIGUSR2, handle_sysmouse);
		the_mouse.operation = MOUSE_SHOW;
		ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse);

#if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO)	/* FreeBSD > 2.x */
		{
#ifndef FBIO_GETMODE		/* FreeBSD 3.x */
#define FBIO_GETMODE    CONS_GET
#define FBIO_MODEINFO   CONS_MODEINFO
#endif /* FBIO_GETMODE */
		    video_info_t the_video;

		    if (ioctl(sp->_mouse_fd,
			      FBIO_GETMODE,
			      &the_video.vi_mode) != -1
			&& ioctl(sp->_mouse_fd,
				 FBIO_MODEINFO,
				 &the_video) != -1) {
			sp->_sysmouse_char_width = the_video.vi_cwidth;
			sp->_sysmouse_char_height = the_video.vi_cheight;
		    }
		}
#endif /* defined(FBIO_MODEINFO) || defined(CONS_MODEINFO) */

		if (sp->_sysmouse_char_width <= 0)
		    sp->_sysmouse_char_width = 8;
		if (sp->_sysmouse_char_height <= 0)
		    sp->_sysmouse_char_height = 16;
		sp->_mouse_type = M_SYSMOUSE;
		returnVoid;
	    }
	}
    }
#endif /* USE_SYSMOUSE */

#ifdef USE_TERM_DRIVER
    CallDriver(sp, td_initmouse);
#else
    /* we know how to recognize mouse events under "xterm" */
    if (NonEmpty(key_mouse)) {
	init_xterm_mouse(sp);
    } else if (strstr(SP_TERMTYPE term_names, "xterm") != 0) {
	if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK)
	    init_xterm_mouse(sp);
    }
#endif

    returnVoid;
}

Project: ncurses

__nc_putp_flush(SCREEN *sp, const char *name, const char *value)
{
    int rc = __nc_putp(sp, name, value);
    if (rc != ERR) {
	NCURSES_SP_NAME(_nc_flush) (sp);
    }
    return rc;
}

Project: ncurses

_nc_va_tracef(const char *fmt, va_list ap)
{
    static const char Called[] = T_CALLED("");
    static const char Return[] = T_RETURN("");

    bool before = FALSE;
    bool after = FALSE;
    unsigned doit = _nc_tracing;
    int save_err = errno;
    FILE *fp = MyFP;

#ifdef TRACE
    /* verbose-trace in the command-line utilities relies on this */
    if (fp == 0 && !MyInit && _nc_tracing >= DEBUG_LEVEL(1))
	fp = stderr;
#endif

    if (strlen(fmt) >= sizeof(Called) - 1) {
	if (!strncmp(fmt, Called, sizeof(Called) - 1)) {
	    before = TRUE;
	    MyLevel++;
	} else if (!strncmp(fmt, Return, sizeof(Return) - 1)) {
	    after = TRUE;
	}
	if (before || after) {
	    if ((MyLevel <= 1)
		|| (doit & TRACE_ICALLS) != 0)
		doit &= (TRACE_CALLS | TRACE_CCALLS);
	    else
		doit = 0;
	}
    }

    if (doit != 0 && fp != 0) {
#ifdef USE_PTHREADS
	/*
	 * TRACE_ICALLS is "really" needed to show normal use with threaded
	 * applications, since anything can be running during a napms(),
	 * making it appear in the hierarchical trace as it other functions
	 * are being called.
	 *
	 * Rather than add the complication of a per-thread stack, just
	 * show the thread-id in each line of the trace.
	 */
# if USE_WEAK_SYMBOLS
	if ((pthread_self))
# endif
#ifdef _WIN32
	    fprintf(fp, "%#lx:", (long) (intptr_t) pthread_self().p);
#else
	    fprintf(fp, "%#lx:", (long) (intptr_t) pthread_self());
#endif
#endif
	if (before || after) {
	    int n;
	    for (n = 1; n < MyLevel; n++)
		fputs("+ ", fp);
	}
	vfprintf(fp, fmt, ap);
	fputc('\n', fp);
	fflush(fp);
    }

    if (after && MyLevel)
	MyLevel--;

    errno = save_err;
}

Project: ncurses

tputs(const char *string, int affcnt GCC_UNUSED, int (*outc) (int) GCC_UNUSED)
/* stub tputs() that dumps sequences in a visible form */
{
    if (profiling)
	xmits += strlen(string);
    else
	(void) fputs(_nc_visbuf(string), stdout);
    return (OK);
}

Project: ncurses

drv_kpad(TERMINAL_CONTROL_BLOCK * TCB, int flag)
{
    int ret = ERR;
    SCREEN *sp;

    AssertTCB();

    sp = TCB->csp;

    if (sp) {
	if (flag) {
	    (void) __nc_putp_flush(sp, "keypad_xmit", keypad_xmit);
	} else if (!flag && keypad_local) {
	    (void) __nc_putp_flush(sp, "keypad_local", keypad_local);
	}
	if (flag && !sp->_tried) {
	    _nc_init_keytry(sp);
	    sp->_tried = TRUE;
	}
	ret = OK;
    }

    return ret;
}

Project: ncurses

drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
	      int color, int r, int g, int b)
{
    SCREEN *sp = TCB->csp;

    AssertTCB();
    if (initialize_color != NULL) {
	NCURSES_PUTP2("initialize_color",
		      TIPARM_4(initialize_color, color, r, g, b));
    }
}

Project: ncurses

drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB,
	      int delay
	      EVENTLIST_2nd(_nc_eventlist * evl))
{
    int rc = 0;
    SCREEN *sp;

    AssertTCB();
    SetSP();

#if USE_SYSMOUSE
    if ((sp->_mouse_type == M_SYSMOUSE)
	&& (sp->_sysmouse_head < sp->_sysmouse_tail)) {
	rc = TW_MOUSE;
    } else
#endif
    {
	rc = TCBOf(sp)->drv->td_twait(TCBOf(sp),
				      TWAIT_MASK,
				      delay,
				      (int *) 0
				      EVENTLIST_2nd(evl));
#if USE_SYSMOUSE
	if ((sp->_mouse_type == M_SYSMOUSE)
	    && (sp->_sysmouse_head < sp->_sysmouse_tail)
	    && (rc == 0)
	    && (errno == EINTR)) {
	    rc |= TW_MOUSE;
	}
#endif
    }
    return rc;
}

Project: ncurses

NCURSES_SP_NAME(vid_attr) (NCURSES_SP_DCLx
			   attr_t newmode,
			   NCURSES_PAIRS_T pair_arg,
			   void *opts)
{
    T((T_CALLED("vid_attr(%s,%d)"), _traceattr(newmode), (int) pair_arg));
    returnCode(NCURSES_SP_NAME(vid_puts) (NCURSES_SP_ARGx
					  newmode,
					  pair_arg,
					  opts,
					  NCURSES_SP_NAME(_nc_putchar)));
}

Project: ncurses

NCURSES_SP_NAME(_nc_mvcur_init) (NCURSES_SP_DCL0)
/* initialize the cost structure */
{
    if (SP_PARM->_ofp && NC_ISATTY(fileno(SP_PARM->_ofp))) {
	SP_PARM->_char_padding = ((BAUDBYTE * 1000 * 10)
				  / (BAUDRATE(SP_PARM) > 0
				     ? BAUDRATE(SP_PARM)
				     : 9600));
    } else {
	SP_PARM->_char_padding = 1;	/* must be nonzero */
    }
    if (SP_PARM->_char_padding <= 0)
	SP_PARM->_char_padding = 1;	/* must be nonzero */
    TR(TRACE_CHARPUT | TRACE_MOVE, ("char_padding %d msecs", SP_PARM->_char_padding));

    /* non-parameterized local-motion strings */
    SP_PARM->_cr_cost = CostOf(carriage_return, 0);
    SP_PARM->_home_cost = CostOf(cursor_home, 0);
    SP_PARM->_ll_cost = CostOf(cursor_to_ll, 0);
#if USE_HARD_TABS
    if (getenv("NCURSES_NO_HARD_TABS") == 0
	&& dest_tabs_magic_smso == 0
	&& HasHardTabs()) {
	SP_PARM->_ht_cost = CostOf(tab, 0);
	SP_PARM->_cbt_cost = CostOf(back_tab, 0);
    } else {
	SP_PARM->_ht_cost = INFINITY;
	SP_PARM->_cbt_cost = INFINITY;
    }
#endif /* USE_HARD_TABS */
    SP_PARM->_cub1_cost = CostOf(cursor_left, 0);
    SP_PARM->_cuf1_cost = CostOf(cursor_right, 0);
    SP_PARM->_cud1_cost = CostOf(cursor_down, 0);
    SP_PARM->_cuu1_cost = CostOf(cursor_up, 0);

    SP_PARM->_smir_cost = CostOf(enter_insert_mode, 0);
    SP_PARM->_rmir_cost = CostOf(exit_insert_mode, 0);
    SP_PARM->_ip_cost = 0;
    if (insert_padding) {
	SP_PARM->_ip_cost = CostOf(insert_padding, 0);
    }

    /*
     * Assumption: if the terminal has memory_relative addressing, the
     * initialization strings or smcup will set single-page mode so we
     * can treat it like absolute screen addressing.  This seems to be true
     * for all cursor_mem_address terminal types in the terminfo database.
     */
    SP_PARM->_address_cursor = cursor_address ? cursor_address : cursor_mem_address;

    /*
     * Parametrized local-motion strings.  This static cost computation
     * depends on the following assumptions:
     *
     * (1) They never have * padding.  In the entire master terminfo database
     *     as of March 1995, only the obsolete Zenith Z-100 pc violates this.
     *     (Proportional padding is found mainly in insert, delete and scroll
     *     capabilities).
     *
     * (2) The average case of cup has two two-digit parameters.  Strictly,
     *     the average case for a 24 * 80 screen has ((10*10*(1 + 1)) +
     *     (14*10*(1 + 2)) + (10*70*(2 + 1)) + (14*70*4)) / (24*80) = 3.458
     *     digits of parameters.  On a 25x80 screen the average is 3.6197.
     *     On larger screens the value gets much closer to 4.
     *
     * (3) The average case of cub/cuf/hpa/ech/rep has 2 digits of parameters
     *     (strictly, (((10 * 1) + (70 * 2)) / 80) = 1.8750).
     *
     * (4) The average case of cud/cuu/vpa has 2 digits of parameters
     *     (strictly, (((10 * 1) + (14 * 2)) / 24) = 1.5833).
     *
     * All these averages depend on the assumption that all parameter values
     * are equally probable.
     */
    SP_PARM->_cup_cost = CostOf(TIPARM_2(SP_PARM->_address_cursor, 23, 23), 1);
    SP_PARM->_cub_cost = CostOf(TIPARM_1(parm_left_cursor, 23), 1);
    SP_PARM->_cuf_cost = CostOf(TIPARM_1(parm_right_cursor, 23), 1);
    SP_PARM->_cud_cost = CostOf(TIPARM_1(parm_down_cursor, 23), 1);
    SP_PARM->_cuu_cost = CostOf(TIPARM_1(parm_up_cursor, 23), 1);
    SP_PARM->_hpa_cost = CostOf(TIPARM_1(column_address, 23), 1);
    SP_PARM->_vpa_cost = CostOf(TIPARM_1(row_address, 23), 1);

    /* non-parameterized screen-update strings */
    SP_PARM->_ed_cost = NormalizedCost(clr_eos, 1);
    SP_PARM->_el_cost = NormalizedCost(clr_eol, 1);
    SP_PARM->_el1_cost = NormalizedCost(clr_bol, 1);
    SP_PARM->_dch1_cost = NormalizedCost(delete_character, 1);
    SP_PARM->_ich1_cost = NormalizedCost(insert_character, 1);

    /*
     * If this is a bce-terminal, we want to bias the choice so we use clr_eol
     * rather than spaces at the end of a line.
     */
    if (back_color_erase)
	SP_PARM->_el_cost = 0;

    /* parameterized screen-update strings */
    SP_PARM->_dch_cost = NormalizedCost(TIPARM_1(parm_dch, 23), 1);
    SP_PARM->_ich_cost = NormalizedCost(TIPARM_1(parm_ich, 23), 1);
    SP_PARM->_ech_cost = NormalizedCost(TIPARM_1(erase_chars, 23), 1);
    SP_PARM->_rep_cost = NormalizedCost(TIPARM_2(repeat_char, ' ', 23), 1);

    SP_PARM->_cup_ch_cost = NormalizedCost(TIPARM_2(SP_PARM->_address_cursor,
						    23, 23),
					   1);
    SP_PARM->_hpa_ch_cost = NormalizedCost(TIPARM_1(column_address, 23), 1);
    SP_PARM->_cuf_ch_cost = NormalizedCost(TIPARM_1(parm_right_cursor, 23), 1);
    SP_PARM->_inline_cost = min(SP_PARM->_cup_ch_cost,
				min(SP_PARM->_hpa_ch_cost,
				    SP_PARM->_cuf_ch_cost));

    /*
     * If save_cursor is used within enter_ca_mode, we should not use it for
     * scrolling optimization, since the corresponding restore_cursor is not
     * nested on the various terminals (vt100, xterm, etc.) which use this
     * feature.
     */
    if (save_cursor != 0
	&& enter_ca_mode != 0
	&& strstr(enter_ca_mode, save_cursor) != 0) {
	T(("...suppressed sc/rc capability due to conflict with smcup/rmcup"));
	save_cursor = 0;
	restore_cursor = 0;
    }

    /*
     * A different, possibly better way to arrange this would be to set the
     * SCREEN's _endwin at window initialization time and let this be called by
     * doupdate's return-from-shellout code.
     */
    NCURSES_SP_NAME(_nc_mvcur_resume) (NCURSES_SP_ARG);
}

Project: ncurses

drv_twait(TERMINAL_CONTROL_BLOCK * TCB,
	  int mode,
	  int milliseconds,
	  int *timeleft
	  EVENTLIST_2nd(_nc_eventlist * evl))
{
    SCREEN *sp;

    AssertTCB();
    SetSP();

    return _nc_timed_wait(sp, mode, milliseconds, timeleft EVENTLIST_2nd(evl));
}

Project: ncurses

NCURSES_SP_NAME(mvcur) (NCURSES_SP_DCLx int yold, int xold, int ynew,
			int xnew)
{
    return _nc_real_mvcur(NCURSES_SP_ARGx
			  yold, xold,
			  ynew, xnew,
			  NCURSES_SP_NAME(_nc_putchar),
			  FALSE);
}

Project: ncurses

_nc_retrace_sp(SCREEN *code)
{
    T((T_RETURN("%p"), (void *) code));
    return code;
}

Project: ncurses

init_extended_color(int color, int r, int g, int b)
{
    return NCURSES_SP_NAME(init_extended_color) (CURRENT_SCREEN,
						 color,
						 r, g, b);
}

Project: ncurses

NCURSES_SP_NAME(mouseinterval) (NCURSES_SP_DCLx int maxclick)
/* set the maximum mouse interval within which to recognize a click */
{
    int oldval;

    T((T_CALLED("mouseinterval(%p,%d)"), (void *) SP_PARM, maxclick));

    if (SP_PARM != 0) {
	oldval = SP_PARM->_maxclick;
	if (maxclick >= 0)
	    SP_PARM->_maxclick = maxclick;
    } else {
	oldval = DEFAULT_MAXCLICK;
    }

    returnCode(oldval);
}

Project: ncurses

cvtchar(register const char *sp)
/* convert a character to a terminfo push */
{
    unsigned char c = 0;
    int len;

    switch (*sp) {
    case '\\':
	switch (*++sp) {
	case '\'':
	case '$':
	case '\\':
	case '%':
	    c = UChar(*sp);
	    len = 2;
	    break;
	case '\0':
	    c = '\\';
	    len = 1;
	    break;
	case '0':
	case '1':
	case '2':
	case '3':
	    len = 1;
	    while (isdigit(UChar(*sp))) {
		c = UChar(8 * c + (*sp++ - '0'));
		len++;
	    }
	    break;
	default:
	    c = UChar(*sp);
	    len = (c != '\0') ? 2 : 1;
	    break;
	}
	break;
    case '^':
	len = 2;
	c = UChar(*++sp);
	if (c == '?') {
	    c = 127;
	} else if (c == '\0') {
	    len = 1;
	} else {
	    c &= 0x1f;
	}
	break;
    default:
	c = UChar(*sp);
	len = (c != '\0') ? 1 : 0;
    }
    if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') {
	dp = save_string(dp, "%\'");
	dp = save_char(dp, c);
	dp = save_char(dp, '\'');
    } else if (c != '\0') {
	dp = save_string(dp, "%{");
	if (c > 99)
	    dp = save_char(dp, c / 100 + '0');
	if (c > 9)
	    dp = save_char(dp, ((int) (c / 10)) % 10 + '0');
	dp = save_char(dp, c % 10 + '0');
	dp = save_char(dp, '}');
    }
    return len;
}

Project: ncurses

_nc_mvcur_wrap(void)
{
    NCURSES_SP_NAME(_nc_mvcur_wrap) (CURRENT_SCREEN);
}

Project: ncurses

failed(const char *msg)
{
    fprintf(stderr, "%s\n", msg);
    ExitProgram(EXIT_FAILURE);
}

Project: ncurses

NCURSES_SP_NAME(_nc_screen_wrap) (NCURSES_SP_DCL0)
{
    if (SP_PARM != 0) {

	UpdateAttrs(SP_PARM, normal);
#if NCURSES_EXT_FUNCS
	if (SP_PARM->_coloron
	    && !SP_PARM->_default_color) {
	    static const NCURSES_CH_T blank = NewChar(BLANK_TEXT);
	    SP_PARM->_default_color = TRUE;
	    NCURSES_SP_NAME(_nc_do_color) (NCURSES_SP_ARGx
					   -1,
					   0,
					   FALSE,
					   NCURSES_SP_NAME(_nc_outch));
	    SP_PARM->_default_color = FALSE;

	    TINFO_MVCUR(NCURSES_SP_ARGx
			SP_PARM->_cursrow,
			SP_PARM->_curscol,
			screen_lines(SP_PARM) - 1,
			0);

	    ClrToEOL(NCURSES_SP_ARGx blank, TRUE);
	}
#endif
	if (SP_PARM->_color_defs) {
	    NCURSES_SP_NAME(_nc_reset_colors) (NCURSES_SP_ARG);
	}
    }
}

Project: ncurses

NCURSES_PUBLIC_VAR(_nc_tputs_trace) (void)
{
    return CURRENT_SCREEN ? CURRENT_SCREEN->_tputs_trace : _nc_prescreen._tputs_trace;
}

Project: ncurses

get_number(NCURSES_CONST char *cap, const char *env)
{
    int result = tgetnum(cap);
    char *value = env ? getenv(env) : 0;
    if (value != 0 && *value != 0) {
	char *next = 0;
	long check = strtol(value, &next, 10);
	if (check > 0 && *next == '\0')
	    result = (int) check;
    }
    return result;
}

Project: ncurses

print_tty_chars(TTY * old_settings, TTY * new_settings)
{
    show_tty_change(old_settings, new_settings, "Erase", VERASE, CERASE);
    show_tty_change(old_settings, new_settings, "Kill", VKILL, CKILL);
    show_tty_change(old_settings, new_settings, "Interrupt", VINTR, CINTR);
}

Project: ncurses

cleanup(void)
{
    endwin();

    fflush(stdout);
    fprintf(stderr, "\n\n%ld total cells, rate %.2f/sec\n",
	    total_chars,
	    ((double) (total_chars) / (double) (time((time_t *) 0) - started)));
}

Project: ncurses

ClrToEOL(NCURSES_SP_DCLx NCURSES_CH_T blank, int needclear)
{
    if (CurScreen(SP_PARM) != 0
	&& SP_PARM->_cursrow >= 0) {
	int j;

	for (j = SP_PARM->_curscol; j < screen_columns(SP_PARM); j++) {
	    if (j >= 0) {
		NCURSES_CH_T *cp =
		&(CurScreen(SP_PARM)->_line[SP_PARM->_cursrow].text[j]);

		if (!CharEq(*cp, blank)) {
		    *cp = blank;
		    needclear = TRUE;
		}
	    }
	}
    }

    if (needclear) {
	UpdateAttrs(SP_PARM, blank);
	if (clr_eol && SP_PARM->_el_cost <= (screen_columns(SP_PARM) - SP_PARM->_curscol)) {
	    NCURSES_PUTP2("clr_eol", clr_eol);
	} else {
	    int count = (screen_columns(SP_PARM) - SP_PARM->_curscol);
	    while (count-- > 0)
		PutChar(NCURSES_SP_ARGx CHREF(blank));
	}
    }
}

Project: ncurses

check_printer(TERMTYPE2 *tp)
{
    (void) tp;
#if defined(enter_doublewide_mode) && defined(exit_doublewide_mode)
    PAIRED(enter_doublewide_mode, exit_doublewide_mode);
#endif
#if defined(enter_italics_mode) && defined(exit_italics_mode)
    PAIRED(enter_italics_mode, exit_italics_mode);
#endif
#if defined(enter_leftward_mode) && defined(exit_leftward_mode)
    PAIRED(enter_leftward_mode, exit_leftward_mode);
#endif
#if defined(enter_micro_mode) && defined(exit_micro_mode)
    PAIRED(enter_micro_mode, exit_micro_mode);
#endif
#if defined(enter_shadow_mode) && defined(exit_shadow_mode)
    PAIRED(enter_shadow_mode, exit_shadow_mode);
#endif
#if defined(enter_subscript_mode) && defined(exit_subscript_mode)
    PAIRED(enter_subscript_mode, exit_subscript_mode);
#endif
#if defined(enter_superscript_mode) && defined(exit_superscript_mode)
    PAIRED(enter_superscript_mode, exit_superscript_mode);
#endif
#if defined(enter_upward_mode) && defined(exit_upward_mode)
    PAIRED(enter_upward_mode, exit_upward_mode);
#endif

#if defined(start_char_set_def) && defined(stop_char_set_def)
    ANDMISSING(start_char_set_def, stop_char_set_def);
#endif

    /* if we have a parameterized form, then the non-parameterized is easy */
#if defined(set_bottom_margin_parm) && defined(set_bottom_margin)
    ANDMISSING(set_bottom_margin_parm, set_bottom_margin);
#endif
#if defined(set_left_margin_parm) && defined(set_left_margin)
    ANDMISSING(set_left_margin_parm, set_left_margin);
#endif
#if defined(set_right_margin_parm) && defined(set_right_margin)
    ANDMISSING(set_right_margin_parm, set_right_margin);
#endif
#if defined(set_top_margin_parm) && defined(set_top_margin)
    ANDMISSING(set_top_margin_parm, set_top_margin);
#endif

#if defined(parm_down_micro) && defined(micro_down)
    ANDMISSING(parm_down_micro, micro_down);
#endif
#if defined(parm_left_micro) && defined(micro_left)
    ANDMISSING(parm_left_micro, micro_left);
#endif
#if defined(parm_right_micro) && defined(micro_right)
    ANDMISSING(parm_right_micro, micro_right);
#endif
#if defined(parm_up_micro) && defined(micro_up)
    ANDMISSING(parm_up_micro, micro_up);
#endif
}

Project: ncurses

handle_sysmouse(int sig GCC_UNUSED)
{
    sysmouse_server(CURRENT_SCREEN);
}

Project: ncurses

_nc_init_color(SCREEN *sp, int color, int r, int g, int b)
{
    int result = ERR;
    int maxcolors;

    T((T_CALLED("init_color(%p,%d,%d,%d,%d)"),
       (void *) sp,
       color,
       r, g, b));

    if (sp == 0 || sp->_direct_color.value)
	returnCode(result);

    maxcolors = MaxColors;

    if (InitColor
	&& sp->_coloron
	&& (color >= 0 && OkColorHi(color))
	&& (okRGB(r) && okRGB(g) && okRGB(b))) {

	sp->_color_table[color].init = 1;
	sp->_color_table[color].r = r;
	sp->_color_table[color].g = g;
	sp->_color_table[color].b = b;

	if (UseHlsPalette) {
	    rgb2hls(r, g, b,
		    &sp->_color_table[color].red,
		    &sp->_color_table[color].green,
		    &sp->_color_table[color].blue);
	} else {
	    sp->_color_table[color].red = r;
	    sp->_color_table[color].green = g;
	    sp->_color_table[color].blue = b;
	}

#ifdef USE_TERM_DRIVER
	CallDriver_4(sp, td_initcolor, color, r, g, b);
#else
	NCURSES_PUTP2("initialize_color",
		      TIPARM_4(initialize_color, color, r, g, b));
#endif
	sp->_color_defs = max(color + 1, sp->_color_defs);

	result = OK;
    }
    returnCode(result);
}

Project: ncurses

out_char(int c)
{
    return putc(c, my_file);
}

Project: ncurses

set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill)
{
    if (DISABLED(tty_settings->c_cc[VERASE]) || my_erase >= 0) {
	tty_settings->c_cc[VERASE] = UChar((my_erase >= 0)
					   ? my_erase
					   : default_erase());
    }

    if (DISABLED(tty_settings->c_cc[VINTR]) || my_intr >= 0) {
	tty_settings->c_cc[VINTR] = UChar((my_intr >= 0)
					  ? my_intr
					  : CINTR);
    }

    if (DISABLED(tty_settings->c_cc[VKILL]) || my_kill >= 0) {
	tty_settings->c_cc[VKILL] = UChar((my_kill >= 0)
					  ? my_kill
					  : CKILL);
    }
}

Project: ncurses

_nc_mouse_inline(SCREEN *sp)
/* mouse report received in the keyboard stream -- parse its info */
{
    bool result = FALSE;
    MEVENT *eventp = sp->_mouse_eventp;

    TR(MY_TRACE, ("_nc_mouse_inline() called"));

    if (sp->_mouse_type == M_XTERM) {
	switch (sp->_mouse_format) {
	case MF_X10:
	    result = decode_xterm_X10(sp, eventp);
	    break;
	case MF_SGR1006:
	    result = decode_xterm_SGR1006(sp, eventp);
	    break;
#ifdef EXP_XTERM_1005
	case MF_XTERM_1005:
	    result = decode_xterm_1005(sp, eventp);
	    break;
#endif
	}

	TR(MY_TRACE,
	   ("_nc_mouse_inline: primitive mouse-event %s has slot %ld",
	    _nc_tracemouse(sp, eventp),
	    (long) IndexEV(sp, eventp)));

	/* bump the next-free pointer into the circular list */
	sp->_mouse_eventp = NEXT(eventp);

	if (!result) {
	    /* If this event is from a wheel-mouse, treat it like position
	     * reports and avoid waiting for the release-events which will
	     * never come.
	     */
	    if (eventp->bstate & BUTTON_PRESSED) {
		int b;

		for (b = 4; b <= MAX_BUTTONS; ++b) {
		    if ((eventp->bstate & MASK_PRESS(b))) {
			result = TRUE;
			break;
		    }
		}
	    }
	}
    }

    return (result);
}

Project: ncurses

cmp_format(const void *p, const void *q)
{
    const char *a = *(char *const *) p;
    const char *b = *(char *const *) q;
    return strcmp(a, b);
}

Project: ncurses

usage(void)
{
    static const char *msg[] =
    {
	"Usage: dots_termcap [options]"
	,""
	,"Options:"
	," -T TERM  override $TERM"
	," -e       allow environment $LINES / $COLUMNS"
	," -m SIZE  set margin (default: 2)"
	," -r SECS  self-interrupt/exit after specified number of seconds"
	," -s MSECS delay 1% of the time (default: 1 msecs)"
    };
    size_t n;

    for (n = 0; n < SIZEOF(msg); n++)
	fprintf(stderr, "%s\n", msg[n]);

    ExitProgram(EXIT_FAILURE);
}

Project: ncurses

PutCharLR(NCURSES_SP_DCLx const ARG_CH_T ch)
{
    if (!auto_right_margin) {
	/* we can put the char directly */
	PutAttrChar(NCURSES_SP_ARGx ch);
    } else if (enter_am_mode && exit_am_mode) {
	/* we can suppress automargin */
	NCURSES_PUTP2("exit_am_mode", exit_am_mode);

	PutAttrChar(NCURSES_SP_ARGx ch);
	SP_PARM->_curscol--;
	position_check(NCURSES_SP_ARGx
		       SP_PARM->_cursrow,
		       SP_PARM->_curscol,
		       "exit_am_mode");

	NCURSES_PUTP2("enter_am_mode", enter_am_mode);
    } else if ((enter_insert_mode && exit_insert_mode)
	       || insert_character || parm_ich) {
	GoTo(NCURSES_SP_ARGx
	     screen_lines(SP_PARM) - 1,
	     screen_columns(SP_PARM) - 2);
	PutAttrChar(NCURSES_SP_ARGx ch);
	GoTo(NCURSES_SP_ARGx
	     screen_lines(SP_PARM) - 1,
	     screen_columns(SP_PARM) - 2);
	InsStr(NCURSES_SP_ARGx
	       NewScreen(SP_PARM)->_line[screen_lines(SP_PARM) - 1].text +
	       screen_columns(SP_PARM) - 2, 1);
    }
}

Project: ncurses

cleanup(void)
{
    outs(exit_attribute_mode);
    if (!outs(orig_colors))
	outs(orig_pair);
    outs(clear_screen);
    outs(cursor_normal);

    fflush(stdout);
    fprintf(stderr, "\n\n%ld total cells, rate %.2f/sec\n",
	    total_chars,
	    ((double) (total_chars) / (double) (time((time_t *) 0) - started)));
}

Project: ncurses

compare_part(const char *part, const char *full)
{
    const char *next_part;
    const char *next_full;
    unsigned used_full = 0;
    unsigned used_delay = 0;

    while (*part != 0) {
	if (*part != *full) {
	    used_full = 0;
	    break;
	}

	/*
	 * Adjust the return-value to allow the rare case of
	 *      string<delay>string
	 * to remove the whole piece.  The most common case is a delay at the
	 * end of the string.  The adjusted string will retain the delay, which
	 * is conservative.
	 */
	if (used_delay != 0) {
	    used_full += used_delay;
	    used_delay = 0;
	}
	if (*part == '$' && *full == '$') {
	    next_part = skip_delay(part);
	    next_full = skip_delay(full);
	    if (next_part != part && next_full != full) {
		used_delay += (unsigned) (next_full - full);
		full = next_full;
		part = next_part;
		continue;
	    }
	}
	++used_full;
	++part;
	++full;
    }
    return used_full;
}

Project: ncurses

NCURSES_SP_NAME(init_extended_color) (NCURSES_SP_DCLx
				      int color,
				      int r, int g, int b)
{
    return _nc_init_color(SP_PARM, color, r, g, b);
}

Project: ncurses

_nc_retrace_char(int code)
{
    T((T_RETURN("%c"), code));
    return (char) code;
}

Project: ncurses

mouse_server(unsigned long param)
#endif
{
    SCREEN *sp = (SCREEN *) param;
    unsigned short fWait = MOU_WAIT;
    /* NOPTRRECT mourt = { 0,0,24,79 }; */
    MOUEVENTINFO mouev;
    HMOU hmou;
    unsigned short mask = MOUSE_BN1_DOWN | MOUSE_BN2_DOWN | MOUSE_BN3_DOWN;
    int nbuttons = 3;
    int oldstate = 0;
    char err[80];
    unsigned long rc;

    /* open the handle for the mouse */
    if (MouOpen(NULL, &hmou) == 0) {
	rc = MouSetEventMask(&mask, hmou);
	if (rc) {		/* retry with 2 buttons */
	    mask = MOUSE_BN1_DOWN | MOUSE_BN2_DOWN;
	    rc = MouSetEventMask(&mask, hmou);
	    nbuttons = 2;
	}
	if (rc == 0 && MouDrawPtr(hmou) == 0) {
	    for (;;) {
		/* sit and wait on the event queue */
		rc = MouReadEventQue(&mouev, &fWait, hmou);
		if (rc) {
		    _nc_SPRINTF(err, _nc_SLIMIT(sizeof(err))
				"Error reading mouse queue, rc=%lu.\r\n", rc);
		    break;
		}
		if (!sp->_emxmouse_activated)
		    goto finish;

		/*
		 * OS/2 numbers a 3-button mouse inconsistently from other
		 * platforms:
		 *      1 = left
		 *      2 = right
		 *      3 = middle.
		 */
		if ((mouev.fs ^ oldstate) & MOUSE_BN1_DOWN)
		    write_event(sp, mouev.fs & MOUSE_BN1_DOWN,
				sp->_emxmouse_buttons[1], mouev.col, mouev.row);
		if ((mouev.fs ^ oldstate) & MOUSE_BN2_DOWN)
		    write_event(sp, mouev.fs & MOUSE_BN2_DOWN,
				sp->_emxmouse_buttons[3], mouev.col, mouev.row);
		if ((mouev.fs ^ oldstate) & MOUSE_BN3_DOWN)
		    write_event(sp, mouev.fs & MOUSE_BN3_DOWN,
				sp->_emxmouse_buttons[2], mouev.col, mouev.row);

	      finish:
		oldstate = mouev.fs;
	    }
	} else {
	    _nc_SPRINTF(err, _nc_SLIMIT(sizeof(err))
			"Error setting event mask, buttons=%d, rc=%lu.\r\n",
			nbuttons, rc);
	}

	DosWrite(2, err, strlen(err), &rc);
	MouClose(hmou);
    }
    DosExit(EXIT_THREAD, 0L);
}

Project: ncurses

expected_params(const char *name)
{
#define DATA(name,count) { { name }, count }
    /* *INDENT-OFF* */
    static const struct {
	const char name[9];
	int count;
    } table[] = {
	DATA( "S0",		1 ),	/* 'screen' extension */
	DATA( "birep",		2 ),
	DATA( "chr",		1 ),
	DATA( "colornm",	1 ),
	DATA( "cpi",		1 ),
	DATA( "csnm",		1 ),
	DATA( "csr",		2 ),
	DATA( "cub",		1 ),
	DATA( "cud",		1 ),
	DATA( "cuf",		1 ),
	DATA( "cup",		2 ),
	DATA( "cuu",		1 ),
	DATA( "cvr",		1 ),
	DATA( "cwin",		5 ),
	DATA( "dch",		1 ),
	DATA( "defc",		3 ),
	DATA( "dial",		1 ),
	DATA( "dispc",		1 ),
	DATA( "dl",		1 ),
	DATA( "ech",		1 ),
	DATA( "getm",		1 ),
	DATA( "hpa",		1 ),
	DATA( "ich",		1 ),
	DATA( "il",		1 ),
	DATA( "indn",		1 ),
	DATA( "initc",		4 ),
	DATA( "initp",		7 ),
	DATA( "lpi",		1 ),
	DATA( "mc5p",		1 ),
	DATA( "mrcup",		2 ),
	DATA( "mvpa",		1 ),
	DATA( "pfkey",		2 ),
	DATA( "pfloc",		2 ),
	DATA( "pfx",		2 ),
	DATA( "pfxl",		3 ),
	DATA( "pln",		2 ),
	DATA( "qdial",		1 ),
	DATA( "rcsd",		1 ),
	DATA( "rep",		2 ),
	DATA( "rin",		1 ),
	DATA( "sclk",		3 ),
	DATA( "scp",		1 ),
	DATA( "scs",		1 ),
	DATA( "scsd",		2 ),
	DATA( "setab",		1 ),
	DATA( "setaf",		1 ),
	DATA( "setb",		1 ),
	DATA( "setcolor",	1 ),
	DATA( "setf",		1 ),
	DATA( "sgr",		9 ),
	DATA( "sgr1",		6 ),
	DATA( "slength",	1 ),
	DATA( "slines",		1 ),
	DATA( "smgbp",		1 ),	/* 2 if smgtp is not given */
	DATA( "smglp",		1 ),
	DATA( "smglr",		2 ),
	DATA( "smgrp",		1 ),
	DATA( "smgtb",		2 ),
	DATA( "smgtp",		1 ),
	DATA( "tsl",		1 ),
	DATA( "u6",		-1 ),
	DATA( "vpa",		1 ),
	DATA( "wind",		4 ),
	DATA( "wingo",		1 ),
    };
    /* *INDENT-ON* */
#undef DATA

    unsigned n;
    int result = 0;		/* function-keys, etc., use none */

    for (n = 0; n < SIZEOF(table); n++) {
	if (!strcmp(name, table[n].name)) {
	    result = table[n].count;
	    break;
	}
    }

    return result;
}

Project: ncurses

spop(void)
{
    char *result = dummy;
    if (TPS(stack_ptr) > 0) {
	TPS(stack_ptr)--;
	if (!TPS(stack)[TPS(stack_ptr)].num_type
	    && TPS(stack)[TPS(stack_ptr)].data.str != 0)
	    result = TPS(stack)[TPS(stack_ptr)].data.str;
    } else {
	DEBUG(2, ("spop: stack underflow: %s", _nc_visbuf(TPS(tparam_base))));
	_nc_tparm_err++;
    }
    return result;
}

Project: ncurses

_nc_mvcur_init(void)
{
    NCURSES_SP_NAME(_nc_mvcur_init) (CURRENT_SCREEN);
}

Project: ncurses

NCURSES_SP_NAME(extended_color_content) (NCURSES_SP_DCLx
					 int color,
					 int *r, int *g, int *b)
{
    return _nc_color_content(SP_PARM, color, r, g, b);
}

Project: ncurses

same_color(NCURSES_CONST char *oldcap, NCURSES_CONST char *newcap, int limit)
{
    bool result = FALSE;
    if (limit > 16)
	limit = 16;
    if (limit >= 8) {
	int n;
	int same;
	for (n = same = 0; n < limit; ++n) {
	    char *oldvalue = safe_strdup(TIPARM_1(oldcap, n));
	    char *newvalue = safe_strdup(TIPARM_1(newcap, n));
	    same += !strcmp(oldvalue, newvalue);
	    free(oldvalue);
	    free(newvalue);
	}
	result = (same == limit);
    }
    return result;
}

Project: ncurses

mcprint(char *data, int len)
{
    return NCURSES_SP_NAME(mcprint) (CURRENT_SCREEN, data, len);
}

Project: ncurses

default_bg(SCREEN *sp)
{
#if NCURSES_EXT_FUNCS
    return sp != 0 ? sp->_default_bg : COLOR_BLACK;
#else
    return COLOR_BLACK;
#endif
}

Project: ncurses

check_delays(TERMTYPE2 *tp, const char *name, const char *value)
{
    const char *p, *q;
    const char *first = 0;
    const char *last = 0;

    for (p = value; *p != '\0'; ++p) {
	if (p[0] == '$' && p[1] == '<') {
	    const char *base = p + 2;
	    const char *mark = 0;
	    bool maybe = TRUE;
	    bool mixed = FALSE;
	    int proportional = 0;
	    int mandatory = 0;

	    first = p;

	    for (q = base; *q != '\0'; ++q) {
		if (*q == '>') {
		    if (mark == 0)
			mark = q;
		    break;
		} else if (*q == '*' || *q == '/') {
		    if (*q == '*')
			++proportional;
		    if (*q == '/')
			++mandatory;
		    if (mark == 0)
			mark = q;
		} else if (!(isalnum(UChar(*q)) || strchr("+-.", *q) != 0)) {
		    maybe = FALSE;
		    break;
		} else if (proportional || mandatory) {
		    mixed = TRUE;
		}
	    }
	    last = *q ? (q + 1) : q;
	    if (*q == '\0') {
		maybe = FALSE;	/* just an isolated "$<" */
	    } else if (maybe) {
		float check_f;
		char check_c;
		int rc = sscanf(base, "%f%c", &check_f, &check_c);
		if ((rc != 2) || (check_c != *mark) || mixed) {
		    _nc_warning("syntax error in %s delay '%.*s'", name,
				(int) (q - base), base);
		} else if (*name == 'k') {
		    _nc_warning("function-key %s has delay", name);
		} else if (proportional && !line_capability(name)) {
		    _nc_warning("non-line capability using proportional delay: %s", name);
		} else if (!xon_xoff &&
			   !mandatory &&
			   strchr(_nc_first_name(tp->term_names), '+') == 0) {
		    _nc_warning("%s in %s is used since no xon/xoff",
				(proportional
				 ? "proportional delay"
				 : "delay"),
				name);
		}
	    } else {
		p = q - 1;	/* restart scan */
	    }
	}
    }

    if (!strcmp(name, "flash") ||
	!strcmp(name, "beep")) {

	if (first != 0) {
	    if (first == value || *last == 0) {
		/*
		 * Delay is on one end or the other.
		 */
		_nc_warning("expected delay embedded within %s", name);
	    }
	} else {
	    int flag;

	    /*
	     * Check for missing delay when using VT100 reverse-video.
	     * A real VT100 might not need this, but terminal emulators do.
	     */
	    if ((p = skip_DECSCNM(value, &flag)) != 0 &&
		flag > 0 &&
		(q = skip_DECSCNM(p, &flag)) != 0 &&
		flag == 0) {
		_nc_warning("expected a delay in %s", name);
	    }
	}
    }
}

Project: ncurses

drv_setsize(TERMINAL_CONTROL_BLOCK * TCB, int l, int c)
{
    AssertTCB();
    lines = (short) l;
    columns = (short) c;
    return OK;
}

Project: ncurses

check_acs(TERMTYPE2 *tp)
{
    int vt100_smacs = 0;
    int vt100_rmacs = 0;
    int vt100_enacs = 0;

    /*
     * ena_acs is not always necessary, but if it is present, the enter/exit
     * capabilities should be.
     */
    ANDMISSING(ena_acs, enter_alt_charset_mode);
    ANDMISSING(ena_acs, exit_alt_charset_mode);
    PAIRED(exit_alt_charset_mode, exit_alt_charset_mode);

    /*
     * vt100-like is frequently used, but perhaps ena_acs is missing, etc.
     */
    if (VALID_STRING(enter_alt_charset_mode)) {
	vt100_smacs = (!strcmp("\033(0", enter_alt_charset_mode)
		       ? 2
		       : (!strcmp("\016", enter_alt_charset_mode)
			  ? 1
			  : 0));
    }
    if (VALID_STRING(exit_alt_charset_mode)) {
	vt100_rmacs = (!strcmp("\033(B", exit_alt_charset_mode)
		       ? 2
		       : (!strcmp("\017", exit_alt_charset_mode)
			  ? 1
			  : 0));
    }
    if (VALID_STRING(ena_acs)) {
	vt100_enacs = (!strcmp("\033(B\033)0", ena_acs)
		       ? 2
		       : 0);
    }
    if (vt100_rmacs && vt100_smacs && (vt100_rmacs != vt100_smacs)) {
	_nc_warning("rmacs/smacs are inconsistent");
    }
    if ((vt100_rmacs == 2) && (vt100_smacs == 2) && vt100_enacs) {
	_nc_warning("rmacs/smacs make enacs redundant");
    }
    if ((vt100_rmacs == 1) && (vt100_smacs == 1) && !vt100_enacs) {
	_nc_warning("VT100-style rmacs/smacs require enacs");
    }

    if (VALID_STRING(acs_chars)) {
	const char *boxes = "lmkjtuvwqxn";
	char mapped[256];
	char missing[256];
	const char *p;
	char *q;

	memset(mapped, 0, sizeof(mapped));
	for (p = acs_chars; *p != '\0'; p += 2) {
	    if (p[1] == '\0') {
		_nc_warning("acsc has odd number of characters");
		break;
	    }
	    mapped[UChar(p[0])] = p[1];
	}

	if (mapped[UChar('I')] && !mapped[UChar('i')]) {
	    _nc_warning("acsc refers to 'I', which is probably an error");
	}

	for (p = boxes, q = missing; *p != '\0'; ++p) {
	    if (!mapped[UChar(p[0])]) {
		*q++ = p[0];
	    }
	}
	*q = '\0';

	assert(strlen(missing) <= strlen(boxes));
	if (*missing != '\0' && strcmp(missing, boxes)) {
	    _nc_warning("acsc is missing some line-drawing mapping: %s", missing);
	}
    }
}

Project: ncurses

TINFO_DOUPDATE(NCURSES_SP_DCL0)
{
    int i;
    int nonempty;
#if USE_TRACE_TIMES
    struct tms before, after;
#endif /* USE_TRACE_TIMES */

    T((T_CALLED("_nc_tinfo:doupdate(%p)"), (void *) SP_PARM));

    _nc_lock_global(update);

    if (SP_PARM == 0) {
	_nc_unlock_global(update);
	returnCode(ERR);
    }
#if !USE_REENTRANT
    /*
     * It is "legal" but unlikely that an application could assign a new
     * value to one of the standard windows.  Check for that possibility
     * and try to recover.
     *
     * We do not allow applications to assign new values in the reentrant
     * model.
     */
#define SyncScreens(internal,exported) \
	if (internal == 0) internal = exported; \
	if (internal != exported) exported = internal

    SyncScreens(CurScreen(SP_PARM), curscr);
    SyncScreens(NewScreen(SP_PARM), newscr);
    SyncScreens(StdScreen(SP_PARM), stdscr);
#endif

    if (CurScreen(SP_PARM) == 0
	|| NewScreen(SP_PARM) == 0
	|| StdScreen(SP_PARM) == 0) {
	_nc_unlock_global(update);
	returnCode(ERR);
    }
#ifdef TRACE
    if (USE_TRACEF(TRACE_UPDATE)) {
	if (CurScreen(SP_PARM)->_clear)
	    _tracef("curscr is clear");
	else
	    _tracedump("curscr", CurScreen(SP_PARM));
	_tracedump("newscr", NewScreen(SP_PARM));
	_nc_unlock_global(tracef);
    }
#endif /* TRACE */

    _nc_signal_handler(FALSE);

    if (SP_PARM->_fifohold)
	SP_PARM->_fifohold--;

#if USE_SIZECHANGE
    if ((SP_PARM->_endwin == ewSuspend)
	|| _nc_handle_sigwinch(SP_PARM)) {
	/*
	 * This is a transparent extension:  XSI does not address it,
	 * and applications need not know that ncurses can do it.
	 *
	 * Check if the terminal size has changed while curses was off
	 * (this can happen in an xterm, for example), and resize the
	 * ncurses data structures accordingly.
	 */
	_nc_update_screensize(SP_PARM);
    }
#endif

    if (SP_PARM->_endwin == ewSuspend) {

	T(("coming back from shell mode"));
	NCURSES_SP_NAME(reset_prog_mode) (NCURSES_SP_ARG);

	NCURSES_SP_NAME(_nc_mvcur_resume) (NCURSES_SP_ARG);
	NCURSES_SP_NAME(_nc_screen_resume) (NCURSES_SP_ARG);
	SP_PARM->_mouse_resume(SP_PARM);

	SP_PARM->_endwin = ewRunning;
    }
#if USE_TRACE_TIMES
    /* zero the metering machinery */
    RESET_OUTCHARS();
    (void) times(&before);
#endif /* USE_TRACE_TIMES */

    /*
     * This is the support for magic-cookie terminals.  The theory:  we scan
     * the virtual screen looking for attribute turnons.  Where we find one,
     * check to make sure it's realizable by seeing if the required number of
     * un-attributed blanks are present before and after the attributed range;
     * try to shift the range boundaries over blanks (not changing the screen
     * display) so this becomes true.  If it is, shift the beginning attribute
     * change appropriately (the end one, if we've gotten this far, is
     * guaranteed room for its cookie).  If not, nuke the added attributes out
     * of the span.
     */
#if USE_XMC_SUPPORT
    if (magic_cookie_glitch > 0) {
	int j, k;
	attr_t rattr = A_NORMAL;

	for (i = 0; i < screen_lines(SP_PARM); i++) {
	    for (j = 0; j < screen_columns(SP_PARM); j++) {
		bool failed = FALSE;
		NCURSES_CH_T *thisline = NewScreen(SP_PARM)->_line[i].text;
		attr_t thisattr = AttrOf(thisline[j]) & SP_PARM->_xmc_triggers;
		attr_t turnon = thisattr & ~rattr;

		/* is an attribute turned on here? */
		if (turnon == 0) {
		    rattr = thisattr;
		    continue;
		}

		TR(TRACE_ATTRS, ("At (%d, %d): from %s...", i, j, _traceattr(rattr)));
		TR(TRACE_ATTRS, ("...to %s", _traceattr(turnon)));

		/*
		 * If the attribute change location is a blank with a "safe"
		 * attribute, undo the attribute turnon.  This may ensure
		 * there's enough room to set the attribute before the first
		 * non-blank in the run.
		 */
#define SAFE(scr,a)	(!((a) & (scr)->_xmc_triggers))
		if (ISBLANK(thisline[j]) && SAFE(SP_PARM, turnon)) {
		    RemAttr(thisline[j], turnon);
		    continue;
		}

		/* check that there's enough room at start of span */
		for (k = 1; k <= magic_cookie_glitch; k++) {
		    if (j - k < 0
			|| !ISBLANK(thisline[j - k])
			|| !SAFE(SP_PARM, AttrOf(thisline[j - k]))) {
			failed = TRUE;
			TR(TRACE_ATTRS, ("No room at start in %d,%d%s%s",
					 i, j - k,
					 (ISBLANK(thisline[j - k])
					  ? ""
					  : ":nonblank"),
					 (SAFE(SP_PARM, AttrOf(thisline[j - k]))
					  ? ""
					  : ":unsafe")));
			break;
		    }
		}
		if (!failed) {
		    bool end_onscreen = FALSE;
		    int m, n = j;

		    /* find end of span, if it's onscreen */
		    for (m = i; m < screen_lines(SP_PARM); m++) {
			for (; n < screen_columns(SP_PARM); n++) {
			    attr_t testattr =
			    AttrOf(NewScreen(SP_PARM)->_line[m].text[n]);
			    if ((testattr & SP_PARM->_xmc_triggers) == rattr) {
				end_onscreen = TRUE;
				TR(TRACE_ATTRS,
				   ("Range attributed with %s ends at (%d, %d)",
				    _traceattr(turnon), m, n));
				goto foundit;
			    }
			}
			n = 0;
		    }
		    TR(TRACE_ATTRS,
		       ("Range attributed with %s ends offscreen",
			_traceattr(turnon)));
		  foundit:;

		    if (end_onscreen) {
			NCURSES_CH_T *lastline =
			NewScreen(SP_PARM)->_line[m].text;

			/*
			 * If there are safely-attributed blanks at the end of
			 * the range, shorten the range.  This will help ensure
			 * that there is enough room at end of span.
			 */
			while (n >= 0
			       && ISBLANK(lastline[n])
			       && SAFE(SP_PARM, AttrOf(lastline[n]))) {
			    RemAttr(lastline[n--], turnon);
			}

			/* check that there's enough room at end of span */
			for (k = 1; k <= magic_cookie_glitch; k++) {
			    if (n + k >= screen_columns(SP_PARM)
				|| !ISBLANK(lastline[n + k])
				|| !SAFE(SP_PARM, AttrOf(lastline[n + k]))) {
				failed = TRUE;
				TR(TRACE_ATTRS,
				   ("No room at end in %d,%d%s%s",
				    i, j - k,
				    (ISBLANK(lastline[n + k])
				     ? ""
				     : ":nonblank"),
				    (SAFE(SP_PARM, AttrOf(lastline[n + k]))
				     ? ""
				     : ":unsafe")));
				break;
			    }
			}
		    }
		}

		if (failed) {
		    int p, q = j;

		    TR(TRACE_ATTRS,
		       ("Clearing %s beginning at (%d, %d)",
			_traceattr(turnon), i, j));

		    /* turn off new attributes over span */
		    for (p = i; p < screen_lines(SP_PARM); p++) {
			for (; q < screen_columns(SP_PARM); q++) {
			    attr_t testattr = AttrOf(newscr->_line[p].text[q]);
			    if ((testattr & SP_PARM->_xmc_triggers) == rattr)
				goto foundend;
			    RemAttr(NewScreen(SP_PARM)->_line[p].text[q], turnon);
			}
			q = 0;
		    }
		  foundend:;
		} else {
		    TR(TRACE_ATTRS,
		       ("Cookie space for %s found before (%d, %d)",
			_traceattr(turnon), i, j));

		    /*
		     * Back up the start of range so there's room for cookies
		     * before the first nonblank character.
		     */
		    for (k = 1; k <= magic_cookie_glitch; k++)
			AddAttr(thisline[j - k], turnon);
		}

		rattr = thisattr;
	    }
	}

#ifdef TRACE
	/* show altered highlights after magic-cookie check */
	if (USE_TRACEF(TRACE_UPDATE)) {
	    _tracef("After magic-cookie check...");
	    _tracedump("newscr", NewScreen(SP_PARM));
	    _nc_unlock_global(tracef);
	}
#endif /* TRACE */
    }
#endif /* USE_XMC_SUPPORT */

    nonempty = 0;
    if (CurScreen(SP_PARM)->_clear || NewScreen(SP_PARM)->_clear) {	/* force refresh ? */
	ClrUpdate(NCURSES_SP_ARG);
	CurScreen(SP_PARM)->_clear = FALSE;	/* reset flag */
	NewScreen(SP_PARM)->_clear = FALSE;	/* reset flag */
    } else {
	int changedlines = CHECK_INTERVAL;

	if (check_pending(NCURSES_SP_ARG))
	    goto cleanup;

	nonempty = min(screen_lines(SP_PARM), NewScreen(SP_PARM)->_maxy + 1);

	if (SP_PARM->_scrolling) {
	    NCURSES_SP_NAME(_nc_scroll_optimize) (NCURSES_SP_ARG);
	}

	nonempty = ClrBottom(NCURSES_SP_ARGx nonempty);

	TR(TRACE_UPDATE, ("Transforming lines, nonempty %d", nonempty));
	for (i = 0; i < nonempty; i++) {
	    /*
	     * Here is our line-breakout optimization.
	     */
	    if (changedlines == CHECK_INTERVAL) {
		if (check_pending(NCURSES_SP_ARG))
		    goto cleanup;
		changedlines = 0;
	    }

	    /*
	     * newscr->line[i].firstchar is normally set
	     * by wnoutrefresh.  curscr->line[i].firstchar
	     * is normally set by _nc_scroll_window in the
	     * vertical-movement optimization code,
	     */
	    if (NewScreen(SP_PARM)->_line[i].firstchar != _NOCHANGE
		|| CurScreen(SP_PARM)->_line[i].firstchar != _NOCHANGE) {
		TransformLine(NCURSES_SP_ARGx i);
		changedlines++;
	    }

	    /* mark line changed successfully */
	    if (i <= NewScreen(SP_PARM)->_maxy) {
		MARK_NOCHANGE(NewScreen(SP_PARM), i);
	    }
	    if (i <= CurScreen(SP_PARM)->_maxy) {
		MARK_NOCHANGE(CurScreen(SP_PARM), i);
	    }
	}
    }

    /* put everything back in sync */
    for (i = nonempty; i <= NewScreen(SP_PARM)->_maxy; i++) {
	MARK_NOCHANGE(NewScreen(SP_PARM), i);
    }
    for (i = nonempty; i <= CurScreen(SP_PARM)->_maxy; i++) {
	MARK_NOCHANGE(CurScreen(SP_PARM), i);
    }

    if (!NewScreen(SP_PARM)->_leaveok) {
	CurScreen(SP_PARM)->_curx = NewScreen(SP_PARM)->_curx;
	CurScreen(SP_PARM)->_cury = NewScreen(SP_PARM)->_cury;

	GoTo(NCURSES_SP_ARGx CurScreen(SP_PARM)->_cury, CurScreen(SP_PARM)->_curx);
    }

  cleanup:
    /*
     * We would like to keep the physical screen in normal mode in case we get
     * other processes writing to the screen.  This goal cannot be met for
     * magic cookies since it interferes with attributes that may propagate
     * past the current position.
     */
#if USE_XMC_SUPPORT
    if (magic_cookie_glitch != 0)
#endif
	UpdateAttrs(SP_PARM, normal);

    NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
    WINDOW_ATTRS(CurScreen(SP_PARM)) = WINDOW_ATTRS(NewScreen(SP_PARM));

#if USE_TRACE_TIMES
    (void) times(&after);
    TR(TRACE_TIMES,
       ("Update cost: %ld chars, %ld clocks system time, %ld clocks user time",
	_nc_outchars,
	(long) (after.tms_stime - before.tms_stime),
	(long) (after.tms_utime - before.tms_utime)));
#endif /* USE_TRACE_TIMES */

    _nc_signal_handler(TRUE);

    _nc_unlock_global(update);
    returnCode(OK);
}

Project: ncurses

enable_gpm_mouse(SCREEN *sp, bool enable)
{
    bool result;

    T((T_CALLED("enable_gpm_mouse(%d)"), enable));

    if (enable && !sp->_mouse_active) {
#ifdef HAVE_LIBDL
	if (sp->_mouse_gpm_found && !sp->_mouse_gpm_loaded) {
	    load_gpm_library(sp);
	}
#endif
	if (sp->_mouse_gpm_loaded) {
	    int code;

	    /* GPM: initialize connection to gpm server */
	    sp->_mouse_gpm_connect.eventMask = GPM_DOWN | GPM_UP;
	    sp->_mouse_gpm_connect.defaultMask =
		(unsigned short) (~(sp->_mouse_gpm_connect.eventMask | GPM_HARD));
	    sp->_mouse_gpm_connect.minMod = 0;
	    sp->_mouse_gpm_connect.maxMod =
		(unsigned short) (~((1 << KG_SHIFT) |
				    (1 << KG_SHIFTL) |
				    (1 << KG_SHIFTR)));
	    /*
	     * Note: GPM hardcodes \E[?1001s and \E[?1000h during its open.
	     * The former is recognized by wscons (SunOS), and the latter by
	     * xterm.  Those will not show up in ncurses' traces.
	     */
	    code = my_Gpm_Open(&sp->_mouse_gpm_connect, 0);
	    result = (code >= 0);

	    /*
	     * GPM can return a -2 if it is trying to do something with xterm.
	     * Ignore that, since it conflicts with our use of stdin.
	     */
	    if (code == -2) {
		my_Gpm_Close();
	    }
	} else {
	    result = FALSE;
	}
	sp->_mouse_active = result;
	T(("GPM open %s", result ? "succeeded" : "failed"));
    } else {
	if (!enable && sp->_mouse_active) {
	    /* GPM: close connection to gpm server */
	    my_Gpm_Close();
	    sp->_mouse_active = FALSE;
	    T(("GPM closed"));
	}
	result = enable;
    }
#ifdef HAVE_LIBDL
    if (!result) {
	unload_gpm_library(sp);
    }
#endif
    returnBool(result);
}

Project: ncurses

trace(const unsigned int tracelevel)
{
    curses_trace(tracelevel);
}

Project: ncurses

skip_delay(const char *s)
{
    if (s[0] == '$' && s[1] == '<') {
	s += 2;
	while (isdigit(UChar(*s)) || *s == '/')
	    ++s;
	if (*s == '>')
	    ++s;
    }
    return s;
}

Project: ncurses

save_char(int c)
{
    if (c == 0)
	c = 0200;
    get_space((size_t) 1);
    TPS(out_buff)[TPS(out_used)++] = (char) c;
}

Project: ncurses

load_term(void)
{
    (void) setupterm(tname, STDOUT_FILENO, NULL);
}

Project: ncurses

reset_color_pair(NCURSES_SP_DCL0)
{
#ifdef USE_TERM_DRIVER
    return CallDriver(SP_PARM, td_rescol);
#else
    bool result = FALSE;

    (void) SP_PARM;
    if (orig_pair != 0) {
	(void) NCURSES_PUTP2("orig_pair", orig_pair);
	result = TRUE;
    }
    return result;
#endif
}

Project: ncurses

_nc_cookie_init(SCREEN *sp)
{
    bool support_cookies = USE_XMC_SUPPORT;
    TERMINAL_CONTROL_BLOCK *TCB = (TERMINAL_CONTROL_BLOCK *) (sp->_term);

    if (sp == 0 || !ENSURE_TINFO(sp))
	return;

#if USE_XMC_SUPPORT
    /*
     * If we have no magic-cookie support compiled-in, or if it is suppressed
     * in the environment, reset the support-flag.
     */
    if (magic_cookie_glitch >= 0) {
	if (getenv("NCURSES_NO_MAGIC_COOKIE") != 0) {
	    support_cookies = FALSE;
	}
    }
#endif

    if (!support_cookies && magic_cookie_glitch >= 0) {
	T(("will disable attributes to work w/o magic cookies"));
    }

    if (magic_cookie_glitch > 0) {	/* tvi, wyse */

	sp->_xmc_triggers = sp->_ok_attributes & XMC_CONFLICT;
#if 0
	/*
	 * We "should" treat colors as an attribute.  The wyse350 (and its
	 * clones) appear to be the only ones that have both colors and magic
	 * cookies.
	 */
	if (has_colors()) {
	    sp->_xmc_triggers |= A_COLOR;
	}
#endif
	sp->_xmc_suppress = sp->_xmc_triggers & (chtype) ~(A_BOLD);

	T(("magic cookie attributes %s", _traceattr(sp->_xmc_suppress)));
	/*
	 * Supporting line-drawing may be possible.  But make the regular
	 * video attributes work first.
	 */
	acs_chars = ABSENT_STRING;
	ena_acs = ABSENT_STRING;
	enter_alt_charset_mode = ABSENT_STRING;
	exit_alt_charset_mode = ABSENT_STRING;
#if USE_XMC_SUPPORT
	/*
	 * To keep the cookie support simple, suppress all of the optimization
	 * hooks except for clear_screen and the cursor addressing.
	 */
	if (support_cookies) {
	    clr_eol = ABSENT_STRING;
	    clr_eos = ABSENT_STRING;
	    set_attributes = ABSENT_STRING;
	}
#endif
    } else if (magic_cookie_glitch == 0) {	/* hpterm */
    }

    /*
     * If magic cookies are not supported, cancel the strings that set
     * video attributes.
     */
    if (!support_cookies && magic_cookie_glitch >= 0) {
	magic_cookie_glitch = ABSENT_NUMERIC;
	set_attributes = ABSENT_STRING;
	enter_blink_mode = ABSENT_STRING;
	enter_bold_mode = ABSENT_STRING;
	enter_dim_mode = ABSENT_STRING;
	enter_reverse_mode = ABSENT_STRING;
	enter_standout_mode = ABSENT_STRING;
	enter_underline_mode = ABSENT_STRING;
    }

    /* initialize normal acs before wide, since we use mapping in the latter */
#if !USE_WIDEC_SUPPORT
    if (_nc_unicode_locale() && _nc_locale_breaks_acs(sp->_term)) {
	acs_chars = NULL;
	ena_acs = NULL;
	enter_alt_charset_mode = NULL;
	exit_alt_charset_mode = NULL;
	set_attributes = NULL;
    }
#endif
}

Project: ncurses

mousemask(mmask_t newmask, mmask_t * oldmask)
{
    return NCURSES_SP_NAME(mousemask) (CURRENT_SCREEN, newmask, oldmask);
}

Project: ncurses

default_fg(NCURSES_SP_DCL0)
{
    return (SP_PARM != 0) ? SP_PARM->_default_fg : COLOR_WHITE;
}

Project: ncurses

failed(const char *msg)
{
    int code = errno;

    (void) fprintf(stderr, "%s: %s: %s\n", _nc_progname, msg, strerror(code));
    restore_tty_settings();
    (void) fprintf(my_file, "\n");
    fflush(my_file);
    ExitProgram(ErrSystem(code));
    /* NOTREACHED */
}

Project: ncurses

ignore_delays(char *s)
{
    int delaying = 0;

    do {
	switch (*s) {
	case '$':
	    if (delaying == 0)
		delaying = 1;
	    break;
	case '<':
	    if (delaying == 1)
		delaying = 2;
	    break;
	case '\0':
	    delaying = 0;
	    break;
	default:
	    if (delaying) {
		s = skip_delay(s);
		if (*s == '>')
		    ++s;
		delaying = 0;
	    }
	    break;
	}
	if (delaying)
	    ++s;
    } while (delaying);
    return s;
}

Project: ncurses

drv_screen_init(SCREEN *sp)
{
    TERMINAL_CONTROL_BLOCK *TCB = TCBOf(sp);

    AssertTCB();

    /*
     * Check for mismatched graphic-rendition capabilities.  Most SVr4
     * terminfo trees contain entries that have rmul or rmso equated to
     * sgr0 (Solaris curses copes with those entries).  We do this only
     * for curses, since many termcap applications assume that
     * smso/rmso and smul/rmul are paired, and will not function
     * properly if we remove rmso or rmul.  Curses applications
     * shouldn't be looking at this detail.
     */
    sp->_use_rmso = SGR0_TEST(exit_standout_mode);
    sp->_use_rmul = SGR0_TEST(exit_underline_mode);

    /*
     * Check whether we can optimize scrolling under dumb terminals in
     * case we do not have any of these capabilities, scrolling
     * optimization will be useless.
     */
    sp->_scrolling = ((scroll_forward && scroll_reverse) ||
		      ((parm_rindex ||
			parm_insert_line ||
			insert_line) &&
		       (parm_index ||
			parm_delete_line ||
			delete_line)));

    NCURSES_SP_NAME(baudrate) (sp);

    NCURSES_SP_NAME(_nc_mvcur_init) (sp);
    /* initialize terminal to a sane state */
    NCURSES_SP_NAME(_nc_screen_init) (sp);
}

Project: ncurses

check_infotocap(TERMTYPE2 *tp, int i, const char *value)
{
    const char *name = ExtStrname(tp, i, strnames);
    int params = ((i < (int) SIZEOF(parametrized))
		  ? parametrized[i]
		  : ((*value == 'k')
		     ? 0
		     : has_params(value)));
    int to_char = 0;
    char *ti_value;
    char *tc_value;
    bool embedded;

    assert(SIZEOF(parametrized) == STRCOUNT);
    if ((ti_value = _nc_tic_expand(value, TRUE, to_char)) == ABSENT_STRING) {
	_nc_warning("tic-expansion of %s failed", name);
    } else if ((tc_value = _nc_infotocap(name, ti_value, params)) == ABSENT_STRING) {
	_nc_warning("tic-conversion of %s failed", name);
    } else if (params > 0) {
	int limit = 5;
	int count;
	bool first = TRUE;

	if (!strcmp(name, "setf")
	    || !strcmp(name, "setb")
	    || !strcmp(name, "setaf")
	    || !strcmp(name, "setab")) {
	    if ((limit = max_colors) > 16)
		limit = 16;
	}
	for (count = 0; count < limit; ++count) {
	    char *ti_check = check_1_infotocap(name, ti_value, count);
	    char *tc_check = check_1_infotocap(name, tc_value, count);

	    if (strcmp(ti_check, tc_check)) {
		if (first) {
		    fprintf(stderr, "check_infotocap(%s)\n", name);
		    fprintf(stderr, "...ti '%s'\n", ti_value);
		    fprintf(stderr, "...tc '%s'\n", tc_value);
		    first = FALSE;
		}
		_nc_warning("tparm-conversion of %s(%d) differs between\n\tterminfo %s\n\ttermcap  %s",
			    name, count, ti_check, tc_check);
	    }
	    free(ti_check);
	    free(tc_check);
	}
    } else if (params == 0 && !same_ti_tc(ti_value, tc_value, &embedded)) {
	if (embedded) {
	    _nc_warning("termcap equivalent of %s cannot use embedded delay", name);
	} else {
	    _nc_warning("tic-conversion of %s changed value\n\tfrom %s\n\tto   %s",
			name, ti_value, tc_value);
	}
    }
}

Project: ncurses

drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
{
    SCREEN *sp;
    unsigned char c2 = 0;
    int n;

    AssertTCB();
    assert(buf);
    SetSP();

# if USE_PTHREADS_EINTR
    if ((pthread_self) && (pthread_kill) && (pthread_equal))
	_nc_globals.read_thread = pthread_self();
# endif
    n = (int) read(sp->_ifd, &c2, (size_t) 1);
#if USE_PTHREADS_EINTR
    _nc_globals.read_thread = 0;
#endif
    *buf = (int) c2;
    return n;
}

Project: ncurses

vid_puts(attr_t newmode,
	 NCURSES_PAIRS_T pair_arg,
	 void *opts GCC_UNUSED,
	 NCURSES_OUTC outc)
{
    SetSafeOutcWrapper(outc);
    return NCURSES_SP_NAME(vid_puts) (CURRENT_SCREEN,
				      newmode,
				      pair_arg,
				      opts,
				      _nc_outc_wrapper);
}

Project: ncurses

init_color(NCURSES_COLOR_T color,
	   NCURSES_COLOR_T r,
	   NCURSES_COLOR_T g,
	   NCURSES_COLOR_T b)
{
    return NCURSES_SP_NAME(init_color) (CURRENT_SCREEN, color, r, g, b);
}

Project: ncurses

NCURSES_SP_NAME(can_change_color) (NCURSES_SP_DCL)
{
    int result = FALSE;

    T((T_CALLED("can_change_color(%p)"), (void *) SP_PARM));

    if (HasTerminal(SP_PARM) && (CanChange != 0)) {
	result = TRUE;
    }

    returnCode(result);
}

Project: ncurses

spush(char *x)
{
    if (TPS(stack_ptr) < STACKSIZE) {
	TPS(stack)[TPS(stack_ptr)].num_type = FALSE;
	TPS(stack)[TPS(stack_ptr)].data.str = x;
	TPS(stack_ptr)++;
    } else {
	DEBUG(2, ("spush: stack overflow: %s", _nc_visbuf(TPS(tparam_base))));
	_nc_tparm_err++;
    }
}

Project: ncurses

skip_list(char *value)
{
    while (*value != '\0' &&
	   (isdigit(UChar(*value)) ||
	    isspace(UChar(*value)) ||
	    strchr("+,", UChar(*value)) != 0)) {
	++value;
    }
    return value;
}

Project: ncurses

_nc_screen_resume(void)
{
    NCURSES_SP_NAME(_nc_screen_resume) (CURRENT_SCREEN);
}

Project: ncurses

skip_DECSCNM(const char *value, int *flag)
{
    *flag = -1;
    if (value != 0) {
	int skip = csi_length(value);
	if (skip > 0 &&
	    value[skip++] == '?' &&
	    value[skip++] == '5') {
	    if (value[skip] == 'h') {
		*flag = 1;
	    } else if (value[skip] == 'l') {
		*flag = 0;
	    }
	    value += skip + 1;
	}
    }
    return value;
}

Project: ncurses

init_string(void)
/* initialize 'my_string', 'my_length' */
{
    if (my_string == 0)
	TYPE_MALLOC(char, my_length = 256, my_string);

    *my_string = '\0';
    return my_string;
}

Project: ncurses

drv_getsize(TERMINAL_CONTROL_BLOCK * TCB, int *l, int *c)
{
    AssertTCB();
    assert(l != 0 && c != 0);
    *l = lines;
    *c = columns;
    return OK;
}

Project: ncurses

visit_nodes(const void *nodep, const VISIT which, const int depth)
{
    (void) depth;
    if (which == preorder || which == leaf) {
	delete_tparm[which_tparm] = *(TPARM_DATA **) nodep;
	which_tparm++;
    }
}

Project: ncurses

save_tc_inequality(char *bufptr, int c1, int c2)
{
    bufptr = save_string(bufptr, "%>");
    bufptr = save_tc_char(bufptr, c1);
    bufptr = save_tc_char(bufptr, c2);
    return bufptr;
}

Project: ncurses

NCURSES_SP_NAME(_nc_mvcur_wrap) (NCURSES_SP_DCL0)
/* wrap up cursor-addressing mode */
{
    /* leave cursor at screen bottom */
    TINFO_MVCUR(NCURSES_SP_ARGx -1, -1, screen_lines(SP_PARM) - 1, 0);

    if (!SP_PARM || !IsTermInfo(SP_PARM))
	return;

    /* set cursor to normal mode */
    if (SP_PARM->_cursor != -1) {
	int cursor = SP_PARM->_cursor;
	NCURSES_SP_NAME(curs_set) (NCURSES_SP_ARGx 1);
	SP_PARM->_cursor = cursor;
    }

    if (exit_ca_mode) {
	NCURSES_PUTP2("exit_ca_mode", exit_ca_mode);
    }
    /*
     * Reset terminal's tab counter.  There's a long-time bug that
     * if you exit a "curses" program such as vi or more, tab
     * forward, and then backspace, the cursor doesn't go to the
     * right place.  The problem is that the kernel counts the
     * escape sequences that reset things as column positions.
     * Utter a \r to reset this invisibly.
     */
    NCURSES_SP_NAME(_nc_outch) (NCURSES_SP_ARGx '\r');
}

Project: ncurses

drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB, int yold, int xold, int ynew, int xnew)
{
    SCREEN *sp = TCB->csp;
    AssertTCB();
    return NCURSES_SP_NAME(_nc_mvcur) (sp, yold, xold, ynew, xnew);
}

Project: ncurses

usage(void)
{
    static const char *msg[] =
    {
	"Usage: dots_curses [options]"
	,""
	,"Options:"
	," -T TERM  override $TERM"
#if HAVE_USE_DEFAULT_COLORS
	," -d       invoke use_default_colors()"
#endif
#if HAVE_USE_ENV
	," -e       allow environment $LINES / $COLUMNS"
#endif
	," -m SIZE  set margin (default: 2)"
	," -r SECS  self-interrupt/exit after specified number of seconds"
	," -s MSECS delay 1% of the time (default: 1 msecs)"
    };
    size_t n;

    for (n = 0; n < SIZEOF(msg); n++)
	fprintf(stderr, "%s\n", msg[n]);

    ExitProgram(EXIT_FAILURE);
}

Project: ncurses

main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
{
    _nc_STRCPY(tname, getenv("TERM"), sizeof(tname));
    load_term();
    _nc_setupscreen(lines, columns, stdout, FALSE, 0);
    baudrate();

    _nc_mvcur_init();

    (void) puts("The mvcur tester.  Type ? for help");

    fputs("smcup:", stdout);
    putchar('\n');

    for (;;) {
	int fy, fx, ty, tx, n, i;
	char buf[BUFSIZ], capname[BUFSIZ];

	if (fputs("> ", stdout) == EOF)
	    break;
	if (fgets(buf, sizeof(buf), stdin) == 0)
	    break;

#define PUTS(s)   (void) puts(s)
#define PUTF(s,t) (void) printf(s,t)
	if (buf[0] == '?') {
	    PUTS("?                -- display this help message");
	    PUTS("fy fx ty tx      -- (4 numbers) display (fy,fx)->(ty,tx) move");
	    PUTS("s[croll] n t b m -- display scrolling sequence");
	    PUTF("r[eload]         -- reload terminal info for %s\n",
		 termname());
	    PUTS("l[oad] <term>    -- load terminal info for type <term>");
	    PUTS("d[elete] <cap>   -- delete named capability");
	    PUTS("i[nspect]        -- display terminal capabilities");
	    PUTS("c[ost]           -- dump cursor-optimization cost table");
	    PUTS("o[optimize]      -- toggle movement optimization");
	    PUTS("t[orture] <num>  -- torture-test with <num> random moves");
	    PUTS("q[uit]           -- quit the program");
	} else if (sscanf(buf, "%d %d %d %d", &fy, &fx, &ty, &tx) == 4) {
	    struct timeval before, after;

	    putchar('"');

	    gettimeofday(&before, NULL);
	    mvcur(fy, fx, ty, tx);
	    gettimeofday(&after, NULL);

	    printf("\" (%ld msec)\n",
		   (long) (after.tv_usec - before.tv_usec
			   + (after.tv_sec - before.tv_sec)
			   * 1000000));
	} else if (sscanf(buf, "s %d %d %d %d", &fy, &fx, &ty, &tx) == 4) {
	    struct timeval before, after;

	    putchar('"');

	    gettimeofday(&before, NULL);
	    _nc_scrolln(fy, fx, ty, tx);
	    gettimeofday(&after, NULL);

	    printf("\" (%ld msec)\n",
		   (long) (after.tv_usec - before.tv_usec + (after.tv_sec -
							     before.tv_sec)
			   * 1000000));
	} else if (buf[0] == 'r') {
	    _nc_STRCPY(tname, termname(), sizeof(tname));
	    load_term();
	} else if (sscanf(buf, "l %s", tname) == 1) {
	    load_term();
	} else if (sscanf(buf, "d %s", capname) == 1) {
	    struct name_table_entry const *np = _nc_find_entry(capname,
							       _nc_get_hash_table(FALSE));

	    if (np == NULL)
		(void) printf("No such capability as \"%s\"\n", capname);
	    else {
		switch (np->nte_type) {
		case BOOLEAN:
		    cur_term->type.Booleans[np->nte_index] = FALSE;
		    (void)
			printf("Boolean capability `%s' (%d) turned off.\n",
			       np->nte_name, np->nte_index);
		    break;

		case NUMBER:
		    cur_term->type.Numbers[np->nte_index] = ABSENT_NUMERIC;
		    (void) printf("Number capability `%s' (%d) set to -1.\n",
				  np->nte_name, np->nte_index);
		    break;

		case STRING:
		    cur_term->type.Strings[np->nte_index] = ABSENT_STRING;
		    (void) printf("String capability `%s' (%d) deleted.\n",
				  np->nte_name, np->nte_index);
		    break;
		}
	    }
	} else if (buf[0] == 'i') {
	    dump_init(NULL, F_TERMINFO, S_TERMINFO,
		      FALSE, 70, 0, 0, FALSE, FALSE, 0);
	    dump_entry(&TerminalType(cur_term), FALSE, TRUE, 0, 0);
	    putchar('\n');
	} else if (buf[0] == 'o') {
	    if (_nc_optimize_enable & OPTIMIZE_MVCUR) {
		_nc_optimize_enable &= ~OPTIMIZE_MVCUR;
		(void) puts("Optimization is now off.");
	    } else {
		_nc_optimize_enable |= OPTIMIZE_MVCUR;
		(void) puts("Optimization is now on.");
	    }
	}
	/*
	 * You can use the `t' test to profile and tune the movement
	 * optimizer.  Use iteration values in three digits or more.
	 * At above 5000 iterations the profile timing averages are stable
	 * to within a millisecond or three.
	 *
	 * The `overhead' field of the report will help you pick a
	 * COMPUTE_OVERHEAD figure appropriate for your processor and
	 * expected line speed.  The `total estimated time' is
	 * computation time plus a character-transmission time
	 * estimate computed from the number of transmits and the baud
	 * rate.
	 *
	 * Use this together with the `o' command to get a read on the
	 * optimizer's effectiveness.  Compare the total estimated times
	 * for `t' runs of the same length in both optimized and un-optimized
	 * modes.  As long as the optimized times are less, the optimizer
	 * is winning.
	 */
	else if (sscanf(buf, "t %d", &n) == 1) {
	    float cumtime = 0.0, perchar;
	    int speeds[] =
	    {2400, 9600, 14400, 19200, 28800, 38400, 0};

	    srand((unsigned) (getpid() + time((time_t *) 0)));
	    profiling = TRUE;
	    xmits = 0;
	    for (i = 0; i < n; i++) {
		/*
		 * This does a move test between two random locations,
		 * Random moves probably short-change the optimizer,
		 * which will work better on the short moves probably
		 * typical of doupdate()'s usage pattern.  Still,
		 * until we have better data...
		 */
#ifdef FIND_COREDUMP
		int from_y = roll(lines);
		int to_y = roll(lines);
		int from_x = roll(columns);
		int to_x = roll(columns);

		printf("(%d,%d) -> (%d,%d)\n", from_y, from_x, to_y, to_x);
		mvcur(from_y, from_x, to_y, to_x);
#else
		mvcur(roll(lines), roll(columns), roll(lines), roll(columns));
#endif /* FIND_COREDUMP */
		if (diff)
		    cumtime += diff;
	    }
	    profiling = FALSE;

	    /*
	     * Average milliseconds per character optimization time.
	     * This is the key figure to watch when tuning the optimizer.
	     */
	    perchar = cumtime / n;

	    (void) printf("%d moves (%ld chars) in %d msec, %f msec each:\n",
			  n, xmits, (int) cumtime, perchar);

	    for (i = 0; speeds[i]; i++) {
		/*
		 * Total estimated time for the moves, computation and
		 * transmission both. Transmission time is an estimate
		 * assuming 9 bits/char, 8 bits + 1 stop bit.
		 */
		float totalest = cumtime + xmits * 9 * 1e6 / speeds[i];

		/*
		 * Per-character optimization overhead in character transmits
		 * at the current speed.  Round this to the nearest integer
		 * to figure COMPUTE_OVERHEAD for the speed.
		 */
		float overhead = speeds[i] * perchar / 1e6;

		(void)
		    printf("%6d bps: %3.2f char-xmits overhead; total estimated time %15.2f\n",
			   speeds[i], overhead, totalest);
	    }
	} else if (buf[0] == 'c') {
	    (void) printf("char padding: %d\n", CURRENT_SCREEN->_char_padding);
	    (void) printf("cr cost: %d\n", CURRENT_SCREEN->_cr_cost);
	    (void) printf("cup cost: %d\n", CURRENT_SCREEN->_cup_cost);
	    (void) printf("home cost: %d\n", CURRENT_SCREEN->_home_cost);
	    (void) printf("ll cost: %d\n", CURRENT_SCREEN->_ll_cost);
#if USE_HARD_TABS
	    (void) printf("ht cost: %d\n", CURRENT_SCREEN->_ht_cost);
	    (void) printf("cbt cost: %d\n", CURRENT_SCREEN->_cbt_cost);
#endif /* USE_HARD_TABS */
	    (void) printf("cub1 cost: %d\n", CURRENT_SCREEN->_cub1_cost);
	    (void) printf("cuf1 cost: %d\n", CURRENT_SCREEN->_cuf1_cost);
	    (void) printf("cud1 cost: %d\n", CURRENT_SCREEN->_cud1_cost);
	    (void) printf("cuu1 cost: %d\n", CURRENT_SCREEN->_cuu1_cost);
	    (void) printf("cub cost: %d\n", CURRENT_SCREEN->_cub_cost);
	    (void) printf("cuf cost: %d\n", CURRENT_SCREEN->_cuf_cost);
	    (void) printf("cud cost: %d\n", CURRENT_SCREEN->_cud_cost);
	    (void) printf("cuu cost: %d\n", CURRENT_SCREEN->_cuu_cost);
	    (void) printf("hpa cost: %d\n", CURRENT_SCREEN->_hpa_cost);
	    (void) printf("vpa cost: %d\n", CURRENT_SCREEN->_vpa_cost);
	} else if (buf[0] == 'x' || buf[0] == 'q')
	    break;
	else
	    (void) puts("Invalid command.");
    }

    (void) fputs("rmcup:", stdout);
    _nc_mvcur_wrap();
    putchar('\n');

    return (0);
}

Project: ncurses

NCURSES_SP_NAME(start_color) (NCURSES_SP_DCL0)
{
    int result = ERR;
    int maxpairs = 0, maxcolors = 0;

    T((T_CALLED("start_color(%p)"), (void *) SP_PARM));

    if (SP_PARM == 0) {
	result = ERR;
    } else if (SP_PARM->_coloron) {
	result = OK;
    } else {
	maxpairs = MaxPairs;
	maxcolors = MaxColors;
	if (reset_color_pair(NCURSES_SP_ARG) != TRUE) {
	    set_foreground_color(NCURSES_SP_ARGx
				 default_fg(NCURSES_SP_ARG),
				 NCURSES_SP_NAME(_nc_outch));
	    set_background_color(NCURSES_SP_ARGx
				 default_bg(NCURSES_SP_ARG),
				 NCURSES_SP_NAME(_nc_outch));
	}
#if !NCURSES_EXT_COLORS
	/*
	 * Without ext-colors, we cannot represent more than 256 color pairs.
	 */
	if (maxpairs > 256)
	    maxpairs = 256;
#endif

	if (maxpairs > 0 && maxcolors > 0) {
	    SP_PARM->_pair_limit = maxpairs;

#if NCURSES_EXT_FUNCS
	    /*
	     * If using default colors, allocate extra space in table to
	     * allow for default-color as a component of a color-pair.
	     */
	    SP_PARM->_pair_limit += (1 + (2 * maxcolors));
#if !NCURSES_EXT_COLORS
	    SP_PARM->_pair_limit = limit_PAIRS(SP_PARM->_pair_limit);
#endif
#endif /* NCURSES_EXT_FUNCS */
	    SP_PARM->_pair_count = maxpairs;
	    SP_PARM->_color_count = maxcolors;
#if !USE_REENTRANT
	    COLOR_PAIRS = maxpairs;
	    COLORS = maxcolors;
#endif

	    ReservePairs(SP_PARM, 16);
	    if (SP_PARM->_color_pairs != 0) {
		if (init_direct_colors(NCURSES_SP_ARG)) {
		    result = OK;
		} else {
		    SP_PARM->_color_table = TYPE_CALLOC(color_t, maxcolors);
		    if (SP_PARM->_color_table != 0) {
			MakeColorPair(SP_PARM->_color_pairs[0],
				      default_fg(NCURSES_SP_ARG),
				      default_bg(NCURSES_SP_ARG));
			init_color_table(NCURSES_SP_ARG);

			result = OK;
		    }
		}
		if (result == OK) {
		    T(("started color: COLORS = %d, COLOR_PAIRS = %d",
		       COLORS, COLOR_PAIRS));

		    SP_PARM->_coloron = 1;
		} else if (SP_PARM->_color_pairs != 0) {
		    FreeAndNull(SP_PARM->_color_pairs);
		}
	    }
	} else {
	    result = OK;
	}
    }
    returnCode(result);
}

Project: ncurses

check_colors(TERMTYPE2 *tp)
{
    char *value;

    if ((max_colors > 0) != (max_pairs > 0)
	|| ((max_colors > max_pairs) && (initialize_pair == 0)))
	_nc_warning("inconsistent values for max_colors (%d) and max_pairs (%d)",
		    max_colors, max_pairs);

    PAIRED(set_foreground, set_background);
    PAIRED(set_a_foreground, set_a_background);
    PAIRED(set_color_pair, initialize_pair);

    if (VALID_STRING(set_foreground)
	&& VALID_STRING(set_a_foreground)) {
	if (!_nc_capcmp(set_foreground, set_a_foreground)) {
	    _nc_warning("expected setf/setaf to be different");
	} else if (same_color(set_foreground, set_a_foreground, max_colors)) {
	    _nc_warning("setf/setaf are equivalent");
	}
    }

    if (VALID_STRING(set_background)
	&& VALID_STRING(set_a_background)) {
	if (!_nc_capcmp(set_background, set_a_background)) {
	    _nc_warning("expected setb/setab to be different");
	} else if (same_color(set_background, set_a_background, max_colors)) {
	    _nc_warning("setb/setab are equivalent");
	}
    }

    /* see: has_colors() */
    if (VALID_NUMERIC(max_colors) && VALID_NUMERIC(max_pairs)
	&& ((VALID_STRING(set_foreground)
	     && VALID_STRING(set_background))
	    || (VALID_STRING(set_a_foreground)
		&& VALID_STRING(set_a_background))
	    || set_color_pair)) {
	if (!VALID_STRING(orig_pair) && !VALID_STRING(orig_colors))
	    _nc_warning("expected either op/oc string for resetting colors");
    }
    if (can_change) {
	if (!VALID_STRING(initialize_pair) &&
	    !VALID_STRING(initialize_color)) {
	    _nc_warning("expected initc or initp because ccc is given");
	}
    } else {
	if (VALID_STRING(initialize_pair) ||
	    VALID_STRING(initialize_color)) {
	    _nc_warning("expected ccc because initc is given");
	}
    }
    value = tigetstr("RGB");
    if (VALID_STRING(value)) {
	int r, g, b;
	char bad;
	int code = sscanf(value, "%d/%d/%d%c", &r, &g, &b, &bad);
	if (code != 3 || r <= 0 || g <= 0 || b <= 0) {
	    _nc_warning("unexpected value for RGB capability: %s", value);
	}
    }
}

Project: ncurses

InsStr(NCURSES_SP_DCLx NCURSES_CH_T *line, int count)
{
    TR(TRACE_UPDATE, ("InsStr(%p, %p,%d) called",
		      (void *) SP_PARM,
		      (void *) line, count));

    /* Prefer parm_ich as it has the smallest cost - no need to shift
     * the whole line on each character. */
    /* The order must match that of InsCharCost. */
    if (parm_ich) {
	TPUTS_TRACE("parm_ich");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(parm_ich, count),
				1,
				NCURSES_SP_NAME(_nc_outch));
	while (count > 0) {
	    PutAttrChar(NCURSES_SP_ARGx CHREF(*line));
	    line++;
	    count--;
	}
    } else if (enter_insert_mode && exit_insert_mode) {
	NCURSES_PUTP2("enter_insert_mode", enter_insert_mode);
	while (count > 0) {
	    PutAttrChar(NCURSES_SP_ARGx CHREF(*line));
	    if (insert_padding) {
		NCURSES_PUTP2("insert_padding", insert_padding);
	    }
	    line++;
	    count--;
	}
	NCURSES_PUTP2("exit_insert_mode", exit_insert_mode);
    } else {
	while (count > 0) {
	    NCURSES_PUTP2("insert_character", insert_character);
	    PutAttrChar(NCURSES_SP_ARGx CHREF(*line));
	    if (insert_padding) {
		NCURSES_PUTP2("insert_padding", insert_padding);
	    }
	    line++;
	    count--;
	}
    }
    position_check(NCURSES_SP_ARGx
		   SP_PARM->_cursrow,
		   SP_PARM->_curscol, "InsStr");
}

Project: ncurses

getmouse(MEVENT * aevent)
{
    return NCURSES_SP_NAME(getmouse) (CURRENT_SCREEN, aevent);
}

Project: ncurses

check_sgr_param(TERMTYPE2 *tp, int code, const char *name, char *value)
{
    if (VALID_STRING(value)) {
	int ncv = ((code != 0) ? (1 << (code - 1)) : 0);
	char *test = tgoto(value, 0, 0);
	if (is_sgr_string(test)) {
	    int param = 0;
	    int count = 0;
	    int skips = 0;
	    int color = (value == set_a_foreground ||
			 value == set_a_background ||
			 value == set_foreground ||
			 value == set_background);
	    while (*test != 0) {
		if (isdigit(UChar(*test))) {
		    param = 10 * param + (*test - '0');
		    ++count;
		} else {
		    if (count) {
			/*
			 * Avoid unnecessary warning for xterm 256color codes.
			 */
			if (color && (param == 38 || param == 48))
			    skips = 3;
			if ((skips-- <= 0) && (param == code))
			    break;
		    }
		    count = 0;
		    param = 0;
		}
		++test;
	    }
	    if (count != 0 && param == code) {
		if (code == 0 ||
		    no_color_video < 0 ||
		    !(no_color_video & ncv)) {
		    _nc_warning("\"%s\" SGR-attribute used in %s",
				sgr_names[code],
				name);
		}
	    }
	}
    }
}

Project: ncurses

set_conversions(TTY * tty_settings)
{
#ifdef ONLCR
    tty_settings->c_oflag |= ONLCR;
#endif
    tty_settings->c_iflag |= ICRNL;
    tty_settings->c_lflag |= ECHO;
#ifdef OXTABS
    tty_settings->c_oflag |= OXTABS;
#endif /* OXTABS */

    /* test used to be tgetflag("NL") */
    if (VALID_STRING(newline) && newline[0] == '\n' && !newline[1]) {
	/* Newline, not linefeed. */
#ifdef ONLCR
	tty_settings->c_oflag &= ~((unsigned) ONLCR);
#endif
	tty_settings->c_iflag &= ~((unsigned) ICRNL);
    }
#ifdef OXTABS
    /* test used to be tgetflag("pt") */
    if (VALID_STRING(set_tab) && VALID_STRING(clear_all_tabs))
	tty_settings->c_oflag &= ~OXTABS;
#endif /* OXTABS */
    tty_settings->c_lflag |= (ECHOE | ECHOK);
}

Project: ncurses

_nc_screen_wrap(void)
{
    NCURSES_SP_NAME(_nc_screen_wrap) (CURRENT_SCREEN);
}

Project: ncurses

NCURSES_SP_NAME(color_content) (NCURSES_SP_DCLx
				NCURSES_COLOR_T color,
				NCURSES_COLOR_T *r,
				NCURSES_COLOR_T *g,
				NCURSES_COLOR_T *b)
{
    int my_r, my_g, my_b;
    int rc = _nc_color_content(SP_PARM, color, &my_r, &my_g, &my_b);
    if (rc == OK) {
	*r = limit_COLOR(my_r);
	*g = limit_COLOR(my_g);
	*b = limit_COLOR(my_b);
    }
    return rc;
}

Project: ncurses

check_keypad(TERMTYPE2 *tp)
{
    char show[80];

    if (VALID_STRING(key_a1) &&
	VALID_STRING(key_a3) &&
	VALID_STRING(key_b2) &&
	VALID_STRING(key_c1) &&
	VALID_STRING(key_c3)) {
	char final[MAX_KP + 1];
	long list[MAX_KP];
	int increase = 0;
	int j, k, kk;
	long last;
	long test;

	final[0] = keypad_final(key_a1);
	final[1] = keypad_final(key_a3);
	final[2] = keypad_final(key_b2);
	final[3] = keypad_final(key_c1);
	final[4] = keypad_final(key_c3);
	final[5] = '\0';

	/* special case: legacy coding using 1,2,3,0,. on the bottom */
	assert(strlen(final) <= MAX_KP);
	if (!strcmp(final, "qsrpn"))
	    return;

	list[0] = keypad_index(key_a1);
	list[1] = keypad_index(key_a3);
	list[2] = keypad_index(key_b2);
	list[3] = keypad_index(key_c1);
	list[4] = keypad_index(key_c3);

	/* check that they're all vt100 keys */
	for (j = 0; j < MAX_KP; ++j) {
	    if (list[j] < 0) {
		return;
	    }
	}

	/* check if they're all in increasing order */
	for (j = 1; j < MAX_KP; ++j) {
	    if (list[j] > list[j - 1]) {
		++increase;
	    }
	}
	if (increase != (MAX_KP - 1)) {
	    show[0] = '\0';

	    for (j = 0, last = -1; j < MAX_KP; ++j) {
		for (k = 0, kk = -1, test = 100; k < 5; ++k) {
		    if (list[k] > last &&
			list[k] < test) {
			test = list[k];
			kk = k;
		    }
		}
		last = test;
		assert(strlen(show) < (MAX_KP * 4));
		switch (kk) {
		case 0:
		    _nc_STRCAT(show, " ka1", sizeof(show));
		    break;
		case 1:
		    _nc_STRCAT(show, " ka3", sizeof(show));
		    break;
		case 2:
		    _nc_STRCAT(show, " kb2", sizeof(show));
		    break;
		case 3:
		    _nc_STRCAT(show, " kc1", sizeof(show));
		    break;
		case 4:
		    _nc_STRCAT(show, " kc3", sizeof(show));
		    break;
		}
	    }

	    _nc_warning("vt100 keypad order inconsistent: %s", show);
	}

    } else if (VALID_STRING(key_a1) ||
	       VALID_STRING(key_a3) ||
	       VALID_STRING(key_b2) ||
	       VALID_STRING(key_c1) ||
	       VALID_STRING(key_c3)) {
	show[0] = '\0';
	if (keypad_index(key_a1) >= 0)
	    _nc_STRCAT(show, " ka1", sizeof(show));
	if (keypad_index(key_a3) >= 0)
	    _nc_STRCAT(show, " ka3", sizeof(show));
	if (keypad_index(key_b2) >= 0)
	    _nc_STRCAT(show, " kb2", sizeof(show));
	if (keypad_index(key_c1) >= 0)
	    _nc_STRCAT(show, " kc1", sizeof(show));
	if (keypad_index(key_c3) >= 0)
	    _nc_STRCAT(show, " kc3", sizeof(show));
	if (*show != '\0')
	    _nc_warning("vt100 keypad map incomplete:%s", show);
    }

    /*
     * These warnings are useful for consistency checks - it is possible that
     * there are real terminals with mismatches in these
     */
    ANDMISSING(key_ic, key_dc);
}

Project: ncurses

show_where(unsigned level)
{
    if (_nc_tracing >= DEBUG_LEVEL(level)) {
	char my_name[MAX_NAME_SIZE];
	_nc_get_type(my_name);
	_tracef("\"%s\", line %d, '%s'",
		_nc_get_source(),
		_nc_curr_line, my_name);
    }
}

Project: ncurses

termattrs(void)
{
    return NCURSES_SP_NAME(termattrs) (CURRENT_SCREEN);
}

Project: ncurses

drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *linep, int *colp)
{
    SCREEN *sp;
    bool useEnv = TRUE;
    bool useTioctl = TRUE;

    AssertTCB();
    sp = TCB->csp;		/* can be null here */

    if (sp) {
	useEnv = sp->_use_env;
	useTioctl = sp->use_tioctl;
    } else {
	useEnv = _nc_prescreen.use_env;
	useTioctl = _nc_prescreen.use_tioctl;
    }

    /* figure out the size of the screen */
    T(("screen size: terminfo lines = %d columns = %d", lines, columns));

    *linep = (int) lines;
    *colp = (int) columns;

    if (useEnv || useTioctl) {
	int value;

#ifdef __EMX__
	{
	    int screendata[2];
	    _scrsize(screendata);
	    *colp = screendata[0];
	    *linep = ((sp != 0 && sp->_filtered)
		      ? 1
		      : screendata[1]);
	    T(("EMX screen size: environment LINES = %d COLUMNS = %d",
	       *linep, *colp));
	}
#endif
#if HAVE_SIZECHANGE
	/* try asking the OS */
	{
	    TERMINAL *termp = (TERMINAL *) TCB;
	    if (NC_ISATTY(termp->Filedes)) {
		STRUCT_WINSIZE size;

		errno = 0;
		do {
		    if (ioctl(termp->Filedes, IOCTL_WINSIZE, &size) >= 0) {
			*linep = ((sp != 0 && sp->_filtered)
				  ? 1
				  : WINSIZE_ROWS(size));
			*colp = WINSIZE_COLS(size);
			T(("SYS screen size: environment LINES = %d COLUMNS = %d",
			   *linep, *colp));
			break;
		    }
		} while
		    (errno == EINTR);
	    }
	}
#endif /* HAVE_SIZECHANGE */

	if (useEnv) {
	    if (useTioctl) {
		/*
		 * If environment variables are used, update them.
		 */
		if ((sp == 0 || !sp->_filtered) && _nc_getenv_num("LINES") > 0) {
		    _nc_setenv_num("LINES", *linep);
		}
		if (_nc_getenv_num("COLUMNS") > 0) {
		    _nc_setenv_num("COLUMNS", *colp);
		}
	    }

	    /*
	     * Finally, look for environment variables.
	     *
	     * Solaris lets users override either dimension with an environment
	     * variable.
	     */
	    if ((value = _nc_getenv_num("LINES")) > 0) {
		*linep = value;
		T(("screen size: environment LINES = %d", *linep));
	    }
	    if ((value = _nc_getenv_num("COLUMNS")) > 0) {
		*colp = value;
		T(("screen size: environment COLUMNS = %d", *colp));
	    }
	}

	/* if we can't get dynamic info about the size, use static */
	if (*linep <= 0) {
	    *linep = (int) lines;
	}
	if (*colp <= 0) {
	    *colp = (int) columns;
	}

	/* the ultimate fallback, assume fixed 24x80 size */
	if (*linep <= 0) {
	    *linep = 24;
	}
	if (*colp <= 0) {
	    *colp = 80;
	}

	/*
	 * Put the derived values back in the screen-size caps, so
	 * tigetnum() and tgetnum() will do the right thing.
	 */
	lines = (short) (*linep);
	columns = (short) (*colp);
    }

    T(("screen size is %dx%d", *linep, *colp));
    return OK;
}

Project: ncurses

color_content(NCURSES_COLOR_T color,
	      NCURSES_COLOR_T *r,
	      NCURSES_COLOR_T *g,
	      NCURSES_COLOR_T *b)
{
    return NCURSES_SP_NAME(color_content) (CURRENT_SCREEN, color, r, g, b);
}

Project: ncurses

drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int key)
{
    bool res = FALSE;

    AssertTCB();
    if (TCB->csp)
	res = TINFO_HAS_KEY(TCB->csp, key) == 0 ? FALSE : TRUE;

    return res;
}

Project: ncurses

normalized_cost(NCURSES_SP_DCLx const char *const cap, int affcnt)
/* compute the effective character-count for an operation (round up) */
{
    int cost = NCURSES_SP_NAME(_nc_msec_cost) (NCURSES_SP_ARGx cap, affcnt);
    if (cost != INFINITY)
	cost = (cost + SP_PARM->_char_padding - 1) / SP_PARM->_char_padding;
    return cost;
}

Project: ncurses

init_direct_colors(NCURSES_SP_DCL0)
{
    static NCURSES_CONST char name[] = "RGB";

    int n;
    const char *s;
    int width;
    rgb_bits_t *result = &(SP_PARM->_direct_color);

    result->value = 0;

    if (COLORS >= 8) {
	/* find the number of bits needed for the maximum color value */
	for (width = 0; (1 << width) - 1 < (COLORS - 1); ++width) {
	    ;
	}

	if ((n = tigetflag(name)) > 0) {
	    n = (width + 2) / 3;
	    result->bits.red = UChar(n);
	    result->bits.green = UChar(n);
	    result->bits.blue = UChar(width - (2 * n));
	} else if ((n = tigetnum(name)) > 0) {
	    result->bits.red = UChar(n);
	    result->bits.green = UChar(n);
	    result->bits.blue = UChar(n);
	} else if ((s = tigetstr(name)) != 0 && VALID_STRING(s)) {
	    int red = n;
	    int green = n;
	    int blue = width - (2 * n);

	    switch (sscanf(s, "%d/%d/%d", &red, &green, &blue)) {
	    default:
		blue = width - (2 * n);
		/* FALLTHRU */
	    case 1:
		green = n;
		/* FALLTHRU */
	    case 2:
		red = n;
		/* FALLTHRU */
	    case 3:
		/* okay */
		break;
	    }
	    result->bits.red = UChar(red);
	    result->bits.green = UChar(green);
	    result->bits.blue = UChar(blue);
	}
    }
    return (result->value != 0);
}

Project: ncurses

check_screen(TERMTYPE2 *tp)
{
    if (_nc_user_definable) {
	int have_XT = tigetflag("XT");
	int have_XM = tigetflag("XM");
	int have_bce = back_color_erase;
	bool have_kmouse = FALSE;
	bool use_sgr_39_49 = FALSE;
	char *name = _nc_first_name(tp->term_names);
	bool is_screen = !strncmp(name, "screen", 6);
	bool screen_base = (is_screen
			    && strchr(name, '.') == 0);

	if (!VALID_BOOLEAN(have_bce)) {
	    have_bce = FALSE;
	}
	if (!VALID_BOOLEAN(have_XM)) {
	    have_XM = FALSE;
	}
	if (!VALID_BOOLEAN(have_XT)) {
	    have_XT = FALSE;
	}
	if (VALID_STRING(key_mouse)) {
	    have_kmouse = !strcmp("\033[M", key_mouse);
	}
	if (VALID_STRING(orig_colors)) {
	    use_sgr_39_49 = uses_SGR_39_49(orig_colors);
	} else if (VALID_STRING(orig_pair)) {
	    use_sgr_39_49 = uses_SGR_39_49(orig_pair);
	}

	if (have_XM && have_XT) {
	    _nc_warning("screen's XT capability conflicts with XM");
	} else if (have_XT && screen_base) {
	    _nc_warning("screen's \"screen\" entries should not have XT set");
	} else if (have_XT) {
	    if (!have_kmouse && is_screen) {
		if (VALID_STRING(key_mouse)) {
		    _nc_warning("value of kmous inconsistent with screen's usage");
		} else {
		    _nc_warning("expected kmous capability with XT");
		}
	    }
	    if (!have_bce && max_colors > 0)
		_nc_warning("expected bce capability with XT");
	    if (!use_sgr_39_49 && have_bce && max_colors > 0)
		_nc_warning("expected orig_colors capability with XT to have 39/49 parameters");
	    if (VALID_STRING(to_status_line))
		_nc_warning("\"tsl\" capability is redundant, given XT");
	} else {
	    if (have_kmouse
		&& !have_XM
		&& !screen_base && strchr(name, '+') == 0) {
		_nc_warning("expected XT to be set, given kmous");
	    }
	}
    }
}

Project: ncurses

drv_init(TERMINAL_CONTROL_BLOCK * TCB)
{
    TERMINAL *trm;

    AssertTCB();

    trm = (TERMINAL *) TCB;

    TCB->info.initcolor = VALID_STRING(initialize_color);
    TCB->info.canchange = can_change;
    TCB->info.hascolor = ((VALID_NUMERIC(max_colors) && VALID_NUMERIC(max_pairs)
			   && (((set_foreground != NULL)
				&& (set_background != NULL))
			       || ((set_a_foreground != NULL)
				   && (set_a_background != NULL))
			       || set_color_pair)) ? TRUE : FALSE);

    TCB->info.caninit = !(exit_ca_mode && non_rev_rmcup);

    TCB->info.maxpairs = VALID_NUMERIC(max_pairs) ? max_pairs : 0;
    TCB->info.maxcolors = VALID_NUMERIC(max_colors) ? max_colors : 0;
    TCB->info.numlabels = VALID_NUMERIC(num_labels) ? num_labels : 0;
    TCB->info.labelwidth = VALID_NUMERIC(label_width) ? label_width : 0;
    TCB->info.labelheight = VALID_NUMERIC(label_height) ? label_height : 0;
    TCB->info.nocolorvideo = VALID_NUMERIC(no_color_video) ? no_color_video
	: 0;
    TCB->info.tabsize = VALID_NUMERIC(init_tabs) ? (int) init_tabs : 8;

    TCB->info.defaultPalette = hue_lightness_saturation ? _nc_hls_palette : _nc_cga_palette;

    /*
     * If an application calls setupterm() rather than initscr() or
     * newterm(), we will not have the def_prog_mode() call in
     * _nc_setupscreen().  Do it now anyway, so we can initialize the
     * baudrate.
     */
    if (NC_ISATTY(trm->Filedes)) {
	TCB->drv->td_mode(TCB, TRUE, TRUE);
    }
}

Project: ncurses

_nc_mouse_parse(SCREEN *sp, int runcount)
/* parse a run of atomic mouse events into a gesture */
{
    MEVENT *eventp = sp->_mouse_eventp;
    MEVENT *next, *ep;
    MEVENT *first_valid = NULL;
    MEVENT *first_invalid = NULL;
    int n;
    int b;
    bool merge;
    bool endLoop;

    TR(MY_TRACE, ("_nc_mouse_parse(%d) called", runcount));

    /*
     * When we enter this routine, the event list next-free pointer
     * points just past a run of mouse events that we know were separated
     * in time by less than the critical click interval. The job of this
     * routine is to collapse this run into a single higher-level event
     * or gesture.
     *
     * We accomplish this in two passes.  The first pass merges press/release
     * pairs into click events.  The second merges runs of click events into
     * double or triple-click events.
     *
     * It's possible that the run may not resolve to a single event (for
     * example, if the user quadruple-clicks).  If so, leading events
     * in the run are ignored if user does not call getmouse in a loop (getting
     * them from newest to older).
     *
     * Note that this routine is independent of the format of the specific
     * format of the pointing-device's reports.  We can use it to parse
     * gestures on anything that reports press/release events on a per-
     * button basis, as long as the device-dependent mouse code puts stuff
     * on the queue in MEVENT format.
     */

    /*
     * Reset all events that were not set, in case the user sometimes calls
     * getmouse only once and other times until there are no more events in
     * queue.
     *
     * This also allows reaching the beginning of the run.
     */
    ep = eventp;
    for (n = runcount; n < EV_MAX; n++) {
	Invalidate(ep);
	ep = NEXT(ep);
    }

#ifdef TRACE
    if (USE_TRACEF(TRACE_IEVENT)) {
	_trace_slot(sp, "before mouse press/release merge:");
	_tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
		RunParams(sp, eventp, ep),
		runcount);
	_nc_unlock_global(tracef);
    }
#endif /* TRACE */

    /* first pass; merge press/release pairs */
    endLoop = FALSE;
    while (!endLoop) {
	next = NEXT(ep);
	if (next == eventp) {
	    /* Will end the loop, but compact before */
	    endLoop = TRUE;
	} else {

#define MASK_CHANGED(x) (!(ep->bstate & MASK_PRESS(x)) \
		      == !(next->bstate & MASK_RELEASE(x)))

	    if (ValidEvent(ep) && ValidEvent(next)
		&& ep->x == next->x && ep->y == next->y
		&& (ep->bstate & BUTTON_PRESSED)
		&& (!(next->bstate & BUTTON_PRESSED))) {
		bool changed = TRUE;

		for (b = 1; b <= MAX_BUTTONS; ++b) {
		    if (!MASK_CHANGED(b)) {
			changed = FALSE;
			break;
		    }
		}

		if (changed) {
		    merge = FALSE;
		    for (b = 1; b <= MAX_BUTTONS; ++b) {
			if ((sp->_mouse_mask & MASK_CLICK(b))
			    && (ep->bstate & MASK_PRESS(b))) {
			    next->bstate &= ~MASK_RELEASE(b);
			    next->bstate |= MASK_CLICK(b);
			    merge = TRUE;
			}
		    }
		    if (merge) {
			Invalidate(ep);
		    }
		}
	    }
	}

	/* Compact valid events */
	if (!ValidEvent(ep)) {
	    if ((first_valid != NULL) && (first_invalid == NULL)) {
		first_invalid = ep;
	    }
	} else {
	    if (first_valid == NULL) {
		first_valid = ep;
	    } else if (first_invalid != NULL) {
		*first_invalid = *ep;
		Invalidate(ep);
		first_invalid = NEXT(first_invalid);
	    }
	}

	ep = next;
    }

    if (first_invalid != NULL) {
	eventp = first_invalid;
    }
#ifdef TRACE
    if (USE_TRACEF(TRACE_IEVENT)) {
	_trace_slot(sp, "before mouse click merge:");
	if (first_valid == NULL) {
	    _tracef("_nc_mouse_parse: no valid event");
	} else {
	    _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
		    RunParams(sp, eventp, first_valid),
		    runcount);
	    _nc_unlock_global(tracef);
	}
    }
#endif /* TRACE */

    /*
     * Second pass; merge click runs.  We merge click events forward in the
     * queue.  For example, double click can be changed to triple click.
     *
     * NOTE: There is a problem with this design!  If the application
     * allows enough click events to pile up in the circular queue so
     * they wrap around, it will cheerfully merge the newest forward
     * into the oldest, creating a bogus doubleclick and confusing
     * the queue-traversal logic rather badly.  Generally this won't
     * happen, because calling getmouse() marks old events invalid and
     * ineligible for merges.  The true solution to this problem would
     * be to timestamp each MEVENT and perform the obvious sanity check,
     * but the timer element would have to have sub-second resolution,
     * which would get us into portability trouble.
     */
    first_invalid = NULL;
    endLoop = (first_valid == NULL);
    ep = first_valid;
    while (!endLoop) {
	next = NEXT(ep);

	if (next == eventp) {
	    /* Will end the loop, but check event type and compact before */
	    endLoop = TRUE;
	} else if (!ValidEvent(next)) {
	    continue;
	} else {
	    /* merge click events forward */
	    if ((ep->bstate & BUTTON_CLICKED)
		&& (next->bstate & BUTTON_CLICKED)) {
		merge = FALSE;
		for (b = 1; b <= MAX_BUTTONS; ++b) {
		    if ((sp->_mouse_mask & MASK_DOUBLE_CLICK(b))
			&& (ep->bstate & MASK_CLICK(b))
			&& (next->bstate & MASK_CLICK(b))) {
			next->bstate &= ~MASK_CLICK(b);
			next->bstate |= MASK_DOUBLE_CLICK(b);
			merge = TRUE;
		    }
		}
		if (merge) {
		    Invalidate(ep);
		}
	    }

	    /* merge double-click events forward */
	    if ((ep->bstate & BUTTON_DOUBLE_CLICKED)
		&& (next->bstate & BUTTON_CLICKED)) {
		merge = FALSE;
		for (b = 1; b <= MAX_BUTTONS; ++b) {
		    if ((sp->_mouse_mask & MASK_TRIPLE_CLICK(b))
			&& (ep->bstate & MASK_DOUBLE_CLICK(b))
			&& (next->bstate & MASK_CLICK(b))) {
			next->bstate &= ~MASK_CLICK(b);
			next->bstate |= MASK_TRIPLE_CLICK(b);
			merge = TRUE;
		    }
		}
		if (merge) {
		    Invalidate(ep);
		}
	    }
	}

	/* Discard event if it does not match event mask */
	if (!(ep->bstate & sp->_mouse_mask2)) {
	    Invalidate(ep);
	}

	/* Compact valid events */
	if (!ValidEvent(ep)) {
	    if (ep == first_valid) {
		first_valid = next;
	    } else if (first_invalid == NULL) {
		first_invalid = ep;
	    }
	} else if (first_invalid != NULL) {
	    *first_invalid = *ep;
	    Invalidate(ep);
	    first_invalid = NEXT(first_invalid);
	}

	ep = next;
    }

    if (first_invalid == NULL) {
	first_invalid = eventp;
    }
    sp->_mouse_eventp = first_invalid;

#ifdef TRACE
    if (first_valid != NULL) {
	if (USE_TRACEF(TRACE_IEVENT)) {
	    _trace_slot(sp, "after mouse event queue compaction:");
	    _tracef("_nc_mouse_parse: run starts at %ld, ends at %ld, count %d",
		    RunParams(sp, first_invalid, first_valid),
		    runcount);
	    _nc_unlock_global(tracef);
	}
	for (ep = first_valid; ep != first_invalid; ep = NEXT(ep)) {
	    if (ValidEvent(ep))
		TR(MY_TRACE,
		   ("_nc_mouse_parse: returning composite mouse event %s at slot %ld",
		    _nc_tracemouse(sp, ep),
		    (long) IndexEV(sp, ep)));
	}
    }
#endif /* TRACE */

    /* after all this, do we have a valid event? */
    return ValidEvent(PREV(first_invalid));
}

Project: ncurses

_nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameterized)
{
    int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0;
    const char *padding;
    const char *trimmed = 0;
    int in0, in1, in2;
    char ch1 = 0, ch2 = 0;
    char *bufptr = init_string();
    char octal[4];
    int len;
    int digits;
    bool syntax_error = FALSE;
    int myfix = 0;
    struct {
	int ch;
	int offset;
    } fixups[MAX_TC_FIXUPS];

    DEBUG_THIS(("_nc_infotocap params %d, %s", parameterized, str));

    /* we may have to move some trailing mandatory padding up front */
    padding = str + strlen(str) - 1;
    if (padding > str && *padding == '>') {
	if (*--padding == '/')
	    --padding;
	while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*')
	    padding--;
	if (padding > str && *padding == '<' && *--padding == '$')
	    trimmed = padding;
	padding += 2;

	while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*')
	    bufptr = save_char(bufptr, *padding++);
    }

    for (; !syntax_error &&
	 *str &&
	 ((trimmed == 0) || (str < trimmed)); str++) {
	int c1, c2;
	char *cp = 0;

	if (str[0] == '^') {
	    if (str[1] == '\0' || (str + 1) == trimmed) {
		bufptr = save_string(bufptr, "\\136");
		++str;
	    } else if (str[1] == '?') {
		/*
		 * Although the 4.3BSD termcap file has an instance of "kb=^?",
		 * that appears to be just cut/paste since neither 4.3BSD nor
		 * 4.4BSD termcap interprets "^?" as DEL.
		 */
		bufptr = save_string(bufptr, "\\177");
		++str;
	    } else {
		bufptr = save_char(bufptr, *str++);
		bufptr = save_char(bufptr, *str);
	    }
	} else if (str[0] == '\\') {
	    if (str[1] == '\0' || (str + 1) == trimmed) {
		bufptr = save_string(bufptr, "\\134");
		++str;
	    } else if (str[1] == '^') {
		bufptr = save_string(bufptr, "\\136");
		++str;
	    } else if (str[1] == ',') {
		bufptr = save_char(bufptr, *++str);
	    } else {
		int xx1;

		bufptr = save_char(bufptr, *str++);
		xx1 = *str;
		if (_nc_strict_bsd) {

		    if (isoctal(UChar(xx1))) {
			int pad = 0;
			int xx2;
			int fix = 0;

			if (!isoctal(UChar(str[1])))
			    pad = 2;
			else if (str[1] && !isoctal(UChar(str[2])))
			    pad = 1;

			/*
			 * Test for "\0", "\00" or "\000" and transform those
			 * into "\200".
			 */
			if (xx1 == '0'
			    && ((pad == 2) || (str[1] == '0'))
			    && ((pad >= 1) || (str[2] == '0'))) {
			    xx2 = '2';
			} else {
			    xx2 = '0';
			    pad = 0;	/* FIXME - optionally pad to 3 digits */
			}
			if (myfix < MAX_TC_FIXUPS) {
			    fix = 3 - pad;
			    fixups[myfix].ch = 0;
			    fixups[myfix].offset = (int) (bufptr
							  - my_string
							  - 1);
			}
			while (pad-- > 0) {
			    bufptr = save_char(bufptr, xx2);
			    if (myfix < MAX_TC_FIXUPS) {
				fixups[myfix].ch <<= 3;
				fixups[myfix].ch |= (xx2 - '0');
			    }
			    xx2 = '0';
			}
			if (myfix < MAX_TC_FIXUPS) {
			    int n;
			    for (n = 0; n < fix; ++n) {
				fixups[myfix].ch <<= 3;
				fixups[myfix].ch |= (str[n] - '0');
			    }
			    if (fixups[myfix].ch < 32) {
				++myfix;
			    }
			}
		    } else if (strchr("E\\nrtbf", xx1) == 0) {
			switch (xx1) {
			case 'e':
			    xx1 = 'E';
			    break;
			case 'l':
			    xx1 = 'n';
			    break;
			case 's':
			    bufptr = save_char(bufptr, '0');
			    bufptr = save_char(bufptr, '4');
			    xx1 = '0';
			    break;
			case ':':
			    /*
			     * Note: termcap documentation claims that ":"
			     * must be escaped as "\072", however the
			     * documentation is incorrect - read the code.
			     * The replacement does not work reliably,
			     * so the advice is not helpful.
			     */
			    bufptr = save_char(bufptr, '0');
			    bufptr = save_char(bufptr, '7');
			    xx1 = '2';
			    break;
			default:
			    /* should not happen, but handle this anyway */
			    _nc_SPRINTF(octal, _nc_SLIMIT(sizeof(octal))
					"%03o", UChar(xx1));
			    bufptr = save_char(bufptr, octal[0]);
			    bufptr = save_char(bufptr, octal[1]);
			    xx1 = octal[2];
			    break;
			}
		    }
		} else {
		    if (myfix < MAX_TC_FIXUPS && isoctal(UChar(xx1))) {
			bool will_fix = TRUE;
			int n;

			fixups[myfix].ch = 0;
			fixups[myfix].offset = (int) (bufptr - my_string - 1);
			for (n = 0; n < 3; ++n) {
			    if (isoctal(str[n])) {
				octal_fixup(myfix, str[n]);
			    } else {
				will_fix = FALSE;
				break;
			    }
			}
			if (will_fix && (fixups[myfix].ch < 32))
			    ++myfix;
		    }
		}
		bufptr = save_char(bufptr, xx1);
	    }
	} else if (str[0] == '$' && str[1] == '<') {	/* discard padding */
	    str += 2;
	    while (isdigit(UChar(*str))
		   || *str == '.'
		   || *str == '*'
		   || *str == '/'
		   || *str == '>')
		str++;
	    --str;
	} else if (sscanf(str,
			  "[%%?%%p1%%{8}%%<%%t%d%%p1%%d%%e%%p1%%{16}%%<%%t%d%%p1%%{8}%%-%%d%%e%d;5;%%p1%%d%%;m",
			  &in0, &in1, &in2) == 3
		   && ((in0 == 4 && in1 == 10 && in2 == 48)
		       || (in0 == 3 && in1 == 9 && in2 == 38))) {
	    /* dumb-down an optimized case from xterm-256color for termcap */
	    if ((str = strstr(str, ";m")) == 0)
		break;		/* cannot happen */
	    ++str;
	    if (in2 == 48) {
		bufptr = save_string(bufptr, "[48;5;%dm");
	    } else {
		bufptr = save_string(bufptr, "[38;5;%dm");
	    }
	} else if (str[0] == '%' && str[1] == '%') {	/* escaped '%' */
	    bufptr = save_string(bufptr, "%%");
	    ++str;
	} else if (*str != '%' || (parameterized < 1)) {
	    bufptr = save_char(bufptr, *str);
	} else if (sscanf(str, "%%?%%{%d}%%>%%t%%{%d}%%+%%;", &c1, &c2) == 2) {
	    str = strchr(str, ';');
	    bufptr = save_tc_inequality(bufptr, c1, c2);
	} else if (sscanf(str, "%%?%%{%d}%%>%%t%%'%c'%%+%%;", &c1, &ch2) == 2) {
	    str = strchr(str, ';');
	    bufptr = save_tc_inequality(bufptr, c1, ch2);
	} else if (sscanf(str, "%%?%%'%c'%%>%%t%%{%d}%%+%%;", &ch1, &c2) == 2) {
	    str = strchr(str, ';');
	    bufptr = save_tc_inequality(bufptr, ch1, c2);
	} else if (sscanf(str, "%%?%%'%c'%%>%%t%%'%c'%%+%%;", &ch1, &ch2) == 2) {
	    str = strchr(str, ';');
	    bufptr = save_tc_inequality(bufptr, ch1, ch2);
	} else if ((len = bcd_expression(str)) != 0) {
	    str += len;
	    bufptr = save_string(bufptr, "%B");
	} else if ((sscanf(str, "%%{%d}%%+%%%c", &c1, &ch2) == 2
		    || sscanf(str, "%%'%c'%%+%%%c", &ch1, &ch2) == 2)
		   && ch2 == 'c'
		   && (cp = strchr(str, '+'))) {
	    str = cp + 2;
	    bufptr = save_string(bufptr, "%+");

	    if (ch1)
		c1 = ch1;
	    bufptr = save_tc_char(bufptr, c1);
	}
	/* FIXME: this "works" for 'delta' */
	else if (strncmp(str, "%{2}%*%-", (size_t) 8) == 0) {
	    str += 7;
	    bufptr = save_string(bufptr, "%D");
	} else if (strncmp(str, "%{96}%^", (size_t) 7) == 0) {
	    str += 6;
	    if (saw_m++ == 0) {
		bufptr = save_string(bufptr, "%n");
	    }
	} else if (strncmp(str, "%{127}%^", (size_t) 8) == 0) {
	    str += 7;
	    if (saw_n++ == 0) {
		bufptr = save_string(bufptr, "%m");
	    }
	} else {		/* cm-style format element */
	    str++;
	    switch (*str) {
	    case '%':
		bufptr = save_char(bufptr, '%');
		break;

	    case '0':
	    case '1':
	    case '2':
	    case '3':
	    case '4':
	    case '5':
	    case '6':
	    case '7':
	    case '8':
	    case '9':
		bufptr = save_char(bufptr, '%');
		ch1 = 0;
		ch2 = 0;
		digits = 0;
		while (isdigit(UChar(*str))) {
		    if (++digits > 2) {
			syntax_error = TRUE;
			break;
		    }
		    ch2 = ch1;
		    ch1 = *str++;
		    if (digits == 2 && ch2 != '0') {
			syntax_error = TRUE;
			break;
		    } else if (_nc_strict_bsd) {
			if (ch1 > '3') {
			    syntax_error = TRUE;
			    break;
			}
		    } else {
			bufptr = save_char(bufptr, ch1);
		    }
		}
		if (syntax_error)
		    break;
		/*
		 * Convert %02 to %2 and %03 to %3
		 */
		if (ch2 == '0' && !_nc_strict_bsd) {
		    ch2 = 0;
		    bufptr[-2] = bufptr[-1];
		    *--bufptr = 0;
		}
		if (_nc_strict_bsd) {
		    if (ch2 != 0 && ch2 != '0') {
			syntax_error = TRUE;
		    } else if (ch1 < '2') {
			ch1 = 'd';
		    }
		    bufptr = save_char(bufptr, ch1);
		}
		if (strchr("oxX.", *str)) {
		    syntax_error = TRUE;	/* termcap doesn't have octal, hex */
		}
		break;

	    case 'd':
		bufptr = save_string(bufptr, "%d");
		break;

	    case 'c':
		bufptr = save_string(bufptr, "%.");
		break;

		/*
		 * %s isn't in termcap, but it's convenient to pass it through
		 * so we can represent things like terminfo pfkey strings in
		 * termcap notation.
		 */
	    case 's':
		if (_nc_strict_bsd) {
		    syntax_error = TRUE;
		} else {
		    bufptr = save_string(bufptr, "%s");
		}
		break;

	    case 'p':
		str++;
		if (*str == '1')
		    seenone = 1;
		else if (*str == '2') {
		    if (!seenone && !seentwo) {
			bufptr = save_string(bufptr, "%r");
			seentwo++;
		    }
		} else if (*str >= '3') {
		    syntax_error = TRUE;
		}
		break;

	    case 'i':
		bufptr = save_string(bufptr, "%i");
		break;

	    default:
		bufptr = save_char(bufptr, *str);
		syntax_error = TRUE;
		break;
	    }			/* endswitch (*str) */
	}			/* endelse (*str == '%') */

	/*
	 * 'str' always points to the end of what was scanned in this step,
	 * but that may not be the end of the string.
	 */
	assert(str != 0);
	if (str == 0 || *str == '\0')
	    break;

    }				/* endwhile (*str) */

    if (!syntax_error &&
	myfix > 0 &&
	((int) strlen(my_string) - (4 * myfix)) < MIN_TC_FIXUPS) {
	while (--myfix >= 0) {
	    char *p = fixups[myfix].offset + my_string;
	    *p++ = '^';
	    *p++ = (char) (fixups[myfix].ch | '@');
	    while ((p[0] = p[2]) != '\0') {
		++p;
	    }
	}
    }

    DEBUG_THIS(("... _nc_infotocap %s",
		syntax_error
		? "<ERR>"
		: _nc_visbuf(my_string)));

    return (syntax_error ? NULL : my_string);
}

Project: ncurses

get_number(NCURSES_CONST char *cap, int map)
{
    int result = map;
    if (cap != 0) {
	int check = tigetnum(cap);
	if (check > 0)
	    result = check;
    }
    return result;
}

Project: ncurses

_nc_do_xmc_glitch(attr_t previous)
{
    NCURSES_SP_NAME(_nc_do_xmc_glitch) (CURRENT_SCREEN, previous);
}

Project: ncurses

lookup_user_capability(const char *name)
{
    struct user_table_entry const *result = 0;
    if (*name != 'k') {
	result = _nc_find_user_entry(name);
    }
    return result;
}

Project: ncurses

NCURSES_PUBLIC_VAR(COLORS) (void)
{
    return CURRENT_SCREEN ? CURRENT_SCREEN->_color_count : -1;
}

Project: ncurses

my_napms(int ms)
{
    if (ms > 0) {
#if defined(_WIN32) || !HAVE_GETTIMEOFDAY
	Sleep((DWORD) ms);
#else
	struct timeval data;
	data.tv_sec = 0;
	data.tv_usec = ms * 1000;
	select(0, NULL, NULL, NULL, &data);
#endif
    }
}

Project: ncurses

exit_code(int token, int value)
{
    int result = 99;

    switch (token) {
    case BOOLEAN:
	result = !value;	/* TRUE=0, FALSE=1 */
	break;
    case NUMBER:
	result = 0;		/* always zero */
	break;
    case STRING:
	result = value;		/* 0=normal, 1=missing */
	break;
    }
    return result;
}

Project: ncurses

skip_zero(char *s)
{
    if (s[0] == '0') {
	if (s[1] == ';')
	    s += 2;
	else if (isalpha(UChar(s[1])))
	    s += 1;
    }
    return s;
}

Project: ncurses

tparm_tc_compat(TPARM_DATA * data)
{
    bool termcap_hack = FALSE;

    TPS(stack_ptr) = 0;

    if (data->num_popped == 0) {
	int i;

	termcap_hack = TRUE;
	for (i = data->num_parsed - 1; i >= 0; i--) {
	    if (data->p_is_s[i])
		spush(data->p_is_s[i]);
	    else
		npush((int) data->param[i]);
	}
    }
    return termcap_hack;
}

Project: ncurses

drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
{
    AssertTCB();
    return TINFO_DOUPDATE(TCB->csp);
}

Project: ncurses

npush(int x)
{
    if (TPS(stack_ptr) < STACKSIZE) {
	TPS(stack)[TPS(stack_ptr)].num_type = TRUE;
	TPS(stack)[TPS(stack_ptr)].data.num = x;
	TPS(stack_ptr)++;
    } else {
	DEBUG(2, ("npush: stack overflow: %s", _nc_visbuf(TPS(tparam_base))));
	_nc_tparm_err++;
    }
}

Project: ncurses

drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
	     int old_pair,
	     int pair,
	     int reverse,
	     NCURSES_SP_OUTC outc)
{
    SCREEN *sp = TCB->csp;
    int fg = COLOR_DEFAULT;
    int bg = COLOR_DEFAULT;
    int old_fg, old_bg;

    AssertTCB();
    if (sp == 0)
	return;

    if (pair < 0 || pair >= COLOR_PAIRS) {
	return;
    } else if (pair != 0) {
	if (set_color_pair) {
	    TPUTS_TRACE("set_color_pair");
	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				    TIPARM_1(set_color_pair, pair), 1, outc);
	    return;
	} else if (sp != 0) {
	    _nc_pair_content(SP_PARM, pair, &fg, &bg);
	}
    }

    if (old_pair >= 0
	&& sp != 0
	&& _nc_pair_content(SP_PARM, old_pair, &old_fg, &old_bg) != ERR) {
	if ((isDefaultColor(fg) && !isDefaultColor(old_fg))
	    || (isDefaultColor(bg) && !isDefaultColor(old_bg))) {
#if NCURSES_EXT_FUNCS
	    /*
	     * A minor optimization - but extension.  If "AX" is specified in
	     * the terminal description, treat it as screen's indicator of ECMA
	     * SGR 39 and SGR 49, and assume the two sequences are independent.
	     */
	    if (sp->_has_sgr_39_49
		&& isDefaultColor(old_bg)
		&& !isDefaultColor(old_fg)) {
		NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx "\033[39m", 1, outc);
	    } else if (sp->_has_sgr_39_49
		       && isDefaultColor(old_fg)
		       && !isDefaultColor(old_bg)) {
		NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx "\033[49m", 1, outc);
	    } else
#endif
		drv_rescol(TCB);
	}
    } else {
	drv_rescol(TCB);
	if (old_pair < 0)
	    return;
    }

#if NCURSES_EXT_FUNCS
    if (isDefaultColor(fg))
	fg = default_fg(sp);
    if (isDefaultColor(bg))
	bg = default_bg(sp);
#endif

    if (reverse) {
	int xx = fg;
	fg = bg;
	bg = xx;
    }

    TR(TRACE_ATTRS, ("setting colors: pair = %d, fg = %d, bg = %d", pair,
		     fg, bg));

    if (!isDefaultColor(fg)) {
	drv_setcolor(TCB, TRUE, fg, outc);
    }
    if (!isDefaultColor(bg)) {
	drv_setcolor(TCB, FALSE, bg, outc);
    }
}

Project: ncurses

NCURSES_SP_NAME(_nc_msec_cost) (NCURSES_SP_DCLx const char *const cap, int affcnt)
/* compute the cost of a given operation */
{
    if (cap == 0)
	return (INFINITY);
    else {
	const char *cp;
	float cum_cost = 0.0;

	for (cp = cap; *cp; cp++) {
	    /* extract padding, either mandatory or required */
	    if (cp[0] == '$' && cp[1] == '<' && strchr(cp, '>')) {
		float number = 0.0;

		for (cp += 2; *cp != '>'; cp++) {
		    if (isdigit(UChar(*cp)))
			number = number * 10 + (float) (*cp - '0');
		    else if (*cp == '*')
			number *= (float) affcnt;
		    else if (*cp == '.' && (*++cp != '>') && isdigit(UChar(*cp)))
			number += (float) ((*cp - '0') / 10.0);
		}

#if NCURSES_NO_PADDING
		if (!GetNoPadding(SP_PARM))
#endif
		    cum_cost += number * 10;
	    } else if (SP_PARM) {
		cum_cost += (float) SP_PARM->_char_padding;
	    }
	}

	return ((int) cum_cost);
    }
}

Project: ncurses

is_user_capability(const char *name)
{
    int result = -1;
    if (name[0] == 'u' &&
	(name[1] >= '0' && name[1] <= '9') &&
	name[2] == '\0') {
	result = (name[1] == '6') ? 2 : 0;
    }
#if NCURSES_XNAMES
    else if (using_extensions) {
	struct user_table_entry const *p = lookup_user_capability(name);
	if (p != 0) {
	    result = (int) p->ute_argc;
	}
    }
#endif
    return result;
}

Project: ncurses

mypair(int fg, int bg)
{
    int pair = (fg * COLORS) + bg;
    return (pair >= COLOR_PAIRS) ? -1 : pair;
}

Project: ncurses

check_user_capability_type(const char *name, int actual)
{
    if (lookup_user_capability(name) == 0) {
	int expected = standard_type(name);
	if (expected >= 0) {
	    _nc_warning("expected %s to be %s, but actually %s",
			name,
			name_of_type(actual),
			name_of_type(expected)
		);
	} else if (*name != 'k') {
	    _nc_warning("undocumented %s capability %s",
			name_of_type(actual),
			name);
	}
    }
}

Project: ncurses

main(int argc, char *argv[])
{
    int ch;
    int fg, bg;
    double r;
    double c;
#if HAVE_USE_DEFAULT_COLORS
    bool d_option = FALSE;
#endif
    int m_option = 2;
    int r_option = 0;
    int s_option = 1;
    size_t need;
    char *my_env;

    while ((ch = getopt(argc, argv, "T:dem:r:s:")) != -1) {
	switch (ch) {
	case 'T':
	    need = 6 + strlen(optarg);
	    my_env = malloc(need);
	    _nc_SPRINTF(my_env, _nc_SLIMIT(need) "TERM=%s", optarg);
	    putenv(my_env);
	    break;
#if HAVE_USE_DEFAULT_COLORS
	case 'd':
	    d_option = TRUE;
	    break;
#endif
#if HAVE_USE_ENV
	case 'e':
	    use_env(TRUE);
	    break;
#endif
	case 'm':
	    m_option = atoi(optarg);
	    break;
	case 'r':
	    r_option = atoi(optarg);
	    break;
	case 's':
	    s_option = atoi(optarg);
	    break;
	default:
	    usage();
	    break;
	}
    }

    srand((unsigned) time(0));

    SetupAlarm(r_option);
    InitAndCatch(initscr(), onsig);

    if (has_colors()) {
	start_color();
#if HAVE_USE_DEFAULT_COLORS
	if (d_option)
	    use_default_colors();
#endif
	for (fg = 0; fg < COLORS; fg++) {
	    for (bg = 0; bg < COLORS; bg++) {
		int pair;
		if (interrupted) {
		    cleanup();
		    ExitProgram(EXIT_FAILURE);
		}
		pair = mypair(fg, bg);
		if (pair > 0)
		    init_pair((short) pair, (short) fg, (short) bg);
	    }
	}
    }

    r = (double) (LINES - (m_option * 2));
    c = (double) (COLS - (m_option * 2));
    started = time((time_t *) 0);

    fg = COLOR_WHITE;
    bg = COLOR_BLACK;
    while (!interrupted) {
	int x = (int) (c * ranf()) + m_option;
	int y = (int) (r * ranf()) + m_option;
	int p = (ranf() > 0.9) ? '*' : ' ';

	move(y, x);
	if (has_colors()) {
	    int z = (int) (ranf() * COLORS);
	    if (ranf() > 0.01) {
		set_colors(fg = z, bg);
		attron(COLOR_PAIR(mypair(fg, bg)));
	    } else {
		set_colors(fg, bg = z);
		if (s_option)
		    napms(s_option);
	    }
	} else {
	    if (ranf() <= 0.01) {
		if (ranf() > 0.6) {
		    attron(A_REVERSE);
		} else {
		    attroff(A_REVERSE);
		}
		if (s_option)
		    napms(s_option);
	    }
	}
	AddCh(p);
	refresh();
	++total_chars;
    }
    cleanup();
    ExitProgram(EXIT_SUCCESS);
}

Project: ncurses

NCURSES_SP_NAME(_nc_do_color) (NCURSES_SP_DCLx
			       int old_pair,
			       int pair,
			       int reverse,
			       NCURSES_SP_OUTC outc)
{
#ifdef USE_TERM_DRIVER
    CallDriver_4(SP_PARM, td_docolor, old_pair, pair, reverse, outc);
#else
    int fg = COLOR_DEFAULT;
    int bg = COLOR_DEFAULT;
    int old_fg = -1;
    int old_bg = -1;

    if (!ValidPair(SP_PARM, pair)) {
	return;
    } else if (pair != 0) {
	if (set_color_pair) {
	    TPUTS_TRACE("set_color_pair");
	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				    TIPARM_1(set_color_pair, pair),
				    1, outc);
	    return;
	} else if (SP_PARM != 0) {
	    if (_nc_pair_content(SP_PARM, pair, &fg, &bg) == ERR)
		return;
	}
    }

    if (old_pair >= 0
	&& SP_PARM != 0
	&& _nc_pair_content(SP_PARM, old_pair, &old_fg, &old_bg) != ERR) {
	if ((isDefaultColor(fg) && !isDefaultColor(old_fg))
	    || (isDefaultColor(bg) && !isDefaultColor(old_bg))) {
#if NCURSES_EXT_FUNCS
	    /*
	     * A minor optimization - but extension.  If "AX" is specified in
	     * the terminal description, treat it as screen's indicator of ECMA
	     * SGR 39 and SGR 49, and assume the two sequences are independent.
	     */
	    if (SP_PARM->_has_sgr_39_49
		&& isDefaultColor(old_bg)
		&& !isDefaultColor(old_fg)) {
		NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx "\033[39m", 1, outc);
	    } else if (SP_PARM->_has_sgr_39_49
		       && isDefaultColor(old_fg)
		       && !isDefaultColor(old_bg)) {
		NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx "\033[49m", 1, outc);
	    } else
#endif
		reset_color_pair(NCURSES_SP_ARG);
	}
    } else {
	reset_color_pair(NCURSES_SP_ARG);
	if (old_pair < 0 && pair <= 0)
	    return;
    }

#if NCURSES_EXT_FUNCS
    if (isDefaultColor(fg))
	fg = default_fg(NCURSES_SP_ARG);
    if (isDefaultColor(bg))
	bg = default_bg(NCURSES_SP_ARG);
#endif

    if (reverse) {
	int xx = fg;
	fg = bg;
	bg = xx;
    }

    TR(TRACE_ATTRS, ("setting colors: pair = %d, fg = %d, bg = %d", pair,
		     fg, bg));

    if (!isDefaultColor(fg)) {
	set_foreground_color(NCURSES_SP_ARGx fg, outc);
    }
    if (!isDefaultColor(bg)) {
	set_background_color(NCURSES_SP_ARGx bg, outc);
    }
#endif
}

Project: ncurses

NCURSES_SP_NAME(_nc_do_xmc_glitch) (NCURSES_SP_DCLx attr_t previous)
{
    if (SP_PARM != 0) {
	attr_t chg = XMC_CHANGES(previous ^ AttrOf(SCREEN_ATTRS(SP_PARM)));

	while (chg != 0) {
	    if (chg & 1) {
		SP_PARM->_curscol += magic_cookie_glitch;
		if (SP_PARM->_curscol >= SP_PARM->_columns)
		    wrap_cursor(NCURSES_SP_ARG);
		TR(TRACE_UPDATE, ("bumped to %d,%d after cookie",
				  SP_PARM->_cursrow, SP_PARM->_curscol));
	    }
	    chg >>= 1;
	}
    }
}

Project: ncurses

cat_file(char *file)
{
    FILE *fp;
    size_t nr;
    char buf[BUFSIZ];
    bool sent = FALSE;

    if (file != 0) {
	if ((fp = fopen(file, "r")) == 0)
	    failed(file);

	while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) {
	    if (fwrite(buf, sizeof(char), nr, my_file) != nr) {
		failed(file);
	    }
	    sent = TRUE;
	}
	fclose(fp);
    }
    return sent;
}

Project: ncurses

read_SGR(SCREEN *sp, SGR_DATA * result)
{
    char kbuf[80];		/* bigger than any possible mouse response */
    int grabbed = 0;
    int ch = 0;
    int now = -1;
    int marker = 1;

    memset(result, 0, sizeof(*result));
# if USE_PTHREADS_EINTR
#  if USE_WEAK_SYMBOLS
    if ((pthread_self) && (pthread_kill) && (pthread_equal))
#  endif
	_nc_globals.read_thread = pthread_self();
# endif

    do {
	int res;

	res = (int) read(
#if USE_EMX_MOUSE
			    (M_FD(sp) >= 0) ? M_FD(sp) : sp->_ifd,
#else
			    sp->_ifd,
#endif
			    (kbuf + grabbed), (size_t) 1);
	if (res == -1)
	    break;
	if ((grabbed + MAX_KBUF) >= (int) sizeof(kbuf)) {
	    result->nerror++;
	    break;
	}
	ch = UChar(kbuf[grabbed]);
	kbuf[grabbed + 1] = 0;
	switch (ch) {
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	    if (marker) {
		++now;
		result->nparam = (now + 1);
	    }
	    marker = 0;
	    result->params[now] = (result->params[now] * 10) + (ch - '0');
	    break;
	case ';':
	    if (marker) {
		++now;
		result->nparam = (now + 1);
	    }
	    marker = 1;
	    break;
	default:
	    if (ch < 32 || ch > 126) {
		/*
		 * Technically other characters could be interspersed in the
		 * response.  Ignore those for now.
		 */
		result->nerror++;
		continue;
	    } else if (isFinal(ch)) {
		if (marker) {
		    result->nparam++;
		}
		result->final = ch;
	    } else {
		result->nerror++;
	    }
	    break;
	}
	++grabbed;
    } while (!isFinal(ch));
#if USE_PTHREADS_EINTR
    _nc_globals.read_thread = 0;
#endif

    kbuf[++grabbed] = 0;
    TR(TRACE_IEVENT,
       ("_nc_mouse_inline sees the following xterm data: '%s'", kbuf));
    return (grabbed > 0) && (result->nerror == 0);
}

Project: ncurses

scroll_csr_forward(NCURSES_SP_DCLx
		   int n,
		   int top,
		   int bot,
		   int miny,
		   int maxy,
		   NCURSES_CH_T blank)
{
    int i;

    if (n == 1 && scroll_forward && top == miny && bot == maxy) {
	GoTo(NCURSES_SP_ARGx bot, 0);
	UpdateAttrs(SP_PARM, blank);
	NCURSES_PUTP2("scroll_forward", scroll_forward);
    } else if (n == 1 && delete_line && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	NCURSES_PUTP2("delete_line", delete_line);
    } else if (parm_index && top == miny && bot == maxy) {
	GoTo(NCURSES_SP_ARGx bot, 0);
	UpdateAttrs(SP_PARM, blank);
	TPUTS_TRACE("parm_index");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(parm_index, n),
				n,
				NCURSES_SP_NAME(_nc_outch));
    } else if (parm_delete_line && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	TPUTS_TRACE("parm_delete_line");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(parm_delete_line, n),
				n,
				NCURSES_SP_NAME(_nc_outch));
    } else if (scroll_forward && top == miny && bot == maxy) {
	GoTo(NCURSES_SP_ARGx bot, 0);
	UpdateAttrs(SP_PARM, blank);
	for (i = 0; i < n; i++) {
	    NCURSES_PUTP2("scroll_forward", scroll_forward);
	}
    } else if (delete_line && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	for (i = 0; i < n; i++) {
	    NCURSES_PUTP2("delete_line", delete_line);
	}
    } else
	return ERR;

#if NCURSES_EXT_FUNCS
    if (FILL_BCE(SP_PARM)) {
	int j;
	for (i = 0; i < n; i++) {
	    GoTo(NCURSES_SP_ARGx bot - i, 0);
	    for (j = 0; j < screen_columns(SP_PARM); j++)
		PutChar(NCURSES_SP_ARGx CHREF(blank));
	}
    }
#endif
    return OK;
}

Project: ncurses

stripped(char *src)
{
    char *dst = 0;

    while (isspace(UChar(*src)))
	src++;

    if (*src != '\0') {
	size_t len;

	if ((dst = strdup(src)) == NULL) {
	    failed("strdup");
	} else {
	    len = strlen(dst);
	    while (--len != 0 && isspace(UChar(dst[len])))
		dst[len] = '\0';
	}
    }
    return dst;
}

Project: ncurses

main(int argc, char *argv[])
{
    int c, tc = FALSE;

    while ((c = getopt(argc, argv, "c")) != EOF)
	switch (c) {
	case 'c':
	    tc = TRUE;
	    break;
	}

    curr_line = 0;
    for (;;) {
	char buf[BUFSIZ];

	++curr_line;
	if (fgets(buf, sizeof(buf), stdin) == 0)
	    break;
	buf[strlen(buf) - 1] = '\0';
	_nc_set_source(buf);

	if (tc) {
	    char *cp = _nc_infotocap("to termcap", buf, 1);

	    if (cp)
		(void) fputs(cp, stdout);
	} else
	    (void) fputs(_nc_captoinfo("to terminfo", buf, 1), stdout);
	(void) putchar('\n');
    }
    return (0);
}

Project: ncurses

sysmouse_server(SCREEN *sp)
{
    struct mouse_info the_mouse;
    MEVENT *work;

    the_mouse.operation = MOUSE_GETINFO;
    if (sp != 0
	&& sp->_mouse_fd >= 0
	&& sp->_sysmouse_tail < FIFO_SIZE
	&& ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse) != -1) {

	if (sp->_sysmouse_head > sp->_sysmouse_tail) {
	    sp->_sysmouse_tail = 0;
	    sp->_sysmouse_head = 0;
	}
	work = &(sp->_sysmouse_fifo[sp->_sysmouse_tail]);
	memset(work, 0, sizeof(*work));
	work->id = NORMAL_EVENT;	/* there's only one mouse... */

	sp->_sysmouse_old_buttons = sp->_sysmouse_new_buttons;
	sp->_sysmouse_new_buttons = the_mouse.u.data.buttons & 0x7;

	if (sp->_sysmouse_new_buttons) {
	    if (sp->_sysmouse_new_buttons & 1)
		work->bstate |= BUTTON1_PRESSED;
	    if (sp->_sysmouse_new_buttons & 2)
		work->bstate |= BUTTON2_PRESSED;
	    if (sp->_sysmouse_new_buttons & 4)
		work->bstate |= BUTTON3_PRESSED;
	} else {
	    if (sp->_sysmouse_old_buttons & 1)
		work->bstate |= BUTTON1_RELEASED;
	    if (sp->_sysmouse_old_buttons & 2)
		work->bstate |= BUTTON2_RELEASED;
	    if (sp->_sysmouse_old_buttons & 4)
		work->bstate |= BUTTON3_RELEASED;
	}

	/* for cosmetic bug in syscons.c on FreeBSD 3.[34] */
	the_mouse.operation = MOUSE_HIDE;
	ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse);
	the_mouse.operation = MOUSE_SHOW;
	ioctl(sp->_mouse_fd, CONS_MOUSECTL, &the_mouse);

	/*
	 * We're only interested if the button is pressed or released.
	 * FIXME: implement continuous event-tracking.
	 */
	if (sp->_sysmouse_new_buttons != sp->_sysmouse_old_buttons) {
	    sp->_sysmouse_tail += 1;
	}
	work->x = the_mouse.u.data.x / sp->_sysmouse_char_width;
	work->y = the_mouse.u.data.y / sp->_sysmouse_char_height;
    }
}

Project: ncurses

csi_length(const char *value)
{
    int result = 0;

    if (value[0] == '\033' && value[1] == '[') {
	result = 2;
    } else if (UChar(value[0]) == 0x9a) {
	result = 1;
    }
    return result;
}

Project: ncurses

reset_tabstops(int wide)
{
    if ((init_tabs != 8)
	&& VALID_NUMERIC(init_tabs)
	&& VALID_STRING(set_tab)
	&& VALID_STRING(clear_all_tabs)) {
	int c;

	to_left_margin();
	tputs(clear_all_tabs, 0, out_char);
	if (init_tabs > 1) {
	    if (init_tabs > wide)
		init_tabs = (short) wide;
	    for (c = init_tabs; c < wide; c += init_tabs) {
		fprintf(my_file, "%*s", init_tabs, " ");
		tputs(set_tab, 0, out_char);
	    }
	    to_left_margin();
	}
	return (TRUE);
    }
    return (FALSE);
}

Project: ncurses

parse_delay_value(const char *src, double *delays, int *always)
{
    int star = 0;

    *delays = 0.0;
    if (always)
	*always = 0;

    while (isdigit(UChar(*src))) {
	(*delays) = (*delays) * 10 + (*src++ - '0');
    }
    if (*src == '.') {
	int gotdot = 1;

	++src;
	while (isdigit(UChar(*src))) {
	    gotdot *= 10;
	    (*delays) += (*src++ - '0') / gotdot;
	}
    }
    while (*src == '*' || *src == '/') {
	if (always == 0 && *src == '/')
	    break;
	if (*src++ == '*') {
	    star = 1;
	} else {
	    *always = 1;
	}
    }
    if (star)
	*delays = -(*delays);
    return src;
}

Project: ncurses

extended_color_content(int color, int *r, int *g, int *b)
{
    return NCURSES_SP_NAME(extended_color_content) (CURRENT_SCREEN,
						    color,
						    r, g, b);
}

Project: ncurses

_nc_locked_tracef(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    _nc_va_tracef(fmt, ap);
    va_end(ap);

    if (--(MyNested) == 0) {
	_nc_unlock_global(tracef);
    }
}

Project: ncurses

onsig(int n GCC_UNUSED)
{
    interrupted = TRUE;
}

Project: ncurses

drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
	     int fore,
	     int color,
	     NCURSES_SP_OUTC outc)
{
    SCREEN *sp;

    AssertTCB();
    SetSP();

    if (fore) {
	if (set_a_foreground) {
	    TPUTS_TRACE("set_a_foreground");
	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				    TIPARM_1(set_a_foreground, color), 1, outc);
	} else {
	    TPUTS_TRACE("set_foreground");
	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				    TIPARM_1(set_foreground,
					     toggled_colors(color)), 1, outc);
	}
    } else {
	if (set_a_background) {
	    TPUTS_TRACE("set_a_background");
	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				    TIPARM_1(set_a_background, color), 1, outc);
	} else {
	    TPUTS_TRACE("set_background");
	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				    TIPARM_1(set_background,
					     toggled_colors(color)), 1, outc);
	}
    }
}

Project: ncurses

scroll_csr_backward(NCURSES_SP_DCLx
		    int n,
		    int top,
		    int bot,
		    int miny,
		    int maxy,
		    NCURSES_CH_T blank)
{
    int i;

    if (n == 1 && scroll_reverse && top == miny && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	NCURSES_PUTP2("scroll_reverse", scroll_reverse);
    } else if (n == 1 && insert_line && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	NCURSES_PUTP2("insert_line", insert_line);
    } else if (parm_rindex && top == miny && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	TPUTS_TRACE("parm_rindex");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(parm_rindex, n),
				n,
				NCURSES_SP_NAME(_nc_outch));
    } else if (parm_insert_line && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	TPUTS_TRACE("parm_insert_line");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(parm_insert_line, n),
				n,
				NCURSES_SP_NAME(_nc_outch));
    } else if (scroll_reverse && top == miny && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	for (i = 0; i < n; i++) {
	    NCURSES_PUTP2("scroll_reverse", scroll_reverse);
	}
    } else if (insert_line && bot == maxy) {
	GoTo(NCURSES_SP_ARGx top, 0);
	UpdateAttrs(SP_PARM, blank);
	for (i = 0; i < n; i++) {
	    NCURSES_PUTP2("insert_line", insert_line);
	}
    } else
	return ERR;

#if NCURSES_EXT_FUNCS
    if (FILL_BCE(SP_PARM)) {
	int j;
	for (i = 0; i < n; i++) {
	    GoTo(NCURSES_SP_ARGx top + i, 0);
	    for (j = 0; j < screen_columns(SP_PARM); j++)
		PutChar(NCURSES_SP_ARGx CHREF(blank));
	}
    }
#endif
    return OK;
}

Project: ncurses

set_colors(int fg, int bg)
{
    int pair = mypair(fg, bg);
    if (pair > 0) {
	(void) color_set((short) pair, NewPair(pair));
    }
}

Project: ncurses

ranf(void)
{
    long r = (rand() & 077777);
    return ((double) r / 32768.);
}

Project: ncurses

relative_move(NCURSES_SP_DCLx
	      string_desc * target,
	      int from_y,
	      int from_x,
	      int to_y,
	      int to_x,
	      int ovw)
/* move via local motions (cuu/cuu1/cud/cud1/cub1/cub/cuf1/cuf/vpa/hpa) */
{
    string_desc save;
    int n, vcost = 0, hcost = 0;

    (void) _nc_str_copy(&save, target);

    if (to_y != from_y) {
	vcost = INFINITY;

	if (row_address != 0
	    && _nc_safe_strcat(target, TIPARM_1(row_address, to_y))) {
	    vcost = SP_PARM->_vpa_cost;
	}

	if (to_y > from_y) {
	    n = (to_y - from_y);

	    if (parm_down_cursor
		&& SP_PARM->_cud_cost < vcost
		&& _nc_safe_strcat(_nc_str_copy(target, &save),
				   TIPARM_1(parm_down_cursor, n))) {
		vcost = SP_PARM->_cud_cost;
	    }

	    if (cursor_down
		&& (*cursor_down != '\n' || SP_PARM->_nl)
		&& (n * SP_PARM->_cud1_cost < vcost)) {
		vcost = repeated_append(_nc_str_copy(target, &save), 0,
					SP_PARM->_cud1_cost, n, cursor_down);
	    }
	} else {		/* (to_y < from_y) */
	    n = (from_y - to_y);

	    if (parm_up_cursor
		&& SP_PARM->_cuu_cost < vcost
		&& _nc_safe_strcat(_nc_str_copy(target, &save),
				   TIPARM_1(parm_up_cursor, n))) {
		vcost = SP_PARM->_cuu_cost;
	    }

	    if (cursor_up && (n * SP_PARM->_cuu1_cost < vcost)) {
		vcost = repeated_append(_nc_str_copy(target, &save), 0,
					SP_PARM->_cuu1_cost, n, cursor_up);
	    }
	}

	if (vcost == INFINITY)
	    return (INFINITY);
    }

    save = *target;

    if (to_x != from_x) {
	char str[OPT_SIZE];
	string_desc check;

	hcost = INFINITY;

	if (column_address
	    && _nc_safe_strcat(_nc_str_copy(target, &save),
			       TIPARM_1(column_address, to_x))) {
	    hcost = SP_PARM->_hpa_cost;
	}

	if (to_x > from_x) {
	    n = to_x - from_x;

	    if (parm_right_cursor
		&& SP_PARM->_cuf_cost < hcost
		&& _nc_safe_strcat(_nc_str_copy(target, &save),
				   TIPARM_1(parm_right_cursor, n))) {
		hcost = SP_PARM->_cuf_cost;
	    }

	    if (cursor_right) {
		int lhcost = 0;

		(void) _nc_str_init(&check, str, sizeof(str));

#if USE_HARD_TABS
		/* use hard tabs, if we have them, to do as much as possible */
		if (init_tabs > 0 && tab) {
		    int nxt, fr;

		    for (fr = from_x; (nxt = NEXTTAB(fr)) <= to_x; fr = nxt) {
			lhcost = repeated_append(&check, lhcost,
						 SP_PARM->_ht_cost, 1, tab);
			if (lhcost == INFINITY)
			    break;
		    }

		    n = to_x - fr;
		    from_x = fr;
		}
#endif /* USE_HARD_TABS */

		if (n <= 0 || n >= (int) check.s_size)
		    ovw = FALSE;
#if BSD_TPUTS
		/*
		 * If we're allowing BSD-style padding in tputs, don't generate
		 * a string with a leading digit.  Otherwise, that will be
		 * interpreted as a padding value rather than sent to the
		 * screen.
		 */
		if (ovw
		    && n > 0
		    && n < (int) check.s_size
		    && vcost == 0
		    && str[0] == '\0') {
		    int wanted = CharOf(WANT_CHAR(SP_PARM, to_y, from_x));
		    if (is8bits(wanted) && isdigit(wanted))
			ovw = FALSE;
		}
#endif
		/*
		 * If we have no attribute changes, overwrite is cheaper.
		 * Note: must suppress this by passing in ovw = FALSE whenever
		 * WANT_CHAR would return invalid data.  In particular, this
		 * is true between the time a hardware scroll has been done
		 * and the time the structure WANT_CHAR would access has been
		 * updated.
		 */
		if (ovw) {
		    int i;

		    for (i = 0; i < n; i++) {
			NCURSES_CH_T ch = WANT_CHAR(SP_PARM, to_y, from_x + i);
			if (!SameAttrOf(ch, SCREEN_ATTRS(SP_PARM))
#if USE_WIDEC_SUPPORT
			    || !Charable(ch)
#endif
			    ) {
			    ovw = FALSE;
			    break;
			}
		    }
		}
		if (ovw) {
		    int i;

		    for (i = 0; i < n; i++)
			*check.s_tail++ = (char) CharOf(WANT_CHAR(SP_PARM, to_y,
								  from_x + i));
		    *check.s_tail = '\0';
		    check.s_size -= (size_t) n;
		    lhcost += n * SP_PARM->_char_padding;
		} else {
		    lhcost = repeated_append(&check, lhcost, SP_PARM->_cuf1_cost,
					     n, cursor_right);
		}

		if (lhcost < hcost
		    && _nc_safe_strcat(_nc_str_copy(target, &save), str)) {
		    hcost = lhcost;
		}
	    }
	} else {		/* (to_x < from_x) */
	    n = from_x - to_x;

	    if (parm_left_cursor
		&& SP_PARM->_cub_cost < hcost
		&& _nc_safe_strcat(_nc_str_copy(target, &save),
				   TIPARM_1(parm_left_cursor, n))) {
		hcost = SP_PARM->_cub_cost;
	    }

	    if (cursor_left) {
		int lhcost = 0;

		(void) _nc_str_init(&check, str, sizeof(str));

#if USE_HARD_TABS
		if (init_tabs > 0 && back_tab) {
		    int nxt, fr;

		    for (fr = from_x; (nxt = LASTTAB(fr)) >= to_x; fr = nxt) {
			lhcost = repeated_append(&check, lhcost,
						 SP_PARM->_cbt_cost,
						 1, back_tab);
			if (lhcost == INFINITY)
			    break;
		    }

		    n = fr - to_x;
		}
#endif /* USE_HARD_TABS */

		lhcost = repeated_append(&check, lhcost,
					 SP_PARM->_cub1_cost,
					 n, cursor_left);

		if (lhcost < hcost
		    && _nc_safe_strcat(_nc_str_copy(target, &save), str)) {
		    hcost = lhcost;
		}
	    }
	}

	if (hcost == INFINITY)
	    return (INFINITY);
    }

    return (vcost + hcost);
}

Project: ncurses

rewrite_sgr(char *s, char *attr)
{
    if (s != 0) {
	if (PRESENT(attr)) {
	    size_t len_s = strlen(s);
	    size_t len_a = strlen(attr);

	    if (len_s > len_a && !strncmp(attr, s, len_a)) {
		unsigned n;
		TR(TRACE_DATABASE, ("rewrite:\n\t%s", s));
		for (n = 0; n < len_s - len_a; ++n) {
		    s[n] = s[n + len_a];
		}
		_nc_STRCPY(s + n, attr, strlen(s) + 1);
		TR(TRACE_DATABASE, ("to:\n\t%s", s));
	    }
	}
	return TRUE;
    }
    return FALSE;		/* oops */
}

Project: ncurses

NCURSES_SP_NAME(init_color) (NCURSES_SP_DCLx
			     NCURSES_COLOR_T color,
			     NCURSES_COLOR_T r,
			     NCURSES_COLOR_T g,
			     NCURSES_COLOR_T b)
{
    return _nc_init_color(SP_PARM, color, r, g, b);
}

Project: ncurses

mypair(int fg, int bg)
{
    int result;
#if HAVE_ALLOC_PAIR
    if (x_option) {
	result = alloc_pair(fg, bg);
    } else
#endif
    {
	int pair = (fg * COLORS) + bg;
	result = (pair >= COLOR_PAIRS) ? -1 : pair;
    }
    return result;
}

Project: ncurses

main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
{
    failed("This program requires the terminfo functions such as tigetstr");
}

Project: ncurses

NCURSES_SP_NAME(getmouse) (NCURSES_SP_DCLx MEVENT * aevent)
{
    int result = ERR;
    MEVENT *eventp;

    T((T_CALLED("getmouse(%p,%p)"), (void *) SP_PARM, (void *) aevent));

    if ((aevent != 0) &&
	(SP_PARM != 0) &&
	(SP_PARM->_mouse_type != M_NONE) &&
	(eventp = SP_PARM->_mouse_eventp) != 0) {
	/* compute the current-event pointer */
	MEVENT *prev = PREV(eventp);

	/*
	 * Discard events not matching mask (there could be still some if
	 * _nc_mouse_parse was not called, e.g., when _nc_mouse_inline returns
	 * false).
	 */
	while (ValidEvent(prev) && (!(prev->bstate & SP_PARM->_mouse_mask2))) {
	    Invalidate(prev);
	    prev = PREV(prev);
	}
	if (ValidEvent(prev)) {
	    /* copy the event we find there */
	    *aevent = *prev;

	    TR(TRACE_IEVENT, ("getmouse: returning event %s from slot %ld",
			      _nc_tracemouse(SP_PARM, prev),
			      (long) IndexEV(SP_PARM, prev)));

	    Invalidate(prev);	/* so the queue slot becomes free */
	    SP_PARM->_mouse_eventp = prev;
	    result = OK;
	} else {
	    /* Reset the provided event */
	    aevent->bstate = 0;
	    Invalidate(aevent);
	    aevent->x = 0;
	    aevent->y = 0;
	    aevent->z = 0;
	}
    }
    returnCode(result);
}

Project: ncurses

keypad_index(const char *string)
{
    char *test;
    const char *list = "PQRSwxymtuvlqrsPpn";	/* app-keypad except "Enter" */
    int ch;
    long result = -1;

    if ((ch = keypad_final(string)) != '\0') {
	test = (strchr) (list, ch);
	if (test != 0)
	    result = (long) (test - list);
    }
    return result;
}

Project: ncurses

wenclose(const WINDOW *win, int y, int x)
/* check to see if given window encloses given screen location */
{
    bool result = FALSE;

    T((T_CALLED("wenclose(%p,%d,%d)"), (const void *) win, y, x));

    if (win != 0) {
	y -= win->_yoffset;
	result = ((win->_begy <= y &&
		   win->_begx <= x &&
		   (win->_begx + win->_maxx) >= x &&
		   (win->_begy + win->_maxy) >= y) ? TRUE : FALSE);
    }
    returnBool(result);
}

Project: ncurses

reset_tty_settings(int fd, TTY * tty_settings)
{
    GET_TTY(fd, tty_settings);

#ifdef TERMIOS
#if defined(VDISCARD) && defined(CDISCARD)
    reset_char(VDISCARD, CDISCARD);
#endif
    reset_char(VEOF, CEOF);
    reset_char(VERASE, CERASE);
#if defined(VFLUSH) && defined(CFLUSH)
    reset_char(VFLUSH, CFLUSH);
#endif
    reset_char(VINTR, CINTR);
    reset_char(VKILL, CKILL);
#if defined(VLNEXT) && defined(CLNEXT)
    reset_char(VLNEXT, CLNEXT);
#endif
    reset_char(VQUIT, CQUIT);
#if defined(VREPRINT) && defined(CRPRNT)
    reset_char(VREPRINT, CRPRNT);
#endif
#if defined(VSTART) && defined(CSTART)
    reset_char(VSTART, CSTART);
#endif
#if defined(VSTOP) && defined(CSTOP)
    reset_char(VSTOP, CSTOP);
#endif
#if defined(VSUSP) && defined(CSUSP)
    reset_char(VSUSP, CSUSP);
#endif
#if defined(VWERASE) && defined(CWERASE)
    reset_char(VWERASE, CWERASE);
#endif

    tty_settings->c_iflag &= ~((unsigned) (IGNBRK
					   | PARMRK
					   | INPCK
					   | ISTRIP
					   | INLCR
					   | IGNCR
#ifdef IUCLC
					   | IUCLC
#endif
#ifdef IXANY
					   | IXANY
#endif
					   | IXOFF));

    tty_settings->c_iflag |= (BRKINT
			      | IGNPAR
			      | ICRNL
			      | IXON
#ifdef IMAXBEL
			      | IMAXBEL
#endif
	);

    tty_settings->c_oflag &= ~((unsigned) (0
#ifdef OLCUC
					   | OLCUC
#endif
#ifdef OCRNL
					   | OCRNL
#endif
#ifdef ONOCR
					   | ONOCR
#endif
#ifdef ONLRET
					   | ONLRET
#endif
#ifdef OFILL
					   | OFILL
#endif
#ifdef OFDEL
					   | OFDEL
#endif
#ifdef NLDLY
					   | NLDLY
#endif
#ifdef CRDLY
					   | CRDLY
#endif
#ifdef TABDLY
					   | TABDLY
#endif
#ifdef BSDLY
					   | BSDLY
#endif
#ifdef VTDLY
					   | VTDLY
#endif
#ifdef FFDLY
					   | FFDLY
#endif
			       ));

    tty_settings->c_oflag |= (OPOST
#ifdef ONLCR
			      | ONLCR
#endif
	);

    tty_settings->c_cflag &= ~((unsigned) (CSIZE
					   | CSTOPB
					   | PARENB
					   | PARODD
					   | CLOCAL));
    tty_settings->c_cflag |= (CS8 | CREAD);
    tty_settings->c_lflag &= ~((unsigned) (ECHONL
					   | NOFLSH
#ifdef TOSTOP
					   | TOSTOP
#endif
#ifdef ECHOPTR
					   | ECHOPRT
#endif
#ifdef XCASE
					   | XCASE
#endif
			       ));

    tty_settings->c_lflag |= (ISIG
			      | ICANON
			      | ECHO
			      | ECHOE
			      | ECHOK
#ifdef ECHOCTL
			      | ECHOCTL
#endif
#ifdef ECHOKE
			      | ECHOKE
#endif
	);
#endif

    SET_TTY(fd, tty_settings);
}

Project: ncurses

position_check(NCURSES_SP_DCLx int expected_y, int expected_x, char *legend)
/* check to see if the real cursor position matches the virtual */
{
    char buf[20];
    char *s;
    int y, x;

    if (!_nc_tracing || (expected_y < 0 && expected_x < 0))
	return;

    NCURSES_SP_NAME(_nc_flush) (NCURSES_SP_ARG);
    memset(buf, '\0', sizeof(buf));
    NCURSES_PUTP2_FLUSH("cpr", "\033[6n");	/* only works on ANSI-compatibles */
    *(s = buf) = 0;
    do {
	int ask = sizeof(buf) - 1 - (s - buf);
	int got = read(0, s, ask);
	if (got == 0)
	    break;
	s += got;
    } while (strchr(buf, 'R') == 0);
    _tracef("probe returned %s", _nc_visbuf(buf));

    /* try to interpret as a position report */
    if (sscanf(buf, "\033[%d;%dR", &y, &x) != 2) {
	_tracef("position probe failed in %s", legend);
    } else {
	if (expected_x < 0)
	    expected_x = x - 1;
	if (expected_y < 0)
	    expected_y = y - 1;
	if (y - 1 != expected_y || x - 1 != expected_x) {
	    NCURSES_SP_NAME(beep) (NCURSES_SP_ARG);
	    NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				    TIPARM_2("\033[%d;%dH",
					     expected_y + 1,
					     expected_x + 1),
				    1, NCURSES_SP_NAME(_nc_outch));
	    _tracef("position seen (%d, %d) doesn't match expected one (%d, %d) in %s",
		    y - 1, x - 1, expected_y, expected_x, legend);
	} else {
	    _tracef("position matches OK in %s", legend);
	}
    }
}

Project: ncurses

enable_xterm_mouse(SCREEN *sp, int enable)
{
#if USE_EMX_MOUSE
    sp->_emxmouse_activated = enable;
#else
    NCURSES_PUTP2("xterm-mouse", TIPARM_1(sp->_mouse_xtermcap, enable));
#endif
    sp->_mouse_active = enable;
}

Project: ncurses

handle_wheel(SCREEN *sp, MEVENT * eventp, int button, int wheel)
{
    bool result = TRUE;

    switch (button & 3) {
    case 0:
	if (wheel) {
	    eventp->bstate = MASK_PRESS(4);
	    /* Do not record in sp->_mouse_bstate; there will be no
	     * corresponding release event.
	     */
	} else {
	    PRESS_POSITION(1);
	}
	break;
    case 1:
	if (wheel) {
#if NCURSES_MOUSE_VERSION >= 2
	    eventp->bstate = MASK_PRESS(5);
	    /* See comment above for button 4 */
#else
	    /* Ignore this event as it is not a true press of the button */
	    eventp->bstate = REPORT_MOUSE_POSITION;
#endif
	} else {
	    PRESS_POSITION(2);
	}
	break;
    case 2:
	PRESS_POSITION(3);
	break;
    default:
	result = FALSE;
	break;
    }
    return result;
}

Project: ncurses

_nc_outch(int ch)
{
    putc(ch, stdout);
    return OK;
}

Project: ncurses

parse_ti_delay(const char *ti, double *delays)
{
    *delays = 0.0;
    while (*ti != '\0') {
	if (*ti == '\\') {
	    ++ti;
	}
	if (ti[0] == '$'
	    && ti[1] == '<'
	    && IsDelay(UChar(ti[2]))) {
	    int ignored;
	    const char *last = parse_delay_value(ti + 2, delays, &ignored);
	    if (*last == '>') {
		ti = last;
	    }
	} else {
	    ++ti;
	}
    }
    return ti;
}

Project: ncurses

write_event(SCREEN *sp, int down, int button, int x, int y)
{
    char buf[6];
    unsigned long ignore;

    _nc_STRCPY(buf, "\033[M", sizeof(buf));	/* should be the same as key_mouse */
    buf[3] = ' ' + (button - 1) + (down ? 0 : 0x40);
    buf[4] = ' ' + x - LEFT_COL + 1;
    buf[5] = ' ' + y - TOP_ROW + 1;
    DosWrite(sp->_emxmouse_wfd, buf, 6, &ignore);
}

Project: ncurses

TransformLine(NCURSES_SP_DCLx int const lineno)
{
    int firstChar, oLastChar, nLastChar;
    NCURSES_CH_T *newLine = NewScreen(SP_PARM)->_line[lineno].text;
    NCURSES_CH_T *oldLine = CurScreen(SP_PARM)->_line[lineno].text;
    int n;
    bool attrchanged = FALSE;

    TR(TRACE_UPDATE, (T_CALLED("TransformLine(%p, %d)"), (void *) SP_PARM, lineno));

    /* copy new hash value to old one */
    if (SP_PARM->oldhash && SP_PARM->newhash)
	SP_PARM->oldhash[lineno] = SP_PARM->newhash[lineno];

    /*
     * If we have colors, there is the possibility of having two color pairs
     * that display as the same colors.  For instance, Lynx does this.  Check
     * for this case, and update the old line with the new line's colors when
     * they are equivalent.
     */
    if (SP_PARM->_coloron) {
	int oldPair;
	int newPair;

	for (n = 0; n < screen_columns(SP_PARM); n++) {
	    if (!CharEq(newLine[n], oldLine[n])) {
		oldPair = GetPair(oldLine[n]);
		newPair = GetPair(newLine[n]);
		if (oldPair != newPair
		    && unColor(oldLine[n]) == unColor(newLine[n])) {
		    if (oldPair < SP_PARM->_pair_limit
			&& newPair < SP_PARM->_pair_limit
			&& (isSamePair(SP_PARM->_color_pairs[oldPair],
				       SP_PARM->_color_pairs[newPair]))) {
			SetPair(oldLine[n], GetPair(newLine[n]));
		    }
		}
	    }
	}
    }

    if (ceol_standout_glitch && clr_eol) {
	firstChar = 0;
	while (firstChar < screen_columns(SP_PARM)) {
	    if (!SameAttrOf(newLine[firstChar], oldLine[firstChar])) {
		attrchanged = TRUE;
		break;
	    }
	    firstChar++;
	}
    }

    firstChar = 0;

    if (attrchanged) {		/* we may have to disregard the whole line */
	GoTo(NCURSES_SP_ARGx lineno, firstChar);
	ClrToEOL(NCURSES_SP_ARGx
		 ClrBlank(NCURSES_SP_ARGx
			  CurScreen(SP_PARM)), FALSE);
	PutRange(NCURSES_SP_ARGx
		 oldLine, newLine, lineno, 0,
		 screen_columns(SP_PARM) - 1);
#if USE_XMC_SUPPORT

	/*
	 * This is a very simple loop to paint characters which may have the
	 * magic cookie glitch embedded.  It doesn't know much about video
	 * attributes which are continued from one line to the next.  It
	 * assumes that we have filtered out requests for attribute changes
	 * that do not get mapped to blank positions.
	 *
	 * FIXME: we are not keeping track of where we put the cookies, so this
	 * will work properly only once, since we may overwrite a cookie in a
	 * following operation.
	 */
    } else if (magic_cookie_glitch > 0) {
	GoTo(NCURSES_SP_ARGx lineno, firstChar);
	for (n = 0; n < screen_columns(SP_PARM); n++) {
	    int m = n + magic_cookie_glitch;

	    /* check for turn-on:
	     * If we are writing an attributed blank, where the
	     * previous cell is not attributed.
	     */
	    if (ISBLANK(newLine[n])
		&& ((n > 0
		     && xmc_turn_on(SP_PARM, newLine[n - 1], newLine[n]))
		    || (n == 0
			&& lineno > 0
			&& xmc_turn_on(SP_PARM,
				       xmc_new(SP_PARM, lineno - 1,
					       screen_columns(SP_PARM) - 1),
				       newLine[n])))) {
		n = m;
	    }

	    PutChar(NCURSES_SP_ARGx CHREF(newLine[n]));

	    /* check for turn-off:
	     * If we are writing an attributed non-blank, where the
	     * next cell is blank, and not attributed.
	     */
	    if (!ISBLANK(newLine[n])
		&& ((n + 1 < screen_columns(SP_PARM)
		     && xmc_turn_off(SP_PARM, newLine[n], newLine[n + 1]))
		    || (n + 1 >= screen_columns(SP_PARM)
			&& lineno + 1 < screen_lines(SP_PARM)
			&& xmc_turn_off(SP_PARM,
					newLine[n],
					xmc_new(SP_PARM, lineno + 1, 0))))) {
		n = m;
	    }

	}
#endif
    } else {
	NCURSES_CH_T blank;

	/* it may be cheap to clear leading whitespace with clr_bol */
	blank = newLine[0];
	if (clr_bol && can_clear_with(NCURSES_SP_ARGx CHREF(blank))) {
	    int oFirstChar, nFirstChar;

	    for (oFirstChar = 0;
		 oFirstChar < screen_columns(SP_PARM);
		 oFirstChar++)
		if (!CharEq(oldLine[oFirstChar], blank))
		    break;
	    for (nFirstChar = 0;
		 nFirstChar < screen_columns(SP_PARM);
		 nFirstChar++)
		if (!CharEq(newLine[nFirstChar], blank))
		    break;

	    if (nFirstChar == oFirstChar) {
		firstChar = nFirstChar;
		/* find the first differing character */
		while (firstChar < screen_columns(SP_PARM)
		       && CharEq(newLine[firstChar], oldLine[firstChar]))
		    firstChar++;
	    } else if (oFirstChar > nFirstChar) {
		firstChar = nFirstChar;
	    } else {		/* oFirstChar < nFirstChar */
		firstChar = oFirstChar;
		if (SP_PARM->_el1_cost < nFirstChar - oFirstChar) {
		    if (nFirstChar >= screen_columns(SP_PARM)
			&& SP_PARM->_el_cost <= SP_PARM->_el1_cost) {
			GoTo(NCURSES_SP_ARGx lineno, 0);
			UpdateAttrs(SP_PARM, blank);
			NCURSES_PUTP2("clr_eol", clr_eol);
		    } else {
			GoTo(NCURSES_SP_ARGx lineno, nFirstChar - 1);
			UpdateAttrs(SP_PARM, blank);
			NCURSES_PUTP2("clr_bol", clr_bol);
		    }

		    while (firstChar < nFirstChar)
			oldLine[firstChar++] = blank;
		}
	    }
	} else {
	    /* find the first differing character */
	    while (firstChar < screen_columns(SP_PARM)
		   && CharEq(newLine[firstChar], oldLine[firstChar]))
		firstChar++;
	}
	/* if there wasn't one, we're done */
	if (firstChar >= screen_columns(SP_PARM)) {
	    TR(TRACE_UPDATE, (T_RETURN("")));
	    return;
	}

	blank = newLine[screen_columns(SP_PARM) - 1];

	if (!can_clear_with(NCURSES_SP_ARGx CHREF(blank))) {
	    /* find the last differing character */
	    nLastChar = screen_columns(SP_PARM) - 1;

	    while (nLastChar > firstChar
		   && CharEq(newLine[nLastChar], oldLine[nLastChar]))
		nLastChar--;

	    if (nLastChar >= firstChar) {
		GoTo(NCURSES_SP_ARGx lineno, firstChar);
		PutRange(NCURSES_SP_ARGx
			 oldLine,
			 newLine,
			 lineno,
			 firstChar,
			 nLastChar);
		memcpy(oldLine + firstChar,
		       newLine + firstChar,
		       (unsigned) (nLastChar - firstChar + 1) * sizeof(NCURSES_CH_T));
	    }
	    TR(TRACE_UPDATE, (T_RETURN("")));
	    return;
	}

	/* find last non-blank character on old line */
	oLastChar = screen_columns(SP_PARM) - 1;
	while (oLastChar > firstChar && CharEq(oldLine[oLastChar], blank))
	    oLastChar--;

	/* find last non-blank character on new line */
	nLastChar = screen_columns(SP_PARM) - 1;
	while (nLastChar > firstChar && CharEq(newLine[nLastChar], blank))
	    nLastChar--;

	if ((nLastChar == firstChar)
	    && (SP_PARM->_el_cost < (oLastChar - nLastChar))) {
	    GoTo(NCURSES_SP_ARGx lineno, firstChar);
	    if (!CharEq(newLine[firstChar], blank))
		PutChar(NCURSES_SP_ARGx CHREF(newLine[firstChar]));
	    ClrToEOL(NCURSES_SP_ARGx blank, FALSE);
	} else if ((nLastChar != oLastChar)
		   && (!CharEq(newLine[nLastChar], oldLine[oLastChar])
		       || !(SP_PARM->_nc_sp_idcok
			    && NCURSES_SP_NAME(has_ic) (NCURSES_SP_ARG)))) {
	    GoTo(NCURSES_SP_ARGx lineno, firstChar);
	    if ((oLastChar - nLastChar) > SP_PARM->_el_cost) {
		if (PutRange(NCURSES_SP_ARGx
			     oldLine,
			     newLine,
			     lineno,
			     firstChar,
			     nLastChar)) {
		    GoTo(NCURSES_SP_ARGx lineno, nLastChar + 1);
		}
		ClrToEOL(NCURSES_SP_ARGx blank, FALSE);
	    } else {
		n = max(nLastChar, oLastChar);
		PutRange(NCURSES_SP_ARGx
			 oldLine,
			 newLine,
			 lineno,
			 firstChar,
			 n);
	    }
	} else {
	    int nLastNonblank = nLastChar;
	    int oLastNonblank = oLastChar;

	    /* find the last characters that really differ */
	    /* can be -1 if no characters differ */
	    while (CharEq(newLine[nLastChar], oldLine[oLastChar])) {
		/* don't split a wide char */
		if (isWidecExt(newLine[nLastChar]) &&
		    !CharEq(newLine[nLastChar - 1], oldLine[oLastChar - 1]))
		    break;
		nLastChar--;
		oLastChar--;
		if (nLastChar == -1 || oLastChar == -1)
		    break;
	    }

	    n = min(oLastChar, nLastChar);
	    if (n >= firstChar) {
		GoTo(NCURSES_SP_ARGx lineno, firstChar);
		PutRange(NCURSES_SP_ARGx
			 oldLine,
			 newLine,
			 lineno,
			 firstChar,
			 n);
	    }

	    if (oLastChar < nLastChar) {
		int m = max(nLastNonblank, oLastNonblank);
#if USE_WIDEC_SUPPORT
		if (n) {
		    while (isWidecExt(newLine[n + 1]) && n) {
			--n;
			--oLastChar;	/* increase cost */
		    }
		} else if (n >= firstChar &&
			   isWidecBase(newLine[n])) {
		    while (isWidecExt(newLine[n + 1])) {
			++n;
			++oLastChar;	/* decrease cost */
		    }
		}
#endif
		GoTo(NCURSES_SP_ARGx lineno, n + 1);
		if ((nLastChar < nLastNonblank)
		    || InsCharCost(SP_PARM, nLastChar - oLastChar) > (m - n)) {
		    PutRange(NCURSES_SP_ARGx
			     oldLine,
			     newLine,
			     lineno,
			     n + 1,
			     m);
		} else {
		    InsStr(NCURSES_SP_ARGx &newLine[n + 1], nLastChar - oLastChar);
		}
	    } else if (oLastChar > nLastChar) {
		GoTo(NCURSES_SP_ARGx lineno, n + 1);
		if (DelCharCost(SP_PARM, oLastChar - nLastChar)
		    > SP_PARM->_el_cost + nLastNonblank - (n + 1)) {
		    if (PutRange(NCURSES_SP_ARGx oldLine, newLine, lineno,
				 n + 1, nLastNonblank)) {
			GoTo(NCURSES_SP_ARGx lineno, nLastNonblank + 1);
		    }
		    ClrToEOL(NCURSES_SP_ARGx blank, FALSE);
		} else {
		    /*
		     * The delete-char sequence will
		     * effectively shift in blanks from the
		     * right margin of the screen.  Ensure
		     * that they are the right color by
		     * setting the video attributes from
		     * the last character on the row.
		     */
		    UpdateAttrs(SP_PARM, blank);
		    DelChar(NCURSES_SP_ARGx oLastChar - nLastChar);
		}
	    }
	}
    }

    /* update the code's internal representation */
    if (screen_columns(SP_PARM) > firstChar)
	memcpy(oldLine + firstChar,
	       newLine + firstChar,
	       (unsigned) (screen_columns(SP_PARM) - firstChar) * sizeof(NCURSES_CH_T));
    TR(TRACE_UPDATE, (T_RETURN("")));
    return;
}

Project: ncurses

_nc_set_tputs_trace(const char *s)
{
    if (CURRENT_SCREEN)
	CURRENT_SCREEN->_tputs_trace = s;
    else
	_nc_prescreen._tputs_trace = s;
}

Project: ncurses

reset_start(FILE *fp, bool is_reset, bool is_init)
{
    my_file = fp;
    use_reset = is_reset;
    use_init = is_init;
}

Project: ncurses

open_input(const char *filename, char *alt_file)
{
    FILE *fp;
    struct stat sb;
    int mode;

    if (!strcmp(filename, "-")) {
	fp = copy_input(stdin, STDIN_NAME, alt_file);
    } else if (stat(filename, &sb) < 0) {
	fprintf(stderr, "%s: %s %s\n", _nc_progname, filename, strerror(errno));
	ExitProgram(EXIT_FAILURE);
    } else if ((mode = (sb.st_mode & S_IFMT)) == S_IFDIR
	       || (mode != S_IFREG && mode != S_IFCHR && mode != S_IFIFO)) {
	fprintf(stderr, "%s: %s is not a file\n", _nc_progname, filename);
	ExitProgram(EXIT_FAILURE);
    } else {
	fp = fopen(filename, "r");

	if (fp == 0) {
	    fprintf(stderr, "%s: Can't open %s\n", _nc_progname, filename);
	    ExitProgram(EXIT_FAILURE);
	}
	if (mode != S_IFREG) {
	    if (alt_file != 0) {
		FILE *fp2 = copy_input(fp, filename, alt_file);
		fp = fp2;
	    } else {
		fprintf(stderr, "%s: %s is not a file\n", _nc_progname, filename);
		ExitProgram(EXIT_FAILURE);
	    }
	}
    }
    return fp;
}

Project: ncurses

NCURSES_PUBLIC_VAR(COLORS) (void)
{
    return SP ? SP->_color_count : -1;
}

Project: ncurses

drv_rescolors(TERMINAL_CONTROL_BLOCK * TCB)
{
    int result = FALSE;
    SCREEN *sp;

    AssertTCB();
    SetSP();

    if (orig_colors != 0) {
	NCURSES_PUTP2("orig_colors", orig_colors);
	result = TRUE;
    }
    return result;
}

Project: ncurses

_nc_mouse_init(SCREEN *sp)
/* initialize the mouse */
{
    bool result = FALSE;

    if (sp != 0) {
	if (!sp->_mouse_initialized) {
	    int i;

	    sp->_mouse_initialized = TRUE;

	    TR(MY_TRACE, ("_nc_mouse_init() called"));

	    sp->_mouse_eventp = FirstEV(sp);
	    for (i = 0; i < EV_MAX; i++)
		Invalidate(sp->_mouse_events + i);

	    initialize_mousetype(sp);

	    T(("_nc_mouse_init() set mousetype to %d", sp->_mouse_type));
	}
	result = sp->_mouse_initialized;
    }
    return result;
}

Project: ncurses

save_text(const char *fmt, const char *s, int len)
{
    size_t s_len = (size_t) len + strlen(s) + strlen(fmt);
    get_space(s_len + 1);

    _nc_SPRINTF(TPS(out_buff) + TPS(out_used),
		_nc_SLIMIT(TPS(out_size) - TPS(out_used))
		fmt, s);
    TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used));
}

Project: ncurses

_nc_reserve_pairs(SCREEN *sp, int want)
{
    int have = sp->_pair_alloc;

    if (have == 0)
	have = 1;
    while (have <= want)
	have *= 2;
    if (have > sp->_pair_limit)
	have = sp->_pair_limit;

    if (sp->_color_pairs == 0) {
	sp->_color_pairs = TYPE_CALLOC(colorpair_t, have);
    } else if (have > sp->_pair_alloc) {
#if NCURSES_EXT_COLORS
	colorpair_t *next;

	if ((next = typeCalloc(colorpair_t, have)) == 0)
	    _nc_err_abort(MSG_NO_MEMORY);
	memcpy(next, sp->_color_pairs, (size_t) sp->_pair_alloc * sizeof(*next));
	_nc_copy_pairs(sp, next, sp->_color_pairs, sp->_pair_alloc);
	free(sp->_color_pairs);
	sp->_color_pairs = next;
#else
	TYPE_REALLOC(colorpair_t, have, sp->_color_pairs);
	if (sp->_color_pairs != 0) {
	    memset(sp->_color_pairs + sp->_pair_alloc, 0,
		   sizeof(colorpair_t) * (size_t) (have - sp->_pair_alloc));
	}
#endif
    }
    if (sp->_color_pairs != 0) {
	sp->_pair_alloc = have;
    }
}

Project: ncurses

DelChar(NCURSES_SP_DCLx int count)
{
    TR(TRACE_UPDATE, ("DelChar(%p, %d) called, position = (%ld,%ld)",
		      (void *) SP_PARM, count,
		      (long) NewScreen(SP_PARM)->_cury,
		      (long) NewScreen(SP_PARM)->_curx));

    if (parm_dch) {
	TPUTS_TRACE("parm_dch");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(parm_dch, count),
				1,
				NCURSES_SP_NAME(_nc_outch));
    } else {
	int n;

	for (n = 0; n < count; n++) {
	    NCURSES_PUTP2("delete_character", delete_character);
	}
    }
}

Project: ncurses

check_sgr(TERMTYPE2 *tp, char *zero, int num, char *cap, const char *name)
{
    char *test;

    _nc_tparm_err = 0;
    test = TIPARM_9(set_attributes,
		    num == 1,
		    num == 2,
		    num == 3,
		    num == 4,
		    num == 5,
		    num == 6,
		    num == 7,
		    num == 8,
		    num == 9);
    if (test != 0) {
	if (PRESENT(cap)) {
	    if (!similar_sgr(num, test, cap)) {
		_nc_warning("%s differs from sgr(%d)\n\t%s=%s\n\tsgr(%d)=%s",
			    name, num,
			    name, _nc_visbuf2(1, cap),
			    num, _nc_visbuf2(2, test));
	    }
	} else if (_nc_capcmp(test, zero)) {
	    _nc_warning("sgr(%d) present, but not %s", num, name);
	}
    } else if (PRESENT(cap)) {
	_nc_warning("sgr(%d) missing, but %s present", num, name);
    }
    if (_nc_tparm_err)
	_nc_warning("stack error in sgr(%d) string", num);
    return test;
}

Project: ncurses

tparm_trace_call(const char *string, TPARM_DATA * data)
{
    if (USE_TRACEF(TRACE_CALLS)) {
	int i;
	for (i = 0; i < data->num_actual; i++) {
	    if (data->p_is_s[i] != 0) {
		save_text(", %s", _nc_visbuf(data->p_is_s[i]), 0);
	    } else if ((long) data->param[i] > MAX_OF_TYPE(NCURSES_INT2) ||
		       (long) data->param[i] < 0) {
		_tracef("BUG: problem with tparm parameter #%d of %d",
			i + 1, data->num_actual);
		break;
	    } else {
		save_number(", %d", (int) data->param[i], 0);
	    }
	}
	_tracef(T_CALLED("%s(%s%s)"), TPS(tname), _nc_visbuf(string), TPS(out_buff));
	TPS(out_used) = 0;
	_nc_unlock_global(tracef);
    }
}

Project: ncurses

__nc_putp(SCREEN *sp, const char *name GCC_UNUSED, const char *value)
{
    int rc = ERR;

    if (value) {
	rc = NCURSES_PUTP2(name, value);
    }
    return rc;
}

Project: ncurses

main(int argc,
     char *argv[])
{
    int ch;
    double r;
    double c;
    int my_colors;
    int f_option = 0;
    int m_option = 2;
    int r_option = 0;
    int s_option = 1;
    size_t need;
    char *my_env;

    while ((ch = getopt(argc, argv, "T:efm:r:s:")) != -1) {
	switch (ch) {
	case 'T':
	    need = 6 + strlen(optarg);
	    my_env = malloc(need);
	    _nc_SPRINTF(my_env, _nc_SLIMIT(need) "TERM=%s", optarg);
	    putenv(my_env);
	    break;
#if HAVE_USE_ENV
	case 'e':
	    use_env(TRUE);
	    break;
#endif
	case 'f':
	    f_option = 1;
	    break;
	case 'm':
	    m_option = atoi(optarg);
	    break;
	case 'r':
	    r_option = atoi(optarg);
	    break;
	case 's':
	    s_option = atoi(optarg);
	    break;
	default:
	    usage();
	    break;
	}
    }

    SetupAlarm(r_option);
    InitAndCatch(setupterm((char *) 0, 1, (int *) 0), onsig);

    srand((unsigned) time(0));

    outs(clear_screen);
    outs(cursor_invisible);

#define GetNumber(ln,sn) get_number(f_option ? #sn : 0, ln)
    my_colors = GetNumber(max_colors, colors);
    if (my_colors > 1) {
	if (!VALID_STRING(set_a_foreground)
	    || !VALID_STRING(set_a_background)
	    || (!VALID_STRING(orig_colors) && !VALID_STRING(orig_pair)))
	    my_colors = -1;
    }

    r = (double) (GetNumber(lines, lines) - (m_option * 2));
    c = (double) (GetNumber(columns, cols) - (m_option * 2));
    started = time((time_t *) 0);

    while (!interrupted) {
	int x = (int) (c * ranf()) + m_option;
	int y = (int) (r * ranf()) + m_option;
	int p = (ranf() > 0.9) ? '*' : ' ';

	tputs(tparm3(cursor_address, y, x), 1, outc);
	if (my_colors > 0) {
	    int z = (int) (ranf() * my_colors);
	    if (ranf() > 0.01) {
		tputs(tparm2(set_a_foreground, z), 1, outc);
	    } else {
		tputs(tparm2(set_a_background, z), 1, outc);
		if (s_option)
		    napms(s_option);
	    }
	} else if (VALID_STRING(exit_attribute_mode)
		   && VALID_STRING(enter_reverse_mode)) {
	    if (ranf() <= 0.01) {
		outs((ranf() > 0.6)
		     ? enter_reverse_mode
		     : exit_attribute_mode);
		if (s_option)
		    napms(s_option);
	    }
	}
	outc(p);
	fflush(stdout);
	++total_chars;
    }
    cleanup();
    ExitProgram(EXIT_SUCCESS);
}

Project: ncurses

putch(int c)
{
    return putchar(c);
}

Project: ncurses

can_change_color(void)
{
    return NCURSES_SP_NAME(can_change_color) (CURRENT_SCREEN);
}

Project: ncurses

drv_cursorSet(TERMINAL_CONTROL_BLOCK * TCB, int vis)
{
    SCREEN *sp;
    int code = ERR;

    AssertTCB();
    SetSP();

    T((T_CALLED("tinfo:drv_cursorSet(%p,%d)"), (void *) SP_PARM, vis));

    if (SP_PARM != 0 && IsTermInfo(SP_PARM)) {
	switch (vis) {
	case 2:
	    code = NCURSES_PUTP2_FLUSH("cursor_visible", cursor_visible);
	    break;
	case 1:
	    code = NCURSES_PUTP2_FLUSH("cursor_normal", cursor_normal);
	    break;
	case 0:
	    code = NCURSES_PUTP2_FLUSH("cursor_invisible", cursor_invisible);
	    break;
	}
    } else {
	code = ERR;
    }
    returnCode(code);
}

Project: ncurses

toggled_colors(int c)
{
    if (c < 16) {
	static const int table[] =
	{0, 4, 2, 6, 1, 5, 3, 7,
	 8, 12, 10, 14, 9, 13, 11, 15};
	c = table[c];
    }
    return c;
}

Project: ncurses

drv_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag)
{
    SCREEN *sp;
    TERMINAL *_term = (TERMINAL *) TCB;
    int code = ERR;

    AssertTCB();
    sp = TCB->csp;

    if (progFlag)		/* prog mode */
    {
	if (defFlag) {
	    /* def_prog_mode */
	    /*
	     * Turn off the XTABS bit in the tty structure if it was on.
	     */
	    if ((drv_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
#ifdef TERMIOS
		_term->Nttyb.c_oflag &= (unsigned) ~OFLAGS_TABS;
#else
		_term->Nttyb.sg_flags &= (unsigned) ~XTABS;
#endif
		code = OK;
	    }
	} else {
	    /* reset_prog_mode */
	    if (drv_sgmode(TCB, TRUE, &(_term->Nttyb)) == OK) {
		if (sp) {
		    if (sp->_keypad_on)
			_nc_keypad(sp, TRUE);
		}
		code = OK;
	    }
	}
    } else {			/* shell mode */
	if (defFlag) {
	    /* def_shell_mode */
	    /*
	     * If XTABS was on, remove the tab and backtab capabilities.
	     */
	    if (drv_sgmode(TCB, FALSE, &(_term->Ottyb)) == OK) {
#ifdef TERMIOS
		if (_term->Ottyb.c_oflag & OFLAGS_TABS)
		    tab = back_tab = NULL;
#else
		if (_term->Ottyb.sg_flags & XTABS)
		    tab = back_tab = NULL;
#endif
		code = OK;
	    }
	} else {
	    /* reset_shell_mode */
	    if (sp) {
		_nc_keypad(sp, FALSE);
		NCURSES_SP_NAME(_nc_flush) (sp);
	    }
	    code = drv_sgmode(TCB, TRUE, &(_term->Ottyb));
	}
    }
    return (code);
}

Project: ncurses

main(void)
{
    printf("This program requires the wide-ncurses library\n");
    ExitProgram(EXIT_FAILURE);
}

Project: ncurses

_nc_mouse_wrap(SCREEN *sp)
/* release mouse -- called by endwin() before shellout/exit */
{
    TR(MY_TRACE, ("_nc_mouse_wrap() called"));

    switch (sp->_mouse_type) {
    case M_XTERM:
	if (sp->_mouse_mask)
	    mouse_activate(sp, FALSE);
	break;
#if USE_GPM_SUPPORT
	/* GPM: pass all mouse events to next client */
    case M_GPM:
	if (sp->_mouse_mask)
	    mouse_activate(sp, FALSE);
	break;
#endif
#if USE_SYSMOUSE
    case M_SYSMOUSE:
	mouse_activate(sp, FALSE);
	break;
#endif
#ifdef USE_TERM_DRIVER
    case M_TERM_DRIVER:
	mouse_activate(sp, FALSE);
	break;
#endif
    case M_NONE:
	break;
    }
}

Project: ncurses

usage(void)
{
    static const char *msg[] =
    {
	"Usage: dots [options]"
	,""
	,"Options:"
	," -T TERM  override $TERM"
#if HAVE_USE_ENV
	," -e       allow environment $LINES / $COLUMNS"
#endif
	," -f       use tigetnum rather than <term.h> mapping"
	," -m SIZE  set margin (default: 2)"
	," -r SECS  self-interrupt/exit after specified number of seconds"
	," -s MSECS delay 1% of the time (default: 1 msecs)"
    };
    size_t n;

    for (n = 0; n < SIZEOF(msg); n++)
	fprintf(stderr, "%s\n", msg[n]);

    ExitProgram(EXIT_FAILURE);
}

Project: ncurses

NCURSES_SP_NAME(init_pair) (NCURSES_SP_DCLx
			    NCURSES_PAIRS_T pair,
			    NCURSES_COLOR_T f,
			    NCURSES_COLOR_T b)
{
    return _nc_init_pair(SP_PARM, pair, f, b);
}

Project: ncurses

mvcur(int yold, int xold, int ynew, int xnew)
{
    return NCURSES_SP_NAME(mvcur) (CURRENT_SCREEN, yold, xold, ynew, xnew);
}

Project: ncurses

main(int argc, char **argv)
{
    char *term;
    int errret;
    bool cmdline = TRUE;
    int c;
    char buf[BUFSIZ];
    int result = 0;
    int fd;
    TTY tty_settings;
    bool opt_x = FALSE;		/* clear scrollback if possible */
    bool is_alias;
    bool need_tty;

    prg_name = check_aliases(_nc_rootname(argv[0]), TRUE);

    term = getenv("TERM");

    while ((c = getopt(argc, argv, "ST:Vx")) != -1) {
	switch (c) {
	case 'S':
	    cmdline = FALSE;
	    break;
	case 'T':
	    use_env(FALSE);
	    use_tioctl(TRUE);
	    term = optarg;
	    break;
	case 'V':
	    puts(curses_version());
	    ExitProgram(EXIT_SUCCESS);
	case 'x':		/* do not try to clear scrollback */
	    opt_x = TRUE;
	    break;
	default:
	    usage();
	    /* NOTREACHED */
	}
    }

    is_alias = (is_clear || is_reset || is_init);
    need_tty = ((is_reset || is_init) ||
		(optind < argc &&
		 (!strcmp(argv[optind], "reset") ||
		  !strcmp(argv[optind], "init"))));

    /*
     * Modify the argument list to omit the options we processed.
     */
    if (is_alias) {
	if (optind-- < argc) {
	    argc -= optind;
	    argv += optind;
	}
	argv[0] = prg_name;
    } else {
	argc -= optind;
	argv += optind;
    }

    if (term == 0 || *term == '\0')
	quit(ErrUsage, "No value for $TERM and no -T specified");

    fd = save_tty_settings(&tty_settings, need_tty);

    if (setupterm(term, fd, &errret) != OK && errret <= 0)
	quit(ErrTermType, "unknown terminal \"%s\"", term);

    if (cmdline) {
	if ((argc <= 0) && !is_alias)
	    usage();
	ExitProgram(tput_cmd(fd, &tty_settings, opt_x, argc, argv));
    }

    while (fgets(buf, sizeof(buf), stdin) != 0) {
	char *argvec[16];	/* command, 9 parms, null, & slop */
	int argnum = 0;
	char *cp;

	/* crack the argument list into a dope vector */
	for (cp = buf; *cp; cp++) {
	    if (isspace(UChar(*cp))) {
		*cp = '\0';
	    } else if (cp == buf || cp[-1] == 0) {
		argvec[argnum++] = cp;
		if (argnum >= (int) SIZEOF(argvec) - 1)
		    break;
	    }
	}
	argvec[argnum] = 0;

	if (argnum != 0
	    && tput_cmd(fd, &tty_settings, opt_x, argnum, argvec) != 0) {
	    if (result == 0)
		result = ErrSystem(0);	/* will return value >4 */
	    ++result;
	}
    }

    ExitProgram(result);
}

Project: ncurses

tparm(const char *string,
      TPARM_ARG a1,
      TPARM_ARG a2,
      TPARM_ARG a3,
      TPARM_ARG a4,
      TPARM_ARG a5,
      TPARM_ARG a6,
      TPARM_ARG a7,
      TPARM_ARG a8,
      TPARM_ARG a9)
{
    TPARM_DATA myData;
    char *result = NULL;

    _nc_tparm_err = 0;
#ifdef TRACE
    TPS(tname) = "tparm";
#endif /* TRACE */

    if (tparm_setup(string, &myData) == OK) {

	myData.param[0] = a1;
	myData.param[1] = a2;
	myData.param[2] = a3;
	myData.param[3] = a4;
	myData.param[4] = a5;
	myData.param[5] = a6;
	myData.param[6] = a7;
	myData.param[7] = a8;
	myData.param[8] = a9;

	result = tparam_internal(string, &myData);
    }
    return result;
}

Project: ncurses

send_init_strings(int fd GCC_UNUSED, TTY * old_settings)
{
    int i;
    bool need_flush = FALSE;

    (void) old_settings;
#ifdef TAB3
    if (old_settings != 0 &&
	old_settings->c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
	old_settings->c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
	SET_TTY(fd, old_settings);
    }
#endif
    if (use_reset || use_init) {
	if (VALID_STRING(init_prog)) {
	    IGNORE_RC(system(init_prog));
	}

	need_flush |= sent_string((use_reset && (reset_1string != 0))
				  ? reset_1string
				  : init_1string);

	need_flush |= sent_string((use_reset && (reset_2string != 0))
				  ? reset_2string
				  : init_2string);

	if (VALID_STRING(clear_margins)) {
	    need_flush |= sent_string(clear_margins);
	} else
#if defined(set_lr_margin)
	if (VALID_STRING(set_lr_margin)) {
	    need_flush |= sent_string(TIPARM_2(set_lr_margin, 0, columns - 1));
	} else
#endif
#if defined(set_left_margin_parm) && defined(set_right_margin_parm)
	    if (VALID_STRING(set_left_margin_parm)
		&& VALID_STRING(set_right_margin_parm)) {
	    need_flush |= sent_string(TIPARM_1(set_left_margin_parm, 0));
	    need_flush |= sent_string(TIPARM_1(set_right_margin_parm,
					       columns - 1));
	} else
#endif
	    if (VALID_STRING(set_left_margin)
		&& VALID_STRING(set_right_margin)) {
	    need_flush |= to_left_margin();
	    need_flush |= sent_string(set_left_margin);
	    if (VALID_STRING(parm_right_cursor)) {
		need_flush |= sent_string(TIPARM_1(parm_right_cursor,
						   columns - 1));
	    } else {
		for (i = 0; i < columns - 1; i++) {
		    out_char(' ');
		    need_flush = TRUE;
		}
	    }
	    need_flush |= sent_string(set_right_margin);
	    need_flush |= to_left_margin();
	}

	need_flush |= reset_tabstops(columns);

	need_flush |= cat_file((use_reset && reset_file) ? reset_file : init_file);

	need_flush |= sent_string((use_reset && (reset_3string != 0))
				  ? reset_3string
				  : init_3string);
    }

    return need_flush;
}

Project: ncurses

_nc_retrace_bool(int code)
{
    T((T_RETURN("%s"), code ? "TRUE" : "FALSE"));
    return code;
}

Project: ncurses

_nc_captoinfo_leaks(void)
{
    if (my_string != 0) {
	FreeAndNull(my_string);
    }
    my_length = 0;
}

Project: ncurses

NCURSES_SP_NAME(ungetmouse) (NCURSES_SP_DCLx MEVENT * aevent)
{
    int result = ERR;
    MEVENT *eventp;

    T((T_CALLED("ungetmouse(%p,%p)"), (void *) SP_PARM, (void *) aevent));

    if (aevent != 0 &&
	SP_PARM != 0 &&
	(eventp = SP_PARM->_mouse_eventp) != 0) {

	/* stick the given event in the next-free slot */
	*eventp = *aevent;

	/* bump the next-free pointer into the circular list */
	SP_PARM->_mouse_eventp = NEXT(eventp);

	/* push back the notification event on the keyboard queue */
	result = NCURSES_SP_NAME(ungetch) (NCURSES_SP_ARGx KEY_MOUSE);
    }
    returnCode(result);
}

Project: ncurses

pop(void)
/* pop the top of the stack into onstack */
{
    if (stackptr == 0) {
	if (onstack == 0)
	    _nc_warning("I'm confused");
	else
	    onstack = 0;
    } else
	onstack = stack[--stackptr];
    param++;
}

Project: ncurses

mouseinterval(int maxclick)
{
    return NCURSES_SP_NAME(mouseinterval) (CURRENT_SCREEN, maxclick);
}

Project: ncurses

check_termtype(TERMTYPE2 *tp, bool literal)
{
    unsigned j;

    check_conflict(tp);

    for_each_string(j, tp) {
	char *a = tp->Strings[j];
	if (VALID_STRING(a)) {
	    const char *name = ExtStrname(tp, (int) j, strnames);
	    /*
	     * If we expect parameters, or if there might be parameters,
	     * check for consistent number of parameters.
	     */
	    if (j >= SIZEOF(parametrized) ||
		is_user_capability(name) >= 0 ||
		parametrized[j] > 0) {
		check_params(tp, name, a, (j >= STRCOUNT));
	    }
	    check_delays(tp, ExtStrname(tp, (int) j, strnames), a);
	    if (capdump) {
		check_infotocap(tp, (int) j, a);
	    }
	}
    }
#if NCURSES_XNAMES
    /* in extended mode, verify that each extension is expected type */
    for_each_ext_boolean(j, tp) {
	check_user_capability_type(ExtBoolname(tp, (int) j, strnames), BOOLEAN);
    }
    for_each_ext_number(j, tp) {
	check_user_capability_type(ExtNumname(tp, (int) j, strnames), NUMBER);
    }
    for_each_ext_string(j, tp) {
	check_user_capability_type(ExtStrname(tp, (int) j, strnames), STRING);
    }
#endif /* NCURSES_XNAMES */

    check_acs(tp);
    check_colors(tp);
    check_cursor(tp);
    check_keypad(tp);
    check_printer(tp);
    check_screen(tp);

    /*
     * These are probably both or none.
     */
    PAIRED(parm_index, parm_rindex);
    PAIRED(parm_ich, parm_dch);

    /*
     * These may be mismatched because the terminal description relies on
     * restoring the cursor visibility by resetting it.
     */
    ANDMISSING(cursor_invisible, cursor_normal);
    ANDMISSING(cursor_visible, cursor_normal);

    if (PRESENT(cursor_visible) && PRESENT(cursor_normal)
	&& !_nc_capcmp(cursor_visible, cursor_normal))
	_nc_warning("cursor_visible is same as cursor_normal");

    /*
     * From XSI & O'Reilly, we gather that sc/rc are required if csr is
     * given, because the cursor position after the scrolling operation is
     * performed is undefined.
     */
    ANDMISSING(change_scroll_region, save_cursor);
    ANDMISSING(change_scroll_region, restore_cursor);

    /*
     * If we can clear tabs, we should be able to initialize them.
     */
    ANDMISSING(clear_all_tabs, set_tab);

    if (PRESENT(set_attributes)) {
	char *zero = 0;

	_nc_tparm_err = 0;
	if (PRESENT(exit_attribute_mode)) {
	    zero = strdup(CHECK_SGR(0, exit_attribute_mode));
	} else {
	    zero = strdup(TIPARM_9(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, 0));
	}
	if (_nc_tparm_err)
	    _nc_warning("stack error in sgr(0) string");

	if (zero != 0) {
	    CHECK_SGR(1, enter_standout_mode);
	    CHECK_SGR(2, enter_underline_mode);
	    CHECK_SGR(3, enter_reverse_mode);
	    CHECK_SGR(4, enter_blink_mode);
	    CHECK_SGR(5, enter_dim_mode);
	    CHECK_SGR(6, enter_bold_mode);
	    CHECK_SGR(7, enter_secure_mode);
	    CHECK_SGR(8, enter_protected_mode);
	    CHECK_SGR(9, enter_alt_charset_mode);
	    free(zero);
	} else {
	    _nc_warning("sgr(0) did not return a value");
	}
    } else if (PRESENT(exit_attribute_mode) &&
	       set_attributes != CANCELLED_STRING) {
	if (_nc_syntax == SYN_TERMINFO)
	    _nc_warning("missing sgr string");
    }
#define CHECK_SGR0(name) check_exit_attribute(#name, name, check_sgr0, exit_attribute_mode)
    if (PRESENT(exit_attribute_mode)) {
	char *check_sgr0 = _nc_trim_sgr0(tp);

	if (check_sgr0 == 0 || *check_sgr0 == '\0') {
	    _nc_warning("trimmed sgr0 is empty");
	} else {
	    show_where(2);
	    if (check_sgr0 != exit_attribute_mode) {
		DEBUG(2,
		      ("will trim sgr0\n\toriginal sgr0=%s\n\ttrimmed  sgr0=%s",
		       _nc_visbuf2(1, exit_attribute_mode),
		       _nc_visbuf2(2, check_sgr0)));
	    } else {
		DEBUG(2,
		      ("will not trim sgr0\n\toriginal sgr0=%s",
		       _nc_visbuf(exit_attribute_mode)));
	    }
	}
#if defined(exit_italics_mode)
	CHECK_SGR0(exit_italics_mode);
#endif
	CHECK_SGR0(exit_standout_mode);
	CHECK_SGR0(exit_underline_mode);
	if (check_sgr0 != exit_attribute_mode) {
	    free(check_sgr0);
	}
    }
#define CHECK_SGR_PARAM(code, name) check_sgr_param(tp, (int)code, #name, name)
    for (j = 0; *sgr_names[j] != '\0'; ++j) {
	CHECK_SGR_PARAM(j, set_a_foreground);
	CHECK_SGR_PARAM(j, set_a_background);
	CHECK_SGR_PARAM(j, set_foreground);
	CHECK_SGR_PARAM(j, set_background);
    }
#ifdef TRACE
    show_where(2);
    if (!auto_right_margin) {
	DEBUG(2,
	      ("can write to lower-right directly"));
    } else if (PRESENT(enter_am_mode) && PRESENT(exit_am_mode)) {
	DEBUG(2,
	      ("can write to lower-right by suppressing automargin"));
    } else if ((PRESENT(enter_insert_mode) && PRESENT(exit_insert_mode))
	       || PRESENT(insert_character) || PRESENT(parm_ich)) {
	DEBUG(2,
	      ("can write to lower-right by using inserts"));
    } else {
	DEBUG(2,
	      ("cannot write to lower-right"));
    }
#endif

    /*
     * Some standard applications (e.g., vi) and some non-curses
     * applications (e.g., jove) get confused if we have both ich1 and
     * smir/rmir.  Let's be nice and warn about that, too, even though
     * ncurses handles it.
     */
    if ((PRESENT(enter_insert_mode) || PRESENT(exit_insert_mode))
	&& PRESENT(insert_character)) {
	_nc_warning("non-curses applications may be confused by ich1 with smir/rmir");
    }

    /*
     * Finally, do the non-verbose checks
     */
    if (save_check_termtype != 0)
	save_check_termtype(tp, literal);
}

Project: ncurses

outs(const char *s)
{
    if (VALID_STRING(s)) {
	tputs(s, 1, outc);
	return TRUE;
    }
    return FALSE;
}

Project: ncurses

repeated_append(string_desc * target, int total, int num, int repeat, const char *src)
{
    size_t need = (size_t) repeat * strlen(src);

    if (need < target->s_size) {
	while (repeat-- > 0) {
	    if (_nc_safe_strcat(target, src)) {
		total += num;
	    } else {
		total = INFINITY;
		break;
	    }
	}
    } else {
	total = INFINITY;
    }
    return total;
}

Project: ncurses

drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB, int fg, int bg)
{
    SCREEN *sp;
    int code = ERR;

    AssertTCB();
    SetSP();

    if (sp != 0 && orig_pair && orig_colors && (initialize_pair != 0)) {
#if NCURSES_EXT_FUNCS
	sp->_default_color = isDefaultColor(fg) || isDefaultColor(bg);
	sp->_has_sgr_39_49 = (NCURSES_SP_NAME(tigetflag) (NCURSES_SP_ARGx
							  "AX")
			      == TRUE);
	sp->_default_fg = isDefaultColor(fg) ? COLOR_DEFAULT : fg;
	sp->_default_bg = isDefaultColor(bg) ? COLOR_DEFAULT : bg;
	if (sp->_color_pairs != 0) {
	    bool save = sp->_default_color;
	    sp->_default_color = TRUE;
	    NCURSES_SP_NAME(init_pair) (NCURSES_SP_ARGx
					0,
					(short)fg,
					(short)bg);
	    sp->_default_color = save;
	}
#endif
	code = OK;
    }
    return (code);
}

Project: ncurses

init_xterm_mouse(SCREEN *sp)
{
    sp->_mouse_type = M_XTERM;
    sp->_mouse_xtermcap = NCURSES_SP_NAME(tigetstr) (NCURSES_SP_ARGx "XM");
    if (!VALID_STRING(sp->_mouse_xtermcap))
	sp->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;";
}

Project: ncurses

npop(void)
{
    int result = 0;
    if (TPS(stack_ptr) > 0) {
	TPS(stack_ptr)--;
	if (TPS(stack)[TPS(stack_ptr)].num_type)
	    result = TPS(stack)[TPS(stack_ptr)].data.num;
    } else {
	DEBUG(2, ("npop: stack underflow: %s", _nc_visbuf(TPS(tparam_base))));
	_nc_tparm_err++;
    }
    return result;
}

Project: ncurses

is_termcap(const char *string)
{
    bool result = TRUE;

    if (string == 0 || *string == '\0') {
	result = FALSE;		/* tparm() handles empty strings */
    } else {
	while ((*string != '\0') && result) {
	    if (*string == '%') {
		switch (*++string) {
		case 'p':
		    result = FALSE;
		    break;
		case '\0':
		    string--;
		    break;
		}
	    } else if (string[0] == '$' && string[1] == '<') {
		result = FALSE;
	    }
	    string++;
	}
    }
    return result;
}

Project: ncurses

push(void)
/* push onstack on to the stack */
{
    if (stackptr >= MAX_PUSHED)
	_nc_warning("string too complex to convert");
    else
	stack[stackptr++] = onstack;
}

Project: ncurses

NCURSES_SP_NAME(vidattr) (NCURSES_SP_DCLx chtype newmode)
{
    T((T_CALLED("vidattr(%p,%s)"), (void *) SP_PARM, _traceattr(newmode)));
    returnCode(NCURSES_SP_NAME(vidputs) (NCURSES_SP_ARGx
					 newmode,
					 NCURSES_SP_NAME(_nc_putchar)));
}

Project: ncurses

PutChar(NCURSES_SP_DCLx const ARG_CH_T ch)
/* insert character, handling automargin stuff */
{
    if (SP_PARM->_cursrow == screen_lines(SP_PARM) - 1 &&
	SP_PARM->_curscol == screen_columns(SP_PARM) - 1) {
	PutCharLR(NCURSES_SP_ARGx ch);
    } else {
	PutAttrChar(NCURSES_SP_ARGx ch);
    }

    if (SP_PARM->_curscol >= screen_columns(SP_PARM))
	wrap_cursor(NCURSES_SP_ARG);

    position_check(NCURSES_SP_ARGx
		   SP_PARM->_cursrow,
		   SP_PARM->_curscol, "PutChar");
}

Project: ncurses

show_fkey_name(NAME_VALUE * data)
{
    if (data->keycode > 0) {
	fprintf(stderr, " %s", keyname(data->keycode));
	fprintf(stderr, " (capability \"%s\")", data->name);
    } else {
	fprintf(stderr, " capability \"%s\"", data->name);
    }
}

Project: ncurses

set_background_color(NCURSES_SP_DCLx int bg, NCURSES_SP_OUTC outc)
{
#ifdef USE_TERM_DRIVER
    CallDriver_3(SP_PARM, td_color, FALSE, bg, outc);
#else
    if (set_a_background) {
	TPUTS_TRACE("set_a_background");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(set_a_background, bg),
				1, outc);
    } else {
	TPUTS_TRACE("set_background");
	NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx
				TIPARM_1(set_background, toggled_colors(bg)),
				1, outc);
    }
#endif
}

Project: ncurses

_nc_retrace_int(int code)
{
    T((T_RETURN("%d"), code));
    return code;
}

Project: ncurses

drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret)
{
    bool result = FALSE;
    int status;
    TERMINAL *termp;
    SCREEN *sp;

    START_TRACE();
    T((T_CALLED("tinfo::drv_CanHandle(%p)"), (void *) TCB));

    assert(TCB != 0 && tname != 0);
    termp = (TERMINAL *) TCB;
    sp = TCB->csp;
    TCB->magic = TCBMAGIC;

#if (NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP)
    status = _nc_setup_tinfo(tname, &TerminalType(termp));
    T(("_nc_setup_tinfo returns %d", status));
#else
    T(("no database available"));
    status = TGETENT_NO;
#endif

    /* try fallback list if entry on disk */
    if (status != TGETENT_YES) {
	const TERMTYPE2 *fallback = _nc_fallback2(tname);

	if (fallback) {
	    T(("found fallback entry"));
	    TerminalType(termp) = *fallback;
	    status = TGETENT_YES;
	}
    }

    if (status != TGETENT_YES) {
	NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx termp);
	if (status == TGETENT_ERR) {
	    ret_error0(status, "terminals database is inaccessible\n");
	} else if (status == TGETENT_NO) {
	    ret_error1(status, "unknown terminal type.\n",
		       tname, NO_COPY);
	} else {
	    ret_error0(status, "unexpected return-code\n");
	}
    }
    result = TRUE;
#if NCURSES_EXT_NUMBERS
    _nc_export_termtype2(&termp->type, &TerminalType(termp));
#endif
#if !USE_REENTRANT
    save_ttytype(termp);
#endif

    if (command_character)
	_nc_tinfo_cmdch(termp, *command_character);

    /*
     * If an application calls setupterm() rather than initscr() or
     * newterm(), we will not have the def_prog_mode() call in
     * _nc_setupscreen().  Do it now anyway, so we can initialize the
     * baudrate.
     */
    if (sp == 0 && NC_ISATTY(termp->Filedes)) {
	get_baudrate(termp);
    }
#if NCURSES_EXT_NUMBERS
#define cleanup_termtype() \
    _nc_free_termtype2(&TerminalType(termp)); \
    _nc_free_termtype(&termp->type)
#else
#define cleanup_termtype() \
    _nc_free_termtype2(&TerminalType(termp))
#endif

    if (generic_type) {
	/*
	 * BSD 4.3's termcap contains mis-typed "gn" for wy99.  Do a sanity
	 * check before giving up.
	 */
	if ((VALID_STRING(cursor_address)
	     || (VALID_STRING(cursor_down) && VALID_STRING(cursor_home)))
	    && VALID_STRING(clear_screen)) {
	    cleanup_termtype();
	    ret_error1(TGETENT_YES, "terminal is not really generic.\n",
		       tname, NO_COPY);
	} else {
	    cleanup_termtype();
	    ret_error1(TGETENT_NO, "I need something more specific.\n",
		       tname, NO_COPY);
	}
    }
    if (hard_copy) {
	cleanup_termtype();
	ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n",
		   tname, NO_COPY);
    }

    returnBool(result);
}

Project: ncurses

_nc_free_tparm(void)
{
#if HAVE_TSEARCH
    if (count_tparm != 0) {
	delete_tparm = typeMalloc(TPARM_DATA *, count_tparm);
	which_tparm = 0;
	twalk(cached_tparm, visit_nodes);
	for (which_tparm = 0; which_tparm < count_tparm; ++which_tparm) {
	    TPARM_DATA *ptr = delete_tparm[which_tparm];
	    tdelete(ptr, &cached_tparm, cmp_format);
	    free((char *) ptr->format);
	    free(ptr);
	}
	which_tparm = 0;
	twalk(cached_tparm, visit_nodes);
	FreeAndNull(delete_tparm);
	count_tparm = 0;
	which_tparm = 0;
    }
#endif
    FreeAndNull(TPS(out_buff));
    TPS(out_size) = 0;
    TPS(out_used) = 0;

    FreeAndNull(TPS(fmt_buff));
    TPS(fmt_size) = 0;
}

Project: ncurses

NCURSES_PUBLIC_VAR(COLOR_PAIRS) (void)
{
    return SP ? SP->_pair_count : -1;
}

Project: ncurses

wmouse_trafo(const WINDOW *win, int *pY, int *pX, bool to_screen)
{
    bool result = FALSE;

    T((T_CALLED("wmouse_trafo(%p,%p,%p,%d)"),
       (const void *) win,
       (void *) pY,
       (void *) pX,
       to_screen));

    if (win && pY && pX) {
	int y = *pY;
	int x = *pX;

	if (to_screen) {
	    y += win->_begy + win->_yoffset;
	    x += win->_begx;
	    if (wenclose(win, y, x))
		result = TRUE;
	} else {
	    if (wenclose(win, y, x)) {
		y -= (win->_begy + win->_yoffset);
		x -= win->_begx;
		result = TRUE;
	    }
	}
	if (result) {
	    *pX = x;
	    *pY = y;
	}
    }
    returnBool(result);
}

Project: ncurses

TPUTS_PROTO(outc, c)
{
    int rc = c;

    if (interrupted) {
	char tmp = (char) c;
	if (write(STDOUT_FILENO, &tmp, (size_t) 1) == -1)
	    rc = EOF;
    } else {
	rc = putc(c, stdout);
    }
    TPUTS_RETURN(rc);
}

Project: ncurses

tput_cmd(int fd, TTY * saved_settings, bool opt_x, int argc, char *argv[])
{
    NCURSES_CONST char *name;
    char *s;
    int status;
#if !PURE_TERMINFO
    bool termcap = FALSE;
#endif

    name = check_aliases(argv[0], FALSE);
    if (is_reset || is_init) {
	TTY oldmode;

	int terasechar = -1;	/* new erase character */
	int intrchar = -1;	/* new interrupt character */
	int tkillchar = -1;	/* new kill character */

	if (is_reset) {
	    reset_start(stdout, TRUE, FALSE);
	    reset_tty_settings(fd, saved_settings);
	} else {
	    reset_start(stdout, FALSE, TRUE);
	}

#if HAVE_SIZECHANGE
	set_window_size(fd, &lines, &columns);
#else
	(void) fd;
#endif
	set_control_chars(saved_settings, terasechar, intrchar, tkillchar);
	set_conversions(saved_settings);
	if (send_init_strings(fd, &oldmode)) {
	    reset_flush();
	}

	update_tty_settings(&oldmode, saved_settings);
	return 0;
    }

    if (strcmp(name, "longname") == 0) {
	PUTS(longname());
	return 0;
    }
#if !PURE_TERMINFO
  retry:
#endif
    if (strcmp(name, "clear") == 0) {
	return (clear_cmd(opt_x) == ERR) ? ErrUsage : 0;
    } else if ((status = tigetflag(name)) != -1) {
	return exit_code(BOOLEAN, status);
    } else if ((status = tigetnum(name)) != CANCELLED_NUMERIC) {
	(void) printf("%d\n", status);
	return exit_code(NUMBER, 0);
    } else if ((s = tigetstr(name)) == CANCELLED_STRING) {
#if !PURE_TERMINFO
	if (!termcap) {
	    const struct name_table_entry *np;

	    termcap = TRUE;
	    if ((np = _nc_find_entry(name, _nc_get_hash_table(termcap))) != 0) {
		switch (np->nte_type) {
		case BOOLEAN:
		    name = boolnames[np->nte_index];
		    break;

		case NUMBER:
		    name = numnames[np->nte_index];
		    break;

		case STRING:
		    name = strnames[np->nte_index];
		    break;
		}
		goto retry;
	    }
	}
#endif
	quit(ErrCapName, "unknown terminfo capability '%s'", name);
    } else if (VALID_STRING(s)) {
	if (argc > 1) {
	    int k;
	    int ignored;
	    long numbers[1 + NUM_PARM];
	    char *strings[1 + NUM_PARM];
	    char *p_is_s[NUM_PARM];

	    /* Nasty hack time. The tparm function needs to see numeric
	     * parameters as numbers, not as pointers to their string
	     * representations
	     */

	    for (k = 1; (k < argc) && (k < NUM_PARM); k++) {
		char *tmp = 0;
		strings[k] = argv[k];
		numbers[k] = strtol(argv[k], &tmp, 0);
		if (tmp == 0 || *tmp != 0)
		    numbers[k] = 0;
	    }
	    for (k = argc; k <= NUM_PARM; k++) {
		numbers[k] = 0;
		strings[k] = 0;
	    }

	    switch (tparm_type(name)) {
	    case Num_Str:
		s = TPARM_2(s, numbers[1], strings[2]);
		break;
	    case Num_Str_Str:
		s = TPARM_3(s, numbers[1], strings[2], strings[3]);
		break;
	    case Numbers:
#define myParam(n) numbers[n]
		s = TIPARM_9(s,
			     myParam(1),
			     myParam(2),
			     myParam(3),
			     myParam(4),
			     myParam(5),
			     myParam(6),
			     myParam(7),
			     myParam(8),
			     myParam(9));
#undef myParam
		break;
	    default:
		(void) _nc_tparm_analyze(s, p_is_s, &ignored);
#define myParam(n) (p_is_s[n - 1] != 0 ? ((TPARM_ARG) strings[n]) : numbers[n])
		s = TPARM_9(s,
			    myParam(1),
			    myParam(2),
			    myParam(3),
			    myParam(4),
			    myParam(5),
			    myParam(6),
			    myParam(7),
			    myParam(8),
			    myParam(9));
#undef myParam
		break;
	    }
	}

	/* use putp() in order to perform padding */
	putp(s);
	return exit_code(STRING, 0);
    }
    return exit_code(STRING, 1);
}

Project: ncurses

pair_content(NCURSES_COLOR_T pair, NCURSES_COLOR_T *f, NCURSES_COLOR_T *b)
{
    return NCURSES_SP_NAME(pair_content) (CURRENT_SCREEN, pair, f, b);
}

Project: ncurses

vidputs(chtype newmode, NCURSES_OUTC outc)
{
    SetSafeOutcWrapper(outc);
    return NCURSES_SP_NAME(vidputs) (CURRENT_SCREEN,
				     newmode,
				     _nc_outc_wrapper);
}

Project: ncurses

reset_flush(void)
{
    if (my_file != 0)
	fflush(my_file);
}

Project: ncurses

drv_print(TERMINAL_CONTROL_BLOCK * TCB, char *data, int len)
{
    SCREEN *sp;

    AssertTCB();
    SetSP();
#if NCURSES_EXT_FUNCS
    return NCURSES_SP_NAME(mcprint) (TCB->csp, data, len);
#else
    return ERR;
#endif
}

Project: ncurses

_nc_fmt_funcptr(char *target, const char *source, size_t size)
{
    size_t n;
    char *dst = target;
    bool leading = TRUE;

    union {
	int value;
	char bytes[sizeof(int)];
    } byteorder;

    byteorder.value = 0x1234;

    *dst++ = '0';
    *dst++ = 'x';

    for (n = 0; n < size; ++n) {
	unsigned ch = ((byteorder.bytes[0] == 0x34)
		       ? UChar(source[size - n - 1])
		       : UChar(source[n]));
	if (ch != 0 || (n + 1) >= size)
	    leading = FALSE;
	if (!leading) {
	    _nc_SPRINTF(dst, _nc_SLIMIT(TR_FUNC_LEN - (size_t) (dst - target))
			"%02x", ch & 0xff);
	    dst += 2;
	}
    }
    *dst = '\0';
    return target;
}

Project: ncurses

show_tty_change(TTY * old_settings,
		TTY * new_settings,
		const char *name,
		int which,
		unsigned def)
{
    unsigned older, newer;
    char *p;

    newer = new_settings->c_cc[which];
    older = old_settings->c_cc[which];

    if (older == newer && older == def)
	return;

    (void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");

    if (DISABLED(newer)) {
	(void) fprintf(stderr, "undef.\n");
	/*
	 * Check 'delete' before 'backspace', since the key_backspace value
	 * is ambiguous.
	 */
    } else if (newer == 0177) {
	(void) fprintf(stderr, "delete.\n");
    } else if ((p = key_backspace) != 0
	       && newer == (unsigned char) p[0]
	       && p[1] == '\0') {
	(void) fprintf(stderr, "backspace.\n");
    } else if (newer < 040) {
	newer ^= 0100;
	(void) fprintf(stderr, "control-%c (^%c).\n", UChar(newer), UChar(newer));
    } else
	(void) fprintf(stderr, "%c.\n", UChar(newer));
}

Project: ncurses

NCURSES_SP_NAME(has_colors) (NCURSES_SP_DCL0)
{
    int code = FALSE;

    (void) SP_PARM;
    T((T_CALLED("has_colors(%p)"), (void *) SP_PARM));
    if (HasTerminal(SP_PARM)) {
#ifdef USE_TERM_DRIVER
	code = HasColor;
#else
	code = ((VALID_NUMERIC(max_colors) && VALID_NUMERIC(max_pairs)
		 && (((set_foreground != NULL)
		      && (set_background != NULL))
		     || ((set_a_foreground != NULL)
			 && (set_a_background != NULL))
		     || set_color_pair)) ? TRUE : FALSE);
#endif
    }
    returnCode(code);
}

Project: ncurses

skip_delay(char *s)
{
    while (*s == '/' || isdigit(UChar(*s)))
	++s;
    return s;
}

Project: ncurses

drv_conattr(TERMINAL_CONTROL_BLOCK * TCB)
{
    SCREEN *sp = TCB->csp;
    chtype attrs = A_NORMAL;

    AssertTCB();
    if (enter_alt_charset_mode)
	attrs |= A_ALTCHARSET;

    if (enter_blink_mode)
	attrs |= A_BLINK;

    if (enter_bold_mode)
	attrs |= A_BOLD;

    if (enter_dim_mode)
	attrs |= A_DIM;

    if (enter_reverse_mode)
	attrs |= A_REVERSE;

    if (enter_standout_mode)
	attrs |= A_STANDOUT;

    if (enter_protected_mode)
	attrs |= A_PROTECT;

    if (enter_secure_mode)
	attrs |= A_INVIS;

    if (enter_underline_mode)
	attrs |= A_UNDERLINE;

    if (sp && sp->_coloron)
	attrs |= A_COLOR;

#if USE_ITALIC
    if (enter_italics_mode)
	attrs |= A_ITALIC;
#endif

    return (attrs);
}

Project: ncurses

isNumeric(char *source)
{
    char *next = 0;
    long value = strtol(source, &next, 0);
    int result = (next == 0 || next == source || *next != '\0') ? 0 : 1;
    (void) value;
    return result;
}

Project: ncurses

tiparm(const char *string, ...)
{
    TPARM_DATA myData;
    va_list ap;
    char *result = NULL;

    _nc_tparm_err = 0;
#ifdef TRACE
    TPS(tname) = "tiparm";
#endif /* TRACE */

    if (tparm_setup(string, &myData) == OK) {

	va_start(ap, string);
	tparm_copy_valist(&myData, FALSE, ap);
	va_end(ap);

	result = tparam_internal(string, &myData);
    }
    return result;
}

Project: ncurses

_nc_screen_init(void)
{
    NCURSES_SP_NAME(_nc_screen_init) (CURRENT_SCREEN);
}

Project: ncurses

_nc_retrace_void_ptr(void *code)
{
    T((T_RETURN("%p"), code));
    return code;
}

Project: ncurses

keypad_final(const char *string)
{
    char result = '\0';

    if (VALID_STRING(string)
	&& *string++ == '\033'
	&& *string++ == 'O'
	&& strlen(string) == 1) {
	result = *string;
    }

    return result;
}

Project: ncurses

drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf)
{
    SCREEN *sp = TCB->csp;
    TERMINAL *_term = (TERMINAL *) TCB;
    int result = OK;

    AssertTCB();
    if (setFlag) {
	for (;;) {
	    if (SET_TTY(_term->Filedes, buf) != 0) {
		if (errno == EINTR)
		    continue;
		if (errno == ENOTTY) {
		    if (sp)
			sp->_notty = TRUE;
		}
		result = ERR;
	    }
	    break;
	}
    } else {
	for (;;) {
	    if (GET_TTY(_term->Filedes, buf) != 0) {
		if (errno == EINTR)
		    continue;
		result = ERR;
	    }
	    break;
	}
    }
    return result;
}