short lbearing;
short rbearing;
XFontSet set;
- } font, bfont, ifont;
+ } font, bfont, ifont, ibfont;
} DC;
static void die(const char*, ...);
static void xdrawcursor(void);
static void xinit(void);
static void xloadcols(void);
+static void xresettitle(void);
static void xseturgency(int);
static void xsetsel(char*);
static void xresize(int, int);
static int utf8size(char *);
static int isfullutf8(char *, int);
+static void *xmalloc(size_t);
+static void *xrealloc(void *, size_t);
+
static void (*handler[LASTEvent])(XEvent *) = {
[KeyPress] = kpress,
[ClientMessage] = cmessage,
static int cmdfd;
static pid_t pid;
static Selection sel;
-static FILE *fileio;
+static int iofd = -1;
static char **opt_cmd = NULL;
static char *opt_io = NULL;
static char *opt_title = NULL;
static char *opt_embed = NULL;
static char *opt_class = NULL;
+void *
+xmalloc(size_t len) {
+ void *p = malloc(len);
+ if(!p)
+ die("Out of memory");
+ return p;
+}
+
+void *
+xrealloc(void *p, size_t len) {
+ if((p = realloc(p, len)) == NULL)
+ die("Out of memory");
+ return p;
+}
+
int
utf8decode(char *s, long *u) {
uchar c;
else {
bufsize = (term.col+1) * (sel.e.y-sel.b.y+1) * UTF_SIZ;
- ptr = str = malloc(bufsize);
+ ptr = str = xmalloc(bufsize);
/* append every set & selected glyph to the selection */
for(y = 0; y < term.row; y++) {
unsetenv("LINES");
unsetenv("TERMCAP");
+ signal(SIGCHLD, SIG_DFL);
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGALRM, SIG_DFL);
+
DEFAULT(envshell, SHELL);
putenv("TERM="TNAME);
args = opt_cmd ? opt_cmd : (char*[]){envshell, "-i", NULL};
signal(SIGCHLD, sigchld);
if(opt_io) {
if(!strcmp(opt_io, "-")) {
- fileio = stdout;
+ iofd = STDOUT_FILENO;
} else {
- if(!(fileio = fopen(opt_io, "w"))) {
+ if((iofd = open(opt_io, O_WRONLY | O_CREAT, 0666)) < 0) {
fprintf(stderr, "Error opening %s:%s\n",
opt_io, strerror(errno));
}
tnew(int col, int row) {
/* set screen size */
term.row = row, term.col = col;
- term.line = malloc(term.row * sizeof(Line));
- term.alt = malloc(term.row * sizeof(Line));
- term.dirty = malloc(term.row * sizeof(*term.dirty));
- term.tabs = malloc(term.col * sizeof(*term.tabs));
+ term.line = xmalloc(term.row * sizeof(Line));
+ term.alt = xmalloc(term.row * sizeof(Line));
+ term.dirty = xmalloc(term.row * sizeof(*term.dirty));
+ term.tabs = xmalloc(term.col * sizeof(*term.tabs));
for(row = 0; row < term.row; row++) {
- term.line[row] = malloc(term.col * sizeof(Glyph));
- term.alt [row] = malloc(term.col * sizeof(Glyph));
+ term.line[row] = xmalloc(term.col * sizeof(Glyph));
+ term.alt [row] = xmalloc(term.col * sizeof(Glyph));
term.dirty[row] = 0;
}
memset(term.tabs, 0, term.col * sizeof(*term.tabs));
case 7:
term.c.attr.mode |= ATTR_REVERSE;
break;
+ case 21:
case 22:
term.c.attr.mode &= ~ATTR_BOLD;
break;
tputc(char *c) {
char ascii = *c;
- if(fileio) {
- putc(ascii, fileio);
- fflush(fileio);
- }
+ if(iofd != -1)
+ write(iofd, c, 1);
if(term.esc & ESC_START) {
if(term.esc & ESC_CSI) {
case 'c': /* RIS -- Reset to inital state */
treset();
term.esc = 0;
+ xresettitle();
break;
case '=': /* DECPAM -- Application keypad */
term.mode |= MODE_APPKEYPAD;
if(sel.bx != -1 && BETWEEN(term.c.y, sel.by, sel.ey))
sel.bx = -1;
switch(ascii) {
+ case '\0': /* padding character, do nothing */
+ break;
case '\t':
tputtab(1);
break;
}
/* resize to new height */
- term.line = realloc(term.line, row * sizeof(Line));
- term.alt = realloc(term.alt, row * sizeof(Line));
- term.dirty = realloc(term.dirty, row * sizeof(*term.dirty));
- term.tabs = realloc(term.tabs, col * sizeof(*term.tabs));
+ term.line = xrealloc(term.line, row * sizeof(Line));
+ term.alt = xrealloc(term.alt, row * sizeof(Line));
+ term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty));
+ term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs));
/* resize each row to new width, zero-pad if needed */
for(i = 0; i < minrow; i++) {
term.dirty[i] = 1;
- term.line[i] = realloc(term.line[i], col * sizeof(Glyph));
- term.alt[i] = realloc(term.alt[i], col * sizeof(Glyph));
+ term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph));
+ term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph));
for(x = mincol; x < col; x++) {
term.line[i][x].state = 0;
term.alt[i][x].state = 0;
}
void
-initfonts(char *fontstr, char *bfontstr, char *ifontstr) {
+initfonts(char *fontstr, char *bfontstr, char *ifontstr, char *ibfontstr) {
if((dc.font.set = xinitfont(fontstr)) == NULL)
die("Can't load font %s\n", fontstr);
if((dc.bfont.set = xinitfont(bfontstr)) == NULL)
die("Can't load bfont %s\n", bfontstr);
if((dc.ifont.set = xinitfont(ifontstr)) == NULL)
die("Can't load ifont %s\n", ifontstr);
+ if((dc.ibfont.set = xinitfont(ibfontstr)) == NULL)
+ die("Can't load ibfont %s\n", ibfontstr);
xgetfontinfo(dc.font.set, &dc.font.ascent, &dc.font.descent,
&dc.font.lbearing, &dc.font.rbearing);
&dc.bfont.lbearing, &dc.bfont.rbearing);
xgetfontinfo(dc.ifont.set, &dc.ifont.ascent, &dc.ifont.descent,
&dc.ifont.lbearing, &dc.ifont.rbearing);
+ xgetfontinfo(dc.ibfont.set, &dc.ibfont.ascent, &dc.ibfont.descent,
+ &dc.ibfont.lbearing, &dc.ibfont.rbearing);
}
void
xw.scr = XDefaultScreen(xw.dpy);
/* font */
- initfonts(FONT, BOLDFONT, ITALICFONT);
+ initfonts(FONT, BOLDFONT, ITALICFONT, ITALICBOLDFONT);
/* XXX: Assuming same size for bold font */
xw.cw = dc.font.rbearing - dc.font.lbearing;
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
- XStoreName(xw.dpy, xw.win, opt_title ? opt_title : "st");
+ xresettitle();
XMapWindow(xw.dpy, xw.win);
xhints();
XSync(xw.dpy, 0);
if(base.mode & ATTR_ITALIC)
fontset = dc.ifont.set;
+ if(base.mode & (ATTR_ITALIC|ATTR_ITALIC))
+ fontset = dc.ibfont.set;
XSetBackground(xw.dpy, dc.gc, dc.col[bg]);
XSetForeground(xw.dpy, dc.gc, dc.col[fg]);
xcopy();
}
+void
+xresettitle(void) {
+ XStoreName(xw.dpy, xw.win, opt_title ? opt_title : "st");
+}
+
void
redraw(void) {
struct timespec tv = {0, REDRAW_TIMEOUT * 1000};