📄 ncurses.c
字号:
*/static voidresize_boxes(unsigned 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; 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 voidwgetch_test(unsigned level, WINDOW *win, int delay){ char buf[BUFSIZ]; int first_y, first_x; int c; int incount = 0; bool flags[256]; bool blocking = (delay < 0); memset(flags, FALSE, sizeof(flags)); flags[UChar('k')] = (win == stdscr); setup_getch(win, flags); wtimeout(win, delay); getyx(win, first_y, first_x); wgetch_help(win, flags); wsetscrreg(win, first_y, getmaxy(win) - 1); scrollok(win, TRUE); for (;;) { while ((c = wGetchar(win)) == ERR) { incount++; if (blocking) { (void) wprintw(win, "%05d: input error", incount); break; } else { (void) wprintw(win, "%05d: input timed out", incount); } wgetch_wrap(win, first_y); } if (c == ERR && blocking) { wprintw(win, "ERR"); wgetch_wrap(win, first_y); } else if (c == 'x' || c == 'q') { break; } else if (c == 'e') { flags[UChar('e')] = !flags[UChar('e')]; setup_getch(win, flags); wgetch_help(win, flags); } else if (c == 'g') { waddstr(win, "getstr test: "); echo(); wgetnstr(win, buf, sizeof(buf) - 1); noecho(); wprintw(win, "I saw %d characters:\n\t`%s'.", (int) strlen(buf), buf); wclrtoeol(win); wgetch_wrap(win, first_y); } else if (c == 'k') { flags[UChar('k')] = !flags[UChar('k')]; setup_getch(win, flags); wgetch_help(win, flags); } else if (c == 'm') { flags[UChar('m')] = !flags[UChar('m')]; setup_getch(win, flags); wgetch_help(win, flags); } else if (c == 's') { ShellOut(TRUE); } else if (c == 'w') { int high = getmaxy(win) - 1 - first_y + 1; int wide = getmaxx(win) - first_x; int old_y, old_x; int new_y = first_y + getbegy(win); int new_x = first_x + getbegx(win); getyx(win, old_y, old_x); if (high > 2 && wide > 2) { WINDOW *wb = newwin(high, wide, new_y, new_x); WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1); box(wb, 0, 0); wrefresh(wb); wmove(wi, 0, 0); remember_boxes(level, wi, wb); wgetch_test(level + 1, wi, delay); delwin(wi); delwin(wb); wgetch_help(win, flags); wmove(win, old_y, old_x); touchwin(win); wrefresh(win); doupdate(); }#ifdef SIGTSTP } else if (c == 'z') { kill(getpid(), SIGTSTP);#endif } else { wprintw(win, "Key pressed: %04o ", c);#ifdef NCURSES_MOUSE_VERSION if (c == KEY_MOUSE) { int y, x; MEVENT event; getmouse(&event); wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event)); getyx(win, y, x); move(event.y, event.x); addch('*'); wmove(win, y, x); } else#endif /* NCURSES_MOUSE_VERSION */ if (c >= KEY_MIN) {#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE if (c == KEY_RESIZE) { resize_boxes(level, win); }#endif (void) waddstr(win, keyname(c)); } else if (c > 0x80) { unsigned c2 = (c & 0x7f); if (isprint(c2)) (void) wprintw(win, "M-%c", UChar(c2)); else (void) wprintw(win, "M-%s", unctrl(c2)); waddstr(win, " (high-half character)"); } else { if (isprint(c)) (void) wprintw(win, "%c (ASCII printable character)", c); else (void) wprintw(win, "%s (ASCII control character)", unctrl(UChar(c))); } wgetch_wrap(win, first_y); } } wtimeout(win, -1);}static intbegin_getch_test(void){ char buf[BUFSIZ]; int delay; refresh();#ifdef NCURSES_MOUSE_VERSION mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);#endif (void) printw("Delay in 10ths of a second (<CR> for blocking input)? "); echo(); getnstr(buf, sizeof(buf) - 1); noecho(); nonl(); if (isdigit(UChar(buf[0]))) { delay = atoi(buf) * 100; } else { delay = -1; } raw(); move(5, 0); return delay;}static voidfinish_getch_test(void){#ifdef NCURSES_MOUSE_VERSION mousemask(0, (mmask_t *) 0);#endif erase(); noraw(); nl(); endwin();}static voidgetch_test(void){ int delay = begin_getch_test(); wgetch_test(0, stdscr, delay); finish_getch_test();}#if USE_WIDEC_SUPPORT/* * For wgetch_test(), we create pairs of windows - one for a box, one for text. * Resize both and paint the box in the parent. */#ifdef KEY_RESIZEstatic voidresize_wide_boxes(unsigned 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; 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_set(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();}#endif /* KEY_RESIZE */static char *wcstos(const wchar_t *src){ int need; mbstate_t state; char *result = 0; const wchar_t *tmp = src; memset(&state, 0, sizeof(state)); if ((need = wcsrtombs(0, &tmp, 0, &state)) > 0) { unsigned have = need; result = (char *) calloc(have + 1, 1); tmp = src; if (wcsrtombs(result, &tmp, have, &state) != have) { free(result); result = 0; } } return result;}static voidwget_wch_test(unsigned level, WINDOW *win, int delay){ wchar_t wchar_buf[BUFSIZ]; wint_t wint_buf[BUFSIZ]; int first_y, first_x; wint_t c; int incount = 0; bool flags[256]; bool blocking = (delay < 0); int y, x, code; char *temp; memset(flags, FALSE, sizeof(flags)); flags[UChar('k')] = (win == stdscr); setup_getch(win, flags); wtimeout(win, delay); getyx(win, first_y, first_x); wgetch_help(win, flags); wsetscrreg(win, first_y, getmaxy(win) - 1); scrollok(win, TRUE); for (;;) { while ((code = wGet_wchar(win, &c)) == ERR) { incount++; if (blocking) { (void) wprintw(win, "%05d: input error", incount); break; } else { (void) wprintw(win, "%05d: input timed out", incount); } wgetch_wrap(win, first_y); } if (code == ERR && blocking) { wprintw(win, "ERR"); wgetch_wrap(win, first_y); } else if (c == 'x' || c == 'q') { break; } else if (c == 'e') { flags[UChar('e')] = !flags[UChar('e')]; setup_getch(win, flags); wgetch_help(win, flags); } else if (c == 'g') { waddstr(win, "getstr test: "); echo(); code = wgetn_wstr(win, wint_buf, sizeof(wint_buf) - 1); noecho(); if (code == ERR) { wprintw(win, "wgetn_wstr returns an error."); } else { int n; for (n = 0; (wchar_buf[n] = wint_buf[n]) != 0; ++n) ; if ((temp = wcstos(wchar_buf)) != 0) { wprintw(win, "I saw %d characters:\n\t`%s'.", wcslen(wchar_buf), temp); free(temp); } else { wprintw(win, "I saw %d characters (cannot convert).", wcslen(wchar_buf)); } } wclrtoeol(win); wgetch_wrap(win, first_y); } else if (c == 'k') { flags[UChar('k')] = !flags[UChar('k')]; setup_getch(win, flags); wgetch_help(win, flags); } else if (c == 'm') { flags[UChar('m')] = !flags[UChar('m')]; setup_getch(win, flags); wgetch_help(win, flags); } else if (c == 's') { ShellOut(TRUE); } else if (c == 'w') { int high = getmaxy(win) - 1 - first_y + 1; int wide = getmaxx(win) - first_x; int old_y, old_x; int new_y = first_y + getbegy(win); int new_x = first_x + getbegx(win); getyx(win, old_y, old_x); if (high > 2 && wide > 2) { WINDOW *wb = newwin(high, wide, new_y, new_x); WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1); box_set(wb, 0, 0); wrefresh(wb); wmove(wi, 0, 0); remember_boxes(level, wi, wb); wget_wch_test(level + 1, wi, delay); delwin(wi); delwin(wb); wgetch_help(win, flags); wmove(win, old_y, old_x); touchwin(win); wrefresh(win); }#ifdef SIGTSTP } else if (c == 'z') { kill(getpid(), SIGTSTP);#endif } else { wprintw(win, "Key pressed: %04o ", c);#ifdef NCURSES_MOUSE_VERSION if (c == KEY_MOUSE) { MEVENT event; getmouse(&event); wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event)); getyx(win, y, x); move(event.y, event.x); addch('*'); wmove(win, y, x); } else#endif /* NCURSES_MOUSE_VERSION */ if (code == KEY_CODE_YES) {#ifdef KEY_RESIZE if (c == KEY_RESIZE) { resize_wide_boxes(level, win); }#endif (void) waddstr(win, key_name((wchar_t) c)); } else { if (c < 256 && iscntrl(c)) { (void) wprintw(win, "%s (control character)", unctrl(c)); } else { wchar_t c2 = c; waddnwstr(win, &c2, 1); (void) wprintw(win, " = %#x (printable character)", c); } } wgetch_wrap(win, first_y); } } wtimeout(win, -1);}static voidget_wch_test(void){ int delay = begin_getch_test(); wget_wch_test(0, stdscr, delay); finish_getch_test();}#endif/**************************************************************************** * * Character attributes test * ****************************************************************************/#define MAX_ATTRSTRING 31#define LEN_ATTRSTRING 26static char attr_test_string[MAX_ATTRSTRING + 1];static voidattr_legend(WINDOW *helpwin){ int row = 1; int col = 1; mvwprintw(helpwin, row++, col, "q or ESC to exit."); mvwprintw(helpwin, row++, col, "^L repaints."); ++row; mvwprintw(helpwin, row++, col, "Modify the test strings:"); mvwprintw(helpwin, row++, col, " A digit sets gaps on each side of displayed attributes"); mvwprintw(helpwin, row++, col, " </> shifts the text left/right. "); ++row; mvwprintw(helpwin, row++, col, "Toggles:"); if (has_colors()) { mvwprintw(helpwin, row++, col, " f/F/b/F toggle foreground/background background color"); mvwprintw(helpwin, row++, col, " t/T toggle text/background color attribute"); } mvwprintw(helpwin, row++, col, " a/A toggle ACS (alternate character set) mapping"); mvwprintw(helpwin, row++, col, " v/V toggle video attribute to combine with each line");}static voidshow_color_attr(int fg, int bg, int tx){ if (has_colors()) { printw(" Colors (fg %d, bg %d", fg, bg); if (tx >= 0) printw(", text %d", tx); printw("),"); }}static boolcycle_color_attr(int ch, int *fg, int *bg, int *tx){ bool error = FALSE; if (has_colors()) { switch (ch) { case 'f': *fg = (*fg + 1); break; case 'F': *fg = (*fg - 1); break; case 'b': *bg = (*bg + 1); break; case 'B': *bg = (*bg - 1); break; case 't': *tx = (*tx + 1); break; case 'T': *tx = (*tx - 1); break; default: beep(); error = TRUE; break; } if (*fg >= COLORS) *fg = min_colors; if (*fg < min_colors) *fg = COLORS - 1; if (*bg >= COLORS) *bg = min_colors; if (*bg < min_colors) *bg = COLORS - 1; if (*tx >= COLORS) *tx = -1; if (*tx < -1) *tx = COLORS - 1; } else { beep(); error = TRUE; } return error;}static voidadjust_attr_string(int adjust){ int first = ((int) UChar(attr_test_string[0])) + adjust; int last = first + LEN_ATTRSTRING; if (first >= ' ' && last <= '~') { /* 32..126 */ int j, k; for (j = 0, k = first; j < MAX_ATTRSTRING && k <= last; ++j, ++k) { attr_test_string[j] = k; if (((k + 1 - first) % 5) == 0) { ++j; if (j < MAX_ATTRSTRING) attr_test_string[j] = ' '; } } while (j < MAX_ATTRSTRING) attr_test_string[j++] = ' '; attr_test_string[j] = '\0'; } else { beep(); }}static voidinit_attr_string(void){ attr_test_string[0] = 'a'; adjust_attr_string(0);}static intshow_attr(int row, int skip, bool arrow, chtype attr, const char *name){ int ncv = tigetnum("ncv"); chtype test = attr & (chtype) (~A_ALTCHARSET); if (arrow) mvprintw(row, 5, "-->"); mvprintw(row, 8, "%s mode:", name); mvprintw(row, 24, "|"); if (skip) printw("%*s", skip, " "); /* * Just for testing, write text using the alternate character set one * character at a time (to pass its rendition directly), and use the * string operation for the other attributes. */ if (attr & A_ALTCHARSET) { const char *s;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -