# HG changeset patch
# User Jeff Sickel <jas@corpus-callosum.com>
# Date 1223518919 18000
# Node ID d3d76ea48f2a742f19fce7d1c0ea9ec5e8c3523d
# Parent  acb992ef797ed6eca7215e97e010a5121d5c2b4a
# Parent  40e84c8c0b64d356619588c4c5a4ebb6344654f2
merge in macfuse changes and file update

diff -r acb992ef797e -r d3d76ea48f2a bin/web
--- a/bin/web	Wed Oct 08 21:16:50 2008 -0500
+++ b/bin/web	Wed Oct 08 21:21:59 2008 -0500
@@ -30,6 +30,21 @@
 	' | osascript
 }
 
+plumbcamino()
+{
+	echo '
+		tell application "Camino"
+		activate
+		tell application "System Events"
+		tell process "camino"
+		keystroke "t" using {command down}
+		end tell
+		end tell
+		Get URL "'$1'"
+		end tell
+	' | osascript
+}
+
 plumbapple()
 {
 	case ${BROWSER:-none} in
@@ -39,8 +54,14 @@
 	safari)
 		plumbsafari "$@"
 		;;
+	camino)
+		plumbcamino "$@"
+		;;
 	none)
-		if [ -d /Applications/Firefox.app ]
+		if [ -d /Applications/Camino.app ]
+		then
+			plumbcamino "$@"
+		elif [ -d /Applications/Firefox.app ]
 		then
 			plumbfirefox "$@"
 		else
diff -r acb992ef797e -r d3d76ea48f2a man/man1/web.1
--- a/man/man1/web.1	Wed Oct 08 21:16:50 2008 -0500
+++ b/man/man1/web.1	Wed Oct 08 21:21:59 2008 -0500
@@ -45,10 +45,11 @@
 .PP
 When run under Mac OS X,
 .B $BROWSER
-should be set to the string
-.B safari
+should be set to
+.B camino ,
+.B firefox ,
 or
-.BR firefox .
+.BR safari .
 .I Web
 uses AppleScript to talk to the browser.
 If 
diff -r acb992ef797e -r d3d76ea48f2a src/cmd/devdraw/devdraw.h
--- a/src/cmd/devdraw/devdraw.h	Wed Oct 08 21:16:50 2008 -0500
+++ b/src/cmd/devdraw/devdraw.h	Wed Oct 08 21:21:59 2008 -0500
@@ -3,4 +3,5 @@
 void _initdisplaymemimage(Memimage*);
 int _latin1(Rune*, int);
 int parsewinsize(char*, Rectangle*, int*);
+int mouseswap(int);
 
diff -r acb992ef797e -r d3d76ea48f2a src/cmd/devdraw/mkfile
--- a/src/cmd/devdraw/mkfile	Wed Oct 08 21:16:50 2008 -0500
+++ b/src/cmd/devdraw/mkfile	Wed Oct 08 21:21:59 2008 -0500
@@ -5,6 +5,7 @@
 WSYSOFILES=\
 	devdraw.$O\
 	latin1.$O\
+	mouseswap.$O\
 	winsize.$O\
 	
 <|sh ./mkwsysrules.sh
diff -r acb992ef797e -r d3d76ea48f2a src/cmd/devdraw/mouseswap.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cmd/devdraw/mouseswap.c	Wed Oct 08 21:21:59 2008 -0500
@@ -0,0 +1,62 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <memdraw.h>
+#include "devdraw.h"
+
+enum
+{
+	Nbutton = 10
+};
+
+static int debug;
+
+static struct
+{
+	int b[Nbutton];
+	int init;
+} map;
+
+static void
+initmap(void)
+{
+	char *p;
+	int i;
+
+	p = getenv("mousedebug");
+	if(p && p[0])
+		debug = atoi(p);
+
+	for(i=0; i<Nbutton; i++)
+		map.b[i] = i;
+	map.init = 1;
+	p = getenv("mousebuttonmap");
+	if(p)
+		for(i=0; i<Nbutton && p[i]; i++)
+			if('0' <= p[i] && p[i] <= '9')
+				map.b[i] = p[i] - '1';
+	if(debug){
+		fprint(2, "mousemap: ");
+		for(i=0; i<Nbutton; i++)
+			fprint(2, " %d", 1+map.b[i]);
+		fprint(2, "\n");
+	}
+}
+
+int
+mouseswap(int but)
+{
+	int i;
+	int nbut;
+
+	if(!map.init)
+		initmap();
+	
+	nbut = 0;
+	for(i=0; i<Nbutton; i++)
+		if((but&(1<<i)) && map.b[i] >= 0)
+			nbut |= 1<<map.b[i];
+	if(debug)
+		fprint(2, "swap %#b -> %#b\n", but, nbut);
+	return nbut;
+}
diff -r acb992ef797e -r d3d76ea48f2a src/cmd/devdraw/osx-screen.c
--- a/src/cmd/devdraw/osx-screen.c	Wed Oct 08 21:16:50 2008 -0500
+++ b/src/cmd/devdraw/osx-screen.c	Wed Oct 08 21:21:59 2008 -0500
@@ -50,6 +50,8 @@
 	CGImageRef image;
 	CGContextRef windowctx;
 	PasteboardRef snarf;
+	int needflush;
+	QLock flushlock;
 } osx;
 
 enum
@@ -319,6 +321,8 @@
 		
 		// OS X swaps button 2 and 3
 		but = (but & ~6) | ((but & 4)>>1) | ((but&2)<<1);
+
+		but = mouseswap(but);
 		
 		// Apply keyboard modifiers and pretend it was a real mouse button.
 		// (Modifiers typed while holding the button go into kbuttons,
@@ -507,6 +511,29 @@
 	osx.image = image;
 	osx.screenimage = m;
 	osx.screenr = r;
+	
+	// I'm not 100% sure why this is necessary
+	// but otherwise some resizes (esp. vertical ones)
+	// stop updating the screen.
+	qlock(&osx.flushlock);
+	QDEndCGContext(GetWindowPort(osx.window), &osx.windowctx);
+	osx.windowctx = nil;
+	qunlock(&osx.flushlock);
+}
+
+void
+flushproc(void *v)
+{
+	for(;;){
+		if(osx.needflush && osx.windowctx && canqlock(&osx.flushlock)){
+			if(osx.windowctx){
+				CGContextFlush(osx.windowctx);
+				osx.needflush = 0;
+			}
+			qunlock(&osx.flushlock);
+		}
+		usleep(33333);
+	}
 }
 
 void
@@ -515,8 +542,11 @@
 	CGRect cgr;
 	CGImageRef subimg;
 
-	if(osx.windowctx == nil)
+	qlock(&osx.flushlock);
+	if(osx.windowctx == nil){
 		QDBeginCGContext(GetWindowPort(osx.window), &osx.windowctx);
+		proccreate(flushproc, nil, 256*1024);
+	}
 	
 	cgr.origin.x = r.min.x;
 	cgr.origin.y = r.min.y;
@@ -525,7 +555,8 @@
 	subimg = CGImageCreateWithImageInRect(osx.image, cgr);
 	cgr.origin.y = Dy(osx.screenr) - r.max.y; // XXX how does this make any sense?
 	CGContextDrawImage(osx.windowctx, cgr, subimg);
-	CGContextFlush(osx.windowctx);
+	osx.needflush = 1;
+	qunlock(&osx.flushlock);
 	CGImageRelease(subimg);
 }
 
@@ -536,6 +567,7 @@
 	static WindowRef oldwindow;
 	GDHandle device;
 
+	qlock(&osx.flushlock);
 	if(osx.isfullscreen){
 		if(osx.windowctx){
 			QDEndCGContext(GetWindowPort(osx.window), &osx.windowctx);
@@ -557,6 +589,7 @@
 		osx.isfullscreen = 1;
 		osx.fullscreentime = msec();
 	}
+	qunlock(&osx.flushlock);
 	eresized(1);
 }
 
diff -r acb992ef797e -r d3d76ea48f2a src/cmd/devdraw/osx-srv.c
--- a/src/cmd/devdraw/osx-srv.c	Wed Oct 08 21:16:50 2008 -0500
+++ b/src/cmd/devdraw/osx-srv.c	Wed Oct 08 21:21:59 2008 -0500
@@ -289,6 +289,7 @@
 /*
  * Reply to m.
  */
+QLock replylock;
 void
 replymsg(Wsysmsg *m)
 {
@@ -303,6 +304,8 @@
 	if(trace) fprint(2, "-> %W\n", m);
 	/* copy to output buffer */
 	n = sizeW2M(m);
+
+	qlock(&replylock);
 	if(n > nmbuf){
 		free(mbuf);
 		mbuf = malloc(n);
@@ -313,6 +316,7 @@
 	convW2M(m, mbuf, n);
 	if(write(4, mbuf, n) != n)
 		sysfatal("write: %r");
+	qunlock(&replylock);
 }
 
 /*
