📄 window.c
字号:
wflush();}/* * Redraw the whole window. */void wredraw(WIN *w, int newdirect){ int minx, maxx, miny, maxy; ELM *e; int x, y; int addcnt; minx = w->x1; maxx = w->x2; miny = w->y1; maxy = w->y2; addcnt = stdwin->xs - w->xs; if (w->border) { minx--; maxx++; miny--; maxy++; addcnt -= 2; } _gotoxy(minx, miny); _cursor(CNONE); e = gmap + (miny * stdwin->xs) + minx; for (y = miny; y <= maxy; y++) { for(x = minx; x <= maxx; x++) { _write(e->value, -1, x, y, e->attr, e->color); e++; } e += addcnt; } _gotoxy(w->x1 + w->curx, w->y1 + w->cury); _cursor(w->cursor); wflush(); w->direct = newdirect;}/* * Clear to end of line, low level. */static int _wclreol(WIN *w){ int x; int doit = 1; int y;#ifdef SMOOTH curwin = w;#endif y = w->cury + w->y1; if (w->direct && (w->x2 == COLS - 1) && CE) { _gotoxy(w->curx + w->x1, y); _setattr(w->attr, w->color); outstr(CE); doit = 0; } for (x = w->curx + w->x1; x <= w->x2; x++) { _write(' ', (w->direct && doit) ? 1 : 0, x, y, w->attr, w->color); } return doit;}/* * Scroll a window. */void wscroll(WIN *win, int dir){ ELM *e, *f; char *src, *dst; int x, y; int doit = 1; int ocurx, fs = 0, len; int phys_scr = 0;#ifdef SMOOTH curwin = win;#endif /* * If the window *is* the physical screen, we can scroll very simple. * This improves performance on slow screens (eg ATARI ST) dramatically. */ if (win->direct && SF != NULL && (dir == S_UP || SR != NULL) && (LINES == win->sy2 - win->sy1 + 1)) { doit = 0; phys_scr = 1; _setattr(win->attr, win->color); if (dir == S_UP) { _gotoxy(0, LINES - 1); outstr(SF); } else { _gotoxy(0, 0); outstr(SR); } } /* * If the window is as wide as the physical screen, we can * scroll it with insert/delete line (or set scroll region - vt100!) */ else if (win->direct && win->xs == COLS && ((CS != NULL && SF != NULL && SR != NULL) || (Dl != NULL && Al != NULL))) { doit = 0; phys_scr = 1; _setattr(win->attr, win->color); if (CS != NULL && SF != NULL && SR != NULL) { /* Scrolling Region */ /* If the scroll region we want to initialize already is as * big as the physical screen, we don't _have_ to * initialize it. */ if (win->sy2 == LINES - 1 && win->sy1 == 0) fs = 1; if (!fs) { outstr(tgoto(CS, win->sy2, win->sy1)); cury = 0; } if (dir == S_UP) { _gotoxy(0, win->sy2); outstr(SF); } else { _gotoxy(0, win->sy1); outstr(SR); } if (!fs) { outstr(tgoto(CS, LINES - 1, 0)); cury = 0; } _gotoxy(0, win->sy2); } else { /* Use insert/delete line */ if (dir == S_UP) { _gotoxy(0, win->sy1); outstr(Dl); _gotoxy(0, win->sy2); outstr(Al); } else { _gotoxy(0, win->sy2); outstr(Dl); _gotoxy(0, win->sy1); outstr(Al); } } } /* If a terminal has automatic margins, we can't write * to the lower right. After scrolling we have to restore * the non-visible character that is now visible. */ if (sflag && win->sy2 == (LINES - 1) && win->sy1 != win->sy2) { if (dir == S_UP) { _write(oldc.value, 1, COLS - 1, LINES - 2, oldc.attr, oldc.color); } sflag = 0; } ocurx = win->curx; /* If this window has a history buf, see if we want to use it. */ if (win->histbuf && dir == S_UP && win->sy2 == win->y2 && win->sy1 == win->y1) { /* Calculate screen buffer */ e = gmap + win->y1 * COLS + win->x1; /* Calculate history buffer */ f = win->histbuf + (win->xs * win->histline); /* Copy line from screen to history buffer */ memcpy((char *)f, (char *)e, win->xs * sizeof(ELM)); /* Postion the next line in the history buffer */ win->histline++; if (win->histline >= win->histlines) win->histline = 0; } /* If the window is screen-wide and has no border, there * is a much simpler & FASTER way of scrolling the memory image !! */ if (phys_scr) { len = (win->sy2 - win->sy1) * win->xs * sizeof(ELM); if (dir == S_UP) { dst = (char *)&gmap[0]; /* First line */ src = (char *)&gmap[win->xs]; /* Second line */ win->cury = win->sy2 - win->y1; } else { src = (char *)&gmap[0]; /* First line */ dst = (char *)&gmap[win->xs]; /* Second line */ win->cury = win->sy1 - win->y1; } /* memmove copies len bytes from src to dst, even if the * objects overlap. */ fflush(stdout);#ifdef _SYSV memcpy((char *)dst, (char *)src, len);#else# ifdef _BSD43 bcopy((char *)src, (char *)dst, len);# else memmove((char *)dst, (char *)src, len);# endif#endif } else { /* Now scroll the memory image. */ if (dir == S_UP) { for (y = win->sy1 + 1; y <= win->sy2; y++) { e = gmap + y * COLS + win->x1; for (x = win->x1; x <= win->x2; x++) { _write(e->value, win->direct && doit, x, y - 1, e->attr, e->color); e++; } } win->curx = 0; win->cury = win->sy2 - win->y1; if (doit) _wclreol(win); } else { for (y = win->sy2 - 1; y >= win->sy1; y--) { e = gmap + y * COLS + win->x1; for (x = win->x1; x <= win->x2; x++) { _write(e->value, win->direct && doit, x, y + 1, e->attr, e->color); e++; } } win->curx = 0; win->cury = win->sy1 - win->y1; if (doit) _wclreol(win); } } win->curx = ocurx; if (!doit) for (x = win->x1; x <= win->x2; x++) _write(' ', 0, x, win->y1 + win->cury, win->attr, win->color); if (!_intern && win->direct) _gotoxy(win->x1 + win->curx, win->y1 + win->cury); if (dirflush && !_intern && win->direct) wflush();}/* * Locate the cursor in a window. */void wlocate(WIN *win, int x, int y){ if (x < 0) x = 0; if (y < 0) y = 0; if (x >= win->xs) x = win->xs - 1; if (y >= win->ys) y = win->ys - 1; win->curx = x; win->cury = y; if (win->direct) _gotoxy(win->x1 + x, win->y1 + y); if (dirflush) wflush();}/* * Print a character in a window. */void wputc(WIN *win, wchar_t c){ int mv = 0;#ifdef SMOOTH curwin = win;#endif switch(c) { case '\r': win->curx = 0; mv++; break; case '\b': if (win->curx == 0) break; win->curx--; mv++; break; case '\007': wbell(); break; case '\t': do { wputc(win, ' '); /* Recursion! */ } while (win->curx % 8); break; case '\n': if (win->autocr) win->curx = 0; /*FALLTHRU*/ default: /* See if we need to scroll/move. (vt100 behaviour!) */ if (c == '\n' || (win->curx >= win->xs && win->wrap)) { if (c != '\n') win->curx = 0; win->cury++; mv++; if (win->cury == win->sy2 - win->y1 + 1) { if (win->doscroll) wscroll(win, S_UP); else win->cury = win->sy1 - win->y1; } if (win->cury >= win->ys) win->cury = win->ys - 1; } /* Now write the character. */ if (c != '\n') { if (!win->wrap && win->curx >= win->xs) c = '>'; _write(c, win->direct, win->curx + win->x1, win->cury + win->y1, win->attr, win->color); if (++win->curx >= win->xs && !win->wrap) { win->curx--; curx = 0; /* Force to move */ mv++; } } break; } if (mv && win->direct) _gotoxy(win->x1 + win->curx, win->y1 + win->cury); if (win->direct && dirflush && !_intern) wflush();}/* Draw one line in a window */void wdrawelm(WIN *w, int y, ELM *e){ int x; /* MARK updated 02/17/94 - Fixes bug, to do all 80 cols, not 79 cols */ for (x = w->x1; x <= w->x2; x++) { _write(e->value, w->direct, x, y + w->y1, e->attr, e->color); /*y + w->y1, XA_NORMAL, e->color);*/ e++; }}/* * fmg 8/20/97 * 'accumulate' one line of ELM's into a string * WHY: need this in search function to see if line contains search pattern */void wdrawelm_var(WIN *w, ELM *e, wchar_t *buf){ int x, c = 0; /* MARK updated 02/17/94 - Fixes bug, to do all 80 cols, not 79 cols */ for (x = w->x1; x <= w->x2; x++) { buf[c++] = e->value; e++; }}/* * fmg 8/20/97 * 'draw' one line of ELM's in a window INVERTED (text-mode-wise) * WHY: need this in search function to see if line contains search pattern */void wdrawelm_inverse(WIN *w, int y, ELM *e){ int x; /* MARK updated 02/17/94 - Fixes bug, to do all 80 cols, not 79 cols */ /* filipg 8/19/97: this will BOLD-up the line */ /* first position */ x = w->x1; _write(e->value, w->direct, x, y + w->y1, XA_NORMAL, e->color); e++; /* everything in the middle will be BLINK */ for (x = w->x1 + 1; x <= w->x2 - 1; x++) { _write(e->value, w->direct, x, y + w->y1, XA_BOLD, WHITE); e++; } /* last position */ x = w->x2; _write(e->value, w->direct, x, y + w->y1, XA_NORMAL, e->color);}/* * Print a string in a window. */void wputs(WIN *win, const char *s){ _intern = 1; while (*s) { wchar_t wc; s += one_mbtowc(&wc, s, MB_LEN_MAX); wputc(win, wc); } if (dirflush && win->direct) wflush(); _intern = 0;}/* * Print a formatted string in a window. * Should return stringlength - but who cares. */int wprintf(WIN *win, const char *fmt, ...){ char buf[160]; va_list va; va_start(va, fmt); vsnprintf(buf, sizeof(buf), fmt, va); va_end(va); wputs(win, buf); return 0;}/* * Sound a bell. */void wbell(void){ if (BL != NULL) outstr(BL); else if (VB != NULL) outstr(VB); else outchar('\007'); wflush();}/* * Set cursor type. */void wcursor(WIN *win, int type){ win->cursor = type; if (win->direct) { _cursor(type); if (dirflush) wflush(); }}void wtitle(WIN *w, int pos, const char *s){ int x = 0;#ifdef SMOOTH curwin = NULL;#endif if (w->border == BNONE) return; if (pos == TLEFT) x = w->x1; if (pos == TRIGHT) x = w->x2 - mbslen(s) - 1; if (pos == TMID) x = w->x1 + (w->xs - mbslen(s)) / 2 - 1; if (x < w->x1) x = w->x1; if (x < w->x2) _write('[', w->direct, x++, w->y1 - 1, w->attr, w->color); while (*s && x <= w->x2) { wchar_t wc; s += one_mbtowc(&wc, s, MB_LEN_MAX); _write(wc, w->direct, x++, w->y1 - 1, w->attr, w->color); } if (x <= w->x2) _write(']', w->direct, x++, w->y1 - 1, w->attr, w->color); if (w->direct) { _gotoxy(w->x1 + w->curx, w->y1 + w->cury); if (dirflush) wflush(); }}/* ==== Menu Functions ==== *//* * Change attributes of one line of a window. */void wcurbar(WIN *w, int y, int attr){ ELM *e; int x;#ifdef SMOOTH curwin = w;#endif y += w->y1; e = gmap + y * COLS + w->x1; /* If we can't do reverse, just put a '>' in front of * the line. We only support XA_NORMAL & XA_REVERSE. */ if (!useattr || MR == NULL) { if (attr & XA_REVERSE) x = '>'; else x = ' '; _write(x, w->direct, w->x1, y, attr, e->color); } else { for (x = w->x1; x <= w->x2; x++) { _write(e->value, w->direct, x, y, attr, e->color); e++; } } if ((VI == NULL || _curstype == CNORMAL) && w->direct) _gotoxy(w->x1, y); if (w->direct) wflush();}/* * wselect - select one of many choices. */int wselect(int x, int y, const char *const *choices, void (*const *funlist)(void), const char *title, int attr, int fg, int bg){ const char *const *a = choices; unsigned int len = 0; int count = 0; int cur = 0; int c; WIN *w; int high_on = XA_REVERSE | attr; int high_off = attr; /* first count how many, and max. width. */ while (*a != NULL) { count++; if (mbslen(_(*a)) > len) len = mbslen(_(*a)); a++; } if (title != NULL && mbslen(title) + 2 > len) len = mbslen(title) + 2; if (attr & XA_REVERSE) { high_on = attr & ~XA_REVERSE; high_off = attr; } if ((w = wopen(x, y, x + len + 2, y + count - 1, BDOUBLE, attr, fg, bg, 0, 0, 0)) == NULL) return -1; wcursor(w, CNONE); if (title != NULL) wtitle(w, TMID, title); for (c = 0; c < count; c++) wprintf(w, " %s%s", _(choices[c]), c == count - 1 ? "" : "\n"); wcurbar(w, cur, high_on); wredraw(w, 1); while (1) { while ((c = wxgetch()) != 27 && c != '\n' && c!= '\r' && c != ' ') { if (c == K_UP || c == K_DN || c == 'j' || c == 'k' || c == K_HOME || c == K_END) wcurbar(w, cur, high_off); switch (c) { case K_UP: case 'k': cur--; if (cur < 0) cur = count - 1; break; case K_DN: case 'j': cur++; if (cur >= count) cur = 0; break; case K_HOME: cur = 0; break; case K_END: cur = count - 1; break; } if (c == K_UP || c == K_DN || c == 'j' || c == 'k' || c == K_HOME || c == K_END) wcurbar(w, cur, high_on); } wcursor(w, CNORMAL); if (c == ' ' || c == 27) { wclose(w, 1); return 0; } if (funlist == NULL || funlist[cur] == NULL) { wclose(w, 1); return cur + 1; } (*funlist[cur])(); wcursor(w, CNONE); }}/* ==== Clearing functions ==== *//* * Clear characters. */void wclrch(WIN *w, int n){ int x, y, x_end;#ifdef SMOOTH curwin = w;#endif y = w->cury + w->y1; x = x_end = w->curx + w->x1; x_end += n - 1; if (x_end > w->x2) x_end = w->x2; if (w->direct) _gotoxy(w->x1, y); for ( ; x <= x_end; x++) _write(' ', w->direct, x, y, w->attr, w->color); if (w->direct && dirflush) wflush();}/* * Clear entire line. */void wclrel(WIN *w){ int ocurx = w->curx; w->curx = 0; _wclreol(w); w->curx = ocurx; wlocate(w, ocurx, w->cury);}/* * Clear to end of line. */void wclreol(WIN *w){ if (_wclreol(w) && w->direct) _gotoxy(w->x1 + w->curx, w->y1 + w->cury); if (dirflush) wflush();}/* * Clear to begin of line */void wclrbol(WIN *w){ int x, y, n;#ifdef SMOOTH curwin = w;#endif y = w->cury + w->y1; if (w->direct) _gotoxy(w->x1, y); n = w->x1 + w->curx; if (n > w->x2) n = w->x2; for (x = w->x1; x <= n; x++) _write(' ', w->direct, x, y, w->attr, w->color); if (w->direct) { _gotoxy(n, y); if (dirflush) wflush(); }}/* * Clear to end of screen */void wclreos(WIN *w){ int y; int ocurx, ocury; ocurx = w->curx; ocury = w->cury;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -