OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [mw/] [src/] [demos/] [nanox/] [nterm.c] - Rev 716

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * Nano-X terminal emulator
 *
 * Al Riddoch
 * Greg Haerr
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
/* SIMO: we use strlen */
#include <string.h>
 
#define MWINCLUDECOLORS
#include "nano-X.h"
 
#define HAVEBLIT 0		/* set if have bitblit (experimental)*/
 
#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)
 
#if DOS_DJGPP
#define SIGCHLD		17 /* from Linux */
#endif
 
static GR_WINDOW_ID	w1;	/* id for window */
static GR_GC_ID		gc1;	/* graphics context */
static GR_GC_ID		gc3;	/* graphics context */
static GR_COORD		xpos;	/* x coord for text */
static GR_COORD		ypos;	/* y coord for text */
static GR_SCREEN_INFO	si;	/* screen info */
static int 		tfd;
 
void do_buttondown();
void do_buttonup();
void do_motion();
void text_init();
int term_init();
void do_keystroke();
void do_focusin();
void do_focusout();
void do_enter();
void do_exit();
void do_fdinput();
void printg();
void HandleEvent(GR_EVENT *ep);
 
int main(int argc, char ** argv)
{
	GR_BITMAP	bitmap1fg[7];	/* mouse cursor */
	GR_BITMAP	bitmap1bg[7];
 
	if (GrOpen() < 0) {
		fprintf(stderr, "cannot open graphics\n");
		exit(1);
	}
 
	GrGetScreenInfo(&si);
 
	w1 = GrNewWindow(GR_ROOT_WINDOW_ID, 50, 30, si.cols - 120,
		si.rows - 60, 1, WHITE, LTBLUE);
 
	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_CLOSE_REQ);
 
	GrMapWindow(w1);
 
	gc1 = GrNewGC();
	gc3 = GrNewGC();
 
	GrSetGCForeground(gc1, GRAY);
	GrSetGCBackground(gc1, LTBLUE);
	GrSetGCFont(gc1, GrCreateFont(GR_FONT_SYSTEM_FIXED, 0, NULL));
	/*GrSetGCFont(gc1, GrCreateFont(GR_FONT_OEM_FIXED, 0, NULL));*/
	GrSetGCForeground(gc3, WHITE);
	GrSetGCBackground(gc3, BLACK);
 
	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, WHITE, BLACK, bitmap1fg, bitmap1bg);
 
	/*GrFillRect(GR_ROOT_WINDOW_ID, gc1, 0, 0, si.cols, si.rows);*/
 
	GrSetGCForeground(gc1, BLACK);
	GrSetGCBackground(gc1, WHITE);
	text_init();
	if (term_init() < 0) {
		GrClose();
		exit(1);
	}
 
	/* we want tfd events also*/
	GrRegisterInput(tfd);
 
#if 1
	GrMainLoop(HandleEvent);
#else
	while(1) {
		GR_EVENT ev;
 
		GrGetNextEvent(&ev);
		HandleEvent(&ev);
	}
#endif
	/* notreached*/
	return 0;
}
 
void
HandleEvent(GR_EVENT *ep)
{
	switch (ep->type) {
		case GR_EVENT_TYPE_KEY_DOWN:
			do_keystroke(&ep->keystroke);
			break;
 
		case GR_EVENT_TYPE_FOCUS_IN:
			do_focusin(&ep->general);
			break;
 
		case GR_EVENT_TYPE_FOCUS_OUT:
			do_focusout(&ep->general);
			break;
 
		case GR_EVENT_TYPE_CLOSE_REQ:
			GrClose();
			exit(0);
 
		case GR_EVENT_TYPE_FDINPUT:
			do_fdinput();
			break;
	}
}
 
#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)
{
	printg("We have a signal right now!\n");
	GrClose();
	exit(0);
}
 
int term_init()
{
	char pty_name[12];
	int n = 0;
	pid_t pid;
 
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(STDERR_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);
		}
		dup2(tfd, STDIN_FILENO);
		dup2(tfd, STDOUT_FILENO);
		dup2(tfd, STDERR_FILENO);
		execv(nargv[0], nargv);
		exit(1);
	}
	return 0;
}
 
 
GR_SIZE		width;		/* width of character */
GR_SIZE		height;		/* height of character */
GR_SIZE		base;		/* height of baseline */
 
void text_init()
{
	GrGetGCTextSize(gc1, "A", 1, GR_TFASCII, &width, &height, &base);
}
 
void char_del(GR_COORD x, GR_COORD y)
{
	xpos -= width;
	GrFillRect(w1, gc3, x, y /*- height*/ /*+ base*/ + 1, width, height);
}
 
void char_out(GR_CHAR ch)
{
	switch(ch) {
	case '\r':
		xpos = 0;
		return;
	case '\n':
		ypos += height;
		if(ypos > si.rows - 60 - height) {
			ypos -= height;
#if HAVEBLIT
			bogl_cfb8_blit(50, 30, si.cols-120,
				si.rows-60-height, 50, 30+height);
			GrFillRect(w1, gc3, 50, ypos, si.cols-120, height);
#else
			/* FIXME: changing FALSE to TRUE crashes nano-X*/
			/* clear screen, no scroll*/
			ypos = 0;
			GrClearWindow(w1, GR_FALSE);
#endif
		}
		return;
	case '\007':			/* bel*/
		return;
	case '\t':
		xpos += width;
		while((xpos/width) & 7)
			char_out(' ');
		return;
	case '\b':			/* assumes fixed width font!!*/
		if (xpos <= 0)
			return;
		char_del(xpos, ypos);
		return;
	}
	GrText(w1, gc1, xpos+1, ypos, &ch, 1, GR_TFTOP);
	xpos += width;
}
 
void printg(char * text)
{
	int i;
 
	for(i = 0; i < strlen(text); i++) {
		char_out(text[i]);
	}
}
 
 
/*
 * Here when a keyboard press occurs.
 */
void
do_keystroke(kp)
	GR_EVENT_KEYSTROKE	*kp;
{
	char foo;
 
	foo = kp->ch;
	write(tfd, &foo, 1);
}
 
 
/*
 * Here when a focus in event occurs.
 */
void
do_focusin(gp)
	GR_EVENT_GENERAL	*gp;
{
	if (gp->wid != w1)
		return;
	GrSetBorderColor(w1, LTBLUE);
}
 
/*
 * Here when a focus out event occurs.
 */
void
do_focusout(gp)
	GR_EVENT_GENERAL	*gp;
{
	if (gp->wid != w1)
		return;
	GrSetBorderColor(w1, GRAY);
}
 
/*
 * Here to read the shell input file descriptor.
 */
void
do_fdinput()
{
	char	c;
 
	if (read(tfd, &c, 1) == 1)
		char_out(c);
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.