📄 ncurses.c
字号:
}, { "^F = scroll forward", 0 }, { "^B = scroll backward", 0 }, { "^K = keypad(%s)", 1 }, { "^S = scrollok(%s)", 2 }, { "^W = save window to file", 0 }, { "^R = restore window", 0 },#if HAVE_WRESIZE { "^X = resize", 0 },#endif { "^Q%s = exit", 3 } }; size_t n; int x; bool do_keypad = HaveKeypad(curp); bool do_scroll = HaveScroll(curp); char buf[BUFSIZ]; move(LINES - 4, 0); for (n = 0; n < SIZEOF(legend); n++) { switch (legend[n].code) { default: strcpy(buf, legend[n].msg); break; case 1: sprintf(buf, legend[n].msg, do_keypad ? "yes" : "no"); break; case 2: sprintf(buf, legend[n].msg, do_scroll ? "yes" : "no"); break; case 3: sprintf(buf, legend[n].msg, do_keypad ? "/ESC" : ""); break; } x = getcurx(stdscr); addstr((COLS < (x + 3 + (int) strlen(buf))) ? "\n" : (n ? ", " : "")); addstr(buf); } clrtoeol();}static voidtransient(FRAME * curp, NCURSES_CONST char *msg){ newwin_legend(curp); if (msg) { mvaddstr(LINES - 1, 0, msg); refresh(); napms(1000); } move(LINES - 1, 0); printw("%s characters are echoed, window should %sscroll.", HaveKeypad(curp) ? "Non-arrow" : "All other", HaveScroll(curp) ? "" : "not "); clrtoeol();}static voidnewwin_report(FRAME * curp)/* report on the cursor's current position, then restore it */{ WINDOW *win = (curp != 0) ? curp->wind : stdscr; int y, x; if (win != stdscr) transient(curp, (char *) 0); getyx(win, y, x); move(LINES - 1, COLS - 17); printw("Y = %2d X = %2d", y, x); if (win != stdscr) refresh(); else wmove(win, y, x);}static pair *selectcell(int uli, int ulj, int lri, int lrj)/* arrows keys move cursor, return location at current on non-arrow key */{ static pair res; /* result cell */ int si = lri - uli + 1; /* depth of the select area */ int sj = lrj - ulj + 1; /* width of the select area */ int i = 0, j = 0; /* offsets into the select area */ res.y = uli; res.x = ulj; for (;;) { move(uli + i, ulj + j); newwin_report((FRAME *) 0); switch (Getchar()) { case KEY_UP: i += si - 1; break; case KEY_DOWN: i++; break; case KEY_LEFT: j += sj - 1; break; case KEY_RIGHT: j++; break; case QUIT: case ESCAPE: return ((pair *) 0);#ifdef NCURSES_MOUSE_VERSION case KEY_MOUSE: { MEVENT event; getmouse(&event); if (event.y > uli && event.x > ulj) { i = event.y - uli; j = event.x - ulj; } else { beep(); break; } } /* FALLTHRU */#endif default: res.y = uli + i; res.x = ulj + j; return (&res); } i %= si; j %= sj; }}static voidouterbox(pair ul, pair lr, bool onoff)/* draw or erase a box *outside* the given pair of corners */{ mvaddch(ul.y - 1, lr.x - 1, onoff ? ACS_ULCORNER : ' '); mvaddch(ul.y - 1, lr.x + 1, onoff ? ACS_URCORNER : ' '); mvaddch(lr.y + 1, lr.x + 1, onoff ? ACS_LRCORNER : ' '); mvaddch(lr.y + 1, ul.x - 1, onoff ? ACS_LLCORNER : ' '); move(ul.y - 1, ul.x); hline(onoff ? ACS_HLINE : ' ', lr.x - ul.x + 1); move(ul.y, ul.x - 1); vline(onoff ? ACS_VLINE : ' ', lr.y - ul.y + 1); move(lr.y + 1, ul.x); hline(onoff ? ACS_HLINE : ' ', lr.x - ul.x + 1); move(ul.y, lr.x + 1); vline(onoff ? ACS_VLINE : ' ', lr.y - ul.y + 1);}static WINDOW *getwindow(void)/* Ask user for a window definition */{ WINDOW *rwindow; pair ul, lr, *tmp; move(0, 0); clrtoeol(); addstr("Use arrows to move cursor, anything else to mark corner 1"); refresh(); if ((tmp = selectcell(2, 1, LINES - BOTLINES - 2, COLS - 2)) == (pair *) 0) return ((WINDOW *) 0); memcpy(&ul, tmp, sizeof(pair)); mvaddch(ul.y - 1, ul.x - 1, ACS_ULCORNER); move(0, 0); clrtoeol(); addstr("Use arrows to move cursor, anything else to mark corner 2"); refresh(); if ((tmp = selectcell(ul.y, ul.x, LINES - BOTLINES - 2, COLS - 2)) == (pair *) 0) return ((WINDOW *) 0); memcpy(&lr, tmp, sizeof(pair)); rwindow = subwin(stdscr, lr.y - ul.y + 1, lr.x - ul.x + 1, ul.y, ul.x); outerbox(ul, lr, TRUE); refresh(); wrefresh(rwindow); move(0, 0); clrtoeol(); return (rwindow);}static voidnewwin_move(FRAME * curp, int dy, int dx){ WINDOW *win = (curp != 0) ? curp->wind : stdscr; int cur_y, cur_x; int max_y, max_x; getyx(win, cur_y, cur_x); getmaxyx(win, max_y, max_x); if ((cur_x += dx) < 0) cur_x = 0; else if (cur_x >= max_x) cur_x = max_x - 1; if ((cur_y += dy) < 0) cur_y = 0; else if (cur_y >= max_y) cur_y = max_y - 1; wmove(win, cur_y, cur_x);}static FRAME *delete_framed(FRAME * fp, bool showit){ FRAME *np; fp->last->next = fp->next; fp->next->last = fp->last; if (showit) { werase(fp->wind); wrefresh(fp->wind); } delwin(fp->wind); np = (fp == fp->next) ? 0 : fp->next; free(fp); return np;}static voidacs_and_scroll(void)/* Demonstrate windows */{ int c, i; FILE *fp; FRAME *current = (FRAME *) 0, *neww; WINDOW *usescr = stdscr;#define DUMPFILE "screendump"#ifdef NCURSES_MOUSE_VERSION mousemask(BUTTON1_CLICKED, (mmask_t *) 0);#endif c = CTRL('C'); raw(); do { transient((FRAME *) 0, (char *) 0); switch (c) { case CTRL('C'): neww = (FRAME *) calloc(1, sizeof(FRAME)); if ((neww->wind = getwindow()) == (WINDOW *) 0) goto breakout; if (current == 0) { /* First element, */ neww->next = neww; /* so point it at itself */ neww->last = neww; } else { neww->next = current->next; neww->last = current; neww->last->next = neww; neww->next->last = neww; } current = neww; /* SVr4 curses sets the keypad on all newly-created windows to * false. Someone reported that PDCurses makes new windows inherit * this flag. Remove the following 'keypad()' call to test this */ keypad(current->wind, TRUE); current->do_keypad = HaveKeypad(current); current->do_scroll = HaveScroll(current); break; case CTRL('N'): /* go to next window */ if (current) current = current->next; break; case CTRL('P'): /* go to previous window */ if (current) current = current->last; break; case CTRL('F'): /* scroll current window forward */ if (current) wscrl(current->wind, 1); break; case CTRL('B'): /* scroll current window backwards */ if (current) wscrl(current->wind, -1); break; case CTRL('K'): /* toggle keypad mode for current */ if (current) { current->do_keypad = !current->do_keypad; keypad(current->wind, current->do_keypad); } break; case CTRL('S'): if (current) { current->do_scroll = !current->do_scroll; scrollok(current->wind, current->do_scroll); } break; case CTRL('W'): /* save and delete window */ if (current == current->next) { transient(current, "Will not save/delete ONLY window"); break; } else if ((fp = fopen(DUMPFILE, "w")) == (FILE *) 0) { transient(current, "Can't open screen dump file"); } else { (void) putwin(current->wind, fp); (void) fclose(fp); current = delete_framed(current, TRUE); } break; case CTRL('R'): /* restore window */ if ((fp = fopen(DUMPFILE, "r")) == (FILE *) 0) { transient(current, "Can't open screen dump file"); } else { neww = (FRAME *) calloc(1, sizeof(FRAME)); neww->next = current->next; neww->last = current; neww->last->next = neww; neww->next->last = neww; neww->wind = getwin(fp); (void) fclose(fp); wrefresh(neww->wind); } break;#if HAVE_WRESIZE case CTRL('X'): /* resize window */ if (current) { pair *tmp, ul, lr; int mx, my; move(0, 0); clrtoeol(); addstr("Use arrows to move cursor, anything else to mark new corner"); refresh(); getbegyx(current->wind, ul.y, ul.x); tmp = selectcell(ul.y, ul.x, LINES - BOTLINES - 2, COLS - 2); if (tmp == (pair *) 0) { beep(); break; } getmaxyx(current->wind, lr.y, lr.x); lr.y += (ul.y - 1); lr.x += (ul.x - 1); outerbox(ul, lr, FALSE); wnoutrefresh(stdscr); /* strictly cosmetic hack for the test */ getmaxyx(current->wind, my, mx); if (my > tmp->y - ul.y) { getyx(current->wind, lr.y, lr.x); wmove(current->wind, tmp->y - ul.y + 1, 0); wclrtobot(current->wind); wmove(current->wind, lr.y, lr.x); } if (mx > tmp->x - ul.x) for (i = 0; i < my; i++) { wmove(current->wind, i, tmp->x - ul.x + 1); wclrtoeol(current->wind); } wnoutrefresh(current->wind); memcpy(&lr, tmp, sizeof(pair)); (void) wresize(current->wind, lr.y - ul.y + 0, lr.x - ul.x + 0); getbegyx(current->wind, ul.y, ul.x); getmaxyx(current->wind, lr.y, lr.x); lr.y += (ul.y - 1); lr.x += (ul.x - 1); outerbox(ul, lr, TRUE); wnoutrefresh(stdscr); wnoutrefresh(current->wind); move(0, 0); clrtoeol(); doupdate(); } break;#endif /* HAVE_WRESIZE */ case KEY_F(10): /* undocumented --- use this to test area clears */ selectcell(0, 0, LINES - 1, COLS - 1); clrtobot(); refresh(); break; case KEY_UP: newwin_move(current, -1, 0); break; case KEY_DOWN: newwin_move(current, 1, 0); break; case KEY_LEFT: newwin_move(current, 0, -1); break; case KEY_RIGHT: newwin_move(current, 0, 1); break; case KEY_BACKSPACE: /* FALLTHROUGH */ case KEY_DC: { int y, x; getyx(current->wind, y, x); if (--x < 0) { if (--y < 0) break; x = getmaxx(current->wind) - 1; } mvwdelch(current->wind, y, x); } break; case '\r': c = '\n'; /* FALLTHROUGH */ default: if (current) waddch(current->wind, (chtype) c); else beep(); break; } newwin_report(current); usescr = (current ? current->wind : stdscr); wrefresh(usescr); } while ((c = wGetchar(usescr)) != QUIT && !((c == ESCAPE) && (keypad_active(usescr))) && (c != ERR)); breakout: while (current != 0) current = delete_framed(current, FALSE); scrollok(stdscr, TRUE); /* reset to driver's default */#ifdef NCURSES_MOUSE_VERSION mousemask(0, (mmask_t *) 0);#endif noraw(); erase(); endwin();}/**************************************************************************** * * Panels tester * ****************************************************************************/#if USE_LIBPANELstatic unsigned long nap_msec = 1;static NCURSES_CONST char *mod[] ={ "test ", "TEST ", "(**) ", "*()* ", "<--> ", "LAST "};/*+------------------------------------------------------------------------- wait_a_while(msec)--------------------------------------------------------------------------*/static voidwait_a_while(unsigned long msec GCC_UNUSED){#if HAVE_NAPMS if (nap_msec == 1) wGetchar(stdscr); else napms(nap_msec);#else if (nap_msec == 1) wGetchar(stdscr); else if (msec > 1000L) sleep((int) msec / 1000L); else sleep(1);#endif} /* end of wait_a_while *//*+------------------------------------------------------------------------- saywhat(text)--------------------------------------------------------------------------*/static voidsaywhat(NCURSES_CONST char *text){ wmove(stdscr, LINES - 1, 0); wclrtoeol(stdscr); waddstr(stdscr, text);} /* end of saywhat *//*+------------------------------------------------------------------------- mkpanel(rows,cols,tly,tlx) - alloc a win and panel and associate them--------------------------------------------------------------------------*/static PANEL *mkpanel(int color, int rows, int cols, int tly, int tlx){ WINDOW *win; PANEL *pan = 0; if ((win = newwin(rows, cols, tly, tlx)) != 0) { if ((pan = new_panel(win)) == 0) { delwin(win); } else if (has_colors()) { int fg = (color == COLOR_BLUE) ? COLOR_WHITE : COLOR_BLACK; int bg = color; init_pair(color, fg, bg); wbkgdset(win, COLOR_PAIR(color) | ' '); } else { wbkgdset(win, A_BOLD | ' '); } } return pan;} /* end of mkpanel *//*+------------------------------------------------------------------------- rmpanel(pan)--------------------------------------------------------------------------*/static voidrmpanel(PANEL * pan){ WINDOW *win = panel_window(pan); del_panel(pan); delwin(win);} /* end of rmpanel *//*+------------------------------------------------------------------------- pflush()------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -