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
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										82
									
								
								st.c
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								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(width == 2) {
 | 
				
			||||||
 | 
							term.line[term.c.y][term.c.x].mode |= ATTR_WIDE;
 | 
				
			||||||
		if(term.c.x+1 < term.col) {
 | 
							if(term.c.x+1 < term.col) {
 | 
				
			||||||
		tmoveto(term.c.x+1, term.c.y);
 | 
								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