X-Git-Url: https://git.xinqibao.xyz/st.git/blobdiff_plain/a1cd28f8099eac3938461f9e63ff6b74d4d824ef..d018c9c8efc3e1781d84d7b7d24e9531bb841b34:/st.c?ds=sidebyside

diff --git a/st.c b/st.c
index 7852de0..0db81f4 100644
--- a/st.c
+++ b/st.c
@@ -77,6 +77,7 @@ enum glyph_attribute {
 	ATTR_BOLD      = 4,
 	ATTR_GFX       = 8,
 	ATTR_ITALIC    = 16,
+	ATTR_BLINK     = 32,
 };
 
 enum cursor_movement {
@@ -325,6 +326,9 @@ static int utf8encode(long *, char *);
 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,
@@ -351,13 +355,28 @@ static STREscape strescseq;
 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;
@@ -551,7 +570,6 @@ bpress(XEvent *e) {
 		sel.mode = 1;
 		sel.ex = sel.bx = X2COL(e->xbutton.x);
 		sel.ey = sel.by = Y2ROW(e->xbutton.y);
-		draw();
 	}
 }
 
@@ -565,7 +583,7 @@ selcopy(void) {
 
 	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++) {
@@ -803,9 +821,9 @@ ttynew(void) {
 		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));
 				}
@@ -918,14 +936,14 @@ void
 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));
@@ -1134,7 +1152,7 @@ tsetattr(int *attr, int l) {
 		switch(attr[i]) {
 		case 0:
 			term.c.attr.mode &= ~(ATTR_REVERSE | ATTR_UNDERLINE | ATTR_BOLD \
-					| ATTR_ITALIC);
+					| ATTR_ITALIC | ATTR_BLINK);
 			term.c.attr.fg = DefaultFG;
 			term.c.attr.bg = DefaultBG;
 			break;
@@ -1147,9 +1165,13 @@ tsetattr(int *attr, int l) {
 		case 4:
 			term.c.attr.mode |= ATTR_UNDERLINE;
 			break;
+		case 5:
+			term.c.attr.mode |= ATTR_BLINK;
+			break;
 		case 7:
 			term.c.attr.mode |= ATTR_REVERSE;
 			break;
+		case 21:
 		case 22:
 			term.c.attr.mode &= ~ATTR_BOLD;
 			break;
@@ -1159,6 +1181,9 @@ tsetattr(int *attr, int l) {
 		case 24:
 			term.c.attr.mode &= ~ATTR_UNDERLINE;
 			break;
+		case 25:
+			term.c.attr.mode &= ~ATTR_BLINK;
+			break;
 		case 27:
 			term.c.attr.mode &= ~ATTR_REVERSE;
 			break;
@@ -1198,7 +1223,7 @@ tsetattr(int *attr, int l) {
 			else if(BETWEEN(attr[i], 90, 97))
 				term.c.attr.fg = attr[i] - 90 + 8;
 			else if(BETWEEN(attr[i], 100, 107))
-				term.c.attr.fg = attr[i] - 100 + 8;
+				term.c.attr.bg = attr[i] - 100 + 8;
 			else
 				fprintf(stderr, "erresc(default): gfx attr %d unknown\n", attr[i]), csidump();
 			break;
@@ -1510,6 +1535,9 @@ strhandle(void) {
 			break;
 		}
 		break;
+	case 'k': /* old title set compatibility */
+		XStoreName(xw.dpy, xw.win, strescseq.buf);
+		break;
 	case 'P': /* DSC -- Device Control String */
 	case '_': /* APC -- Application Program Command */
 	case '^': /* PM -- Privacy Message */
@@ -1572,10 +1600,8 @@ void
 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) {
@@ -1625,6 +1651,7 @@ tputc(char *c) {
 			case '_': /* APC -- Application Program Command */
 			case '^': /* PM -- Privacy Message */
 			case ']': /* OSC -- Operating System Command */
+			case 'k': /* old title set compatibility */
 				strreset();
 				strescseq.type = ascii;
 				term.esc |= ESC_STR;
@@ -1751,16 +1778,16 @@ tresize(int col, int row) {
 	}
 
 	/* 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;
@@ -1934,6 +1961,17 @@ xinit(void) {
 		die("Can't open display\n");
 	xw.scr = XDefaultScreen(xw.dpy);
 
+	/* font */
+	initfonts(FONT, BOLDFONT, ITALICFONT);
+
+	/* XXX: Assuming same size for bold font */
+	xw.cw = dc.font.rbearing - dc.font.lbearing;
+	xw.ch = dc.font.ascent + dc.font.descent;
+
+	/* colors */
+	xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
+	xloadcols();
+
 	/* adjust fixed window geometry */
 	if(xw.isfixed) {
 		sw = DisplayWidth(xw.dpy, xw.scr);
@@ -1953,17 +1991,6 @@ xinit(void) {
 		xw.fy = 0;
 	}
 
-	/* font */
-	initfonts(FONT, BOLDFONT, ITALICFONT);
-
-	/* XXX: Assuming same size for bold font */
-	xw.cw = dc.font.rbearing - dc.font.lbearing;
-	xw.ch = dc.font.ascent + dc.font.descent;
-
-	/* colors */
-	xw.cmap = XDefaultColormap(xw.dpy, xw.scr);
-	xloadcols();
-
 	attrs.background_pixel = dc.col[DefaultBG];
 	attrs.border_pixel = dc.col[DefaultBG];
 	attrs.bit_gravity = NorthWestGravity;