Make all windows Refbackup.
Implement painter's algorithm to redraw screen.
Position windows' backing canvases directly with css because redraw was too slow.
.
Reference: /n/atom/patch/applied/wd-screen-refback
Date: Fri Jun 13 19:33:12 CES 2014
Signed-off-by: root@davidrhoskin.com
--- /usr/web/9wd/9wd.html	Fri Jun 13 19:29:56 2014
+++ /usr/web/9wd/9wd.html	Fri Jun 13 19:29:57 2014
@@ -37,6 +37,7 @@
 		
 			cursor 
 			/dev/draw 
+			cover 
 		
 		
 		
--- /usr/web/9wd/css/9wd.css	Fri Jun 13 19:30:00 2014
+++ /usr/web/9wd/css/9wd.css	Fri Jun 13 19:30:01 2014
@@ -17,6 +17,14 @@
 	position: absolute;
 	top: 0em;
 	left: 0em;
+	z-index: 9000;
+}
+
+#cover {
+	position: absolute;
+	top: 0em;
+	left: 0em;
+	z-index: 9001;
 }
 
 #cons {
--- /usr/web/9wd/js/composetab.js	Fri Jun 13 19:30:04 2014
+++ /usr/web/9wd/js/composetab.js	Fri Jun 13 19:30:05 2014
@@ -1,3 +1,4 @@
+/* Generated by latin2js. */
 var Composetab = {
 	" ": {from:" i", to:"␣ı"},
 	"!~": {from:"-=~", to:"≄≇≉"},
--- /usr/web/9wd/js/init.js	Fri Jun 13 19:30:08 2014
+++ /usr/web/9wd/js/init.js	Fri Jun 13 19:30:09 2014
@@ -24,6 +24,7 @@
 	var wsurl = Socket.wsurl(window.location.toString());
 	//var wsurl = Socket.wsurl("http://wd.9atom.org/9wd.html");
 	var webdraw = elem("webdraw");
+	var cover = elem("cover");
 
 	basetime = Date.now();
 	cons = new Cons();
@@ -40,13 +41,13 @@
 	Draw9p.imgnames["webdraw"] = Draw9p.RootImage();
 	Draw9p.label = "webdraw".toUTF8Array();
 
-	setevent(webdraw, "mousedown", function(e){
+	setevent(cover, "mousedown", function(e){
 		return mouse.handlebutton(e, 1);
 	});
-	setevent(webdraw, "mouseup", function(e){
+	setevent(cover, "mouseup", function(e){
 		return mouse.handlebutton(e, 0);
 	});
-	setevent(webdraw, "mousemove", function(e){
+	setevent(cover, "mousemove", function(e){
 		return mouse.handlemove(e);
 	});
 	setevent(window, "keydown", function(e){
@@ -58,24 +59,24 @@
 	setevent(window, "keyup", function(e){
 		return cons.handlekeys(e, cons.kbd.up);
 	});
-	setevent(webdraw, "contextmenu", function(e){
+	setevent(cover, "contextmenu", function(e){
 		e.preventDefault();
 		e.stopPropagation();
 		return false;
 	});
-	setevent(webdraw, "click", function(e){
+	setevent(cover, "click", function(e){
 		e.preventDefault();
 		e.stopPropagation();
 		if(
-			document.pointerLockElement !== webdraw &&
-			document.mozPointerLockElement !== webdraw &&
-			document.webkitPointerLockElement !== webdraw
+			document.pointerLockElement !== cover &&
+			document.mozPointerLockElement !== cover &&
+			document.webkitPointerLockElement !== cover
 		){
-			webdraw.requestPointerLock =
-				webdraw.requestPointerLock ||
-				webdraw.mozRequestPointerLock ||
-				webdraw.webkitRequestPointerLock;
-			webdraw.requestPointerLock();
+			cover.requestPointerLock =
+				cover.requestPointerLock ||
+				cover.mozRequestPointerLock ||
+				cover.webkitRequestPointerLock;
+			cover.requestPointerLock();
 			return false;
 		}else{
 			return false;
--- /usr/web/9wd/js/draw/data.js	Fri Jun 13 19:30:13 2014
+++ /usr/web/9wd/js/draw/data.js	Fri Jun 13 19:30:14 2014
@@ -191,6 +191,7 @@
 		if(screen){
 			delete screen.imgs[id];
 		}
+		img.canvas.parentNode.removeChild(img.canvas);
 		delete conn.imgs[id];
 	},
 	"F": function(conn, offset, ai){
@@ -314,6 +315,16 @@
 		}catch(e){
 			throw("short draw message");
 		}
+		if(conn.imgs[id] == undefined){
+			throw("invalid image id");
+		}
+		var img = conn.imgs[id];
+		if(img.screen == undefined){
+			throw("image is not a window");
+		}
+		img.r = rectaddpt(img.r, subpt(rmin, img.r.min));
+		img.clipr = rectaddpt(img.clipr, subpt(rmin, img.clipr.min));
+		img.scrmove(scr);
 	},
 	"O": function(conn, offset, ai){
 		try{
@@ -488,7 +499,9 @@
 		}
 	},
 	"v": function(conn, offset, ai){
-		//cons.log("writedrawdata: 'v' (flush) unimplemented!");
+		for(var i in conn.screens){
+			conn.screens[i].repaint();
+		}
 	},
 	"y": function(conn, offset, ai){
 		try{
--- /usr/web/9wd/js/draw/image.js	Fri Jun 13 19:30:17 2014
+++ /usr/web/9wd/js/draw/image.js	Fri Jun 13 19:30:18 2014
@@ -48,28 +48,61 @@
 	this.ctx.putImageData(data, 0, 0);
 }
 
-/* XXX ScreenImage will not work as a drawing source */
-/* due to the assumption that the canvas maps 1-1 to the image data. */
 Draw9p.ScreenImage = function(screen, refresh, chan, repl, r, clipr, color){
 	if(screen == undefined || screen.backimg == undefined){
 		throw("invalid screen");
 	}
 	this.screen = screen;
+	this.scrmin = r.min;
 
 	/* if(chan != this.screen.backimg.chan){ */
 	/* 	throw("chan mismatch between image and screen"); */
 	/* } */
 
+	/* refresh methods */
+	/* Refbackup = 0, */
+	/* Refnone = 1, */
+	/* Refmesg = 2 */
+
 	this.refresh = refresh;
 	this.chan = chan;
 	this.repl = repl;
 	this.r = r;
 	this.clipr = clipr;
 
-	/* XXX We should create a backing store, depending on refresh value. */
-	this.canvas = this.screen.backimg.canvas;
+	this.canvas = document.createElement("canvas");
+	this.canvas.width = r.max.x - r.min.x;
+	this.canvas.height = r.max.y - r.min.y;
 	this.ctx = CtxWrap(this.canvas.getContext("2d"));
-	/* XXX Fill ScreenImage with background colour. */
+
+	var red = (color >> 24) & 0xFF;
+	var green = (color >> 16) & 0xFF;
+	var blue = (color >> 8) & 0xFF;
+	var alpha = (color) & 0xFF;
+
+	var data = this.ctx.createImageData(this.canvas.width, this.canvas.height);
+	for(var i = 0; i < data.data.length; i += 4){
+		data.data[i + 0] = red;
+		data.data[i + 1] = green;
+		data.data[i + 2] = blue;
+		data.data[i + 3] = alpha;
+	}
+
+	this.ctx.putImageData(data, 0, 0);
+
+	this.screen.imgs.push(this);
+	this.screen.repaint();
+	this.canvas.style.position = "absolute";
+	document.getElementById("container").appendChild(this.canvas);
+	this.canvas.style.left = this.scrmin.x + "px";
+	this.canvas.style.top = this.scrmin.y + "px";
+}
+
+Draw9p.ScreenImage.prototype.scrmove = function(scrmin){
+	this.scrmin = scrmin;
+	this.canvas.style.left = this.scrmin.x + "px";
+	this.canvas.style.top = this.scrmin.y + "px";
+	this.screen.dirty = true;
 }
 
 /* XXX Creating a new rootwindow object for each connection will probably */
--- /usr/web/9wd/js/draw/memdraw.js	Fri Jun 13 19:30:22 2014
+++ /usr/web/9wd/js/draw/memdraw.js	Fri Jun 13 19:30:23 2014
@@ -129,6 +129,9 @@
 		dst.ctx.pdrawImage(src.canvas, addpt(subpt(r.min, dst.r.min), subpt(src.r.min, sp)));
 	}
 	dst.ctx.restore();
+
+	if(dst.screen != undefined)
+		dst.screen.dirty = true;
 	return;
 }
 
--- /usr/web/9wd/js/draw/screen.js	Fri Jun 13 19:30:26 2014
+++ /usr/web/9wd/js/draw/screen.js	Fri Jun 13 19:30:27 2014
@@ -2,6 +2,28 @@
 	this.id = id;
 	this.public = public;
 	this.backimg = backimg;
+	drawmasked(backimg, backimg.r, fillimg, fillimg.r.min, undefined, undefined, Memdraw.Opdefs.SoverD.key);
+	this.dirty = true;
+	cons.log("new screen");
 	/* Memdraw.draw(this.backimg, this.fillimg); */
 	this.imgs = []; /* not sure how this should be represented? */
+}
+
+Draw9p.Screen.prototype.repaint = function(){
+	var i;
+
+	return "repaint disabled";
+
+	if(this.dirty == true)
+		this.dirty = false;
+	else
+		return;
+
+	for(i in this.imgs){
+		//rectsubpt(this.imgs[i].r, this.imgs[i].scrmin),
+		drawmasked(this.backimg, this.imgs[i].r,
+			this.imgs[i], this.imgs[i].r.min,
+			undefined, undefined,
+			Memdraw.Opdefs.SoverD.key);
+	}
 }