libdraw: add visibleclicks mode

R=rsc
http://codereview.appspot.com/6501137
diff --git a/src/libdraw/drawclient.c b/src/libdraw/drawclient.c
index f6cc586..f0c0943 100644
--- a/src/libdraw/drawclient.c
+++ b/src/libdraw/drawclient.c
@@ -9,6 +9,7 @@
 #include <drawfcall.h>
 #include <mux.h>
 
+extern Mouse _drawmouse;
 int chattydrawclient = 0;
 
 static int	drawgettag(Mux *mux, void *vmsg);
@@ -259,6 +260,7 @@
 	tx.type = Trdmouse;
 	if(displayrpc(d, &tx, &rx, nil) < 0)
 		return -1;
+	_drawmouse = rx.mouse;
 	*m = rx.mouse;
 	*resized = rx.resized;
 	return 0;
@@ -283,7 +285,10 @@
 
 	tx.type = Tmoveto;
 	tx.mouse.xy = p;
-	return displayrpc(d, &tx, &rx, nil);
+	if(displayrpc(d, &tx, &rx, nil) < 0)
+		return -1;
+	_drawmouse.xy = p;
+	return flushimage(d, 1);
 }
 
 int
diff --git a/src/libdraw/event.c b/src/libdraw/event.c
index e41814f..f113d1f 100644
--- a/src/libdraw/event.c
+++ b/src/libdraw/event.c
@@ -9,6 +9,7 @@
 
 typedef struct	Slave Slave;
 typedef struct	Ebuf Ebuf;
+extern Mouse _drawmouse;
 
 struct Slave
 {
@@ -331,6 +332,7 @@
 			if(finishrpc(eslave[i].rpc, &w)){
 				eslave[i].rpc = nil;
 				eb = newebuf(&eslave[i], sizeof(Mouse));
+				_drawmouse = w.mouse;
 				eb->u.mouse = w.mouse;
 				if(w.resized)
 					eresized(1);
diff --git a/src/libdraw/init.c b/src/libdraw/init.c
index bbce668..0ddb3ad 100644
--- a/src/libdraw/init.c
+++ b/src/libdraw/init.c
@@ -1,6 +1,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <mouse.h>
 
 Display	*display;
 Font	*font;
@@ -13,6 +14,11 @@
 int		debuglockdisplay = 1;
 char	*winsize;
 
+int		visibleclicks = 0;
+Image	*mousebuttons;
+Image	*mousesave;
+Mouse	_drawmouse;
+
 /*
 static void
 drawshutdown(void)
@@ -31,7 +37,7 @@
 geninitdraw(char *devdir, void(*error)(Display*, char*), char *fontname, char *label, char *windir, int ref)
 {
 	Subfont *df;
-	char buf[128];
+	char buf[128], *p;
 
 	if(label == nil)
 		label = argv0;
@@ -87,6 +93,22 @@
 	draw(screen, screen->r, display->white, nil, ZP);
 	flushimage(display, 1);
 
+	p = getenv("visibleclicks");
+	visibleclicks = p != nil && *p == '1';
+	if(visibleclicks) {
+		Font *f;
+		
+		f = display->defaultfont;
+		mousebuttons = allocimage(display, Rect(0,0,64,22), screen->chan, 0, DWhite);
+		border(mousebuttons, mousebuttons->r, 1, display->black, ZP);
+		border(mousebuttons, Rect(0, 0, 22, 22), 1, display->black, ZP);
+		border(mousebuttons, Rect(42, 0, 64, 22), 1, display->black, ZP);
+		string(mousebuttons, Pt(10-stringwidth(display->defaultfont, "1")/2, 11-f->height/2), display->black, ZP, display->defaultfont, "1");
+		string(mousebuttons, Pt(21+10-stringwidth(display->defaultfont, "2")/2, 11-f->height/2), display->black, ZP, display->defaultfont, "2");
+		string(mousebuttons, Pt(42+10-stringwidth(display->defaultfont, "3")/2, 11-f->height/2), display->black, ZP, display->defaultfont, "3");
+		mousesave = allocimage(display, Rect(0,0,64,22), screen->chan, 0, 0);
+	}
+
 	/*
 	 * I don't see any reason to go away gracefully,
 	 * and if some other proc exits holding the display
@@ -346,6 +368,29 @@
 int
 flushimage(Display *d, int visible)
 {
+	if(visible == 1 && visibleclicks && mousebuttons && _drawmouse.buttons) {
+		Rectangle r, r1;
+		int ret;
+
+		r = mousebuttons->r;
+		r = rectaddpt(r, _drawmouse.xy);
+		r = rectaddpt(r, Pt(-Dx(mousebuttons->r)/2, -Dy(mousebuttons->r)-3));
+		drawop(mousesave, mousesave->r, screen, nil, r.min, S);
+		
+		r1 = rectaddpt(Rect(0, 0, 22, 22), r.min);
+		if(_drawmouse.buttons & 1)
+			drawop(screen, r1, mousebuttons, nil, ZP, S);
+		r1 = rectaddpt(r1, Pt(21, 0));
+		if(_drawmouse.buttons & 2)
+			drawop(screen, r1, mousebuttons, nil, Pt(21, 0), S);
+		r1 = rectaddpt(r1, Pt(21, 0));
+		if(_drawmouse.buttons & 4)
+			drawop(screen, r1, mousebuttons, nil, Pt(42, 0), S);
+		ret = flushimage(d, 2);
+		drawop(screen, r, mousesave, nil, ZP, S);
+		return ret;
+	}
+	
 	if(visible){
 		*d->bufp++ = 'v';	/* five bytes always reserved for this */
 		if(d->_isnewdisplay){