#include <X11/keysym.h>
#include <X11/Xutil.h>
+#if defined(LINUX)
+ #include <pty.h>
+#elif defined(OPENBSD)
+ #include <util.h>
+#elif defined(FREEBSD)
+ #include <libutil.h>
+#endif
+
/* Arbitrary sizes */
#define ESC_TITLE_SIZ 256
#define ESC_BUF_SIZ 256
Glyph attr; /* current char attributes */
int x;
int y;
+ char hide;
} TCursor;
/* CSI Escape sequence structs */
int col; /* nb col */
Line* line; /* screen */
TCursor c; /* cursor */
- char hidec;
int top; /* top scroll limit */
int bot; /* bottom scroll limit */
int mode; /* terminal mode flags */
static void tputs(char*, int);
static void treset(void);
static void tresize(int, int);
-static void tscroll(void);
static void tscrollup(int);
static void tscrolldown(int);
static void tsetattr(int*, int);
void
execsh(void) {
char *args[3] = {getenv("SHELL"), "-i", NULL};
- DEFAULT(args[0], "/bin/sh"); /* default shell if getenv() failed */
+ DEFAULT(args[0], "/bin/sh"); /* if getenv() failed */
putenv("TERM=" TNAME);
execvp(args[0], args);
}
void
-xbell(void) { /* visual bell */
- XRectangle r = { BORDER, BORDER, xw.bufw, xw.bufh };
+xbell(void) {
XSetForeground(xw.dis, dc.gc, dc.col[BellCol]);
- XFillRectangles(xw.dis, xw.win, dc.gc, &r, 1);
- /* usleep(30000); */
+ XFillRectangle(xw.dis, xw.win, dc.gc, BORDER, BORDER, xw.bufw, xw.bufh);
+ usleep(BellTime);
draw(SCREEN_REDRAW);
}
void
ttynew(void) {
int m, s;
- char *pts;
-
- if((m = posix_openpt(O_RDWR | O_NOCTTY)) < 0)
- die("openpt failed: %s\n", SERRNO);
- if(grantpt(m) < 0)
- die("grantpt failed: %s\n", SERRNO);
- if(unlockpt(m) < 0)
- die("unlockpt failed: %s\n", SERRNO);
- if(!(pts = ptsname(m)))
- die("ptsname failed: %s\n", SERRNO);
- if((s = open(pts, O_RDWR | O_NOCTTY)) < 0)
- die("Couldn't open slave: %s\n", SERRNO);
- fcntl(s, F_SETFL, O_NDELAY);
+
+ /* seems to work fine on linux, openbsd and freebsd */
+ struct winsize w = {term.row, term.col, 0, 0};
+ if(openpty(&m, &s, NULL, NULL, &w) < 0)
+ die("openpty failed: %s\n", SERRNO);
+
switch(pid = fork()) {
case -1:
die("fork failed\n");
void
treset(void) {
- term.c.attr.mode = ATTR_NULL;
- term.c.attr.fg = DefaultFG;
- term.c.attr.bg = DefaultBG;
- term.c.x = term.c.y = 0;
- term.hidec = 0;
+ term.c = (TCursor){{
+ .mode = ATTR_NULL,
+ .fg = DefaultFG,
+ .bg = DefaultBG
+ }, .x = 0, .y = 0, .hide = 0};
+
term.top = 0, term.bot = term.row - 1;
term.mode = MODE_WRAP;
tclearregion(0, 0, term.col-1, term.row-1);
void
tnew(int col, int row) {
- /* screen size */
+ /* set screen size */
term.row = row, term.col = col;
- term.top = 0, term.bot = term.row - 1;
- /* mode */
- term.mode = MODE_WRAP;
- /* cursor */
- term.c.attr.mode = ATTR_NULL;
- term.c.attr.fg = DefaultFG;
- term.c.attr.bg = DefaultBG;
- term.c.x = term.c.y = 0;
- term.hidec = 0;
- /* allocate screen */
- term.line = calloc(term.row, sizeof(Line));
+ term.line = malloc(term.row * sizeof(Line));
for(row = 0 ; row < term.row; row++)
- term.line[row] = calloc(term.col, sizeof(Glyph));
-}
-
-/* TODO: Replace with scrollup/scolldown */
-void
-tscroll(void) {
- Line temp = term.line[term.top];
- int i;
-
- for(i = term.top; i < term.bot; i++)
- term.line[i] = term.line[i+1];
- memset(temp, 0, sizeof(Glyph) * term.col);
- term.line[term.bot] = temp;
+ term.line[row] = malloc(term.col * sizeof(Glyph));
+ /* setup screen */
+ treset();
}
void
tnewline(void) {
int y = term.c.y + 1;
if(y > term.bot)
- tscroll(), y = term.bot;
+ tscrollup(1), y = term.bot;
tmoveto(0, y);
}
case 12: /* att610 -- Stop blinking cursor (IGNORED) */
break;
case 25:
- term.hidec = 1;
+ term.c.hide = 1;
break;
case 1048: /* XXX: no alt. screen to erase/save */
case 1049:
case 12: /* att610 -- Start blinking cursor (IGNORED) */
break;
case 25:
- term.hidec = 0;
+ term.c.hide = 0;
break;
case 1048:
case 1049: /* XXX: no alt. screen to erase/save */
void
xinit(void) {
- xw.dis = XOpenDisplay(NULL);
- xw.scr = XDefaultScreen(xw.dis);
- if(!xw.dis)
+ if(!(xw.dis = XOpenDisplay(NULL)))
die("Can't open display\n");
+ xw.scr = XDefaultScreen(xw.dis);
/* font */
if(!(dc.font = XLoadQueryFont(xw.dis, FONT)) || !(dc.bfont = XLoadQueryFont(xw.dis, BOLDFONT)))
if(term.line[y][x].state & GLYPH_SET)
xdrawc(x, y, term.line[y][x]);
- if(!term.hidec)
+ if(!term.c.hide)
xcursor(CURSOR_DRAW);
XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER);
XFlush(xw.dis);
}
xdraws(buf, base, ox, y, i);
}
- xcursor(term.hidec ? CURSOR_HIDE : CURSOR_DRAW);
+ xcursor(term.c.hide ? CURSOR_HIDE : CURSOR_DRAW);
XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER);
XFlush(xw.dis);
}