1
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								TODO
									
									
									
									
									
								
							| @@ -1,7 +1,6 @@ | |||||||
| vt emulation | vt emulation | ||||||
| ------------ | ------------ | ||||||
|  |  | ||||||
| * wide-character support in conjunction with fallback xft code  |  | ||||||
| * double-height support | * double-height support | ||||||
|  |  | ||||||
| code & interface | code & interface | ||||||
|   | |||||||
							
								
								
									
										84
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								st.c
									
									
									
									
									
								
							| @@ -27,6 +27,7 @@ | |||||||
| #include <X11/keysym.h> | #include <X11/keysym.h> | ||||||
| #include <X11/Xft/Xft.h> | #include <X11/Xft/Xft.h> | ||||||
| #include <fontconfig/fontconfig.h> | #include <fontconfig/fontconfig.h> | ||||||
|  | #include <wchar.h> | ||||||
|  |  | ||||||
| #include "arg.h" | #include "arg.h" | ||||||
|  |  | ||||||
| @@ -96,6 +97,8 @@ enum glyph_attribute { | |||||||
| 	ATTR_ITALIC    = 16, | 	ATTR_ITALIC    = 16, | ||||||
| 	ATTR_BLINK     = 32, | 	ATTR_BLINK     = 32, | ||||||
| 	ATTR_WRAP      = 64, | 	ATTR_WRAP      = 64, | ||||||
|  | 	ATTR_WIDE      = 128, | ||||||
|  | 	ATTR_WDUMMY    = 256, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum cursor_movement { | enum cursor_movement { | ||||||
| @@ -165,7 +168,7 @@ typedef unsigned short ushort; | |||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
| 	char c[UTF_SIZ]; /* character code */ | 	char c[UTF_SIZ]; /* character code */ | ||||||
| 	uchar mode;      /* attribute flags */ | 	ushort mode;      /* attribute flags */ | ||||||
| 	ulong fg;        /* foreground  */ | 	ulong fg;        /* foreground  */ | ||||||
| 	ulong bg;        /* background  */ | 	ulong bg;        /* background  */ | ||||||
| } Glyph; | } Glyph; | ||||||
| @@ -719,8 +722,13 @@ selsnap(int mode, int *x, int *y, int direction) { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			if(term.line[*y][*x+direction].mode & ATTR_WDUMMY) { | ||||||
|  | 				*x += direction; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			if(strchr(worddelimiters, | 			if(strchr(worddelimiters, | ||||||
| 					term.line[*y][*x + direction].c[0])) { | 					term.line[*y][*x+direction].c[0])) { | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -932,7 +940,7 @@ selcopy(void) { | |||||||
| 				/* nothing */; | 				/* nothing */; | ||||||
|  |  | ||||||
| 			for(x = 0; gp <= last; x++, ++gp) { | 			for(x = 0; gp <= last; x++, ++gp) { | ||||||
| 				if(!selected(x, y)) | 				if(!selected(x, y) || (gp->mode & ATTR_WDUMMY)) | ||||||
| 					continue; | 					continue; | ||||||
|  |  | ||||||
| 				size = utf8size(gp->c); | 				size = utf8size(gp->c); | ||||||
| @@ -1533,6 +1541,16 @@ tsetchar(char *c, Glyph *attr, int x, int y) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if(term.line[y][x].mode & ATTR_WIDE) { | ||||||
|  | 		if(x+1 < term.col) { | ||||||
|  | 			term.line[y][x+1].c[0] = ' '; | ||||||
|  | 			term.line[y][x+1].mode &= ~ATTR_WDUMMY; | ||||||
|  | 		} | ||||||
|  | 	} else if(term.line[y][x].mode & ATTR_WDUMMY) { | ||||||
|  | 		term.line[y][x-1].c[0] = ' '; | ||||||
|  | 		term.line[y][x-1].mode &= ~ATTR_WIDE; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	term.dirty[y] = 1; | 	term.dirty[y] = 1; | ||||||
| 	term.line[y][x] = *attr; | 	term.line[y][x] = *attr; | ||||||
| 	memcpy(term.line[y][x].c, c, UTF_SIZ); | 	memcpy(term.line[y][x].c, c, UTF_SIZ); | ||||||
| @@ -2222,6 +2240,15 @@ void | |||||||
| tputc(char *c, int len) { | tputc(char *c, int len) { | ||||||
| 	uchar ascii = *c; | 	uchar ascii = *c; | ||||||
| 	bool control = ascii < '\x20' || ascii == 0177; | 	bool control = ascii < '\x20' || ascii == 0177; | ||||||
|  | 	long u8char; | ||||||
|  | 	int width; | ||||||
|  |  | ||||||
|  | 	if(len == 1) { | ||||||
|  | 		width = 1; | ||||||
|  | 	} else { | ||||||
|  | 		utf8decode(c, &u8char); | ||||||
|  | 		width = wcwidth(u8char); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if(iofd != -1) { | 	if(iofd != -1) { | ||||||
| 		if(xwrite(iofd, c, len) < 0) { | 		if(xwrite(iofd, c, len) < 0) { | ||||||
| @@ -2469,9 +2496,20 @@ tputc(char *c, int len) { | |||||||
| 			(term.col - term.c.x - 1) * sizeof(Glyph)); | 			(term.col - term.c.x - 1) * sizeof(Glyph)); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if(term.c.x+width > term.col) | ||||||
|  | 		tnewline(1); | ||||||
|  |  | ||||||
| 	tsetchar(c, &term.c.attr, term.c.x, term.c.y); | 	tsetchar(c, &term.c.attr, term.c.x, term.c.y); | ||||||
| 	if(term.c.x+1 < term.col) { |  | ||||||
| 		tmoveto(term.c.x+1, term.c.y); | 	if(width == 2) { | ||||||
|  | 		term.line[term.c.y][term.c.x].mode |= ATTR_WIDE; | ||||||
|  | 		if(term.c.x+1 < term.col) { | ||||||
|  | 			term.line[term.c.y][term.c.x+1].c[0] = '\0'; | ||||||
|  | 			term.line[term.c.y][term.c.x+1].mode = ATTR_WDUMMY; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if(term.c.x+width < term.col) { | ||||||
|  | 		tmoveto(term.c.x+width, term.c.y); | ||||||
| 	} else { | 	} else { | ||||||
| 		term.c.state |= CURSOR_WRAPNEXT; | 		term.c.state |= CURSOR_WRAPNEXT; | ||||||
| 	} | 	} | ||||||
| @@ -3173,7 +3211,7 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { | |||||||
| 				xp, winy + frc[i].font->ascent, | 				xp, winy + frc[i].font->ascent, | ||||||
| 				(FcChar8 *)u8c, u8cblen); | 				(FcChar8 *)u8c, u8cblen); | ||||||
|  |  | ||||||
| 		xp += xw.cw; | 		xp += xw.cw * wcwidth(u8char); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| @@ -3193,18 +3231,27 @@ xdraws(char *s, Glyph base, int x, int y, int charlen, int bytelen) { | |||||||
| void | void | ||||||
| xdrawcursor(void) { | xdrawcursor(void) { | ||||||
| 	static int oldx = 0, oldy = 0; | 	static int oldx = 0, oldy = 0; | ||||||
| 	int sl; | 	int sl, width, curx; | ||||||
| 	Glyph g = {{' '}, ATTR_NULL, defaultbg, defaultcs}; | 	Glyph g = {{' '}, ATTR_NULL, defaultbg, defaultcs}; | ||||||
|  |  | ||||||
| 	LIMIT(oldx, 0, term.col-1); | 	LIMIT(oldx, 0, term.col-1); | ||||||
| 	LIMIT(oldy, 0, term.row-1); | 	LIMIT(oldy, 0, term.row-1); | ||||||
|  |  | ||||||
|  | 	curx = term.c.x; | ||||||
|  |  | ||||||
|  | 	/* adjust position if in dummy */ | ||||||
|  | 	if(term.line[oldy][oldx].mode & ATTR_WDUMMY) | ||||||
|  | 		oldx--; | ||||||
|  | 	if(term.line[term.c.y][curx].mode & ATTR_WDUMMY) | ||||||
|  | 		curx--; | ||||||
|  |  | ||||||
| 	memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ); | 	memcpy(g.c, term.line[term.c.y][term.c.x].c, UTF_SIZ); | ||||||
|  |  | ||||||
| 	/* remove the old cursor */ | 	/* remove the old cursor */ | ||||||
| 	sl = utf8size(term.line[oldy][oldx].c); | 	sl = utf8size(term.line[oldy][oldx].c); | ||||||
|  | 	width = (term.line[oldy][oldx].mode & ATTR_WIDE)? 2 : 1; | ||||||
| 	xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, | 	xdraws(term.line[oldy][oldx].c, term.line[oldy][oldx], oldx, | ||||||
| 			oldy, 1, sl); | 			oldy, width, sl); | ||||||
|  |  | ||||||
| 	/* draw the new one */ | 	/* draw the new one */ | ||||||
| 	if(!(IS_SET(MODE_HIDE))) { | 	if(!(IS_SET(MODE_HIDE))) { | ||||||
| @@ -3216,26 +3263,28 @@ xdrawcursor(void) { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			sl = utf8size(g.c); | 			sl = utf8size(g.c); | ||||||
| 			xdraws(g.c, g, term.c.x, term.c.y, 1, sl); | 			width = (term.line[term.c.y][curx].mode & ATTR_WIDE)\ | ||||||
|  | 				? 2 : 1; | ||||||
|  | 			xdraws(g.c, g, term.c.x, term.c.y, width, sl); | ||||||
| 		} else { | 		} else { | ||||||
| 			XftDrawRect(xw.draw, &dc.col[defaultcs], | 			XftDrawRect(xw.draw, &dc.col[defaultcs], | ||||||
| 					borderpx + term.c.x * xw.cw, | 					borderpx + curx * xw.cw, | ||||||
| 					borderpx + term.c.y * xw.ch, | 					borderpx + term.c.y * xw.ch, | ||||||
| 					xw.cw - 1, 1); | 					xw.cw - 1, 1); | ||||||
| 			XftDrawRect(xw.draw, &dc.col[defaultcs], | 			XftDrawRect(xw.draw, &dc.col[defaultcs], | ||||||
| 					borderpx + term.c.x * xw.cw, | 					borderpx + curx * xw.cw, | ||||||
| 					borderpx + term.c.y * xw.ch, | 					borderpx + term.c.y * xw.ch, | ||||||
| 					1, xw.ch - 1); | 					1, xw.ch - 1); | ||||||
| 			XftDrawRect(xw.draw, &dc.col[defaultcs], | 			XftDrawRect(xw.draw, &dc.col[defaultcs], | ||||||
| 					borderpx + (term.c.x + 1) * xw.cw - 1, | 					borderpx + (curx + 1) * xw.cw - 1, | ||||||
| 					borderpx + term.c.y * xw.ch, | 					borderpx + term.c.y * xw.ch, | ||||||
| 					1, xw.ch - 1); | 					1, xw.ch - 1); | ||||||
| 			XftDrawRect(xw.draw, &dc.col[defaultcs], | 			XftDrawRect(xw.draw, &dc.col[defaultcs], | ||||||
| 					borderpx + term.c.x * xw.cw, | 					borderpx + curx * xw.cw, | ||||||
| 					borderpx + (term.c.y + 1) * xw.ch - 1, | 					borderpx + (term.c.y + 1) * xw.ch - 1, | ||||||
| 					xw.cw, 1); | 					xw.cw, 1); | ||||||
| 		} | 		} | ||||||
| 		oldx = term.c.x, oldy = term.c.y; | 		oldx = curx, oldy = term.c.y; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -3284,6 +3333,7 @@ drawregion(int x1, int y1, int x2, int y2) { | |||||||
| 	Glyph base, new; | 	Glyph base, new; | ||||||
| 	char buf[DRAW_BUF_SIZ]; | 	char buf[DRAW_BUF_SIZ]; | ||||||
| 	bool ena_sel = sel.ob.x != -1; | 	bool ena_sel = sel.ob.x != -1; | ||||||
|  | 	long u8char; | ||||||
|  |  | ||||||
| 	if(sel.alt ^ IS_SET(MODE_ALTSCREEN)) | 	if(sel.alt ^ IS_SET(MODE_ALTSCREEN)) | ||||||
| 		ena_sel = 0; | 		ena_sel = 0; | ||||||
| @@ -3301,6 +3351,8 @@ drawregion(int x1, int y1, int x2, int y2) { | |||||||
| 		ic = ib = ox = 0; | 		ic = ib = ox = 0; | ||||||
| 		for(x = x1; x < x2; x++) { | 		for(x = x1; x < x2; x++) { | ||||||
| 			new = term.line[y][x]; | 			new = term.line[y][x]; | ||||||
|  | 			if(new.mode == ATTR_WDUMMY) | ||||||
|  | 				continue; | ||||||
| 			if(ena_sel && selected(x, y)) | 			if(ena_sel && selected(x, y)) | ||||||
| 				new.mode ^= ATTR_REVERSE; | 				new.mode ^= ATTR_REVERSE; | ||||||
| 			if(ib > 0 && (ATTRCMP(base, new) | 			if(ib > 0 && (ATTRCMP(base, new) | ||||||
| @@ -3313,10 +3365,10 @@ drawregion(int x1, int y1, int x2, int y2) { | |||||||
| 				base = new; | 				base = new; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			sl = utf8size(new.c); | 			sl = utf8decode(new.c, &u8char); | ||||||
| 			memcpy(buf+ib, new.c, sl); | 			memcpy(buf+ib, new.c, sl); | ||||||
| 			ib += sl; | 			ib += sl; | ||||||
| 			++ic; | 			ic += (new.mode & ATTR_WIDE)? 2 : 1; | ||||||
| 		} | 		} | ||||||
| 		if(ib > 0) | 		if(ib > 0) | ||||||
| 			xdraws(buf, base, ox, y, ic, ib); | 			xdraws(buf, base, ox, y, ic, ib); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user