X-Git-Url: https://git.xinqibao.xyz/st.git/blobdiff_plain/6b315558f8095b91988d5b305ed06e082da48889..ba36d1394b3add5b9d4c174f1443cc312bcc7e09:/st.c

diff --git a/st.c b/st.c
index c50a202..79a4e0a 100644
--- a/st.c
+++ b/st.c
@@ -94,12 +94,11 @@ enum glyph_attribute {
 	ATTR_REVERSE   = 1,
 	ATTR_UNDERLINE = 2,
 	ATTR_BOLD      = 4,
-	ATTR_GFX       = 8,
-	ATTR_ITALIC    = 16,
-	ATTR_BLINK     = 32,
-	ATTR_WRAP      = 64,
-	ATTR_WIDE      = 128,
-	ATTR_WDUMMY    = 256,
+	ATTR_ITALIC    = 8,
+	ATTR_BLINK     = 16,
+	ATTR_WRAP      = 32,
+	ATTR_WIDE      = 64,
+	ATTR_WDUMMY    = 128,
 };
 
 enum cursor_movement {
@@ -341,7 +340,7 @@ typedef struct {
 
 /* Drawing Context */
 typedef struct {
-	Colour col[LEN(colorname) < 256 ? 256 : LEN(colorname)];
+	Colour col[MAX(LEN(colorname), 256)];
 	Font font, bfont, ifont, ibfont;
 	GC gc;
 } DC;
@@ -393,10 +392,9 @@ static void tsetdirtattr(int);
 static void tsetmode(bool, bool, int *, int);
 static void tfulldirt(void);
 static void techo(char *, int);
-static bool tcontrolcode(uchar );
+static void tcontrolcode(uchar );
 static void tdectest(char );
 static int32_t tdefcolor(int *, int *, int);
-static void tselcs(void);
 static void tdeftran(char);
 static inline bool match(uint, uint);
 static void ttynew(void);
@@ -767,7 +765,7 @@ selsnap(int mode, int *x, int *y, int direction) {
 void
 getbuttoninfo(XEvent *e) {
 	int type;
-	uint state = e->xbutton.state &~Button1Mask;
+	uint state = e->xbutton.state & ~(Button1Mask | forceselmod);
 
 	sel.alt = IS_SET(MODE_ALTSCREEN);
 
@@ -831,6 +829,8 @@ mousereport(XEvent *e) {
 			/* MODE_MOUSEX10: no button release reporting */
 			if(IS_SET(MODE_MOUSEX10))
 				return;
+			if (button == 64 || button == 65)
+				return;
 		}
 	}
 
@@ -860,7 +860,7 @@ bpress(XEvent *e) {
 	struct timeval now;
 	Mousekey *mk;
 
-	if(IS_SET(MODE_MOUSE)) {
+	if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
 		mousereport(e);
 		return;
 	}
@@ -951,7 +951,7 @@ getsel(void) {
 		 * st.
 		 * FIXME: Fix the computer world.
 		 */
-		if(y < sel.ne.y && x > 0 && !((gp-1)->mode & ATTR_WRAP))
+		if(y < sel.ne.y && !(x > 0 && (gp-1)->mode & ATTR_WRAP))
 			*ptr++ = '\n';
 
 		/*
@@ -1092,7 +1092,7 @@ xsetsel(char *str) {
 
 void
 brelease(XEvent *e) {
-	if(IS_SET(MODE_MOUSE)) {
+	if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
 		mousereport(e);
 		return;
 	}
@@ -1115,7 +1115,7 @@ void
 bmotion(XEvent *e) {
 	int oldey, oldex, oldsby, oldsey;
 
-	if(IS_SET(MODE_MOUSE)) {
+	if(IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
 		mousereport(e);
 		return;
 	}
@@ -1535,7 +1535,7 @@ tsetchar(char *c, Glyph *attr, int x, int y) {
 	/*
 	 * The table is proudly stolen from rxvt.
 	 */
-	if(attr->mode & ATTR_GFX) {
+	if(term.trantbl[term.charset] == CS_GRAPHIC0) {
 		if(BETWEEN(c[0], 0x41, 0x7e) && vt100_0[c[0] - 0x41]) {
 			c = vt100_0[c[0] - 0x41];
 		}
@@ -1839,7 +1839,7 @@ tsetmode(bool priv, bool set, int *args, int narg) {
 				if (!allowaltscreen)
 					break;
 				tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
-				/* FALLTHRU */
+				/* FALLTHROUGH */
 			case 47: /* swap screen */
 			case 1047:
 				if (!allowaltscreen)
@@ -1853,7 +1853,7 @@ tsetmode(bool priv, bool set, int *args, int narg) {
 					tswapscreen();
 				if(*args != 1049)
 					break;
-				/* FALLTRU */
+				/* FALLTHROUGH */
 			case 1048:
 				tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD);
 				break;
@@ -2148,7 +2148,7 @@ strhandle(void) {
 			if(narg < 3)
 				break;
 			p = strescseq.args[2];
-			/* fall through */
+			/* FALLTHROUGH */
 		case 104: /* color reset, here p = NULL */
 			j = (narg > 1) ? atoi(strescseq.args[1]) : -1;
 			if (!xsetcolorname(j, p)) {
@@ -2317,9 +2317,7 @@ void
 tdeftran(char ascii) {
 	char c, (*bp)[2];
 	static char tbl[][2] = {
-		{'0', CS_GRAPHIC0}, {'1', CS_GRAPHIC1}, {'A', CS_UK},
-		{'B', CS_USA},      {'<', CS_MULTI},    {'K', CS_GER},
-		{'5', CS_FIN},      {'C', CS_FIN},
+		{'0', CS_GRAPHIC0}, {'B', CS_USA},
 		{0, 0}
 	};
 
@@ -2333,32 +2331,25 @@ tdeftran(char ascii) {
 }
 
 void
-tselcs(void) {
-	MODBIT(term.c.attr.mode,
-	       term.trantbl[term.charset] == CS_GRAPHIC0,
-	       ATTR_GFX);
-}
-
-bool
 tcontrolcode(uchar ascii) {
 	static char question[UTF_SIZ] = "?";
 
 	switch(ascii) {
 	case '\t':   /* HT */
 		tputtab(1);
-		break;
+		return;
 	case '\b':   /* BS */
 		tmoveto(term.c.x-1, term.c.y);
-		break;
+		return;
 	case '\r':   /* CR */
 		tmoveto(0, term.c.y);
-		break;
+		return;
 	case '\f':   /* LF */
 	case '\v':   /* VT */
 	case '\n':   /* LF */
 		/* go to first col if the mode is set */
 		tnewline(IS_SET(MODE_CRLF));
-		break;
+		return;
 	case '\a':   /* BEL */
 		if(term.esc & ESC_STR_END) {
 			/* backwards compatibility to xterm */
@@ -2374,15 +2365,13 @@ tcontrolcode(uchar ascii) {
 		csireset();
 		term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST);
 		term.esc |= ESC_START;
-		return 1;
+		return;
 	case '\016': /* SO */
 		term.charset = 0;
-		tselcs();
-		break;
+		return;
 	case '\017': /* SI */
 		term.charset = 1;
-		tselcs();
-		break;
+		return;
 	case '\032': /* SUB */
 		tsetchar(question, &term.c.attr, term.c.x, term.c.y);
 	case '\030': /* CAN */
@@ -2393,6 +2382,7 @@ tcontrolcode(uchar ascii) {
 	case '\021': /* XON (IGNORED) */
 	case '\023': /* XOFF (IGNORED) */
 	case 0177:   /* DEL (IGNORED) */
+		return;
 	case 0x84:   /* TODO: IND */
 	case 0x85:   /* TODO: NEL */
 	case 0x88:   /* TODO: HTS */
@@ -2408,11 +2398,10 @@ tcontrolcode(uchar ascii) {
 	case 0x9e:   /* TODO: PM */
 	case 0x9f:   /* TODO: APC */
 		break;
-	default:
-		return 0;
 	}
+	/* only CAN, SUB, \a and C1 chars interrupt a sequence */
 	term.esc &= ~(ESC_STR_END|ESC_STR);
-	return 1;
+	return;
 }
 
 void
@@ -2461,7 +2450,7 @@ tputc(char *c, int len) {
 		   (ascii == '\a' || ascii == 030 ||
 		    ascii == 032  || ascii == 033 ||
 		    ISCONTROLC1(unicodep))) {
-			term.esc &= ~ESC_STR;
+			term.esc &= ~(ESC_START|ESC_STR);
 			term.esc |= ESC_STR_END;
 		} else if(strescseq.len + len < sizeof(strescseq.buf) - 1) {
 			memmove(&strescseq.buf[strescseq.len], c, len);
@@ -2491,8 +2480,11 @@ tputc(char *c, int len) {
 	 * they must not cause conflicts with sequences.
 	 */
 	if(control) {
-		if (tcontrolcode(ascii))
-			return;
+		tcontrolcode(ascii);
+		/*
+		 * control codes are not shown ever
+		 */
+		return;
 	} else if(term.esc & ESC_START) {
 		if(term.esc & ESC_CSI) {
 			csiescseq.buf[csiescseq.len++] = ascii;
@@ -2506,7 +2498,6 @@ tputc(char *c, int len) {
 			return;
 		} else if(term.esc & ESC_ALTCHARSET) {
 			tdeftran(ascii);
-			tselcs();
 		} else if(term.esc & ESC_TEST) {
 			tdectest(ascii);
 		} else {
@@ -2590,11 +2581,6 @@ tputc(char *c, int len) {
 		 */
 		return;
 	}
-	/*
-	 * Display control codes only if we are in graphic mode
-	 */
-	if(control && !(term.c.attr.mode & ATTR_GFX))
-		return;
 	if(sel.ob.x != -1 && BETWEEN(term.c.y, sel.ob.y, sel.oe.y))
 		selclear(NULL);
 
@@ -2731,7 +2717,7 @@ sixd_to_16bit(int x) {
 
 void
 xloadcols(void) {
-	int i, r, g, b;
+	int i;
 	XRenderColor color = { .alpha = 0xffff };
 	static bool loaded;
 	Colour *cp;
@@ -2741,7 +2727,7 @@ xloadcols(void) {
 			XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
 	}
 
-	/* load colors [0-15] colors and [256-LEN(colorname)[ (config.h) */
+	/* load colours [0-15] and [256-LEN(colorname)] (config.h) */
 	for(i = 0; i < LEN(colorname); i++) {
 		if(!colorname[i])
 			continue;
@@ -2750,27 +2736,20 @@ xloadcols(void) {
 		}
 	}
 
-	/* load colors [16-255] ; same colors as xterm */
-	for(i = 16, r = 0; r < 6; r++) {
-		for(g = 0; g < 6; g++) {
-			for(b = 0; b < 6; b++) {
-				color.red = sixd_to_16bit(r);
-				color.green = sixd_to_16bit(g);
-				color.blue = sixd_to_16bit(b);
-				if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i])) {
-					die("Could not allocate color %d\n", i);
-				}
-				i++;
-			}
-		}
+	/* load colours [16-231] ; same colours as xterm */
+	for(i = 16; i < 6*6*6+16; i++) {
+		color.red   = sixd_to_16bit( ((i-16)/36)%6 );
+		color.green = sixd_to_16bit( ((i-16)/6) %6 );
+		color.blue  = sixd_to_16bit( ((i-16)/1) %6 );
+		if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i]))
+			die("Could not allocate color %d\n", i);
 	}
 
-	for(r = 0; r < 24; r++, i++) {
-		color.red = color.green = color.blue = 0x0808 + 0x0a0a * r;
-		if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color,
-					&dc.col[i])) {
+	/* load colours [232-255] ; grayscale */
+	for(; i < 256; i++) {
+		color.red = color.green = color.blue = 0x0808 + 0x0a0a * (i-(6*6*6+16));
+		if(!XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &color, &dc.col[i]))
 			die("Could not allocate color %d\n", i);
-		}
 	}
 	loaded = true;
 }
@@ -3165,24 +3144,20 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) {
 	}
 
 	if(base.mode & ATTR_BOLD) {
-		if(BETWEEN(base.fg, 0, 7)) {
-			/* basic system colors */
-			fg = &dc.col[base.fg + 8];
-		} else if(BETWEEN(base.fg, 16, 195)) {
-			/* 256 colors */
-			fg = &dc.col[base.fg + 36];
-		} else if(BETWEEN(base.fg, 232, 251)) {
-			/* greyscale */
-			fg = &dc.col[base.fg + 4];
-		}
 		/*
-		 * Those ranges will not be brightened:
-		 *    8 - 15 – bright system colors
-		 *    196 - 231 – highest 256 color cube
-		 *    252 - 255 – brightest colors in greyscale
+		 * change basic system colours [0-7]
+		 * to bright system colours [8-15]
 		 */
-		font = &dc.bfont;
-		frcflags = FRC_BOLD;
+		if(BETWEEN(base.fg, 0, 7))
+			fg = &dc.col[base.fg + 8];
+
+		if(base.mode & ATTR_ITALIC) {
+			font = &dc.ibfont;
+			frcflags = FRC_ITALICBOLD;
+		} else {
+			font = &dc.bfont;
+			frcflags = FRC_BOLD;
+		}
 	}
 
 	if(IS_SET(MODE_REVERSE)) {
@@ -3455,6 +3430,7 @@ void
 redraw(int timeout) {
 	struct timespec tv = {0, timeout * 1000};
 
+	tfulldirt();
 	draw();
 
 	if(timeout > 0) {