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); |