📄 wmh.c
字号:
if (c == ERASE) { if (bp <= ip) continue; bp--; break; } if (c == KILL) { if (bp <= ip) continue; bp = ip; break; } if (c == WERASC) { if (bp <= ip) continue; do { bp--; } while (isspace (*bp) && bp > ip); if (bp > ip) { do { bp--; } while (!isspace (*bp) && bp > buffer); if (isspace (*bp)) bp++; } break; } if (c < ' ' || c >= '\177') continue; *bp++ = c; break; } *bp = NULL; Redisplay (w, 0); break; case VT_MOUSE: switch (vt -> u.mouse.buttons & (VT_MOUSE_LEFT | VT_MOUSE_MIDDLE | VT_MOUSE_RIGHT)) { case VT_MOUSE_LEFT: DisplayStatus (w -> w_fd, "use middle or right button"); break;#define WPOP "WMH\0Advance\0Burst\0Exit\0EOF\0" case VT_MOUSE_MIDDLE: SetPosition (w -> w_fd, vt -> u.mouse.x, vt -> u.mouse.y); switch (DisplayPopUp (w -> w_fd, WPOP)) { case 1: /* Advance */ do_advance: ; (void) strcpy (buffer, "advance"); return DONE; case 2: /* Burst */ (void) strcpy (buffer, "burst"); return DONE; case 3: /* Exit */ (void) strcpy (buffer, "exit"); return DONE; case 4: /* EOF */ return OK; default: /* failed or none taken */ break; } break;#undef WPOP case VT_MOUSE_RIGHT: goto do_advance; } break; case VT_EOF: adios (NULLCP, "end-of-file on window");/* NOTREACHED */ default: DisplayStatus (w -> w_fd, "unknown VT sequence"); break; }}/* */static int WINputc (w, c)register WINDOW *w;register char c;{ register int i; register char *cp; register struct line *lp; switch (c) { default: if (!isascii (c)) { if (WINputc (w, 'M') == NOTOK || WINputc (w, '-') == NOTOK) return NOTOK; c = toascii (c); } else if (c < ' ' || c == '\177') { if (WINputc (w, '^') == NOTOK) return NOTOK; c ^= 0100; } break; case '\t': for (i = 8 - (w -> w_bufpos & 0x07); i > 0; i--) if (WINputc (w, ' ') == NOTOK) return NOTOK; return OK; case '\b': if (w -> w_bufpos > 0) w -> w_bufpos--; return OK; case '\n': break; } if (c != '\n') { w -> w_buffer[w -> w_bufpos++] = c; return OK; } w -> w_buffer[w -> w_bufpos] = NULL; w -> w_bufpos = 0; if ((lp = (struct line *) calloc (1, sizeof *lp)) == NULL) adios (NULLCP, "unable to allocate line storage"); lp -> l_no = (w -> w_tail ? w -> w_tail -> l_no : 0) + 1; lp -> l_buf = getcpy (w -> w_buffer); for (cp = lp -> l_buf + strlen (lp -> l_buf) - 1; cp >= lp -> l_buf; cp--) if (isspace (*cp)) *cp = NULL; else break; if (w -> w_head == NULL) w -> w_head = lp; if (w -> w_top == NULL) w -> w_top = lp; if (w -> w_bottom == NULL) w -> w_bottom = lp; if (w -> w_tail) w -> w_tail -> l_next = lp; lp -> l_prev = w -> w_tail; w -> w_tail = lp; return DONE;}/* */#define PSLOP 2static char mylineno[5];static bool cancel[] = { 1 };static struct choice mychoices[] = { LABEL, "cancel", VT_White };static struct question myquestions[] = { STRING, "Line", SZ (mylineno), (struct choice *) 0, TOGGLE, "", SZ (mychoices), mychoices};static struct menu mymenu = { "Goto", SZ (myquestions), myquestions };static int *myanswers[] = { (int *) mylineno, (int *) cancel };static WINless (w)register WINDOW *w;{ int clear, pos, forw, refresh; struct vtseq vts; register struct vtseq *vt = &vts; if (w -> w_fd == NOTOK) { if (w -> w_head) DisplayStatus (dfd, w -> w_top -> l_buf); else RemoveStatus (dfd); return; } if (ChangeWindowDepth (dfd, w -> w_wd, 0) == NOTOK) adios ("failed", "ChangeWindowDepth"); Redisplay (w, 0); if (w -> w_bottom == w -> w_tail) return; if (w -> w_eb == NULL) adios (NULLCP, "internal error--no elevator bar"); for (clear = refresh = 0, forw = 1;;) { if (clear) { RemoveStatus (w -> w_fd); clear = 0; } if (refresh) { Redisplay (w, 0); refresh = 0; } switch (getvtseq (w -> w_fd, vt)) { case VT_HARDKEY: case VT_ASCII: DisplayStatus (w -> w_fd, "use the mouse"); clear++; break; case VT_MOUSE: switch (vt -> u.mouse.buttons & (VT_MOUSE_LEFT | VT_MOUSE_MIDDLE | VT_MOUSE_RIGHT)) { case VT_MOUSE_LEFT: if ((pos = vt -> u.mouse.x) < EWIDTH) { pos = w -> w_ebloc = DoElevatorBar (w -> w_eb, pos, vt -> u.mouse.y); refresh = WINgoto (w, ((pos * (w -> w_tail -> l_no - w -> w_head -> l_no)) / EB_MAX) + w -> w_head -> l_no); } break;#define WPOP "Paging\0Next\0Prev\0Left\0Right\0First\0Last\0Goto ...\0Exit\0" case VT_MOUSE_MIDDLE: SetPosition (w -> w_fd, vt -> u.mouse.x, vt -> u.mouse.y); switch (DisplayPopUp (w -> w_fd, WPOP)) { case 1: /* Next */ do_next_page: ; if (w -> w_bottom == w -> w_tail) forw = 0; refresh = WINgoto (w, w -> w_bottom -> l_no + 1 - PSLOP); break; case 2: /* Prev */ do_prev_page: ; if (w -> w_top == w -> w_head) forw = 1; refresh = WINgoto (w, w -> w_top -> l_no - w -> w_height + PSLOP); break; case 3: /* Left */ case 4: /* Right */ DisplayStatus (w -> w_fd, "not yet"); clear++; break; case 5: /* First */ forw = 1; refresh = WINgoto (w, w -> w_head -> l_no); break; case 6: /* Last */ forw = 0; refresh = WINgoto (w, w -> w_tail -> l_no - w -> w_height + 1); break; case 7: /* Goto ... */ (void) sprintf (mylineno, "%d", w -> w_top -> l_no); cancel[0] = 0; if (PresentMenu (&mymenu, myanswers) || cancel[0]) break; if (sscanf (mylineno, "%d", &pos) != 1) { DisplayStatus (w -> w_fd, "bad format"); clear++; break; } if (pos < w -> w_head -> l_no || pos > w -> w_tail -> l_no) { DisplayStatus (w -> w_fd, "no such line"); clear++; break; } refresh = WINgoto (w, pos); break; case 8: /* Exit */ return; default: /* failed or none taken */ break; } break;#undef WPOP case VT_MOUSE_RIGHT: if (forw) { if (w -> w_bottom == w -> w_tail) return; else goto do_next_page; } else goto do_prev_page; } break; case VT_EOF: adios (NULLCP, "end-of-file on window");/* NOTREACHED */ default: DisplayStatus (w -> w_fd, "unknown VT sequence"); clear++; break; } }}/* */static int WINgoto (w, n)register WINDOW *w;register int n;{ register int i, j; register struct line *lp; if (n > (i = w -> w_tail -> l_no - w -> w_height + 1)) n = i; if (n < w -> w_head -> l_no) n = w -> w_head -> l_no; if ((i = n - (lp = w -> w_head) -> l_no) > (j = abs (n - w -> w_top -> l_no))) i = j, lp = w -> w_top; if (i > (j = abs (w -> w_tail -> l_no - n))) i = j, lp = w -> w_tail; if (n >= lp -> l_no) { for (; lp; lp = lp -> l_next) if (lp -> l_no == n) break; } else { for (; lp; lp = lp -> l_prev) if (lp -> l_no == n) break; if (!lp) lp = w -> w_head; } if (w -> w_top == lp) return 0; w -> w_top = lp; return 1;}/* */static int ADJser (id, ww, wh)int id;short ww, wh;{ register WINDOW *w; if (id < 0 || id >= numwins) adios (NULLCP, "ADJser on bogus window (%d)", id); w = windows[id]; if (w -> w_fd == NOTOK) adios (NULLCP, "ADJser on closed window (%d)", id); w -> w_ws.width = w -> w_ws.tw = ww; w -> w_ws.height = w -> w_ws.th = wh; if (w -> w_eb) { DeleteElevatorBar (w -> w_eb); w -> w_eb = CreateElevatorBar (w -> w_fd, 0, 0, EWIDTH, w -> w_ws.height, VT_Gray50, 1, EB_VERTICAL, EB_ARROWS, w -> w_ebloc = 0, w -> w_ebsize = EB_MAX, VT_White); if (w -> w_eb == NULL) adios (NULLCP, "CreateElevatorBar failed"); } Redisplay (w, 1);}/* ARGSUSED */static int REFser (id, wx, wy, ww, wh)int id;short wx, wy, ww, wh;{ short cx, cy, cw, ch; register WINDOW *w; if (id < 0 || id >= numwins) adios (NULLCP, "REFser on bogus window (%d)", id); w = windows[id]; if (w -> w_fd == NOTOK) adios (NULLCP, "REFser on closed window (%d)", id); if (GetWindowState (w -> w_fd, &w -> w_ws) == NOTOK) adios ("failed", "GetWindowState"); GetPermanentClipping (w -> w_fd, &cx, &cy, &cw, &ch); SetPermanentClipping (w -> w_fd, wx, wy, ww, wh); Redisplay (w, 1); SetPermanentClipping (w -> w_fd, cx, cy, cw, ch);}/* */static Redisplay (w, doeb)register WINDOW *w;int doeb;{ register int y; short sx; register struct line *lp; if (w -> w_fd == NOTOK) return; sx = w -> w_eb ? (EWIDTH + ESLOP) : 0; w -> w_height = w -> w_ws.height / w -> w_cheight; if (w -> w_height < 1) w -> w_height = 1; w -> w_width = (w -> w_ws.width - (w -> w_eb ? (EWIDTH + ESLOP) : 0)) / w -> w_cwidth; if (w -> w_width < 1) w -> w_width = 1; SetPosition (w -> w_fd, sx, 0); SetColor (w -> w_fd, VT_White); PaintRectangleInterior (w -> w_fd, w -> w_ws.width, w -> w_ws.height); if (w -> w_head) { SetColor (w -> w_fd, VT_Black); for (lp = w -> w_top, y = 0; lp && y < w -> w_height; w -> w_bottom = lp, lp = lp -> l_next, y++) { SetPosition (w -> w_fd, sx, y * w -> w_cheight + w -> w_cbase); PaintString (w -> w_fd, VT_STREND, lp -> l_buf); } } if (w -> w_eb) { if ((y = EB_LOC (w)) != w -> w_ebloc) MoveElevator (w -> w_eb, w -> w_ebloc = y); if ((y = EB_SIZE (w)) != w -> w_ebsize) SizeElevator (w -> w_eb, w -> w_ebsize = y); if (doeb) RefreshElevatorBar (w -> w_eb); } Flush (w -> w_fd);}/* */static int EB_SIZE (w)register WINDOW *w;{ register int i; if (w -> w_head == NULL) return 0; if ((i = w -> w_tail -> l_no - w -> w_head -> l_no) <= 0) return EB_MAX; return (((w -> w_bottom -> l_no - w -> w_top -> l_no) * EB_MAX) / i);}static int EB_LOC (w)register WINDOW *w;{ register int i; if (w -> w_head == NULL) return 0; if ((i = w -> w_tail -> l_no - w -> w_head -> l_no) <= 0) return EB_MAX; return (((w -> w_top -> l_no - w -> w_head -> l_no) * EB_MAX) / i);}/* SIGNALS */static SIGinit () { foreground (); if (ioctl (fileno (stdin), TIOCGETP, (char *) &sg) == NOTOK) adios ("failed", "ioctl TIOCGETP"); if (ioctl (fileno (stdin), TIOCGETC, (char *) &tc) == NOTOK) adios ("failed", "ioctl TIOCGETC"); if (ioctl (fileno (stdin), TIOCGLTC, (char *) <c) == NOTOK) adios ("failed", "ioctl TIOCGLTC"); sideground (); (void) signal (SIGHUP, SIGser); (void) signal (SIGINT, SIGser); (void) signal (SIGQUIT, SIGser);}/* */static foreground () {#ifdef TIOCGPGRP int pgrp, tpgrp; TYPESIG (*tstat) (); if ((pgrp = getpgrp (0)) == NOTOK) adios ("process group", "unable to determine"); for (;;) { if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK) adios ("tty's process group", "unable to determine"); if (pgrp == tpgrp) break; tstat = signal (SIGTTIN, SIG_DFL); (void) kill (0, SIGTTIN); (void) signal (SIGTTIN, tstat); } (void) signal (SIGTTIN, SIG_IGN); (void) signal (SIGTTOU, SIG_IGN); (void) signal (SIGTSTP, SIG_IGN);#endif TIOCGPGRP}static sideground () {#ifdef TIOCGPGRP (void) signal (SIGTTIN, SIG_DFL); (void) signal (SIGTTOU, SIG_DFL); (void) signal (SIGTSTP, SIG_DFL);#endif TIOCGPGRP}/* *//* ARGSUSED */static int ALRMser (sig)int sig;{ longjmp (PEERctx, DONE);}#ifdef BSD42/* ARGSUSED */#endif BSD42static int PIPEser (sig)int sig;{#ifndef BSD42 (void) signal (sig, SIG_IGN);#endif BSD42 adios (NULLCP, "lost peer");}#ifdef BSD42/* ARGSUSED */#endif BSD42static int SIGser (sig)int sig;{#ifndef BSD42 (void) signal (sig, SIG_IGN);#endif BSD42 done (1);}/* MISCELLANY */void done (status)int status;{ if (dfd != NOTOK) RemoveStatus (dfd); (void) pFIN (); exit (status);}/* *//* VARARGS2 */static void adorn (what, fmt, a, b, c, d, e, f)char *what, *fmt, *a, *b, *c, *d, *e, *f;{ char *cp = invo_name; invo_name = NULL; advise (what, fmt, a, b, c, d, e, f); invo_name = cp;}/* *//* VARARGS3 */void advertise (what, tail, fmt, a, b, c, d, e, f)char *what, *tail, *fmt, *a, *b, *c, *d, *e, *f;{ int eindex = errno; char buffer[BUFSIZ], err[BUFSIZ]; struct iovec iob[20]; register struct iovec *iov = iob; (void) fflush (stdout); (void) fflush (stderr); if (invo_name) { iov -> iov_len = strlen (iov -> iov_base = invo_name); iov++; iov -> iov_len = strlen (iov -> iov_base = ": "); iov++; } (void) sprintf (buffer, fmt, a, b, c, d, e, f); iov -> iov_len = strlen (iov -> iov_base = buffer); iov++; if (what) { if (*what) { iov -> iov_len = strlen (iov -> iov_base = " "); iov++; iov -> iov_len = strlen (iov -> iov_base = what); iov++; iov -> iov_len = strlen (iov -> iov_base = ": "); iov++; } if (eindex > 0 && eindex < sys_nerr) iov -> iov_len = strlen (iov -> iov_base = sys_errlist[eindex]); else { (void) sprintf (err, "Error %d", eindex); iov -> iov_len = strlen (iov -> iov_base = err); } iov++; } if (tail && *tail) { iov -> iov_len = strlen (iov -> iov_base = ", "); iov++; iov -> iov_len = strlen (iov -> iov_base = tail); iov++; } iov -> iov_len = strlen (iov -> iov_base = "\n"); iov++; if (dfd != NOTOK) (void) DisplayVector (iob, iov - iob); else (void) writev (fileno (stderr), iob, iov - iob);}/* */static DisplayVector (iov, n)register struct iovec *iov;register int n;{ register int i; register char *cp; char buffer[BUFSIZ]; for (i = 0, cp = NULL; i < n; i++, iov++) { (void) sprintf (buffer, "%*.*s", iov -> iov_len, iov -> iov_len, iov -> iov_base); cp = add (buffer, cp); } DisplayStatus (dfd, cp); free (cp); sleep (PAUSE); RemoveStatus (dfd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -