nanogui: Thread: Terminal program for Nano-X


[<<] [<] Page 1 of 1 [>] [>>]
Subject: Terminal program for Nano-X
From: gelonida ####@####.####
Date: 25 May 2005 15:49:00 +0100
Message-Id: <42949019.6040309@arcor.de>

Hello,
Basically I'm looking for a nxterm application with vt100 or xterm support
support does not have to be complete, but good enough to run vi after 
having set the terminal sizes manually.


I'm alittle confused about the state of Nano-X.
It seems to be quite interesting for small applications, but I'm a 
little unsure if Nano-X is still alive
or if I'm betting on a dead end.

I did not find any Nano-X applications except the ones delivered with 
the source code.

Is there any place where people post their Nona-X applications?


Thanks in advance for any info and bye



Gel
Subject: Re: [nanogui] Terminal program for Nano-X
From: "Greg Haerr" ####@####.####
Date: 25 May 2005 22:13:48 +0100
Message-Id: <0ac001c5616e$6086a1e0$0300a8c0@RDP>

: Basically I'm looking for a nxterm application with vt100 or xterm support
: support does not have to be complete, but good enough to run vi after 
: having set the terminal sizes manually.

I started with nxterm and nterm, both included in the
distribution.  I thought that nxterm was complete enough
to run vi.



: I'm alittle confused about the state of Nano-X.
: It seems to be quite interesting for small applications, but I'm a 
: little unsure if Nano-X is still alive
: or if I'm betting on a dead end.

Quite a few people are using nano-X.  However, it hasn't
been updated recently, although it works well.

 
: Is there any place where people post their Nona-X applications?

I've asked people to post their applications, very few do.
At Century Software, we posted all our nano-X apps on
www.pixil.org, there's quite a  few PDA-style apps there.

Regards,

Greg
Subject: Re: Terminal program for Nano-X
From: "Aaron J. Grier" ####@####.####
Date: 26 May 2005 01:27:45 +0100
Message-Id: <20050526002716.GX9263@mordor.unix.fryenet>

On Wed, May 25, 2005 at 04:47:53PM +0200, gelonida wrote:
> I'm alittle confused about the state of Nano-X.  It seems to be quite
> interesting for small applications, but I'm a little unsure if Nano-X
> is still alive or if I'm betting on a dead end.

so long as you have source code, the project is alive!  (:

> I did not find any Nano-X applications except the ones delivered with
> the source code.
>
> Is there any place where people post their Nona-X applications?

a bit difficult to do when you are dealing with custom embedded
platforms.

-- 
  Aaron J. Grier  |   Frye Electronics, Tigard, OR   |  ####@####.####
Subject: Re: [nanogui] Terminal program for Nano-X
From: "Greg Haerr" ####@####.####
Date: 26 May 2005 23:59:40 +0100
Message-Id: <0c0701c56246$5bb24650$0300a8c0@RDP>

: As I do have problems connecting to the CVS server
: I can no more check if I did make any accidental changes

The file microwindows-src-snapshot.tar.gz on the ftp
site is a mirror of the current CVS.

Regards,

Greg

Subject: Re: [nanogui] Terminal program for Nano-X
From: Klaus Foerster ####@####.####
Date: 26 May 2005 21:33:18 +0100
Message-Id: <42963282.8000103@dungeon.de>

Hi Greg,

perhaps the linux termcaps in my distribution are broken for
vt52 and wterm.

I'm no Expert. I did just change nxterm to parse the -g settings  and to 
run the passed executable for
the non BSD-unix case.

when typing 'clear; in the TERM  I do just see the characters
'H' and 'J' in a new line

I do receive the output the variable TERM is set to vt52.

Perhaps one of my 'patches' broke something.

As I do have problems connecting to the CVS server
I can no more check if I did make any accidental changes



bye


Klaus

P.S. Is there any way to force an nxterm to a certain screen position ?



or I shoud Greg Haerr wrote:

>: Basically I'm looking for a nxterm application with vt100 or xterm support
>: support does not have to be complete, but good enough to run vi after 
>: having set the terminal sizes manually.
>
>I started with nxterm and nterm, both included in the
>distribution.  I thought that nxterm was complete enough
>to run vi.
>
>
>
>: I'm alittle confused about the state of Nano-X.
>: It seems to be quite interesting for small applications, but I'm a 
>: little unsure if Nano-X is still alive
>: or if I'm betting on a dead end.
>
>Quite a few people are using nano-X.  However, it hasn't
>been updated recently, although it works well.
>
> 
>: Is there any place where people post their Nona-X applications?
>
>I've asked people to post their applications, very few do.
>At Century Software, we posted all our nano-X apps on
>www.pixil.org, there's quite a  few PDA-style apps there.
>
>Regards,
>
>Greg
>  
>


/*
 * nxterm - terminal emulator for Nano-X
 *
 * (C) 1994,95,96 by Torsten Scherer (TeSche)
 * ####@####.####
 *
 * - quite some changes for W1R1
 * - yet more changes for W1R2
 *
 * TeSche 01/96:
 * - supports W_ICON & W_CLOSE
 * - supports /etc/utmp logging for SunOS4 and Linux
 * - supports catching of console output for SunOS4
 * Phx 02-06/96:
 * - supports NetBSD-Amiga
 * Eero 11/97:
 * - unsetenv(DISPLAY), setenv(LINES, COLUMNS).
 * - Add new text modes (you need to use terminfo...).
 * Eero 2/98:
 * - Implemented fg/bgcolor setting.  With monochrome server it changes
 *   bgmode variable, which tells in which mode to draw to screen
 *   (M_CLEAR/M_DRAW) and affects F_REVERSE settings.
 * - Added a couple of checks.
 *
 * TODO:
 * - Allocate and set sensible window palette for fg/bg color setting.
 * - add scroll-region ('cs') command. Fairly many programs
 *   can take advantage of that.
 * - Add xterm like mouse event to terminfo key event conversion... :)
 * - check if current NetBSD really needs ifdefs below with
 *   current W server/library.
 */
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <utmp.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <pwd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MWINCLUDECOLORS
#include "nano-X.h"
#include "nxterm.h"

#define TITLE	"nxterm"

#define	SMALLBUFFER 80
#define	LARGEBUFFER 1024

/*
 * some pty helper functions
 */
#ifdef linux
#define NSIG _NSIG
#endif

#ifdef __FreeBSD__
#include <libutil.h>
#endif


/*
 * some global variables
 */

static GR_WINDOW_ID	w1;	/* id for window */
static GR_GC_ID		gc1;	/* graphics context */
static GR_FONT_ID       regFont;
/*static GR_FONT_ID       boldFont;*/

static GR_SCREEN_INFO	si;	/* screen info */
static GR_FONT_INFO     fi;     /* Font Info */
static GR_WINDOW_INFO   wi;
static GR_GC_INFO       gi;
static GR_BOOL		havefocus = GR_FALSE;

static pid_t pid;
static short winw, winh, console;
static int pipeh;
static short cblink = 0, visualbell = 0, debug = 0;
#ifdef __FreeBSD__
static char pty[SMALLBUFFER];
static struct winsize winsz;
#endif

#define fonh fi.height
#define fonw fi.maxwidth

int term_init(void);
void maximize(void);
void sigpipe(int sig);
void sigchld(int sig);
void sigquit(int sig);
void sflush(void);
void lineRedraw(void);
void sadd (char c);
void show_cursor (void);
void draw_cursor (void);
void hide_cursor (void);
void vscroll(int lines);
void esc5(unsigned char c);
void esc4(unsigned char c);
void esc3(unsigned char c);
void esc2(unsigned char c);
void esc1(unsigned char c);
void esc0(unsigned char c);
void printc(unsigned char c);
void init(void);
void term(void);
void usage(char *s);
void *mysignal(int signum, void *handler);
void sigchild(int signo);


/* **************************************************************************/

/*
 *
 */

/* static int isIconified; */
static int isMaximized=0;

void maximize(void)
{
    static short x0, y0, w, h, w_max,h_max;

    if (!isMaximized) 
    {
      
	w_max=si.cols-wi.bordersize;
	h_max=si.rows-wi.bordersize;
	GrMoveWindow(w1,0,0);
	GrResizeWindow(w1,w_max, h_max);
	isMaximized=1;
    } 
    else 
    {
	GrResizeWindow(w1, w, h);
	GrMoveWindow(w1, x0, y0);
	isMaximized=0;
    }
}


/* **************************************************************************/


/*
 * some common tool functions
 */

void sigpipe(int sig)
{
  /* this one musn't close the window */
/*  _write_utmp(pty, "", "", 0);  */
  kill(-pid, SIGHUP);
  _exit(sig);
}


void sigchld(int sig)
{
/*  _write_utmp(pty, "", "", 0);  */
  _exit(sig);
}


void sigquit(int sig)
{
  signal(sig, SIG_IGN);
  kill(-pid, SIGHUP);
}


/*
 * this is the wterm terminal code, almost like VT52
 */

short	bgmode, escstate, curx, cury, curon, curvis;
short	savx, savy, wrap, style;
short	col, row, colmask = 0x7f, rowmask = 0x7f;

/*
 * something to buffer plain text output
 */

short	sbufcnt = 0;
short	sbufx, sbufy;
char    lineBuffer[SMALLBUFFER+1];
char	*sbuf=lineBuffer;

void sflush(void)
{
    if (sbufcnt) 
    {
	GrText(w1,gc1, sbufx*fonw, sbufy*fonh, sbuf, sbufcnt, GR_TFTOP);
	sbufcnt = 0;
    }
}


void lineRedraw(void)
{
    GrSetGCForeground(gc1,gi.background);
    GrFillRect(w1, gc1, curx*fonw, cury*fonh, (col-curx)*fonw, fonh);
    GrSetGCForeground(gc1,gi.foreground);

    if (sbufcnt) 
    {
	sbuf[sbufcnt] = 0;
	GrText(w1,gc1, sbufx*fonw, sbufy*fonh, sbuf, sbufcnt, GR_TFTOP);
    }
}

void sadd (char c)
{
    if (sbufcnt == SMALLBUFFER)
    {
	sflush ();
    }

    if (!sbufcnt)
    { 
 	sbufx = curx; 
 	sbufy = cury; 
    } 

    sbuf[sbufcnt++] = c;
}

void show_cursor (void)
{
	GrSetGCMode(gc1,GR_MODE_XOR);
	GrSetGCForeground(gc1, WHITE);
	GrFillRect(w1, gc1, curx*fonw, cury*fonh+1, fonw, fonh-1);
	GrSetGCForeground(gc1, gi.foreground);
	GrSetGCMode(gc1,GR_MODE_COPY);
}


void draw_cursor (void)
{
    if (!curvis)
    {
	curvis = 1;
	show_cursor();
    }
}
void hide_cursor (void)
{
    if (curvis) 
    {
	curvis = 0;
	show_cursor();
    }
}


void vscroll(int lines)
{
    hide_cursor();
    GrCopyArea(w1,gc1,0, 0, winw, winh-(lines*fonh),
	       w1, 0, (lines*fonh), MWROP_SRCCOPY);
    
    GrSetGCForeground(gc1,gi.background);    
    GrFillRect(w1, gc1, 0, winh-(lines*fonh),
	       winw, (lines*fonh));
    GrSetGCForeground(gc1,gi.foreground);    
}

void esc5(unsigned char c)	/* setting background color */
{

    GrSetGCBackground(gc1, c);
    GrGetGCInfo(gc1,&gi);
    escstate = 0;
}

void esc4(unsigned char c)	/* setting foreground color */
{
    GrSetGCForeground(gc1,c);
    GrGetGCInfo(gc1,&gi);
    escstate = 0;
}

void esc3(unsigned char c)	/* cursor position x axis */
{
    curx = (c - 32) & colmask;
    if (curx >= col)
	curx = col - 1;
    else if (curx < 0)
	curx = 0;
    escstate = 0;
}


void esc2(unsigned char c)	/* cursor position y axis */
{
  cury = (c - 32) & rowmask;
  if (cury >= row)
    cury = row - 1;
  else if (cury < 0)
    cury = 0;
  escstate = 3;
}


void esc1(unsigned char c)	/* various control codes */
{
    static int ReverseMode=0;
    escstate = 0;

    switch(c) 
    {
    case 'A':/* cursor up */
	hide_cursor();
	if ((cury -= 1) < 0)
	    cury = 0;
	break;

    case 'B':/* cursor down */
	hide_cursor();
	if ((cury += 1) >= row)
	    cury = row - 1;
	break;

    case 'C':/* cursor right */
	hide_cursor();
	if ((curx += 1) >= col)
	    curx = col - 1;
	break;

    case 'D':/* cursor left */
	hide_cursor();
	if ((curx -= 1) < 0)
	    curx = 0;
	break;

    case 'E':/* clear screen & home */
	GrClearWindow(w1, 0);
	curx = 0;
	cury = 0;
	break;

    case 'H':/* cursor home */
	curx = 0;
	cury = 0;
	break;

    case 'I':/* reverse index */
	if ((cury -= 1) < 0) 
	{
	    cury = 0;
	    vscroll(1);
	}
	break;

    case 'J':/* erase to end of page */

 	if (cury < row-1) 
	{
	    GrSetGCForeground(gc1,gi.background);
	    GrFillRect(w1,gc1, 0,(cury+1)*fonh, winw, (row-1-cury)*fonh);
	    GrSetGCForeground(gc1,gi.foreground);
	}
	GrSetGCForeground(gc1,gi.background);
 	GrFillRect(w1, gc1, curx*fonw, cury*fonh, (col-curx)*fonw, fonh);
	GrSetGCForeground(gc1,gi.foreground);
	break;

    case 'K':/* erase to end of line */
	GrSetGCForeground(gc1,gi.background);
	GrFillRect(w1, gc1, curx*fonw, cury*fonh, (col-curx)*fonw, fonh);
	GrSetGCForeground(gc1,gi.foreground);
	break;

    case 'L':/* insert line */
 	if (cury < row-1) 
	{
	    vscroll(1);
	}
 	curx = 0;
	break;

    case 'M':/* delete line */
 	if (cury < row-1) 
	{ 
	    vscroll(1);
 	}
 	curx = 0;
	break;

    case 'Y':/* position cursor */
	escstate = 2;
	break;

    case 'b':/* set foreground color */
	escstate = 4;
	break;

    case 'c':/* set background color */
	escstate = 5;
	break;

    case 'd':/* erase beginning of display */
/* 	w_setmode(win, bgmode); */
 	if (cury > 0) 
	{
	    GrSetGCForeground(gc1,gi.background);
	    GrFillRect(w1,gc1, 0, 0, winw, cury*fonh);
	    GrSetGCForeground(gc1,gi.foreground);
	}
 	if (curx > 0) 
	{
	    GrSetGCForeground(gc1,gi.background);
	    GrFillRect(w1,gc1, 0, cury*fonh, curx*fonw, fonh);
	    GrSetGCForeground(gc1,gi.foreground);
	}
	break;

    case 'e':/* enable cursor */
	curon = 1;
	break;

    case 'f':/* disable cursor */
	curon = 0;
	break;

    case 'j':/* save cursor position */
	savx = curx;
	savy = cury;
	break;

    case 'k':/* restore cursor position */
	curx = savx;
	cury = savy;
	break;

    case 'l':/* erase entire line */
	GrSetGCForeground(gc1,gi.background);
	GrRect(w1,gc1, 0, cury*fonh, winw, fonh);
	GrSetGCForeground(gc1,gi.foreground);
	curx = 0;
	break;

    case 'o':/* erase beginning of line */
	if (curx > 0)
	{
	    GrSetGCForeground(gc1,gi.background);
	    GrRect(w1,gc1,0, cury*fonh, curx*fonw, fonh);
	    GrSetGCForeground(gc1,gi.foreground);
	}
	break;

    case 'p':/* enter reverse video mode */
    {
	if(!ReverseMode)
	{
	    GrSetGCForeground(gc1,gi.background);
	    GrSetGCBackground(gc1,gi.foreground);
 	    ReverseMode=1; 
	}
    }
	break;

    case 'q':/* exit reverse video mode */
    {
	if(ReverseMode)
	{
	    GrSetGCForeground(gc1,gi.foreground);
	    GrSetGCBackground(gc1,gi.background);
 	    ReverseMode=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 extentions not in VT52 */

    case 'G': /* clear all attributes */
	break;

    case 'g': /* enter bold mode */
/*	GrSetGCFont(gc1, boldFont); */
	break;

    case 'h': /* exit bold mode */
/*	GrSetGCFont(gc1, regFont); */
	break;

    case 'i': /* enter underline mode */
	break;

	/* j, k and l are already used */

    case 'm': /* exit underline mode */
	break;

/* these ones aren't yet on the termcap entries */

    case 'n': /* enter italic mode */
	break;
	/* o, p and q are already used */

    case 'r': /* exit italic mode */
	break;

    case 's': /* enter light mode */
	break;

    case 't': /* exit ligth mode */
	break;

    default: /* unknown escape sequence */
	break;
    }
}

/*
 * un-escaped character print routine
 */

void esc0 (unsigned char c)
{
    switch (c) 
    {
    case 0:
	/*
	 * printing \000 on a terminal means "do nothing".
	 * But since we use \000 as string terminator none
	 * of the characters that follow were printed.
	 *
	 * perl -e 'printf("a%ca", 0);'
	 *
	 * said 'a' in a wterm, but should say 'aa'. This
	 * bug screwed up most ncurses programs.
	 *
	 * kay.
	 */
	break;
 
    case 7: /* bell */
	if (visualbell) 
	{
/* 	    w_setmode(win, M_INVERS); */
/* 	    w_pbox(win, 0, 0, winw, winh); */
/* 	    w_test(win, 0, 0); */
/* 	    w_pbox(win, 0, 0, winw, winh); */
	    ;
	} 
	else 
	{
	    ;
 	    GrBell();
	}
	break;

    case 8: /* backspace */
	lineRedraw();
	if (--curx < 0) 
	{
	    curx = 0;
	}
	break;

    case 9: /* tab */
    {
	int borg,i;

	borg=(((curx >> 3) + 1) << 3);
	if(borg >= col)
	{
	    borg=col-1;
	}
	borg=borg-curx;
	for(i=0; i < borg; ++i){sadd(' ');}
 	if ((curx = ((curx >> 3) + 1) << 3) >= col) 
 	{ 
 	    curx = col - 1; 
 	} 
    }
	break;

    case 10: /* line feed */
	sflush();
	if (++cury >= row) 
	{
	    vscroll(1);
	    cury = row-1;
	}
	break;

    case 13: /* carriage return */
	sflush();
	curx = 0;
	break;

    case 27: /* escape */
	sflush();
	escstate = 1;
	break;

    case 127: /* delete */
	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(void)
{
    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");
    printf("\n");
    printf("-b     blinking cursor (not implemented)\n");
    printf("-d     debug (not implemented)\n");
    printf("-f <font family>   not implemented\n");
    printf("-s <font size>   not implemented\n");
    printf("-g <x_y_x0_y0>   partially implemented\n");
    printf("-v      visualbell not implemented)\n");
    printf("-g      shows this help text\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... :)
 */

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


static char nargv0[128];

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;
        printf("SHELL from cmdline is <%s>\n",shell);
    }
    if (!shell) {
	    shell = getenv("SHELL");
        printf("SHELL from ENV is <%s>\n",shell);
    }
    if (!shell) {
	    shell = pw->pw_shell;
        printf("SHELL from pw->pw)shell  is <%s>\n",shell);

    }
    if (!shell) {
	    shell = "/bin/sh";
        printf("default shell  is <%s>\n",shell);
    }

    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;
        printf("THESH is <%s>\n",thesh);
    }
    strncpy(nargv0,shell,127);
    nargv[0]=nargv0;

    col = 30;
    row = 10;
    xp = 0;
    yp = 0;
    if (geometry) 
    {
        int tcol,trow,txp,typ;
        char *p=geometry;
        for(p=geometry;*p != 0;p++){
            if(*p < '0' || *p >'9')
                *p=' ';
        }
        sscanf(geometry,"%d %d %d %d",&tcol,&trow,&txp,&typ);
        col=tcol;
        row=trow;
        xp=txp;
        yp=typ;
        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, xp,yp,winw, winh,0,BLACK,LTBLUE);
    GrGetWMProperties(w1, &props);
    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);

    nargv[0]=shell;
    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 */
        printf("NOW RUNNING SHELL <%s> with following args:\n",shell); 
        for(i=0;argv[i] == NULL;i++){
            printf("\t<%s>\n",argv[i]);
        }
        execvp(shell, argv);

        /* oops? */
        fprintf(stderr,"wterm: can't start shell\r\n");
        sleep(3);
        GrKillWindow(w1);
        _exit(-1);
    }
#else
    pipeh = term_init();
    printf("TERMINIT called\n");
#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;
}

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

int term_init(void)
{
	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

/* These contained 'pt:re=\\EC' entries.  I deleted them from MiNT and linux
 * because neither of my (linux) termcap nor terminfo manual pages listed
 * them.
 *	++eero
 */
#ifdef __MINT__

static char termcap_string[1024] =
"TERMCAP=wterm|WTerm terminal:al=\\EL:am:bc=\\ED:bl=^G:bs:cd=\\EJ:\
ce=\\EK:cl=\\EE:cm=\\EY%+ %+ :cr=^M:dl=\\EM:do=\\EB:ho=\\EH:is=\\Ev\\Eq:\
l0=F10:le=\\ED:ms:nd=\\EC:rc=\\Ek:rs=\\Ev\\Eq\\EE:sc=\\Ej:sr=\\EI:\
ti=\\Ev\\Ee\\EG:up=\\EA:ve=\\Ee:vi=\\Ef:so=\\Ep:se=\\Eq:mb=\\Ei:md=\\Eg:\
mr=\\Ep:me=\\EG:te=\\EG:us=\\Ei:ue=\\EG:\
kb=^H:kl=\\ED:kr=\\EC:ku=\\EA:kd=\\EB:kI=\\EI:kh=\\EE:kP=\\Ea:kN=\\Eb:k0=\\EY:\
k1=\\EP:k2=\\EQ:k3=\\ER:k4=\\ES:k5=\\ET:k6=\\EU:k7=\\EV:k8=\\EW:k9=\\EX:\
s0=\\Ey:s1=\\Ep:s2=\\Eq:s3=\\Er:s4=\\Es:s5=\\Et:s6=\\Eu:s7=\\Ev:s8=\\Ew:\
s9=\\Ex:";

#elif defined(linux) || defined(__FreeBSD__)

static char termcap_string[1024] =
"TERMCAP=wterm|WTerm terminal:al=\\EL:am:bc=\\ED:bl=^G:bs:cd=\\EJ:\
ce=\\EK:cl=\\EE:cm=\\EY%+ %+ :cr=^M:dl=\\EM:do=\\EB:ho=\\EH:is=\\Ev\\Eq:\
l0=F10:le=\\ED:ms:nd=\\EC:rc=\\Ek:rs=\\Ev\\Eq\\EE:sc=\\Ej:sr=\\EI:\
ti=\\Ev\\Ee\\EG:up=\\EA:ve=\\Ee:vi=\\Ef:so=\\Ep:se=\\Eq:mb=\\Ei:md=\\Eg:\
mr=\\Ep:me=\\EG:te=\\EG:us=\\Ei:ue=\\EG:\
kb=^H:kl=\\E[D:kr=\\E[C:ku=\\E[A:kd=\\E[B:kI=\\EI:kh=\\EE:kP=\\Ea:kN=\\Eb:\
k0=\\EY:k1=\\EP:k2=\\EQ:k3=\\ER:k4=\\ES:k5=\\ET:k6=\\EU:k7=\\EV:k8=\\EW:\
k9=\\EX:s0=\\Ey:s1=\\Ep:s2=\\Eq:s3=\\Er:s4=\\Es:s5=\\Et:s6=\\Eu:s7=\\Ev:\
s8=\\Ew:s9=\\Ex:";

#elif defined(sun)

  /* only very basic cursor keys so far... */

static char termcap_string[1024] =
"TERMCAP=wterm|WTerm terminal:al=\\EL:am:bc=\\ED:bl=^G:bs:cd=\\EJ:\
ce=\\EK:cl=\\EE:cm=\\EY%+ %+ :cr=^M:dl=\\EM:do=\\EB:ho=\\EH:is=\\Ev\\Eq:\
l0=F10:le=\\ED:ms:nd=\\EC:pt:re=\\EC:rc=\\Ek:rs=\\Ev\\Eq\\EE:sc=\\Ej:sr=\\EI:\
ti=\\Ev\\Ee\\EG:up=\\EA:ve=\\Ee:vi=\\Ef:so=\\Ep:se=\\Eq:mb=\\Ei:md=\\Eg:\
mr=\\Ep:me=\\EG:te=\\EG:us=\\Ei:ue=\\EG:\
kb=^H:kl=\\E[D:kr=\\E[C:ku=\\E[A:kd=\\E[B:\
k1=\\E[224z:k2=\\E[225z:k3=\\E[226z:k4=\\E[227z:k5=\\E[228z:\
k6=\\E[229z:k7=\\E[230z:k8=\\E[231z:k9=\\E[232z:k0=\\E[233z:\
kN=\\E[222z:kP=\\E[216z:kh=\\E[214z:kH=\\E220z:";

#elif defined(__NetBSD__)

static char termcap_string[1024] =
"TERMCAP=wterm|WTerm terminal:al=\\EL:am:bc=\\ED:bl=^G:bs:cd=\\EJ:\
ce=\\EK:cl=\\EE:cm=\\EY%+ %+ :cr=^M:dl=\\EM:do=\\EB:ho=\\EH:is=\\Ev\\Eq:\
l0=F10:le=\\ED:ms:nd=\\EC:pt:re=\\EC:rc=\\Ek:rs=\\Ev\\Eq\\EE:sc=\\Ej:sr=\\EI:\
ti=\\Ev\\Ee\\EG:up=\\EA:ve=\\Ee:vi=\\Ef:so=\\Ep:se=\\Eq:mb=\\Ei:md=\\Eg:\
mr=\\Ep:me=\\EG:te=\\EG:us=\\Ei:ue=\\EG:\
kb=^H:kl=\\E[D:kr=\\E[C:ku=\\E[A:kd=\\E[B:\
k1=\\E[224z:k2=\\E[225z:k3=\\E[226z:k4=\\E[227z:k5=\\E[228z:\
k6=\\E[229z:k7=\\E[230z:k8=\\E[231z:k9=\\E[232z:k0=\\E[233z:\
kN=\\E[222z:kP=\\E[216z:kh=\\E[214z:kH=\\E220z:";

#else

#error oops, a new operating system?
This is a compile time error

#endif

[<<] [<] Page 1 of 1 [>] [>>]


Powered by ezmlm-browse 0.20.