X-Git-Url: https://git.xinqibao.xyz/st.git/blobdiff_plain/ed132e11271d18a5d8aa163096bc6192c694bc47..5683b1f80c5ac274adf98517ce2217b4d4896243:/st.c

diff --git a/st.c b/st.c
index 1a8fa1f..ea0726c 100644
--- a/st.c
+++ b/st.c
@@ -21,13 +21,8 @@
 #include <time.h>
 #include <unistd.h>
 #include <libgen.h>
-#include <fontconfig/fontconfig.h>
 #include <wchar.h>
 
-/* X11 */
-#include <X11/cursorfont.h>
-#include <X11/Xft/Xft.h>
-
 #include "st.h"
 #include "win.h"
 
@@ -48,7 +43,6 @@
 
 /* macros */
 #define NUMMAXLEN(x)		((int)(sizeof(x) * 2.56 + 0.5) + 1)
-#define DEFAULT(a, b)		(a) = (a) ? (a) : (b)
 #define ISCONTROLC0(c)		(BETWEEN(c, 0, 0x1f) || (c) == '\177')
 #define ISCONTROLC1(c)		(BETWEEN(c, 0x80, 0x9f))
 #define ISCONTROL(c)		(ISCONTROLC0(c) || ISCONTROLC1(c))
@@ -110,22 +104,9 @@ typedef struct {
 	int narg;              /* nb of args */
 } STREscape;
 
-/* function definitions used in config.h */
-static void clipcopy(const Arg *);
-static void clippaste(const Arg *);
-static void numlock(const Arg *);
-static void selpaste(const Arg *);
-static void printsel(const Arg *);
-static void printscreen(const Arg *) ;
-static void iso14755(const Arg *);
-static void toggleprinter(const Arg *);
-static void sendbreak(const Arg *);
-
-/* config.h for applying patches and the configuration. */
-#include "config.h"
-
-static void execsh(void);
-static void stty(void);
+
+static void execsh(char **);
+static void stty(char **);
 static void sigchld(int);
 
 static void csidump(void);
@@ -162,8 +143,8 @@ static void tsetchar(Rune, Glyph *, int, int);
 static void tsetscroll(int, int);
 static void tswapscreen(void);
 static void tsetmode(int, int, int *, int);
+static int twrite(const char *, int, int);
 static void tfulldirt(void);
-static void techo(Rune);
 static void tcontrolcode(uchar );
 static void tdectest(char );
 static void tdefutf8(char);
@@ -184,19 +165,10 @@ static char *base64dec(const char *);
 static ssize_t xwrite(int, const char *, size_t);
 
 /* Globals */
-TermWindow win;
 Term term;
 Selection sel;
 int cmdfd;
 pid_t pid;
-char **opt_cmd  = NULL;
-char *opt_class = NULL;
-char *opt_embed = NULL;
-char *opt_font  = NULL;
-char *opt_io    = NULL;
-char *opt_line  = NULL;
-char *opt_name  = NULL;
-char *opt_title = NULL;
 int oldbutton   = 3; /* button event on startup: 3 = release */
 
 static CSIEscape csiescseq;
@@ -208,14 +180,6 @@ static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
 static Rune utfmin[UTF_SIZ + 1] = {       0,    0,  0x80,  0x800,  0x10000};
 static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
 
-/* config.h array lengths */
-size_t colornamelen = LEN(colorname);
-size_t mshortcutslen = LEN(mshortcuts);
-size_t shortcutslen = LEN(shortcuts);
-size_t selmaskslen = LEN(selmasks);
-size_t keyslen = LEN(key);
-size_t mappedkeyslen = LEN(mappedkeys);
-
 ssize_t
 xwrite(int fd, const char *s, size_t len)
 {
@@ -263,7 +227,7 @@ xstrdup(char *s)
 }
 
 size_t
-utf8decode(char *c, Rune *u, size_t clen)
+utf8decode(const char *c, Rune *u, size_t clen)
 {
 	size_t i, j, len, type;
 	Rune udecoded;
@@ -401,13 +365,9 @@ base64dec(const char *src)
 void
 selinit(void)
 {
-	clock_gettime(CLOCK_MONOTONIC, &sel.tclick1);
-	clock_gettime(CLOCK_MONOTONIC, &sel.tclick2);
 	sel.mode = SEL_IDLE;
 	sel.snap = 0;
 	sel.ob.x = -1;
-	sel.primary = NULL;
-	sel.clipboard = NULL;
 }
 
 int
@@ -455,7 +415,8 @@ selnormalize(void)
 int
 selected(int x, int y)
 {
-	if (sel.mode == SEL_EMPTY)
+	if (sel.mode == SEL_EMPTY || sel.ob.x == -1 ||
+			sel.alt != IS_SET(MODE_ALTSCREEN))
 		return 0;
 
 	if (sel.type == SEL_RECTANGULAR)
@@ -594,24 +555,6 @@ getsel(void)
 	return str;
 }
 
-void
-selpaste(const Arg *dummy)
-{
-	xselpaste();
-}
-
-void
-clipcopy(const Arg *dummy)
-{
-	xclipcopy();
-}
-
-void
-clippaste(const Arg *dummy)
-{
-	xclippaste();
-}
-
 void
 selclear(void)
 {
@@ -634,9 +577,9 @@ die(const char *errstr, ...)
 }
 
 void
-execsh(void)
+execsh(char **args)
 {
-	char **args, *sh, *prog;
+	char *sh, *prog;
 	const struct passwd *pw;
 
 	errno = 0;
@@ -650,13 +593,13 @@ execsh(void)
 	if ((sh = getenv("SHELL")) == NULL)
 		sh = (pw->pw_shell[0]) ? pw->pw_shell : shell;
 
-	if (opt_cmd)
-		prog = opt_cmd[0];
+	if (args)
+		prog = args[0];
 	else if (utmp)
 		prog = utmp;
 	else
 		prog = sh;
-	args = (opt_cmd) ? opt_cmd : (char *[]) {prog, NULL};
+	DEFAULT(args, ((char *[]) {prog, NULL}));
 
 	unsetenv("COLUMNS");
 	unsetenv("LINES");
@@ -697,7 +640,7 @@ sigchld(int a)
 
 
 void
-stty(void)
+stty(char **args)
 {
 	char cmd[_POSIX_ARG_MAX], **p, *q, *s;
 	size_t n, siz;
@@ -707,7 +650,7 @@ stty(void)
 	memcpy(cmd, stty_args, n);
 	q = cmd + n;
 	siz = sizeof(cmd) - n;
-	for (p = opt_cmd; p && (s = *p); ++p) {
+	for (p = args; p && (s = *p); ++p) {
 		if ((n = strlen(s)) > siz-1)
 			die("stty parameter length too long\n");
 		*q++ = ' ';
@@ -721,31 +664,30 @@ stty(void)
 }
 
 void
-ttynew(void)
+ttynew(char *line, char *out, char **args)
 {
 	int m, s;
-	struct winsize w = {term.row, term.col, 0, 0};
 
-	if (opt_io) {
+	if (out) {
 		term.mode |= MODE_PRINT;
-		iofd = (!strcmp(opt_io, "-")) ?
-			  1 : open(opt_io, O_WRONLY | O_CREAT, 0666);
+		iofd = (!strcmp(out, "-")) ?
+			  1 : open(out, O_WRONLY | O_CREAT, 0666);
 		if (iofd < 0) {
 			fprintf(stderr, "Error opening %s:%s\n",
-				opt_io, strerror(errno));
+				out, strerror(errno));
 		}
 	}
 
-	if (opt_line) {
-		if ((cmdfd = open(opt_line, O_RDWR)) < 0)
+	if (line) {
+		if ((cmdfd = open(line, O_RDWR)) < 0)
 			die("open line failed: %s\n", strerror(errno));
 		dup2(cmdfd, 0);
-		stty();
+		stty(args);
 		return;
 	}
 
 	/* seems to work fine on linux, openbsd and freebsd */
-	if (openpty(&m, &s, NULL, NULL, &w) < 0)
+	if (openpty(&m, &s, NULL, NULL, NULL) < 0)
 		die("openpty failed: %s\n", strerror(errno));
 
 	switch (pid = fork()) {
@@ -762,7 +704,7 @@ ttynew(void)
 			die("ioctl TIOCSCTTY failed: %s\n", strerror(errno));
 		close(s);
 		close(m);
-		execsh();
+		execsh(args);
 		break;
 	default:
 		close(s);
@@ -777,38 +719,19 @@ ttyread(void)
 {
 	static char buf[BUFSIZ];
 	static int buflen = 0;
-	char *ptr;
-	int charsize; /* size of utf8 char in bytes */
-	Rune unicodep;
+	int written;
 	int ret;
 
 	/* append read bytes to unprocessed bytes */
 	if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0)
 		die("Couldn't read from shell: %s\n", strerror(errno));
-
 	buflen += ret;
-	ptr = buf;
-
-	for (;;) {
-		if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
-			/* process a complete utf8 char */
-			charsize = utf8decode(ptr, &unicodep, buflen);
-			if (charsize == 0)
-				break;
-			tputc(unicodep);
-			ptr += charsize;
-			buflen -= charsize;
 
-		} else {
-			if (buflen <= 0)
-				break;
-			tputc(*ptr++ & 0xFF);
-			buflen--;
-		}
-	}
+	written = twrite(buf, buflen, 0);
+	buflen -= written;
 	/* keep any uncomplete utf8 char for the next call */
 	if (buflen > 0)
-		memmove(buf, ptr, buflen);
+		memmove(buf, buf + written, buflen);
 
 	return ret;
 }
@@ -873,27 +796,9 @@ write_error:
 void
 ttysend(char *s, size_t n)
 {
-	int len;
-	char *t, *lim;
-	Rune u;
-
 	ttywrite(s, n);
-	if (!IS_SET(MODE_ECHO))
-		return;
-
-	lim = &s[n];
-	for (t = s; t < lim; t += len) {
-		if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
-			len = utf8decode(t, &u, n);
-		} else {
-			u = *t & 0xFF;
-			len = 1;
-		}
-		if (len <= 0)
-			break;
-		techo(u);
-		n -= len;
-	}
+	if (IS_SET(MODE_ECHO))
+		twrite(s, n, 1);
 }
 
 void
@@ -1618,7 +1523,7 @@ csihandle(void)
 		break;
 	case 'c': /* DA -- Device Attributes */
 		if (csiescseq.arg[0] == 0)
-			ttywrite(vtiden, sizeof(vtiden) - 1);
+			ttywrite(vtiden, strlen(vtiden));
 		break;
 	case 'C': /* CUF -- Cursor <n> Forward */
 	case 'a': /* HPR -- Cursor <n> Forward */
@@ -1768,11 +1673,8 @@ csihandle(void)
 	case ' ':
 		switch (csiescseq.mode[1]) {
 		case 'q': /* DECSCUSR -- Set Cursor Style */
-			DEFAULT(csiescseq.arg[0], 1);
-			if (!BETWEEN(csiescseq.arg[0], 0, 6)) {
+			if (xsetcursor(csiescseq.arg[0]))
 				goto unknown;
-			}
-			win.cursor = csiescseq.arg[0];
 			break;
 		default:
 			goto unknown;
@@ -1836,8 +1738,8 @@ strhandle(void)
 
 				dec = base64dec(strescseq.args[2]);
 				if (dec) {
-					xsetsel(dec, CurrentTime);
-					clipcopy(NULL);
+					xsetsel(dec);
+					xclipcopy();
 				} else {
 					fprintf(stderr, "erresc: invalid base64\n");
 				}
@@ -1942,8 +1844,7 @@ void
 tprinter(char *s, size_t len)
 {
 	if (iofd != -1 && xwrite(iofd, s, len) < 0) {
-		fprintf(stderr, "Error writing in %s:%s\n",
-			opt_io, strerror(errno));
+		perror("Error writing to output file");
 		close(iofd);
 		iofd = -1;
 	}
@@ -2041,22 +1942,6 @@ tputtab(int n)
 	term.c.x = LIMIT(x, 0, term.col-1);
 }
 
-void
-techo(Rune u)
-{
-	if (ISCONTROL(u)) { /* control code */
-		if (u & 0x80) {
-			u &= 0x7f;
-			tputc('^');
-			tputc('[');
-		} else if (u != '\n' && u != '\r' && u != '\t') {
-			u ^= 0x40;
-			tputc('^');
-		}
-	}
-	tputc(u);
-}
-
 void
 tdefutf8(char ascii)
 {
@@ -2197,7 +2082,7 @@ tcontrolcode(uchar ascii)
 	case 0x99:   /* TODO: SGCI */
 		break;
 	case 0x9a:   /* DECID -- Identify Terminal */
-		ttywrite(vtiden, sizeof(vtiden) - 1);
+		ttywrite(vtiden, strlen(vtiden));
 		break;
 	case 0x9b:   /* TODO: CSI */
 	case 0x9c:   /* TODO: ST */
@@ -2269,7 +2154,7 @@ eschandle(uchar ascii)
 		}
 		break;
 	case 'Z': /* DECID -- Identify Terminal */
-		ttywrite(vtiden, sizeof(vtiden) - 1);
+		ttywrite(vtiden, strlen(vtiden));
 		break;
 	case 'c': /* RIS -- Reset to inital state */
 		treset();
@@ -2447,6 +2332,38 @@ check_control_code:
 	}
 }
 
+int
+twrite(const char *buf, int buflen, int show_ctrl)
+{
+	int charsize;
+	Rune u;
+	int n;
+
+	for (n = 0; n < buflen; n += charsize) {
+		if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) {
+			/* process a complete utf8 char */
+			charsize = utf8decode(buf + n, &u, buflen - n);
+			if (charsize == 0)
+				break;
+		} else {
+			u = buf[n] & 0xFF;
+			charsize = 1;
+		}
+		if (show_ctrl && ISCONTROL(u)) {
+			if (u & 0x80) {
+				u &= 0x7f;
+				tputc('^');
+				tputc('[');
+			} else if (u != '\n' && u != '\r' && u != '\t') {
+				u ^= 0x40;
+				tputc('^');
+			}
+		}
+		tputc(u);
+	}
+	return n;
+}
+
 void
 tresize(int col, int row)
 {
@@ -2532,7 +2449,7 @@ tresize(int col, int row)
 void
 resettitle(void)
 {
-	xsettitle(opt_title ? opt_title : "st");
+	xsettitle(NULL);
 }
 
 void