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

📄 lib_mvcur.c

📁 ncurses 库 可能有用酒用 没用就算了 我觉得还可以用
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************** * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc.              * *                                                                          * * Permission is hereby granted, free of charge, to any person obtaining a  * * copy of this software and associated documentation files (the            * * "Software"), to deal in the Software without restriction, including      * * without limitation the rights to use, copy, modify, merge, publish,      * * distribute, distribute with modifications, sublicense, and/or sell       * * copies of the Software, and to permit persons to whom the Software is    * * furnished to do so, subject to the following conditions:                 * *                                                                          * * The above copyright notice and this permission notice shall be included  * * in all copies or substantial portions of the Software.                   * *                                                                          * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    * * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               * *                                                                          * * Except as contained in this notice, the name(s) of the above copyright   * * holders shall not be used in advertising or otherwise to promote the     * * sale, use or other dealings in this Software without prior written       * * authorization.                                                           * ****************************************************************************//**************************************************************************** *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               * *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         * *     and: Thomas E. Dickey                        1996-on                 * ****************************************************************************//***	lib_mvcur.c****	The routines for moving the physical cursor and scrolling:****		void _nc_mvcur_init(void)****		void _nc_mvcur_resume(void)****		int mvcur(int old_y, int old_x, int new_y, int new_x)****		void _nc_mvcur_wrap(void)**** Comparisons with older movement optimizers:**    SVr3 curses mvcur() can't use cursor_to_ll or auto_left_margin.**    4.4BSD curses can't use cuu/cud/cuf/cub/hpa/vpa/tab/cbt for local** motions.  It doesn't use tactics based on auto_left_margin.  Weirdly** enough, it doesn't use its own hardware-scrolling routine to scroll up** destination lines for out-of-bounds addresses!**    old ncurses optimizer: less accurate cost computations (in fact,** it was broken and had to be commented out!).**** Compile with -DMAIN to build an interactive tester/timer for the movement** optimizer.  You can use it to investigate the optimizer's behavior.** You can also use it for tuning the formulas used to determine whether** or not full optimization is attempted.**** This code has a nasty tendency to find bugs in terminfo entries, because it** exercises the non-cup movement capabilities heavily.  If you think you've** found a bug, try deleting subsets of the following capabilities (arranged** in decreasing order of suspiciousness): it, tab, cbt, hpa, vpa, cuu, cud,** cuf, cub, cuu1, cud1, cuf1, cub1.  It may be that one or more are wrong.**** Note: you should expect this code to look like a resource hog in a profile.** That's because it does a lot of I/O, through the tputs() calls.  The I/O** cost swamps the computation overhead (and as machines get faster, this** will become even more true).  Comments in the test exerciser at the end** go into detail about tuning and how you can gauge the optimizer's** effectiveness.**//**************************************************************************** * * Constants and macros for optimizer tuning. * ****************************************************************************//* * The average overhead of a full optimization computation in character * transmission times.  If it's too high, the algorithm will be a bit * over-biased toward using cup rather than local motions; if it's too * low, the algorithm may spend more time than is strictly optimal * looking for non-cup motions.  Profile the optimizer using the `t' * command of the exerciser (see below), and round to the nearest integer. * * Yes, I (esr) thought about computing expected overhead dynamically, say * by derivation from a running average of optimizer times.  But the * whole point of this optimization is to *decrease* the frequency of * system calls. :-) */#define COMPUTE_OVERHEAD	1	/* I use a 90MHz Pentium @ 9.6Kbps *//* * LONG_DIST is the distance we consider to be just as costly to move over as a * cup sequence is to emit.  In other words, it's the length of a cup sequence * adjusted for average computation overhead.  The magic number is the length * of "\033[yy;xxH", the typical cup sequence these days. */#define LONG_DIST		(8 - COMPUTE_OVERHEAD)/* * Tell whether a motion is optimizable by local motions.  Needs to be cheap to * compute. In general, all the fast moves go to either the right or left edge * of the screen.  So any motion to a location that is (a) further away than * LONG_DIST and (b) further inward from the right or left edge than LONG_DIST, * we'll consider nonlocal. */#define NOT_LOCAL(fy, fx, ty, tx)	((tx > LONG_DIST) \ 		 && (tx < screen_columns - 1 - LONG_DIST) \		 && (abs(ty-fy) + abs(tx-fx) > LONG_DIST))/**************************************************************************** * * External interfaces * ****************************************************************************//* * For this code to work OK, the following components must live in the * screen structure: * *	int		_char_padding;	// cost of character put *	int		_cr_cost;	// cost of (carriage_return) *	int		_cup_cost;	// cost of (cursor_address) *	int		_home_cost;	// cost of (cursor_home) *	int		_ll_cost;	// cost of (cursor_to_ll) *#if USE_HARD_TABS *	int		_ht_cost;	// cost of (tab) *	int		_cbt_cost;	// cost of (back_tab) *#endif USE_HARD_TABS *	int		_cub1_cost;	// cost of (cursor_left) *	int		_cuf1_cost;	// cost of (cursor_right) *	int		_cud1_cost;	// cost of (cursor_down) *	int		_cuu1_cost;	// cost of (cursor_up) *	int		_cub_cost;	// cost of (parm_cursor_left) *	int		_cuf_cost;	// cost of (parm_cursor_right) *	int		_cud_cost;	// cost of (parm_cursor_down) *	int		_cuu_cost;	// cost of (parm_cursor_up) *	int		_hpa_cost;	// cost of (column_address) *	int		_vpa_cost;	// cost of (row_address) *	int		_ech_cost;	// cost of (erase_chars) *	int		_rep_cost;	// cost of (repeat_char) * * The USE_HARD_TABS switch controls whether it is reliable to use tab/backtabs * for local motions.  On many systems, it's not, due to uncertainties about * tab delays and whether or not tabs will be expanded in raw mode.  If you * have parm_right_cursor, tab motions don't win you a lot anyhow. */#include <curses.priv.h>#include <term.h>#include <ctype.h>MODULE_ID("$Id: lib_mvcur.c,v 1.103 2005/06/11 19:30:15 tom Exp $")#define WANT_CHAR(y, x)	SP->_newscr->_line[y].text[x]	/* desired state */#define BAUDRATE	cur_term->_baudrate	/* bits per second */#if defined(MAIN) || defined(NCURSES_TEST)#include <sys/time.h>static bool profiling = FALSE;static float diff;#endif /* MAIN */#define OPT_SIZE 512static int normalized_cost(const char *const cap, int affcnt);/**************************************************************************** * * Initialization/wrapup (including cost pre-computation) * ****************************************************************************/#ifdef TRACEstatic inttrace_cost_of(const char *capname, const char *cap, int affcnt){    int result = _nc_msec_cost(cap, affcnt);    TR(TRACE_CHARPUT | TRACE_MOVE,       ("CostOf %s %d %s", capname, result, _nc_visbuf(cap)));    return result;}#define CostOf(cap,affcnt) trace_cost_of(#cap,cap,affcnt);static inttrace_normalized_cost(const char *capname, const char *cap, int affcnt){    int result = normalized_cost(cap, affcnt);    TR(TRACE_CHARPUT | TRACE_MOVE,       ("NormalizedCost %s %d %s", capname, result, _nc_visbuf(cap)));    return result;}#define NormalizedCost(cap,affcnt) trace_normalized_cost(#cap,cap,affcnt);#else#define CostOf(cap,affcnt) _nc_msec_cost(cap,affcnt);#define NormalizedCost(cap,affcnt) normalized_cost(cap,affcnt);#endifNCURSES_EXPORT(int)_nc_msec_cost(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 + (*cp - '0');		    else if (*cp == '*')			number *= affcnt;		    else if (*cp == '.' && (*++cp != '>') && isdigit(UChar(*cp)))			number += (*cp - '0') / 10.0;		}#if NCURSES_NO_PADDING		if (!(SP->_no_padding))#endif		    cum_cost += number * 10;	    } else		cum_cost += SP->_char_padding;	}	return ((int) cum_cost);    }}static intnormalized_cost(const char *const cap, int affcnt)/* compute the effective character-count for an operation (round up) */{    int cost = _nc_msec_cost(cap, affcnt);    if (cost != INFINITY)	cost = (cost + SP->_char_padding - 1) / SP->_char_padding;    return cost;}static voidreset_scroll_region(void)/* Set the scroll-region to a known state (the default) */{    if (change_scroll_region) {	TPUTS_TRACE("change_scroll_region");	putp(tparm(change_scroll_region, 0, screen_lines - 1));    }}NCURSES_EXPORT(void)_nc_mvcur_resume(void)/* what to do at initialization time and after each shellout */{    /* initialize screen for cursor access */    if (enter_ca_mode) {	TPUTS_TRACE("enter_ca_mode");	putp(enter_ca_mode);    }    /*     * Doing this here rather than in _nc_mvcur_wrap() ensures that     * ncurses programs will see a reset scroll region even if a     * program that messed with it died ungracefully.     *     * This also undoes the effects of terminal init strings that assume     * they know the screen size.  This is useful when you're running     * a vt100 emulation through xterm.     */    reset_scroll_region();    SP->_cursrow = SP->_curscol = -1;    /* restore cursor shape */    if (SP->_cursor != -1) {	int cursor = SP->_cursor;	SP->_cursor = -1;	curs_set(cursor);    }}NCURSES_EXPORT(void)_nc_mvcur_init(void)/* initialize the cost structure */{    if (isatty(fileno(SP->_ofp)))	SP->_char_padding = ((BAUDBYTE * 1000 * 10)			     / (BAUDRATE > 0 ? BAUDRATE : 9600));    else	SP->_char_padding = 1;	/* must be nonzero */    if (SP->_char_padding <= 0)	SP->_char_padding = 1;	/* must be nonzero */    TR(TRACE_CHARPUT | TRACE_MOVE, ("char_padding %d msecs", SP->_char_padding));    /* non-parameterized local-motion strings */    SP->_cr_cost = CostOf(carriage_return, 0);    SP->_home_cost = CostOf(cursor_home, 0);    SP->_ll_cost = CostOf(cursor_to_ll, 0);#if USE_HARD_TABS    SP->_ht_cost = CostOf(tab, 0);    SP->_cbt_cost = CostOf(back_tab, 0);#endif /* USE_HARD_TABS */    SP->_cub1_cost = CostOf(cursor_left, 0);    SP->_cuf1_cost = CostOf(cursor_right, 0);    SP->_cud1_cost = CostOf(cursor_down, 0);    SP->_cuu1_cost = CostOf(cursor_up, 0);    SP->_smir_cost = CostOf(enter_insert_mode, 0);    SP->_rmir_cost = CostOf(exit_insert_mode, 0);    SP->_ip_cost = 0;    if (insert_padding) {	SP->_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->_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->_cup_cost = CostOf(tparm(SP->_address_cursor, 23, 23), 1);    SP->_cub_cost = CostOf(tparm(parm_left_cursor, 23), 1);    SP->_cuf_cost = CostOf(tparm(parm_right_cursor, 23), 1);    SP->_cud_cost = CostOf(tparm(parm_down_cursor, 23), 1);    SP->_cuu_cost = CostOf(tparm(parm_up_cursor, 23), 1);    SP->_hpa_cost = CostOf(tparm(column_address, 23), 1);    SP->_vpa_cost = CostOf(tparm(row_address, 23), 1);    /* non-parameterized screen-update strings */    SP->_ed_cost = NormalizedCost(clr_eos, 1);    SP->_el_cost = NormalizedCost(clr_eol, 1);    SP->_el1_cost = NormalizedCost(clr_bol, 1);    SP->_dch1_cost = NormalizedCost(delete_character, 1);    SP->_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->_el_cost = 0;    /* parameterized screen-update strings */    SP->_dch_cost = NormalizedCost(tparm(parm_dch, 23), 1);    SP->_ich_cost = NormalizedCost(tparm(parm_ich, 23), 1);    SP->_ech_cost = NormalizedCost(tparm(erase_chars, 23), 1);    SP->_rep_cost = NormalizedCost(tparm(repeat_char, ' ', 23), 1);    SP->_cup_ch_cost = NormalizedCost(tparm(SP->_address_cursor, 23, 23), 1);    SP->_hpa_ch_cost = NormalizedCost(tparm(column_address, 23), 1);    SP->_cuf_ch_cost = NormalizedCost(tparm(parm_right_cursor, 23), 1);    SP->_inline_cost = min(SP->_cup_ch_cost,			   min(SP->_hpa_ch_cost,			       SP->_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     * SP->_endwin = TRUE at window initialization time and let this be     * called by doupdate's return-from-shellout code.     */    _nc_mvcur_resume();}

⌨️ 快捷键说明

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