📄 nxterm.c
字号:
//FIXME //GrSetGCForeground(gc1,gi.background); //GrSetGCBackground(gc1,gi.foreground); reverse = 1; } break; case 'q': /* exit reverse video mode */ if (reverse) { //GrSetGCForeground(gc1,gi.foreground); //GrSetGCBackground(gc1,gi.background); reverse = 0; } break; case 'v': /* enable wrap at end of line */ wrap = 1; break; case 'w': /* disable wrap at end of line */ wrap = 0; break; /* and these are the extensions not in VT52 */ case '[': escstate = 6; break; case 'G': /* clear all attributes */ case 'g': /* enter bold mode */ case 'h': /* exit bold mode */ case 'i': /* enter underline mode */ /* j, k and l are already used */ case 'm': /* exit underline mode */ /* these ones aren't yet on the termcap entries */ case 'n': /* enter italic mode */ /* o, p and q are already used */ case 'r': /* exit italic mode */ case 's': /* enter light mode */ case 't': /* exit light mode */ default: /* unknown escape sequence */ printf("Escape sequence %c\n", c); break; }}voidesc0(int c){ switch (c) { case 0: /* nul */ break; case 7: /* bell */ break; case 8: /* backspace */ sflush(); if (--curx < 0) curx = 0; esc0(' '); sflush(); if (--curx < 0) curx = 0; break; case 9: /* tab */ do { esc0(' '); } while (curx & 7); break; case 10: /* line feed */ sflush(); if (++cury >= row) { vscroll(); cury = row - 1; } break; case 13: /* carriage return */ sflush(); curx = 0; break; case 27: /* escape */ escstate = 1; break; case 127: /* delete */ break; default: /* any printable char */ if (c < ' ') return; sadd(c); if (++curx >= col) { sflush(); if (!wrap) curx = col - 1; else { curx = 0; if (++cury >= row) { vscroll(); cury = row - 1; } } } break; }}voidprintc(int c){ switch (escstate) { case 0: esc0(c); break; case 1: sflush(); esc1(c); break; case 2: sflush(); esc2(c); break; case 3: sflush(); esc3(c); break; case 4: sflush(); esc4(c); break; case 5: sflush(); esc5(c); break; case 6: handle_csi(c); break; default: escstate = 0; break; }}voidinit(){ curx = savx = 0; cury = savy = 0; wrap = 1; curon = 1; curvis = 0; reverse = 0; escstate = 0; g_fgcolor = 0; g_bgcolor = 15;}voidmainloop(void){ int in, l; MWKEY key; GR_EVENT wevent; unsigned char ch; unsigned char buf[1024]; GrRegisterInput(pipeh); while (42) { if (havefocus) draw_cursor(); GrGetNextEvent(&wevent); switch (wevent.type) { case GR_EVENT_TYPE_CLOSE_REQ: GrClose(); exit(0); break; case GR_EVENT_TYPE_EXPOSURE: redisplay(); break; case GR_EVENT_TYPE_KEY_DOWN: key = wevent.keystroke.ch; /* toss all special keys */ if (key & MWKEY_NONASCII_MASK) handle_key(key); else { ch = (unsigned char) key; write(pipeh, &ch, 1); } break; case GR_EVENT_TYPE_FOCUS_IN: havefocus = GR_TRUE; break; case GR_EVENT_TYPE_FOCUS_OUT: havefocus = GR_FALSE; hide_cursor(); break; case GR_EVENT_TYPE_UPDATE: switch (wevent.update.utype) { case GR_UPDATE_UNMAPTEMP: /* * if we get temporarily unmapped (moved), * set cursor state off. */ curvis = 0; break; case GR_UPDATE_SIZE: resize(wevent.update.width, wevent.update.height); break; } break; case GR_EVENT_TYPE_FDINPUT: hide_cursor(); while ((in = read(pipeh, buf, sizeof(buf))) > 0) { for (l = 0; l < in; l++) printc(buf[l]); sflush(); } break; } }}voidusage(char *s){ if (s) fprintf(stderr, "error: %s\n", s); printf("usage: nxterm [-g <geometry>] [-c] [-h] [program {args}]\n"); exit(0);}voidsigchld(int sig){ int status; int pid = wait(&status); printf("Pid %d died\n", pid); /* FIXME: Should we exit here? */}#if 0000void *mysignal(int signum, void *handler){ struct sigaction sa, so; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(signum, &sa, &so); return so.sa_handler;}voidsigpipe(int sig){ /* this one musn't close the window */ kill(-pid, SIGHUP); _exit(sig);}/* Responsibly handling the child */voidsigquit(int sig){ signal(sig, SIG_IGN); kill(-pid, SIGHUP);}#endifintmain(int argc, char **argv){ GR_BITMAP bitmap1fg[7]; /* mouse cursor */ GR_BITMAP bitmap1bg[7]; GR_FONT_INFO fi; /* Font Info */ char *shell = NULL; struct passwd *pw; char thesh[128];#ifdef SIGTTOU /* just in case we're started in the background */ signal(SIGTTOU, SIG_IGN);#endif /* who am I? */ if (!(pw = getpwuid(getuid()))) { fprintf(stderr, "nxterm: can't determine determine your login name\n"); exit(-1); } if (GrOpen() < 0) { fprintf(stderr, "cannot open graphics\n"); exit(1); } /* * scan arguments... */ argv++; while (*argv && **argv == '-') switch (*(*argv + 1)) { case 'c': console = 1; argv++; break; case 'h': /* this will never return */ usage(""); default: usage("unknown option"); } /* * now *argv either points to a program to start or is zero */ if (*argv) { shell = *argv; } if (!shell) { shell = getenv("SHELL="); } if (!shell) { shell = pw->pw_shell; } if (!shell) { shell = "/bin/sh"; } if (!*argv) { char *cptr; /* * the '-' makes the shell think it is a login shell, * we leave argv[0] alone if it isn`t a shell (ie. * the user specified the program to run as an argument * to wterm. */ cptr = strrchr(shell, '/'); sprintf(thesh, "-%s", cptr ? cptr + 1 : shell); *--argv = thesh; } init(); regFont = GrCreateFont(GR_FONT_SYSTEM_FIXED, 0, NULL); GrGetFontInfo(regFont, &fi); wChar = fi.maxwidth; hChar = fi.height; resize(80 * wChar, 25 * hChar); w1 = GrNewWindowEx(DEF_STYLE, DEF_TITLE, GR_ROOT_WINDOW_ID, 10, 10, wScreen, hScreen, g_colors[g_bgcolor]); GrSelectEvents(w1, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_FOCUS_IN | GR_EVENT_MASK_FOCUS_OUT | GR_EVENT_MASK_UPDATE | GR_EVENT_MASK_CLOSE_REQ); GrMapWindow(w1); gc1 = GrNewGC(); GrSetGCForeground(gc1, g_colors[g_fgcolor]); GrSetGCBackground(gc1, g_colors[g_bgcolor]); GrSetGCFont(gc1, regFont); gc2 = GrNewGC(); GrSetGCForeground(gc2, g_colors[g_bgcolor]);#define _ ((unsigned) 0) /* off bits */#define X ((unsigned) 1) /* on bits */#define MASK(a,b,c,d,e,f,g) \ (((((((((((((a * 2) + b) * 2) + c) * 2) + d) * 2) \ + e) * 2) + f) * 2) + g) << 9) bitmap1fg[0] = MASK(_, _, X, _, X, _, _); bitmap1fg[1] = MASK(_, _, _, X, _, _, _); bitmap1fg[2] = MASK(_, _, _, X, _, _, _); bitmap1fg[3] = MASK(_, _, _, X, _, _, _); bitmap1fg[4] = MASK(_, _, _, X, _, _, _); bitmap1fg[5] = MASK(_, _, _, X, _, _, _); bitmap1fg[6] = MASK(_, _, X, _, X, _, _); bitmap1bg[0] = MASK(_, X, X, X, X, X, _); bitmap1bg[1] = MASK(_, _, X, X, X, _, _); bitmap1bg[2] = MASK(_, _, X, X, X, _, _); bitmap1bg[3] = MASK(_, _, X, X, X, _, _); bitmap1bg[4] = MASK(_, _, X, X, X, _, _); bitmap1bg[5] = MASK(_, _, X, X, X, _, _); bitmap1bg[6] = MASK(_, X, X, X, X, X, _); GrSetCursor(w1, 7, 7, 3, 3, g_colors[g_fgcolor], g_colors[g_bgcolor], bitmap1fg, bitmap1bg);#ifdef __FreeBSD__ putenv("TERM=wterm");#else putenv("TERM=vt52");#endif /* create a pty */ pipeh = term_init(); /* prepare to catch console output */ if (console) ioctl(pipeh, TIOCCONS, 0); //signal(SIGCHLD, sigchld);#if 0 /* catch some signals */ mysignal(SIGTERM, sigquit); mysignal(SIGHUP, sigquit); mysignal(SIGINT, SIG_IGN); mysignal(SIGQUIT, sigquit); mysignal(SIGPIPE, sigpipe); mysignal(SIGCHLD, sigchld);#endif mainloop(); return 0;}#ifdef __FreeBSD__intterm_init(){ struct winsize winsz; char *ptr; char pty[128]; winsz.ws_col = col; winsz.ws_row = row; if ((pid = forkpty(&pipeh, pty, NULL, &winsz)) < 0) { fprintf(stderr, "wterm: can't create pty\r\n"); perror("wterm"); sleep(2); GrKillWindow(w1); exit(-1); } if ((ptr = rindex(pty, '/'))) strcpy(pty, ptr + 1); if (!pid) { int i; for (i = getdtablesize(); --i >= 3;) close(i); /* * SIG_IGN are not reset on exec() */ for (i = NSIG; --i >= 0;) signal(i, SIG_DFL); /* caution: start shell with correct user id! */ seteuid(getuid()); setegid(getgid()); /* this shall not return */ execvp(shell, argv); /* oops? */ fprintf(stderr, "wterm: can't start shell\r\n"); GrKillWindow(w1); _exit(-1); } return pipeh;}#else /* !FreeBSD */voidsigchild(int signo){ int status; int pid = wait(&status); printf("THE CHILD HAS DIED [%d]\n", pid); if (!inresize) { GrClose(); exit(0); }}#if ELKSchar *nargv[2] = { "/bin/sash", NULL };#else#if DOS_DJGPPchar *nargv[2] = { "bash", NULL };#elsechar *nargv[2] = { "/bin/sh", NULL };#endif#endifintterm_init(){ int tfd; int n = 0; pid_t pid; char pty_name[12]; again: sprintf(pty_name, "/dev/ptyp%d", n); if ((tfd = open(pty_name, O_RDWR | O_NONBLOCK)) < 0) { if ((errno == EBUSY || errno == EIO) && n < 10) { n++; goto again; } fprintf(stderr, "Can't create pty %s\n", pty_name); return -1; } signal(SIGCHLD, sigchild); signal(SIGINT, sigchild); if ((pid = fork()) == -1) { fprintf(stderr, "No processes\n"); return -1; } if (!pid) { close(STDIN_FILENO); close(STDOUT_FILENO); close(tfd); setsid(); pty_name[5] = 't'; if ((tfd = open(pty_name, O_RDWR)) < 0) { fprintf(stderr, "Child: Can't open pty %s [%s]\n", pty_name, strerror(errno)); exit(1); } close(STDERR_FILENO); dup2(tfd, STDIN_FILENO); dup2(tfd, STDOUT_FILENO); dup2(tfd, STDERR_FILENO); execv(nargv[0], nargv); exit(1); } return tfd;}#endif /* !FreeBSD */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -