📄 window.c
字号:
int x, y; ELM *e;#ifdef SMOOTH curwin = NIL_WIN;#endif curattr = -1; curcolor = -1; (void) setcbreak(1); /* Cbreak, no echo */ if (KS != CNULL) outstr(KS); /* Keypad mode */ if (IS != CNULL) outstr(IS); /* Initialization string */ _gotoxy(0, 0); _cursor(ocursor); e = gmap; for(y = 0; y <LINES; y++) { for(x = 0; x < COLS; x++) { _write(e->value, -1, x, y, e->attr, e->color); e++; } } _gotoxy(oldx, oldy); wflush();}/* * Redraw the whole window. */void wredraw(w, newdirect)WIN *w;int newdirect;{ int minx, maxx, miny, maxy; register ELM *e; register 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; } _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; } _cursor(w->cursor); _gotoxy(w->x1 + w->curx, w->y1 + w->cury); wflush(); w->direct = newdirect;}/* * Clear to end of line, low level. */static int _wclreol(w)WIN *w;{ register x; register doit = 1; register 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, x, y, w->attr, w->color); return(doit); }/* * Scroll a window. */void wscroll(win, dir)WIN *win;int dir;{ register ELM *e, *f; register char *src, *dst; register int x, y; register 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 != CNULL && (dir == S_UP || SR != CNULL) && (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 != CNULL && SF != CNULL && SR != CNULL) || (Dl != CNULL && Al != CNULL))) { doit = 0; phys_scr = 1; _setattr(win->attr, win->color); if (CS != CNULL && SF != CNULL && SR != CNULL) { /* 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 HISTORY /* 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; }#endif /* 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 memmove((char *)dst, (char *)src, len);#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) (void) _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) (void) _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, x, y)WIN *win;int x, 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, c)WIN *win;int c;{ register mv = 0;#ifdef SMOOTH curwin = win;#endif switch(c) { case '\r': win->curx = 0; mv++; break; case '\n': win->cury++; if (win->autocr) 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; default: _write(c, win->direct, win->curx + win->x1, win->cury + win->y1, win->attr, win->color); if (++win->curx >= win->xs) { if (win->wrap) { win->curx = 0; win->cury++; } else { win->curx--; curx = 0; /* Force to move */ } mv++; } break; } if (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; if (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(w, y, e)WIN *w;int y;ELM *e;{ int x; for(x = w->x1; x < w->x2; x++) { _write(e->value, w->direct, x, y + w->y1, e->attr, e->color); e++; }}/* * Print a string in a window. */void wputs(win, s)WIN *win;register char *s;{ _intern = 1; while(*s) wputc(win, *s++); if (dirflush && win->direct) wflush(); _intern = 0;}/* * Print a formatted string in a window. * Should return stringlength - but who cares. *//*VARARGS1*/int wprintf(win, s, a1, a2, a3, a4, a5, a6, a7, a8)WIN *win;char *s, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;{ char buf[128]; char *t; t = buf; _intern = 1; sprintf(buf, s, a1, a2, a3, a4, a5, a6, a7, a8); while(*t) wputc(win, *t++); _intern = 0; if (dirflush && win->direct) wflush(); return(0);}/* * Sound a bell. */void wbell(){ if (VB != CNULL) outstr(VB); else (void) outchar('\007'); wflush();}/* * Set cursor type. */void wcursor(win, type)WIN *win;int type;{ win->cursor = type; if (win->direct) { _cursor(type); if (dirflush) wflush(); }}void wtitle(w, pos, s)WIN *w;int pos;char *s;{ int x;#ifdef SMOOTH curwin = NIL_WIN;#endif if (w->border == BNONE) return; if (pos == TLEFT) x = w->x1; if (pos == TRIGHT) x = w->x2 - strlen(s) - 1; if (pos == TMID) x = w->x1 + (w->xs - strlen(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) _write(*s++, 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(w, y, attr)WIN *w;int y;int attr;{ ELM *e; register 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 A_NORMAL & A_REVERSE. */ if (!useattr || MR == CNULL) { if (attr & A_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 == CNULL || _curstype == CNORMAL) && w->direct) _gotoxy(w->x1, y); if (w->direct) wflush();}/* * wselect - select one of many choices. */int wselect(x, y, choices, funlist, title, attr, fg, bg)int x, y;char **choices;void (**funlist)();char *title;int attr, fg, bg;{ char **a = choices; int len = 0; int count = 0; int cur = 0; int c; WIN *w; int high_on = A_REVERSE | attr; int high_off = attr; /* first count how many, and max. width. */ while(*a != CNULL) { count++; if (strlen(*a) > len) len = strlen(*a); a++; } if (title != CNULL && strlen(title) + 2 > len) len = strlen(title) + 2; if (attr & A_REVERSE) { high_on = attr & ~A_REVERSE; high_off = attr; } if ((w = wopen(x, y, x + len + 2, y + count - 1, BDOUBLE, attr, fg, bg, 0, 0, 0)) == (WIN *)0) return(-1); wcursor(w, CNONE); if (title != CNULL) 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 = getch()) != 27 && c != '\n' && c!= '\r' && c != ' ') { if (c == K_UP || c == K_DN || c == 'j' || c == 'k') 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; } if (c == K_UP || c == K_DN || c == 'j' || c == 'k') wcurbar(w, cur, high_on); } wcursor(w, CNORMAL); if (c == ' ' || c == 27) { wclose(w, 1); return(0); } if (funlist == NIL_FUNLIST || funlist[cur] == NIL_FUN) { wclose(w, 1); return(cur + 1); } (*funlist[cur])(); wcursor(w, CNONE); }}/* ==== Clearing functions ==== *//* * Clear entire line. */void wclrel(w)WIN *w;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -