shithub: riscv

Download patch

ref: b831ec005baf286bb3418c51baf7e5814a940bfa
parent: ecab88b983e779cc7c5824069a993db788f87350
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Oct 27 15:05:40 EDT 2013

vt: utf-8 support

--- a/sys/src/cmd/vt/cons.h
+++ b/sys/src/cmd/vt/cons.h
@@ -59,14 +59,13 @@
 extern void	newline(void);
 extern int	get_next_char(void);
 extern void	ringbell(void);
-extern int	number(char *, int *);
+extern int	number(Rune *, int *);
 extern void	scroll(int,int,int,int);
 extern void	backup(int);
 extern void	sendnchars(int, char *);
-extern void	sendnchars2(int, char *);
 extern Point	pt(int, int);
 extern void	funckey(int);
-extern void	drawstring(Point, char*, int);
+extern void	drawstring(Point, Rune*, int);
 
 extern int	debug;
 extern int	yscrmin, yscrmax;
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -32,7 +32,7 @@
 /* variables associated with the screen */
 
 int	x, y;	/* character positions */
-char	*backp;
+Rune	*backp;
 int	backc;
 int	atend;
 int	nbacklines;
@@ -45,8 +45,8 @@
 int	cursoron = 1;
 Menu	menu2;
 Menu	menu3;
-char	*histp;
-char	hist[HISTSIZ];
+Rune	*histp;
+Rune	hist[HISTSIZ];
 int	yscrmin, yscrmax;
 int	attr, defattr;
 int	wctlout;
@@ -99,6 +99,7 @@
 
 char	*host_buf;
 char	*hostp;				/* input from host */
+
 int	host_bsize = 2*BSIZE;
 int	hostlength;			/* amount of input from host */
 char	echo_input[BSIZE];
@@ -277,7 +278,7 @@
 get_next_char(void)
 {
 	int c = peekc;
-	uchar buf[1];
+
 	peekc = 0;
 	if(c > 0)
 		return(c);
@@ -292,11 +293,9 @@
 			}
 			backp = 0;
 		}
-		c = (uchar)waitchar();
-		if(c > 0 && logfd >= 0) {
-			buf[0] = c;
-			write(logfd, buf, 1);
-		}
+		c = waitchar();
+		if(c > 0 && logfd >= 0)
+			fprint(logfd, "%C", (Rune)c);
 	}
 	*histp++ = c;
 	if(histp >= &hist[HISTSIZ])
@@ -305,68 +304,89 @@
 	return(c);
 }
 
+char*
+backrune(char *start, char *cp)
+{
+	char *ep;
+
+	ep = cp;
+	cp -= UTFmax;
+	if(cp < start)
+		cp = start;
+	while(cp < ep){
+		Rune r;
+		int n;
+
+		n = chartorune(&r, cp);
+		if(cp + n >= ep)
+			break;
+		cp += n;
+	}
+	return cp;
+}
+
 int
-canon(char *ep, int c)
+canon(char *ep, Rune c)
 {
-	if(c&0200)
-		return(SCROLL);
 	switch(c) {
-		case '\b':
-			if(sendp > sendbuf)
-				sendp--;
+	case Kdown:
+	case Kpgdown:
+		return SCROLL;
+	case '\b':
+		if(sendp > sendbuf){
+			sendp = backrune(sendbuf, sendp);
 			*ep++ = '\b';
 			*ep++ = ' ';
 			*ep++ = '\b';
-			break;
-		case 0x15:	/* ^U line kill */
-			sendp = sendbuf;
-			*ep++ = '^';
-			*ep++ = 'U';
+		}
+		break;
+	case 0x15:	/* ^U line kill */
+		sendp = sendbuf;
+		*ep++ = '^';
+		*ep++ = 'U';
+		*ep++ = '\n';
+		break;
+	case 0x17:	/* ^W word kill */
+		while(sendp > sendbuf && !alnum(*sendp)) {
+			sendp = backrune(sendbuf, sendp);
+			*ep++ = '\b';
+			*ep++ = ' ';
+			*ep++ = '\b';
+		}
+		while(sendp > sendbuf && alnum(*sendp)) {
+			sendp = backrune(sendbuf, sendp);
+			*ep++ = '\b';
+			*ep++ = ' ';
+			*ep++ = '\b';
+		}
+		break;
+	case '\177':	/* interrupt */
+		sendp = sendbuf;
+		send_interrupt();
+		return(NEWLINE);
+	case '\021':	/* quit */
+	case '\r':
+	case '\n':
+		if(sendp < &sendbuf[BSIZE])
+			*sendp++ = '\n';
+		sendnchars((int)(sendp-sendbuf), sendbuf);
+		sendp = sendbuf;
+		if(c == '\n' || c == '\r')
 			*ep++ = '\n';
-			break;
-		case 0x17:	/* ^W word kill */
-			while(sendp > sendbuf && !alnum(*sendp)) {
-				*ep++ = '\b';
-				*ep++ = ' ';
-				*ep++ = '\b';
-				sendp--;
-			}
-			while(sendp > sendbuf && alnum(*sendp)) {
-				*ep++ = '\b';
-				*ep++ = ' ';
-				*ep++ = '\b';
-				sendp--;
-			}
-			break;
-		case '\177':	/* interrupt */
-			sendp = sendbuf;
-			send_interrupt();
-			return(NEWLINE);
-		case '\021':	/* quit */
-		case '\r':
-		case '\n':
-			if(sendp < &sendbuf[512])
-				*sendp++ = '\n';
-			sendnchars((int)(sendp-sendbuf), sendbuf);
-			sendp = sendbuf;
-			if(c == '\n' || c == '\r') {
-				*ep++ = '\n';
-			}
+		*ep = 0;
+		return(NEWLINE);
+	case '\004':	/* EOT */
+		if(sendp == sendbuf) {
+			sendnchars(0,sendbuf);
 			*ep = 0;
 			return(NEWLINE);
-		case '\004':	/* EOT */
-			if(sendp == sendbuf) {
-				sendnchars(0,sendbuf);
-				*ep = 0;
-				return(NEWLINE);
-			}
-			/* fall through */
-		default:
-			if(sendp < &sendbuf[512])
-				*sendp++ = c;
-			*ep++ = c;
-			break;
-		
+		}
+		/* fall through */
+	default:
+		if(sendp < &sendbuf[BSIZE-UTFmax])
+			sendp += runetochar(sendp, &c);
+		ep += runetochar(ep, &c);
+		break;
 	}
 	*ep = 0;
 	return(OTHER);
@@ -380,7 +400,7 @@
 
 	for(i=0; fk[i].name; i++)
 		if(strcmp(name, fk[i].name)==0){
-			sendnchars2(strlen(fk[i].sequence), fk[i].sequence);
+			sendnchars(strlen(fk[i].sequence), fk[i].sequence);
 			return;
 		}
 }
@@ -390,14 +410,11 @@
 {
 	Event e;
 	int c;
-	char c2;
 	int newmouse;
 	int wasblocked;
-	int kbdchar = -1;
-	char echobuf[3*BSIZE];
-	static int lastc = -1;
+	Rune kbdchar = 0;
+	char echobuf[4*BSIZE];
 
-
 	for(;;) {
 		if(resize_flag)
 			resize();
@@ -407,26 +424,31 @@
 		if(ecanmouse() && (button2() || button3()))
 			readmenu();
 		if(snarffp) {
-			if((c = Bgetc(snarffp)) < 0) {
+			static Rune lastc = ~0;
+
+			if((c = Bgetrune(snarffp)) < 0) {
 				if(lastc != '\n')
 					write(outfd,"\n",1);
 				Bterm(snarffp);
 				snarffp = 0;
 				if(lastc != '\n') {
-					lastc = -1;
+					lastc = ~0;
 					return('\n');
 				}
-				lastc = -1;
+				lastc = ~0;
 				continue;
 			}
 			lastc = c;
-			c2 = c;
-			write(outfd, &c2, 1);
+			write(outfd, echobuf, runetochar(echobuf, &lastc));
 			return(c);
 		}
 		if(!blocked && host_avail())
 			return(rcvchar());
 		if(kbdchar > 0) {
+			if(backc){
+				backc = 0;
+				backup(backc);
+			}
 			if(blocked)
 				resize();
 			if(cs->raw) {
@@ -494,8 +516,7 @@
 					sendnchars(1, echobuf);
 					break;
 				default:
-					echobuf[0] = kbdchar;
-					sendnchars(1, echobuf);
+					sendnchars(runetochar(echobuf, &kbdchar), echobuf);
 					break;
 				}
 			} else if(canon(echobuf,kbdchar) == SCROLL) {
@@ -504,7 +525,7 @@
 			} else
 				strcat(echo_input,echobuf);
 			blocked = 0;
-			kbdchar = -1;
+			kbdchar = 0;
 			continue;
 		}
 		curson(wasblocked);	/* turn on cursor while we're waiting */
@@ -682,8 +703,8 @@
 void
 backup(int count)
 {
-	register n;
-	register char *cp;
+	Rune *cp;
+	int n;
 
 	eresized(0);
 	if(count == 0 && !pagemode) {
@@ -747,7 +768,7 @@
 }
 
 int
-number(char *p, int *got)
+number(Rune *p, int *got)
 {
 	int c, n = 0;
 
@@ -767,13 +788,6 @@
 void
 sendnchars(int n,char *p)
 {
-	sendnchars2(n, p);
-	p[n+1] = 0;
-}
-
-void
-sendnchars2(int n,char *p)
-{
 	if(write(outfd,p,n) < 0) {
 		close(outfd);
 		close(0);
@@ -786,35 +800,44 @@
 int
 host_avail(void)
 {
-	return(*echop || ((hostp - host_buf) < hostlength));
+	if(*echop != 0 && fullrune(echop, strlen(echop)))
+		return 1;
+	if((hostp - host_buf) < hostlength)
+		return fullrune(hostp, hostlength - (hostp - host_buf));
+	return 0;
 }
 
 int
 rcvchar(void)
 {
-	int c;
-	if(*echop) {
-		c = *echop++;
-		if(!*echop) {
+	Rune r;
+
+	if(*echop != 0) {
+		echop += chartorune(&r, echop);
+		if(*echop == 0) {
 			echop = echo_input;	
 			*echop = 0;
 		}
-		return c;
+		return r;
 	}
-	return *hostp++;
+	hostp += chartorune(&r, hostp);
+	return r;
 }
 
 void
 set_host(Event *e)
 {
-	hostlength = e->n;
+	hostlength -= (hostp - host_buf);
+	if(hostlength > 0)
+		memmove(host_buf, hostp, hostlength);
+	hostlength += e->n;
 	if(hostlength >= host_bsize) {
 		host_bsize = BSIZE*((hostlength + BSIZE)/BSIZE);
-		host_buf = realloc(host_buf,host_bsize);
+		host_buf = realloc(host_buf, host_bsize);
 	}
+	memmove(host_buf + hostlength - e->n, e->data, e->n);
+	host_buf[hostlength] = 0;
 	hostp = host_buf;
-	memmove(host_buf,e->data,hostlength);
-	host_buf[hostlength]=0;
 }
 
 void
@@ -854,12 +877,12 @@
 		return;
 	if(fk[key].name == 0)
 		return;
-	sendnchars2(strlen(fk[key].sequence), fk[key].sequence);
+	sendnchars(strlen(fk[key].sequence), fk[key].sequence);
 }
 
 
 void
-drawstring(Point p, char *str, int attr)
+drawstring(Point p, Rune *str, int attr)
 {
 	int i;
 	Image *txt, *bg, *tmp;
@@ -877,6 +900,6 @@
 				txt = hicolors[i];
 	}
 
-	draw(screen, Rpt(p, addpt(p, stringsize(font, str))), bg, nil, p);
-	string(screen, p, txt, ZP, font, str);
+	draw(screen, Rpt(p, addpt(p, runestringsize(font, str))), bg, nil, p);
+	runestring(screen, p, txt, ZP, font, str);
 }
--- a/sys/src/cmd/vt/vt.c
+++ b/sys/src/cmd/vt/vt.c
@@ -133,7 +133,7 @@
 void
 emulate(void)
 {
-	char buf[BUFS+1];
+	Rune buf[BUFS+1];
 	int i;
 	int n;
 	int c;
@@ -328,8 +328,8 @@
 			 */
 			case 'Z':
 			Ident:
-				sendnchars2(7, "\033[?1;2c");	/* VT100 with AVO option */
-//				sendnchars2(5, "\033[?6c");	/* VT102 (insert/delete-char, etc.) */
+				sendnchars(7, "\033[?1;2c");	/* VT100 with AVO option */
+//				sendnchars(5, "\033[?6c");	/* VT102 (insert/delete-char, etc.) */
 				break;
 
 			/*
@@ -532,11 +532,11 @@
 					case 'n':
 						switch(operand[0]){
 						case 5:	/* status */
-							sendnchars2(4, "\033[0n");	/* terminal ok */
+							sendnchars(4, "\033[0n");	/* terminal ok */
 							break;
 						case 6:	/* cursor position */
-							sendnchars2(sprint(buf, "\033[%d;%dR",
-								originrelative ? y+1 - yscrmin : y+1, x+1), buf);
+							sendnchars(sprint((char*)buf, "\033[%d;%dR",
+								originrelative ? y+1 - yscrmin : y+1, x+1), (char*)buf);
 							break;
 						}
 						break;
@@ -573,7 +573,7 @@
 					 * x - report terminal parameters
 					 */
 					case 'x':
-						sendnchars2(20, "\033[3;1;1;120;120;1;0x");
+						sendnchars(20, "\033[3;1;1;120;120;1;0x");
 						break;
 
 					/*
@@ -847,8 +847,8 @@
 
 		default:		/* ordinary char */
 Default:
-			if(isgraphics && gmap[(uchar) buf[0]])
-				buf[0] = gmap[(uchar) buf[0]];
+			if(isgraphics && buf[0] < nelem(gmap) && gmap[buf[0]])
+				buf[0] = gmap[buf[0]];
 
 			/* line wrap */
 			if (x > xmax){
@@ -867,7 +867,6 @@
 				c = 0;
 			}
 			buf[n] = 0;
-//			clear(Rpt(pt(x,y), pt(x+n, y+1)));
 			drawstring(pt(x, y), buf, attr);
 			x += n;
 			peekc = c;
--