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

📄 nxterm.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * nxterm - terminal emulator for Nano-X
 *
 * (C) 1994,95,96 by Torsten Scherer (TeSche)
 * itschere@techfak.uni-bielefeld.de
 *
 * - 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 short winw, winh, pid, 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();

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

/*
 *
 */

/* 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 */

⌨️ 快捷键说明

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