📄 window.c
字号:
w->curx = 0; for (y = w->cury + 1; y <= w->y2 - w->y1; y++) { w->cury = y; _wclreol(w); } w->curx = ocurx; w->cury = ocury; if (_wclreol(w) && w->direct) _gotoxy(w->x1 + w->curx, w->y1 + w->cury); if (dirflush && w->direct) wflush();}/* * Clear to begin of screen. */void wclrbos(WIN *w){ int ocurx, ocury; int y; ocurx = w->curx; ocury = w->cury; w->curx = 0; for (y = 0; y < ocury; y++) { w->cury = y; _wclreol(w); } w->curx = ocurx; w->cury = ocury; wclrbol(w);}/* * Clear a window. */void winclr(WIN *w){ int y; int olddir = w->direct; ELM *e, *f; int i; int m; /* If this window has history, save the image. */ if (w->histbuf) { /* MARK updated 02/17/95 - Scan backwards from the bottom of the */ /* window for the first non-empty line. We should save all other */ /* blank lines inside screen, since some nice BBS ANSI menus */ /* contains them for cosmetic purposes or as separators. */ for (m = w->y2; m >= w->y1; m--) { /* Start of this line in the global map. */ e = gmap + m * COLS + w->x1; /* Quick check to see if line is empty. */ for (i = 0; i < w->xs; i++) if (e[i].value != ' ') break; if (i != w->xs) break; /* Non empty line */ } /* Copy window into history buffer line-by-line. */ for (y = w->y1; y <= m; y++) { /* Start of this line in the global map. */ e = gmap + y * COLS + w->x1; /* Now copy this line. */ f = w->histbuf + (w->xs * w->histline); /* History buffer */ memcpy((char *)f, (char *)e, w->xs * sizeof(ELM)); w->histline++; if (w->histline >= w->histlines) w->histline = 0; } } _setattr(w->attr, w->color); w->curx = 0; if (CL && w->y1 == 0 && w->y2 == LINES-1 && w->x1 == 0 && w->x2 == COLS-1) { w->direct = 0; curx = 0; cury = 0; outstr(CL); } for (y = w->ys - 1; y >= 0; y--) { w->cury = y; _wclreol(w); } w->direct = olddir; _gotoxy(w->x1, w->y1); if (dirflush) wflush();}/* ==== Insert / Delete functions ==== */void winsline(WIN *w){ int osy1, osy2; osy1 = w->sy1; osy2 = w->sy2; w->sy1 = w->y1 + w->cury; w->sy2 = w->y2; if (w->sy1 < osy1) w->sy1 = osy1; if (w->sy2 > osy2) w->sy2 = osy2; wscroll(w, S_DOWN); w->sy1 = osy1; w->sy2 = osy2;}void wdelline(WIN *w){ int osy1, osy2; int ocury; ocury = w->cury; osy1 = w->sy1; osy2 = w->sy2; w->sy1 = w->y1 + w->cury; w->sy2 = w->y2; if (w->sy1 < osy1) w->sy1 = osy1; if (w->sy2 > osy2) w->sy2 = osy2; _intern = 1; wscroll(w, S_UP); _intern = 0; wlocate(w, 0, ocury); w->sy1 = osy1; w->sy2 = osy2;}/* * Insert a space at cursor position. */void winschar2(WIN *w, wchar_t c, int move){ int y; int x; int doit = 1; ELM *buf, *e; int len, odir; int oldx;#ifdef SMOOTH curwin = w;#endif /* See if we need to insert. */ if (c == 0 || wcschr(L"\r\n\t\b\007", c) || w->curx >= w->xs - 1) { wputc(w, c); return; } odir = w->direct; if (w->xs == COLS && IC != NULL) { /* We can use the insert character capability. */ if (w->direct) outstr(IC); /* No need to draw the character if it's a space. */ if (c == ' ') w->direct = 0; /* We don't need to draw the new line at all. */ doit = 0; } /* Get the rest of line into buffer */ y = w->y1 + w->cury; x = w->x1 + w->curx; oldx = w->curx; len = w->xs - w->curx; buf = malloc(sizeof(ELM) * len); if (!buf) return; /* Umm... */ memcpy(buf, gmap + COLS * y + x, sizeof(ELM) * len); /* Now, put the new character on screen. */ wputc(w, c); if (!move) w->curx = oldx; /* Write buffer to screen */ e = buf; for (++x; x <= w->x2; x++) { _write(e->value, doit && w->direct, x, y, e->attr, e->color); e++; } free(buf); w->direct = odir; wlocate(w, w->curx, w->cury);}void winschar(WIN *w){ winschar2(w, ' ', 0);}/* * Delete character under the cursor. */void wdelchar(WIN *w){ int x, y; int doit = 1; ELM *e;#ifdef SMOOTH curwin = w;#endif x = w->x1 + w->curx; y = w->y1 + w->cury; if (w->direct && w->xs == COLS && DC != NULL) { /*_gotoxy(x - 1, y);*/ _gotoxy(x, y); outstr(DC); doit = 0; } e = gmap + y * COLS + x + 1; for (; x < w->x2; x++) { _write(e->value, doit && w->direct, x, y, e->attr, e->color); e++; } _write(' ', doit && w->direct, x, y, w->attr, w->color); wlocate(w, w->curx, w->cury);}/* ============= Support: edit a line on the screen. ============ *//* Redraw the line we are editting. */static void lredraw(WIN *w, int x, int y, wchar_t *s, int len){ int i, f; i = 0; wlocate(w, x, y); for (f = 0; f < len; f++) { if (s[f] == 0) i++; wputc(w, i ? ' ' : s[f]); }}#if MAC_LEN > 256# define BUFLEN MAC_LEN#else# define BUFLEN 256#endif/* wgetwcs - edit one line in a window. */int wgetwcs(WIN *w, wchar_t *s, int linelen, int maxlen){ int c; int idx; int offs = 0; int f, st = 0, i; wchar_t buf[BUFLEN]; int quit = 0; int once = 1; int x, y, r; int direct = dirflush; int delete = 1; x = w->curx; y = w->cury; i = w->xs - x; if (linelen >= i - 1) linelen = i - 1; /* We assume the line has already been drawn on the screen. */ if ((idx = wcslen(s)) > linelen) idx = linelen; wcsncpy(buf, s, sizeof(buf) / sizeof(*buf)); wlocate(w, x + idx, y); dirflush = 0; wflush(); while (!quit) { if (once) { c = K_END; once--; } else { c = wxgetch(); if (c > 255 || c == K_BS || c == K_DEL) delete = 0; } switch(c) { case '\r': case '\n': st = 0; quit = 1; break; case K_ESC: /* Exit without changing. */ wlocate(w, x, y); lredraw(w, x, y, s, linelen); wflush(); st = -1; quit = 1; break; case K_HOME: /* Home */ r = offs > 0; offs = 0; idx = 0; if (r) lredraw(w, x, y, buf, linelen); wlocate(w, x, y); wflush(); break; case K_END: /* End of line. */ idx = wcslen(buf); r = 0; while (idx - offs > linelen) { r = 1; offs += 4; } if (r) lredraw(w, x, y, buf + offs, linelen); wlocate(w, x + idx - offs, y); wflush(); break; case K_LT: /* Cursor left. */ case K_BS: /* Backspace is first left, then DEL. */ if (idx == 0) break; idx--; if (idx < offs) { offs -= 4; /*if (c == K_LT) FIXME? */ lredraw(w, x, y, buf + offs, linelen); } if (c == K_LT) { wlocate(w, x + idx - offs, y); wflush(); break; } /*FALLTHRU*/ case K_DEL: /* Delete character under cursor. */ if (buf[idx] == 0) break; for (f = idx; buf[f]; f++) buf[f] = buf[f+1]; lredraw(w, x + idx - offs, y, buf + idx, linelen - (idx - offs)); wlocate(w, x + idx - offs, y); wflush(); break; case K_RT: if (buf[idx] == 0) break; idx++; if (idx - offs > linelen) { offs += 4; lredraw(w, x, y, buf + offs, linelen); } wlocate(w, x + idx - offs, y); wflush(); break; default: /* If delete == 1, delete the buffer. */ if (delete) { if ((i = wcslen(buf)) > linelen) i = linelen; buf[0] = 0; idx = 0; offs = 0; wlocate(w, x, y); for (f = 0; f < i; f++) wputc(w, ' '); delete = 0; } /* Insert character at cursor position. */ if (c < 32 || c > 255) break; f = wcslen(buf) + 2; if (f >= maxlen) break; while (f > idx) { buf[f] = buf[f-1]; f--; } buf[idx] = c; if (idx - offs >= linelen) { offs += 4; lredraw(w, x, y, buf + offs, linelen); } else lredraw(w, x + idx - offs, y, buf + idx, linelen - (idx - offs)); idx++; wlocate(w, x + idx - offs, y); wflush(); break; } } if (st == 0) wcscpy(s, buf); dirflush = direct; return st;}/* wgets - edit one line in a window. */int wgets(WIN *w, char *s, int linelen, int maxlen){ int st; wchar_t buf[BUFLEN]; size_t i; char *sptr; sptr = s; for (i = 0; *sptr != 0 && i < sizeof (buf) - 1; i++) sptr += one_mbtowc(buf + i, sptr, MB_LEN_MAX); buf[i] = 0; st = wgetwcs(w, buf, linelen, maxlen); if (st == 0) { sptr = s; for (i = 0; buf[i] != 0; i++) { char tmp[MB_LEN_MAX]; size_t l; /* This truncates data; too bad */ l = one_wctomb(tmp, buf[i]); if (sptr + l >= s + maxlen) break; memcpy(sptr, tmp, l); sptr += l; } *sptr = 0; } return st;}/* ==== Initialization code ==== */static char tbuf[1024];static char cbuf[2048];/* Map AC characters. */static int acmap(int c){ const char *p; for (p = AC; *p; p += 2) if (*p == c) return *++p; return '.';}/* * Initialize the window system */#ifdef BBS/* Code for the BBS system.. */int win_init(char *term, int lines){ int fg = WHITE; int bg = BLACK; int attr = XA_NORMAL;#else/* Code for other applications (minicom!) */int win_init(int fg, int bg, int attr){ char *term;#endif static WIN _stdwin; int f, olduseattr; if (w_init) return 0;#ifndef BBS if ((term = getenv("TERM")) == NULL) { fprintf(stderr, _("Environment variable TERM not set\n")); return -1; }#endif switch ((f = tgetent(cbuf, term))) { case 0: fprintf(stderr, _("No termcap entry for %s\n"), term); return -1 ; case -1: fprintf(stderr, _("No termcap database present!\n")); return -1 ; default: break; } _tptr = tbuf; if ((CM = tgetstr("cm", &_tptr)) == NULL) { fprintf(stderr, _("No cursor motion capability (cm)\n")); return -1; } LINES = COLS = 0; getrowcols(&LINES, &COLS);#ifdef BBS LINES = lines;#endif if (LINES == 0 && (LINES = tgetnum("li")) <= 0) { fprintf(stderr, _("Number of terminal lines unknown\n")); return -1; } if (COLS == 0 && (COLS = tgetnum("co")) <= 0) { fprintf(stderr, _("Number of terminal columns unknown\n")); return -1; } /* Terminal Capabilities */ ME = tgetstr("me", &_tptr); SE = tgetstr("se", &_tptr); UE = tgetstr("ue", &_tptr); AS = tgetstr("as", &_tptr); AE = tgetstr("ae", &_tptr); MB = tgetstr("mb", &_tptr); MD = tgetstr("md", &_tptr); MR = tgetstr("mr", &_tptr); SO = tgetstr("so", &_tptr); US = tgetstr("us", &_tptr); CE = tgetstr("ce", &_tptr); Al = tgetstr("al", &_tptr); Dl = tgetstr("dl", &_tptr); AL = tgetstr("AL", &_tptr); DL = tgetstr("DL", &_tptr); CS = tgetstr("cs", &_tptr); SF = tgetstr("sf", &_tptr); SR = tgetstr("sr", &_tptr); VB = tgetstr("vb", &_tptr); BL = tgetstr("bl", &_tptr); VE = tgetstr("ve", &_tptr); VI = tgetstr("vi", &_tptr); IS = tgetstr("is", &_tptr); RS = tgetstr("rs", &_tptr); KS = tgetstr("ks", &_tptr); KE = tgetstr("ke", &_tptr); CD = tgetstr("cd", &_tptr); CL = tgetstr("cl", &_tptr); IC = tgetstr("ic", &_tptr); DC = tgetstr("dc", &_tptr); BC = tgetstr("bc", &_tptr); CR = tgetstr("cr", &_tptr); NL = tgetstr("nl", &_tptr); AC = tgetstr("ac", &_tptr); EA = tgetstr("eA", &_tptr);#ifdef ST_LINE TS = tgetstr("ts", &_tptr); FS = tgetstr("fs", &_tptr); DS = tgetstr("ds", &_tptr);#endif if (MR == NULL) MR = SO; /* Try standout */ if (MR == NULL) MR = US; /* Try underline */ if (MR == NULL) MR = MD; /* Try bold */ if (SF == NULL) SF = "\n"; if (AC == NULL || *AC == 0) AC = def_ac; /* Standard vt100 mappings. */ /* cr and nl are often not defined but result in great optimization. * I only hope that minicom does not break on terminals where this * really does not work.. */ if (CR == NULL) CR = "\r"; if (NL == NULL) NL = "\n";#ifdef ST_LINE /* See if we can use the status line. */ if (!tgetflag("hs") || !tgetflag("es") || !TS || !FS) use_status = 0;#else use_status = 0;#endif if (IS != NULL) outstr(IS); /* Initialization string */ /* Reset attributes */ olduseattr = useattr; useattr = 1; _setattr(XA_NORMAL, COLATTR(WHITE, BLACK)); useattr = olduseattr; /* No reverse? don't use attributes at all. */ if (MR == NULL) useattr = 0; /* If we have the "ug" flag, don't allow attributes to be displayed. */ if (tgetnum("ug") > 0) useattr = 0; _has_am = tgetflag("am"); _mv_standout = tgetflag("ms"); if (tgetflag("bs")) { if (BC == NULL) BC = "\b"; } else BC = NULL; /* Special IBM box-drawing characters */ D_UL = 201; D_HOR = 205; D_UR = 187; D_LL = 200; D_VER = 186; D_LR = 188; S_UL = 218; S_HOR = 240; S_UR = 191; S_LL = 192; S_VER = 179; S_LR = 217; if (AS != NULL && !screen_ibmpc) { /* Try to find AC mappings. */ D_UL = S_UL = acmap('l'); D_HOR = S_HOR = acmap('q'); D_UR = S_UR = acmap('k'); D_LL = S_LL = acmap('m'); D_VER = S_VER = acmap('x'); D_LR = S_LR = acmap('j'); } if (screen_iso) { /* Try to find AC mappings. */ D_UL = S_UL = '+'; D_HOR = S_HOR = '-'; D_UR = S_UR = '+'; D_LL = S_LL = '+'; D_VER = S_VER = '|'; D_LR = S_LR = '+'; } /* Memory for global map */ if ((gmap = malloc(sizeof(ELM) * (LINES + 1) * COLS)) == NULL) { fprintf(stderr, "Not enough memory\n"); return -1; }; _buffend = _bufstart + BUFFERSIZE; /* Initialize stdwin */ stdwin = &_stdwin; stdwin->wrap = 1; stdwin->cursor = CNORMAL; stdwin->autocr = 1; stdwin->doscroll = 1; stdwin->x1 = 0; stdwin->sy1 = stdwin->y1 = 0; stdwin->x2 = COLS - 1; stdwin->sy2 = stdwin->y2 = LINES - 1; stdwin->xs = COLS; stdwin->ys = LINES; stdwin->attr = attr; stdwin->color = COLATTR(fg, bg); stdwin->direct = 1; stdwin->histbuf = NULL; if (EA != NULL) outstr(EA); /* Graphics init. */ if (KS != NULL) outstr(KS); /* Keypad mode */ setcbreak(1); /* Cbreak, no echo */ winclr(stdwin); w_init = 1; return 0;}void win_end(void){ if (gmap == NULL || w_init == 0) return; setcbreak(0); /* Reset */ stdwin->attr = XA_NORMAL; stdwin->color = COLATTR(WHITE, BLACK); _setattr(stdwin->attr, stdwin->color); winclr(stdwin);#ifdef ST_LINE if (DS) outstr(DS);#endif wcursor(stdwin, CNORMAL); if (KE != NULL) outstr(KE); if (RS != NULL) outstr(RS); else if (IS != NULL) outstr(IS); wflush(); free(gmap); gmap = NULL; stdwin = NULL; w_init = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -