⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib_mvcur.c

📁 ncurses 库 可能有用酒用 没用就算了 我觉得还可以用
💻 C
📖 第 1 页 / 共 3 页
字号:
NCURSES_EXPORT(void)_nc_mvcur_wrap(void)/* wrap up cursor-addressing mode */{    /* leave cursor at screen bottom */    mvcur(-1, -1, screen_lines - 1, 0);    /* set cursor to normal mode */    if (SP->_cursor != -1)	curs_set(1);    if (exit_ca_mode) {	TPUTS_TRACE("exit_ca_mode");	putp(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.     */    _nc_outch('\r');}/**************************************************************************** * * Optimized cursor movement * ****************************************************************************//* * Perform repeated-append, returning cost */static inline intrepeated_append(string_desc * target, int total, int num, int repeat, const char *src){    size_t need = 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;}#ifndef NO_OPTIMIZE#define NEXTTAB(fr)	(fr + init_tabs - (fr % init_tabs))/* * Assume back_tab (CBT) does not wrap backwards at the left margin, return * a negative value at that point to simplify the loop. */#define LASTTAB(fr)	((fr > 0) ? ((fr - 1) / init_tabs) * init_tabs : -1)static intrelative_move(string_desc * target, int from_y, int from_x, int to_y, int	      to_x, bool 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, tparm(row_address, to_y))) {	    vcost = SP->_vpa_cost;	}	if (to_y > from_y) {	    n = (to_y - from_y);	    if (parm_down_cursor		&& SP->_cud_cost < vcost		&& _nc_safe_strcat(_nc_str_copy(target, &save),				   tparm(parm_down_cursor, n))) {		vcost = SP->_cud_cost;	    }	    if (cursor_down		&& (*cursor_down != '\n' || SP->_nl)		&& (n * SP->_cud1_cost < vcost)) {		vcost = repeated_append(_nc_str_copy(target, &save), 0,					SP->_cud1_cost, n, cursor_down);	    }	} else {		/* (to_y < from_y) */	    n = (from_y - to_y);	    if (parm_up_cursor		&& SP->_cuu_cost < vcost		&& _nc_safe_strcat(_nc_str_copy(target, &save),				   tparm(parm_up_cursor, n))) {		vcost = SP->_cuu_cost;	    }	    if (cursor_up && (n * SP->_cuu1_cost < vcost)) {		vcost = repeated_append(_nc_str_copy(target, &save), 0,					SP->_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),			       tparm(column_address, to_x))) {	    hcost = SP->_hpa_cost;	}	if (to_x > from_x) {	    n = to_x - from_x;	    if (parm_right_cursor		&& SP->_cuf_cost < hcost		&& _nc_safe_strcat(_nc_str_copy(target, &save),				   tparm(parm_right_cursor, n))) {		hcost = SP->_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->_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(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(to_y, from_x + i);			if (!SameAttrOf(ch, SCREEN_ATTRS(SP))#if USE_WIDEC_SUPPORT			    || !Charable(ch)#endif			    ) {			    ovw = FALSE;			    break;			}		    }		}		if (ovw) {		    int i;		    for (i = 0; i < n; i++)			*check.s_tail++ = CharOf(WANT_CHAR(to_y, from_x + i));		    *check.s_tail = '\0';		    check.s_size -= n;		    lhcost += n * SP->_char_padding;		} else {		    lhcost = repeated_append(&check, lhcost, SP->_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->_cub_cost < hcost		&& _nc_safe_strcat(_nc_str_copy(target, &save),				   tparm(parm_left_cursor, n))) {		hcost = SP->_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->_cbt_cost, 1, back_tab);			if (lhcost == INFINITY)			    break;		    }		    n = fr - to_x;		}#endif /* USE_HARD_TABS */		lhcost = repeated_append(&check, lhcost, SP->_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);}#endif /* !NO_OPTIMIZE *//* * With the machinery set up above, it's conceivable that * onscreen_mvcur could be modified into a recursive function that does * an alpha-beta search of motion space, as though it were a chess * move tree, with the weight function being boolean and the search * depth equated to length of string.  However, this would jack up the * computation cost a lot, especially on terminals without a cup * capability constraining the search tree depth.  So we settle for * the simpler method below. */static inline intonscreen_mvcur(int yold, int xold, int ynew, int xnew, bool ovw)/* onscreen move from (yold, xold) to (ynew, xnew) */{    string_desc result;    char buffer[OPT_SIZE];    int tactic = 0, newcost, usecost = INFINITY;    int t5_cr_cost;#if defined(MAIN) || defined(NCURSES_TEST)    struct timeval before, after;    gettimeofday(&before, NULL);#endif /* MAIN */#define NullResult _nc_str_null(&result, sizeof(buffer))#define InitResult _nc_str_init(&result, buffer, sizeof(buffer))    /* tactic #0: use direct cursor addressing */    if (_nc_safe_strcpy(InitResult, tparm(SP->_address_cursor, ynew, xnew))) {	tactic = 0;	usecost = SP->_cup_cost;#if defined(TRACE) || defined(NCURSES_TEST)	if (!(_nc_optimize_enable & OPTIMIZE_MVCUR))	    goto nonlocal;#endif /* TRACE */	/*	 * We may be able to tell in advance that the full optimization	 * will probably not be worth its overhead.  Also, don't try to	 * use local movement if the current attribute is anything but	 * A_NORMAL...there are just too many ways this can screw up	 * (like, say, local-movement \n getting mapped to some obscure	 * character because A_ALTCHARSET is on).	 */	if (yold == -1 || xold == -1 || NOT_LOCAL(yold, xold, ynew, xnew)) {#if defined(MAIN) || defined(NCURSES_TEST)	    if (!profiling) {		(void) fputs("nonlocal\n", stderr);		goto nonlocal;	/* always run the optimizer if profiling */	    }#else	    goto nonlocal;#endif /* MAIN */	}    }#ifndef NO_OPTIMIZE    /* tactic #1: use local movement */    if (yold != -1 && xold != -1	&& ((newcost = relative_move(NullResult, yold, xold, ynew, xnew,				     ovw)) != INFINITY)	&& newcost < usecost) {	tactic = 1;	usecost = newcost;    }    /* tactic #2: use carriage-return + local movement */    if (yold != -1 && carriage_return	&& ((newcost = relative_move(NullResult, yold, 0, ynew, xnew, ovw))	    != INFINITY)	&& SP->_cr_cost + newcost < usecost) {	tactic = 2;	usecost = SP->_cr_cost + newcost;    }    /* tactic #3: use home-cursor + local movement */    if (cursor_home	&& ((newcost = relative_move(NullResult, 0, 0, ynew, xnew, ovw)) != INFINITY)	&& SP->_home_cost + newcost < usecost) {	tactic = 3;	usecost = SP->_home_cost + newcost;    }    /* tactic #4: use home-down + local movement */    if (cursor_to_ll	&& ((newcost = relative_move(NullResult, screen_lines - 1, 0, ynew,				     xnew, ovw)) != INFINITY)	&& SP->_ll_cost + newcost < usecost) {	tactic = 4;	usecost = SP->_ll_cost + newcost;    }    /*     * tactic #5: use left margin for wrap to right-hand side,     * unless strange wrap behavior indicated by xenl might hose us.     */    t5_cr_cost = (xold > 0 ? SP->_cr_cost : 0);    if (auto_left_margin && !eat_newline_glitch	&& yold > 0 && cursor_left	&& ((newcost = relative_move(NullResult, yold - 1, screen_columns -				     1, ynew, xnew, ovw)) != INFINITY)	&& t5_cr_cost + SP->_cub1_cost + newcost < usecost) {	tactic = 5;	usecost = t5_cr_cost + SP->_cub1_cost + newcost;    }    /*     * These cases are ordered by estimated relative frequency.     */    if (tactic)	InitResult;    switch (tactic) {    case 1:	(void) relative_move(&result, yold, xold, ynew, xnew, ovw);	break;    case 2:	(void) _nc_safe_strcpy(&result, carriage_return);	(void) relative_move(&result, yold, 0, ynew, xnew, ovw);	break;    case 3:	(void) _nc_safe_strcpy(&result, cursor_home);	(void) relative_move(&result, 0, 0, ynew, xnew, ovw);	break;    case 4:	(void) _nc_safe_strcpy(&result, cursor_to_ll);	(void) relative_move(&result, screen_lines - 1, 0, ynew, xnew, ovw);	break;    case 5:	if (xold > 0)	    (void) _nc_safe_strcat(&result, carriage_return);	(void) _nc_safe_strcat(&result, cursor_left);	(void) relative_move(&result, yold - 1, screen_columns - 1, ynew,			     xnew, ovw);	break;    }#endif /* !NO_OPTIMIZE */  nonlocal:#if defined(MAIN) || defined(NCURSES_TEST)    gettimeofday(&after, NULL);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -