⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nxterm.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
	break;

    default: /* any printable char */
	sadd(c);
	if (++curx >= col) 
	{
	    sflush();
	    if (!wrap) 
	    {
		curx = col-1;
	    } 
	    else 
	    {
		curx = 0;
		if (++cury >= row) 
		{
		    vscroll(1);
		}
	    }
	}
	break;
    }
}


void printc(unsigned char 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;

    default: 
	escstate = 0;
	break;
    }
}


void init()
{
    curx = savx = 0;
    cury = savy = 0;
    wrap = 1;
    curon = 1;
    curvis = 0;
    escstate = 0;
}


/*
 * general code...
 */

void
term(void)
{
	long 		in, l;
	GR_EVENT 	wevent;
	GR_EVENT_KEYSTROKE *kp;
	unsigned char 	buf[LARGEBUFFER];

	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_KEY_DOWN:
			kp=(GR_EVENT_KEYSTROKE *)&wevent;
			/* toss all special keys*/
			if (kp->ch & MWKEY_NONASCII_MASK)
				break;
			*buf = kp->ch & 0xff;
			write(pipeh, buf,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:
			/*
			 * if we get temporarily unmapped (moved),
			 * set cursor state off.
			 */
			if (wevent.update.utype == GR_UPDATE_UNMAPTEMP)
				curvis = 0;
			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]); 
					if (buf[l] == '\n')
						printc('\r');
				}
				sflush();
			}
	    		break;
		}
	}
}


void usage(char *s)
{
    if (s) 
	fprintf(stderr, "error: %s\n", s);
    printf("usage: nxterm [-b] [-d] [-f <font family>] [-s <font size>]\n");
    printf("       [-g <geometry>] [-v] [-c] [-h] [program {args}]\n");
    exit(0);
}


void *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;
}

/*
 * guess what... :)
 */

int main(int argc, char **argv)
{
    GR_BITMAP	bitmap1fg[7];	/* mouse cursor */
    GR_BITMAP	bitmap1bg[7];
    GR_WM_PROPERTIES props;

    short xp, yp, fsize;
    char *family, *shell = NULL, *cptr, *geometry = NULL;
    struct passwd *pw;
    char buf[80];
    short uid;
    char thesh[128];
#ifdef __FreeBSD__
    char *ptr;
#endif

#ifdef SIGTTOU
    /* just in case we're started in the background */
    signal(SIGTTOU, SIG_IGN);
#endif

    /* who am I? */
    if (!(pw = getpwuid((uid = getuid())))) 
    {
	fprintf(stderr, "error: wterm can't determine determine your login name\n");
	exit(-1);
    }

  
    if (GrOpen() < 0) 
    {
	fprintf(stderr, "cannot open graphics\n");
	exit(1);
    }

    GrGetScreenInfo(&si);
    /*
     * scan arguments...
     */

    console = 0;
    argv++;
    while (*argv && **argv=='-') 
	switch (*(*argv+1)) 
	{
	case 'b':
	    cblink = 1;
	    argv++;
	    break;

	case 'c':
	    console = 1;
	    argv++;
	    break;

	case 'd':
	    debug = 1;
	    argv++;
	    break;

	case 'f':
	    if (*++argv) {
		family = *argv++;
	    } else {
		usage("-f option requires an argument");
	    }
	    break;

	case 's':
	    if (*++argv) {
		fsize = atoi(*argv++);
	    } else {
		usage("-s option requires an argument");
	    }
	    break;

	case 'g':
	    if (*++argv) {
		geometry = *argv++;
	    } else {
		usage("-g option requires an argument");
	    }
	    break;

	case 'h':
	    /* this will never return */
	    usage("");

	case 'v':
	    visualbell = 1;
	    argv++;
	    break;

	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) {
	/*
	 * 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;
    }

    col = 80;
    row = 25;
    xp = 0;
    yp = 0;
    if (geometry) 
    {
	if (col < 1) 
	{
	    col = 80;
	}
	if (row < 1) 
	{
	    row = 25;
	}
	if (col > 0x7f)
	    colmask = 0xffff;
	if (row > 0x7f)
	    rowmask = 0xffff;
    }
    
    regFont=GrCreateFont(GR_FONT_SYSTEM_FIXED, 0, NULL);
    /*regFont=GrCreateFont(GR_FONT_OEM_FIXED, 0, NULL);*/
    /*boldFont=GrCreateFont(GR_FONT_SYSTEM_FIXED, 0, NULL);*/
    GrGetFontInfo(regFont, &fi);

    winw=col*fi.maxwidth;
    winh=row*fi.height;
    w1 = GrNewWindow(GR_ROOT_WINDOW_ID, 10,10,winw, winh,0,BLACK,LTBLUE);
    props.flags = GR_WM_FLAGS_TITLE;
    props.title = TITLE;
    GrSetWMProperties(w1, &props);

    GrSelectEvents(w1, GR_EVENT_MASK_BUTTON_DOWN |
		   GR_EVENT_MASK_KEY_DOWN | 
		   GR_EVENT_MASK_FOCUS_IN | GR_EVENT_MASK_FOCUS_OUT |
		   GR_EVENT_MASK_UPDATE | GR_EVENT_MASK_CLOSE_REQ);

    GrMapWindow(w1);

    gc1 = GrNewGC();
    GrSetGCFont(gc1, regFont);

#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, GREEN, BLACK, bitmap1fg, bitmap1bg);
    GrSetGCForeground(gc1, GREEN);
    GrSetGCBackground(gc1, BLACK);
    GrGetWindowInfo(w1,&wi);
    GrGetGCInfo(gc1,&gi);

    sprintf(buf, "wterm: %s", shell);

    /*
     * what kind of terminal do we want to emulate?
     */
#ifdef __FreeBSD__
    putenv ("TERM=wterm");
#else
    putenv ("TERM=vt52");
#endif

    /*
     * this one should enable us to get rid of an /etc/termcap entry for
     * both curses and ncurses, hopefully...
     */

    if (termcap_string) 
    {
	sprintf (termcap_string + strlen (termcap_string), "li#%d:co#%d:",
		 row, col);
	putenv (termcap_string);
    }
    /* in case program absolutely needs terminfo entry, these 'should'
     * transmit the screen size of correctly (at least xterm sets these
     * and everything seems to work correctly...). Unlike putenv(),
     * setenv() allocates also the given string not just a pointer.
     */
    sprintf (buf, "%d", col);
    setenv ("COLUMNS", buf, 1);
    sprintf (buf, "%d", row);
    setenv ("LINES", buf, 1);

    init();

    /*
     * create a pty
     */
#ifdef __FreeBSD__
    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");
	sleep(3);
	GrKillWindow(w1);
	_exit(-1);
    }
#else
    pipeh = term_init();
#endif

/*    _write_utmp(pty, pw->pw_name, "", time(0)); */

#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

    /* prepare to catch console output */
    if (console) 
    {
	/* for any OS chr$(7) might cause endless loops if 
	 * catched from console 
	 */
	visualbell = 1;
	console = 0;       /* data will come to normal pipe handle */
	ioctl(pipeh, TIOCCONS, 0);
    }

    term();
    return 0;
}

#if ELKS
char * nargv[2] = {"/bin/sash", NULL};
#else
#if DOS_DJGPP
char * nargv[2] = {"bash", NULL};
#else
char * nargv[2] = {"/bin/sh", NULL};
#endif
#endif

void sigchild(int signo)
{
	GrClose();
	exit(0);
}

int term_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\n", pty_name);
			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;
}

#if 0
void _write_utmp(char *line, char *user, char *host, int time)
{
    int fh, offset, isEmpty, isLine;
    struct utmp ut;

    if ((fh = open("/etc/utmp", O_RDWR)) < 0) {
	return;
    }

    /* first of all try to find an entry with the same line */

    offset = 0;
    isEmpty = -1;
    isLine = -1;

    while ((isLine < 0) && (read(fh, &ut, sizeof(ut)) == sizeof(ut))) {
	if (!ut.ut_line[0]) 
	{
	    if (isEmpty < 0) 
	    {
		isEmpty = offset;
	    }
	} 
	else 
	{
	    if (!strncmp(ut.ut_line, line, sizeof(ut.ut_line))) {
		isLine = offset;
	    }
	}
	offset += sizeof(ut);
    }

    if (isLine != -1) {
	/* we've found a match */
	lseek(fh, isLine, SEEK_SET);
    } else if (isEmpty != -1) {
	/* no match found, but at least an empty entry */
	lseek(fh, isLine, SEEK_SET);
    } else {
	/* not even an empty entry found, assume we can append to the file */
    }

    if (time) 
    {
	strncpy(ut.ut_line, line, sizeof(ut.ut_line));
	strncpy(ut.ut_name, user, sizeof(ut.ut_name));
	strncpy(ut.ut_host, host, sizeof(ut.ut_host));
	ut.ut_time = time;
    } 
    else 
    {
	memset(&ut, 0, sizeof(ut));
    }
    write(fh, &ut, sizeof(ut));
    close(fh);
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -