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

📄 ncurses.c

📁 ncurses-5.4
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************** * Copyright (c) 1998-2003,2004 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.                                                           * ****************************************************************************//****************************************************************************NAME   ncurses.c --- ncurses library exerciserSYNOPSIS   ncursesDESCRIPTION   An interactive test module for the ncurses library.AUTHOR   Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993           Thomas E. Dickey (beginning revision 1.27 in 1996).$Id: ncurses.c,v 1.202 2004/02/07 20:24:08 tom Exp $***************************************************************************/#include <test.priv.h>#if HAVE_GETTIMEOFDAY#if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT#include <sys/time.h>#endif#if HAVE_SYS_SELECT_H#include <sys/select.h>#endif#endif#if USE_LIBPANEL#include <panel.h>#endif#if USE_LIBMENU#include <menu.h>#endif#if USE_LIBFORM#include <form.h>#endif#ifdef NCURSES_VERSION#ifdef TRACEstatic int save_trace = TRACE_ORDINARY | TRACE_CALLS;extern int _nc_tracing;#endif#else#define mmask_t chtype		/* not specified in XSI */#ifdef CURSES_ACS_ARRAY#define ACS_S3          (CURSES_ACS_ARRAY['p'])		/* scan line 3 */#define ACS_S7          (CURSES_ACS_ARRAY['r'])		/* scan line 7 */#define ACS_LEQUAL      (CURSES_ACS_ARRAY['y'])		/* less/equal */#define ACS_GEQUAL      (CURSES_ACS_ARRAY['z'])		/* greater/equal */#define ACS_PI          (CURSES_ACS_ARRAY['{'])		/* Pi */#define ACS_NEQUAL      (CURSES_ACS_ARRAY['|'])		/* not equal */#define ACS_STERLING    (CURSES_ACS_ARRAY['}'])		/* UK pound sign */#else#define ACS_S3          (A_ALTCHARSET + 'p')	/* scan line 3 */#define ACS_S7          (A_ALTCHARSET + 'r')	/* scan line 7 */#define ACS_LEQUAL      (A_ALTCHARSET + 'y')	/* less/equal */#define ACS_GEQUAL      (A_ALTCHARSET + 'z')	/* greater/equal */#define ACS_PI          (A_ALTCHARSET + '{')	/* Pi */#define ACS_NEQUAL      (A_ALTCHARSET + '|')	/* not equal */#define ACS_STERLING    (A_ALTCHARSET + '}')	/* UK pound sign */#endif#ifdef CURSES_WACS_ARRAY#define WACS_S3         (&(CURSES_WACS_ARRAY['p']))	/* scan line 3 */#define WACS_S7         (&(CURSES_WACS_ARRAY['r']))	/* scan line 7 */#define WACS_LEQUAL     (&(CURSES_WACS_ARRAY['y']))	/* less/equal */#define WACS_GEQUAL     (&(CURSES_WACS_ARRAY['z']))	/* greater/equal */#define WACS_PI         (&(CURSES_WACS_ARRAY['{']))	/* Pi */#define WACS_NEQUAL     (&(CURSES_WACS_ARRAY['|']))	/* not equal */#define WACS_STERLING   (&(CURSES_WACS_ARRAY['}']))	/* UK pound sign */#endif#endif#define P(string)	printw("%s\n", string)#define BLANK		' '	/* this is the background character */#undef max_colorsstatic int max_colors;		/* the actual number of colors we'll use */#undef max_pairsstatic int max_pairs;		/* ...and the number of color pairs *//* The behavior of mvhline, mvvline for negative/zero length is unspecified, * though we can rely on negative x/y values to stop the macro. */static voiddo_h_line(int y, int x, chtype c, int to){    if ((to) > (x))	mvhline(y, x, c, (to) - (x));}static voiddo_v_line(int y, int x, chtype c, int to){    if ((to) > (y))	mvvline(y, x, c, (to) - (y));}/* Common function to allow ^T to toggle trace-mode in the middle of a test * so that trace-files can be made smaller. */static intwGetchar(WINDOW *win){    int c;#ifdef TRACE    while ((c = wgetch(win)) == CTRL('T')) {	if (_nc_tracing) {	    save_trace = _nc_tracing;	    _tracef("TOGGLE-TRACING OFF");	    _nc_tracing = 0;	} else {	    _nc_tracing = save_trace;	}	trace(_nc_tracing);	if (_nc_tracing)	    _tracef("TOGGLE-TRACING ON");    }#else    c = wgetch(win);#endif    return c;}#define Getchar() wGetchar(stdscr)/* replaces wgetnstr(), since we want to be able to edit values */static voidwGetstring(WINDOW *win, char *buffer, int limit){    int y0, x0, x, ch;    bool done = FALSE;    echo();    getyx(win, y0, x0);    wattrset(win, A_REVERSE);    x = strlen(buffer);    while (!done) {	if (x > (int) strlen(buffer))	    x = (int) strlen(buffer);	wmove(win, y0, x0);	wprintw(win, "%-*s", limit, buffer);	wmove(win, y0, x0 + x);	switch (ch = wGetchar(win)) {	case '\n':	case KEY_ENTER:	    done = TRUE;	    break;	case CTRL('U'):	    *buffer = '\0';	    break;	case '\b':	case KEY_BACKSPACE:	case KEY_DC:	    if (x > 0) {		int j;		for (j = --x; (buffer[j] = buffer[j + 1]) != '\0'; ++j) {		    ;		}	    } else {		beep();	    }	    break;	case KEY_LEFT:	    if (x > 0) {		--x;	    } else {		flash();	    }	    break;	case KEY_RIGHT:	    ++x;	    break;	default:	    if (!isprint(ch) || ch >= KEY_MIN) {		beep();	    } else if ((int) strlen(buffer) < limit) {		int j;		for (j = strlen(buffer) + 1; j > x; --j) {		    buffer[j] = buffer[j - 1];		}		buffer[x++] = ch;	    } else {		flash();	    }	}    }    wattroff(win, A_REVERSE);    wmove(win, y0, x0);    noecho();}#if USE_WIDEC_SUPPORTstatic intwGet_wchar(WINDOW *win, wint_t * result){    int c;#ifdef TRACE    while ((c = wget_wch(win, result)) == CTRL('T')) {	if (_nc_tracing) {	    save_trace = _nc_tracing;	    _tracef("TOGGLE-TRACING OFF");	    _nc_tracing = 0;	} else {	    _nc_tracing = save_trace;	}	trace(_nc_tracing);	if (_nc_tracing)	    _tracef("TOGGLE-TRACING ON");    }#else    c = wget_wch(win, result);#endif    return c;}#define Get_wchar(result) wGet_wchar(stdscr, result)/* replaces wgetn_wstr(), since we want to be able to edit values */static voidwGet_wstring(WINDOW *win, wchar_t * buffer, int limit){    int y0, x0, x;    wint_t ch;    bool done = FALSE;    echo();    getyx(win, y0, x0);    wattrset(win, A_REVERSE);    x = wcslen(buffer);    while (!done) {	if (x > (int) wcslen(buffer))	    x = (int) wcslen(buffer);	wmove(win, y0, x0);	waddnwstr(win, buffer, limit);	if (x < limit)	    wprintw(win, "%*s", limit - x, " ");	wmove(win, y0, x0 + x);	switch (wGet_wchar(win, &ch)) {	case KEY_CODE_YES:	    switch (ch) {	    case KEY_ENTER:		ch = '\n';		break;	    case KEY_BACKSPACE:	    case KEY_DC:		ch = '\b';		break;	    case KEY_LEFT:	    case KEY_RIGHT:		break;	    default:		ch = (wint_t) - 1;		break;	    }	case OK:	    break;	default:	    ch = (wint_t) - 1;	    break;	}	switch (ch) {	case '\n':	    done = TRUE;	    break;	case CTRL('U'):	    *buffer = '\0';	    break;	case '\b':	    if (x > 0) {		int j;		for (j = --x; (buffer[j] = buffer[j + 1]) != '\0'; ++j) {		    ;		}	    } else {		beep();	    }	    break;	case KEY_LEFT:	    if (x > 0) {		--x;	    } else {		flash();	    }	    break;	case KEY_RIGHT:	    ++x;	    break;	default:	    if (!isprint(ch) || ch >= KEY_MIN) {		beep();	    } else if ((int) wcslen(buffer) < limit) {		int j;		for (j = wcslen(buffer) + 1; j > x; --j) {		    buffer[j] = buffer[j - 1];		}		buffer[x++] = ch;	    } else {		flash();	    }	}    }    wattroff(win, A_REVERSE);    wmove(win, y0, x0);    noecho();}#endifstatic voidPause(void){    move(LINES - 1, 0);    addstr("Press any key to continue... ");    (void) Getchar();}static voidCannot(const char *what){    printw("\nThis %s terminal %s\n\n", getenv("TERM"), what);    Pause();}static voidShellOut(bool message){    if (message)	addstr("Shelling out...");    def_prog_mode();    endwin();    system("sh");    if (message)	addstr("returned from shellout.\n");    refresh();}#ifdef NCURSES_MOUSE_VERSIONstatic const char *mouse_decode(MEVENT const *ep){    static char buf[80];    (void) sprintf(buf, "id %2d  at (%2d, %2d, %2d) state %4lx = {",		   ep->id, ep->x, ep->y, ep->z, ep->bstate);#define SHOW(m, s) if ((ep->bstate & m)==m) {strcat(buf,s); strcat(buf, ", ");}    SHOW(BUTTON1_RELEASED, "release-1");    SHOW(BUTTON1_PRESSED, "press-1");    SHOW(BUTTON1_CLICKED, "click-1");    SHOW(BUTTON1_DOUBLE_CLICKED, "doubleclick-1");    SHOW(BUTTON1_TRIPLE_CLICKED, "tripleclick-1");    SHOW(BUTTON1_RESERVED_EVENT, "reserved-1");    SHOW(BUTTON2_RELEASED, "release-2");    SHOW(BUTTON2_PRESSED, "press-2");    SHOW(BUTTON2_CLICKED, "click-2");    SHOW(BUTTON2_DOUBLE_CLICKED, "doubleclick-2");    SHOW(BUTTON2_TRIPLE_CLICKED, "tripleclick-2");    SHOW(BUTTON2_RESERVED_EVENT, "reserved-2");    SHOW(BUTTON3_RELEASED, "release-3");    SHOW(BUTTON3_PRESSED, "press-3");    SHOW(BUTTON3_CLICKED, "click-3");    SHOW(BUTTON3_DOUBLE_CLICKED, "doubleclick-3");    SHOW(BUTTON3_TRIPLE_CLICKED, "tripleclick-3");    SHOW(BUTTON3_RESERVED_EVENT, "reserved-3");    SHOW(BUTTON4_RELEASED, "release-4");    SHOW(BUTTON4_PRESSED, "press-4");    SHOW(BUTTON4_CLICKED, "click-4");    SHOW(BUTTON4_DOUBLE_CLICKED, "doubleclick-4");    SHOW(BUTTON4_TRIPLE_CLICKED, "tripleclick-4");    SHOW(BUTTON4_RESERVED_EVENT, "reserved-4");    SHOW(BUTTON_CTRL, "ctrl");    SHOW(BUTTON_SHIFT, "shift");    SHOW(BUTTON_ALT, "alt");    SHOW(ALL_MOUSE_EVENTS, "all-events");    SHOW(REPORT_MOUSE_POSITION, "position");#undef SHOW    if (buf[strlen(buf) - 1] == ' ')	buf[strlen(buf) - 2] = '\0';    (void) strcat(buf, "}");    return (buf);}#endif /* NCURSES_MOUSE_VERSION *//**************************************************************************** * * Character input test * ****************************************************************************/static voidsetup_getch(WINDOW *win, bool flags[]){    keypad(win, flags['k']);	/* should be redundant, but for testing */    meta(win, flags['m']);	/* force this to a known state */    if (flags['e'])	echo();    else	noecho();}static voidwgetch_help(WINDOW *win, bool flags[]){    static const char *help[] =    {	"e -- toggle echo mode"	,"g -- triggers a getstr test"	,"k -- toggle keypad/literal mode"	,"m -- toggle meta (7-bit/8-bit) mode"	,"q -- quit (x also exits)"	,"s -- shell out\n"	,"w -- create a new window"#ifdef SIGTSTP	,"z -- suspend this process"#endif    };    int y, x;    unsigned chk = ((SIZEOF(help) + 1) / 2);    unsigned n;    getyx(win, y, x);    move(0, 0);    printw("Type any key to see its %s value.  Also:\n",	   flags['k'] ? "keypad" : "literal");    for (n = 0; n < SIZEOF(help); ++n) {	int row = 1 + (n % chk);	int col = (n >= chk) ? COLS / 2 : 0;	int flg = ((strstr(help[n], "toggle") != 0)		   && (flags[UChar(*help[n])] != FALSE));	if (flg)	    standout();	mvprintw(row, col, "%s", help[n]);	if (col == 0)	    clrtoeol();	if (flg)	    standend();    }    wrefresh(stdscr);    wmove(win, y, x);}static voidwgetch_wrap(WINDOW *win, int first_y){    int last_y = getmaxy(win) - 1;    int y = getcury(win) + 1;    if (y >= last_y)	y = first_y;    wmove(win, y, 0);    wclrtoeol(win);}#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZEtypedef struct {    WINDOW *text;    WINDOW *frame;} WINSTACK;static WINSTACK *winstack = 0;static unsigned len_winstack = 0;static voidremember_boxes(unsigned level, WINDOW *txt_win, WINDOW *box_win){    unsigned need = (level + 1) * 2;    if (winstack == 0) {	len_winstack = 20;	winstack = (WINSTACK *) malloc(len_winstack * sizeof(WINSTACK));    } else if (need >= len_winstack) {	len_winstack = need;	winstack = (WINSTACK *) realloc(winstack, len_winstack * sizeof(WINSTACK));    }    winstack[level].text = txt_win;    winstack[level].frame = box_win;}/* * For wgetch_test(), we create pairs of windows - one for a box, one for text. * Resize both and paint the box in the parent. */static voidresize_boxes(int level, WINDOW *win){    unsigned n;    int base = 5;    int high = LINES - base;    int wide = COLS;    touchwin(stdscr);    wnoutrefresh(stdscr);    /* FIXME: this chunk should be done in resizeterm() */    slk_touch();    slk_clear();    slk_noutrefresh();    for (n = 0; (int) n < level; ++n) {	wresize(winstack[n].frame, high, wide);	wresize(winstack[n].text, high - 2, wide - 2);	high -= 2;	wide -= 2;	werase(winstack[n].text);	box(winstack[n].frame, 0, 0);	wnoutrefresh(winstack[n].frame);	wprintw(winstack[n].text,		"size %dx%d\n",		getmaxy(winstack[n].text),		getmaxx(winstack[n].text));	wnoutrefresh(winstack[n].text);	if (winstack[n].text == win)	    break;    }    doupdate();}#else#define remember_boxes(level,text,frame)	/* nothing */#endifstatic void

⌨️ 快捷键说明

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