diff options
| -rw-r--r-- | config.h | 2 | ||||
| -rw-r--r-- | config.mk | 3 | ||||
| -rw-r--r-- | st.c | 115 | 
3 files changed, 61 insertions, 59 deletions
@@ -29,8 +29,6 @@ static const char *colorname[] = {  #define DefaultFG 7  #define DefaultBG 0  #define DefaultCS 1 -#define BellCol   DefaultFG -#define BellTime  30000 /* microseconds */  /* special keys */  static Key key[] = { @@ -14,7 +14,8 @@ X11LIB = /usr/X11R6/lib  INCS = -I. -I/usr/include -I${X11INC}  LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lutil -# uncomment your system # +# uncomment manualy your system if compilation fail +SYSTEM = -D`uname | tr a-z A-Z`  #SYSTEM = -DLINUX  #SYSTEM = -DOPENBSD  #SYSTEM = -DFREEBSD @@ -16,7 +16,6 @@  #include <sys/types.h>  #include <sys/wait.h>  #include <unistd.h> -#include <pty.h>  #include <X11/Xlib.h>  #include <X11/keysym.h>  #include <X11/Xutil.h> @@ -47,8 +46,9 @@  /* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */  enum { ATTR_NULL=0 , ATTR_REVERSE=1 , ATTR_UNDERLINE=2, ATTR_BOLD=4, ATTR_GFX=8 }; -enum { CURSOR_UP, CURSOR_DOWN, CURSOR_LEFT, CURSOR_RIGHT, CURSOR_HIDE = 1,  -       CURSOR_DRAW = 0, CURSOR_SAVE, CURSOR_LOAD }; +enum { CURSOR_UP, CURSOR_DOWN, CURSOR_LEFT, CURSOR_RIGHT, +       CURSOR_SAVE, CURSOR_LOAD }; +enum { CURSOR_DEFAULT = 0, CURSOR_HIDE = 1, CURSOR_WRAPNEXT = 2 };  enum { GLYPH_SET=1, GLYPH_DIRTY=2 };  enum { MODE_WRAP=1, MODE_INSERT=2, MODE_APPKEYPAD=4 };  enum { ESC_START=1, ESC_CSI=2, ESC_OSC=4, ESC_TITLE=8, ESC_ALTCHARSET=16 }; @@ -68,7 +68,7 @@ typedef struct {  	Glyph attr;	 /* current char attributes */  	int x;  	int y; -	char hide; +	char state;  } TCursor;  /* CSI Escape sequence structs */ @@ -108,6 +108,7 @@ typedef struct {  	int bufh; /* pixmap height */  	int ch; /* char height */  	int cw; /* char width  */ +	int hasfocus;  } XWindow;   typedef struct { @@ -161,23 +162,27 @@ static void ttyread(void);  static void ttyresize(int, int);  static void ttywrite(const char *, size_t); -static void xbell(void);  static void xdraws(char *, Glyph, int, int, int);  static void xhints(void);  static void xclear(int, int, int, int); -static void xcursor(int); +static void xdrawcursor(void);  static void xinit(void);  static void xloadcols(void); +static void xseturgency(int);  static void expose(XEvent *);  static char* kmap(KeySym);  static void kpress(XEvent *);  static void resize(XEvent *); +static void focus(XEvent *); +  static void (*handler[LASTEvent])(XEvent *) = {  	[KeyPress] = kpress,  	[Expose] = expose, -	[ConfigureNotify] = resize +	[ConfigureNotify] = resize, +	[FocusIn] = focus, +	[FocusOut] = focus,  };  /* Globals */ @@ -187,7 +192,6 @@ static Term term;  static CSIEscape escseq;  static int cmdfd;  static pid_t pid; -static int running;  #ifdef DEBUG  void @@ -227,15 +231,6 @@ execsh(void) {  	execvp(args[0], args);  } -void -xbell(void) { -	XSetForeground(xw.dis, dc.gc, dc.col[BellCol]); -	XFillRectangle(xw.dis, xw.win, dc.gc, BORDER, BORDER, xw.bufw, xw.bufh); -	XFlush(xw.dis); -	usleep(BellTime); -	draw(SCREEN_REDRAW); -} -  void   sigchld(int a) {  	int stat = 0; @@ -330,7 +325,7 @@ treset(void) {  		.mode = ATTR_NULL,   		.fg = DefaultFG,   		.bg = DefaultBG -	}, .x = 0, .y = 0, .hide = 0}; +	}, .x = 0, .y = 0, .state = CURSOR_DEFAULT};  	term.top = 0, term.bot = term.row - 1;  	term.mode = MODE_WRAP; @@ -415,8 +410,11 @@ csiparse(void) {  void  tmoveto(int x, int y) { -	term.c.x = x < 0 ? 0 : x >= term.col ? term.col-1 : x; -	term.c.y = y < 0 ? 0 : y >= term.row ? term.row-1 : y; +	LIMIT(x, 0, term.col-1); +	LIMIT(y, 0, term.row-1); +	term.c.state &= ~CURSOR_WRAPNEXT; +	term.c.x = x; +	term.c.y = y;  }  void @@ -712,7 +710,7 @@ csihandle(void) {  			case 12: /* att610 -- Stop blinking cursor (IGNORED) */  				break;  			case 25: -				term.c.hide = CURSOR_HIDE; +				term.c.state |= CURSOR_HIDE;  				break;  			case 1048: /* XXX: no alt. screen to erase/save */  			case 1049: @@ -761,7 +759,7 @@ csihandle(void) {  			case 12: /* att610 -- Start blinking cursor (IGNORED) */  				break;  			case 25: -				term.c.hide = CURSOR_DRAW; +				term.c.state &= ~CURSOR_HIDE;  				break;  			case 1048:   			case 1049: /* XXX: no alt. screen to erase/save */ @@ -789,6 +787,7 @@ csihandle(void) {  			DEFAULT(escseq.arg[0], 1);  			DEFAULT(escseq.arg[1], term.row);  			tsetscroll(escseq.arg[0]-1, escseq.arg[1]-1); +			tmoveto(0, 0);  		}  		break;  	case 's': /* DECSC -- Save cursor position (ANSI.SYS) */ @@ -868,20 +867,11 @@ tputc(char c) {  			case '(':  				term.esc |= ESC_ALTCHARSET;  				break; -			case 'A': -				tmoveto(term.c.x, term.c.y-1); -				term.esc = 0; -				break; -			case 'B': -				tmoveto(term.c.x, term.c.y+1); -				term.esc = 0; -				break; -			case 'C': -				tmoveto(term.c.x+1, term.c.y); -				term.esc = 0; -				break; -			case 'D': /* XXX: CUP (VT100) or IND (VT52) ... */ -				tmoveto(term.c.x-1, term.c.y); +			case 'D': /* IND -- Linefeed */ +				if(term.c.y == term.bot) +					tscrollup(1); +				else +					tmoveto(term.c.x, term.c.y+1);  				term.esc = 0;  				break;  			case 'E': /* NEL -- Next line */ @@ -935,18 +925,21 @@ tputc(char c) {  			tnewline();  			break;  		case '\a': -			xbell(); +			if(!xw.hasfocus) +				xseturgency(1);  			break;  		case '\033':  			csireset();  			term.esc = ESC_START;  			break;  		default: +			if(IS_SET(MODE_WRAP) && term.c.state & CURSOR_WRAPNEXT) +				tnewline();  			tsetchar(c); -			if(term.c.x+1 < term.col) { +			if(term.c.x+1 < term.col)  				tmoveto(term.c.x+1, term.c.y); -			} else if(IS_SET(MODE_WRAP)) -				tnewline(); +			else +				term.c.state |= CURSOR_WRAPNEXT;  			break;  		}  	} @@ -984,13 +977,12 @@ tresize(int col, int row) {  	for(/* i == minrow */; i < row; i++)  		term.line[i] = calloc(col, sizeof(Glyph)); -	LIMIT(term.c.x, 0, col-1); -	LIMIT(term.c.y, 0, row-1); -	LIMIT(term.top, 0, row-1); -	LIMIT(term.bot, 0, row-1); -	 -	term.bot = row-1; +	/* update terminal size */  	term.col = col, term.row = row; +	/* make use of the LIMIT in tmoveto */ +	tmoveto(term.c.x, term.c.y); +	/* reset scrolling region */ +	tsetscroll(0, row-1);  }  void @@ -1075,9 +1067,6 @@ xinit(void) {  	/* colors */  	xloadcols(); -	term.c.attr.fg = DefaultFG; -	term.c.attr.bg = DefaultBG; -	term.c.attr.mode = ATTR_NULL;  	/* windows */  	xw.h = term.row * xw.ch + 2*BORDER;  	xw.w = term.col * xw.cw + 2*BORDER; @@ -1122,7 +1111,7 @@ xdraws(char *s, Glyph base, int x, int y, int len) {  }  void -xcursor(int mode) { +xdrawcursor(void) {  	static int oldx = 0;  	static int oldy = 0;  	Glyph g = {' ', ATTR_NULL, DefaultBG, DefaultCS, 0}; @@ -1140,7 +1129,7 @@ xcursor(int mode) {  		xclear(oldx, oldy, oldx, oldy);  	/* draw the new one */ -	if(mode == CURSOR_DRAW) { +	if(!(term.c.state & CURSOR_HIDE)) {  		xdraws(&g.c, g, term.c.x, term.c.y, 1);  		oldx = term.c.x, oldy = term.c.y;  	} @@ -1167,7 +1156,7 @@ draw(int dummy) {  			if(term.line[y][x].state & GLYPH_SET)  				xdrawc(x, y, term.line[y][x]); -	xcursor(term.c.hide); +	xdrawcursor();  	XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER);  	XFlush(xw.dis);  } @@ -1203,7 +1192,7 @@ draw(int redraw_all) {  		if(i > 0)  			xdraws(buf, base, ox, y, i);  	} -	xcursor(term.c.hide); +	xdrawcursor();  	XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER);  	XFlush(xw.dis);  } @@ -1215,6 +1204,20 @@ expose(XEvent *ev) {  	draw(SCREEN_REDRAW);  } +void +xseturgency(int add) { +	XWMHints *h = XGetWMHints(xw.dis, xw.win); +	h->flags = add ? (h->flags | XUrgencyHint) : (h->flags & ~XUrgencyHint); +	XSetWMHints(xw.dis, xw.win, h); +	XFree(h); +} + +void +focus(XEvent *ev) { +	if((xw.hasfocus = ev->type == FocusIn)) +		xseturgency(0); +} +  char*  kmap(KeySym k) {  	int i; @@ -1289,12 +1292,12 @@ run(void) {  	XEvent ev;  	fd_set rfd;  	int xfd = XConnectionNumber(xw.dis); +	long mask = ExposureMask | KeyPressMask | StructureNotifyMask | FocusChangeMask; -	running = 1; -	XSelectInput(xw.dis, xw.win, ExposureMask | KeyPressMask | StructureNotifyMask); +	XSelectInput(xw.dis, xw.win, mask);  	XResizeWindow(xw.dis, xw.win, xw.w, xw.h); /* XXX: fix resize bug in wmii (?) */ -	while(running) { +	while(1) {  		FD_ZERO(&rfd);  		FD_SET(cmdfd, &rfd);  		FD_SET(xfd, &rfd);  | 
