shithub: patch

Download patch

ref: bef4378c5cac18cea163dcdd6aea424e08e56ebf
parent: 15da5161aa7a11eaf0a0e6ea21297019bf807e2a
parent: 2663fd26c74a163a30328f9fecbe8b5f46c977f6
author: qwx <qwx@sciops.net>
date: Sun Oct 27 16:52:13 EDT 2024

merge

--- a/doom-udpip
+++ b/doom-udpip
@@ -1,43 +1,7 @@
-port udp/ip code from release.
-this works, but parts of the code suck and need to be altered. what sucks
-is that the doom networking protocol is shit. it's a peer-to-peer thing
-where each node needs to send frame information (ticcmd's) to every other
-node, and receive ticcmd's from every other node. any node that has a
-slower connection or is a slower machine will bring the game down for
-everyone. also, high bandwidth required.
-
-shitfuck n2: no port uses this protocol, since it sucks, and everyone
-implements their own incompatible crap, so no one port can talk to another,
-besides maybe the ports back to DOS. the code in i_net.c is unlikely to
-change too much though, unless this implementation is amended.
-one idea is to ask for chocolate-doom's networking protocol specs.
-chocolate-doom works fairly well, and supports a bunch of different OS',
-including openbsd, and being able to connect with 9front doom to another
-OS' shit is advanteageous, at least because live servers with bunches of
-players will be accessible. 9front doom and chocolate-doom _should_ be
-compatible, but idk.
-as it is, sdldoom might be able to connect to 9front doom with this patch,
-but good luck making sdldoom work.
-
-player 0 is special, and sets the game settings, sending them to the other
-nodes.
-testing this is more difficult without other patches because of the issues
-in the sound code, so try with doom-sndmus.patch and doom-sleep.patch.
-
-syntax: doom [-srv port] [-pn 0-3] [-net host!port...]
-defaults: udp port 666, player number 0
-
-example for a 3 player game, two nodes being on the same host (for shits):
-u14% games/doom -altdeath -nomonsters -warp7 -net u6!666 u14!667
-u6% games/doom -pn 1 -net u14!666 u14!667
-u14-1% games/doom -pn 2 -srv 667 -net u14!666 u6!666
-
-TODO: cf FIXME's in the code, conreq shit, more testing(?)
-
-diff -Naur a/sys/src/games/doom/i_net.c b/sys/src/games/doom/i_net.c
---- a/sys/src/games/doom/i_net.c	Wed Jan 18 01:13:24 2012
-+++ b/sys/src/games/doom/i_net.c	Wed Sep 16 06:45:07 2015
-@@ -20,142 +20,298 @@
+diff 790a516884e45ee2a3a11b915f5e125a0ccb02ca uncommitted
+--- a/sys/src/games/doom/i_net.c
++++ b/sys/src/games/doom/i_net.c
+@@ -20,142 +20,296 @@
  //
  //-----------------------------------------------------------------------------
  
@@ -53,6 +17,7 @@
 +#include <bio.h>
 +#include <ndb.h>
 +#include <ip.h>
++#include <thread.h>
  #include "m_argv.h"
 -
 +#include "i_system.h"
@@ -66,19 +31,12 @@
 -// I_InitNetwork
 -//
 -void I_InitNetwork (void)
--{
--printf("PORTME i_net.c I_InitNetwork (use 9P)\n");
 +enum{
 +	HDRSZ = 16+16+16+2+2	/* sizeof Udphdr w/o padding */
 +};
- 
--	doomcom = malloc (sizeof(*doomcom));
--	memset (doomcom, 0, sizeof(*doomcom));
++
 +static char lsrv[6] = "666";
- 
--	/* set up for network */
--	doomcom->ticdup = 1;
--	doomcom->extratics = 0;
++
 +struct Addr{
 +	Udphdr h;
 +	char srv[6];	/* convenience */
@@ -86,33 +44,36 @@
 +	long called;
 +};
 +static Addr raddr[MAXNETNODES];
- 
--//	netsend = PacketSend;
--//	netget = PacketGet;
--//	netgame = true;
++
 +static int ucfd;
 +static int udfd;
 +static int upfd[2];
 +static int upid;
- 
--	/* parse player number and host list */
--//	doomcom->consoleplayer = myargv[i+1][0]-'1';
- 
--	doomcom->numnodes = 1;	// this node for sure
++
++
 +static void
 +conreq(doomdata_t *d)
-+{
+ {
+-printf("PORTME i_net.c I_InitNetwork (use 9P)\n");
 +	int fd;
 +	long t;
 +	char ip[64];
 +	Addr *p;
-+
+ 
+-	doomcom = malloc (sizeof(*doomcom));
+-	memset (doomcom, 0, sizeof(*doomcom));
 +	p = &raddr[doomcom->remotenode];
-+
+ 
+-	/* set up for network */
+-	doomcom->ticdup = 1;
+-	doomcom->extratics = 0;
 +	t = time(nil);
 +	if(t - p->called < 1)
 +		return;
-+
+ 
+-//	netsend = PacketSend;
+-//	netget = PacketGet;
+-//	netgame = true;
 +	snprint(ip, sizeof ip, "%I", p->h.raddr);
 +	if((fd = dial(netmkaddr(ip, "udp", p->srv), lsrv, nil, nil)) < 0)
 +		sysfatal("dial: %r");
@@ -122,8 +83,8 @@
 +	p->called = t;
 +}
  
--	doomcom->id = DOOMCOM_ID;
--	doomcom->numplayers = doomcom->numnodes;
+-	/* parse player number and host list */
+-//	doomcom->consoleplayer = myargv[i+1][0]-'1';
 +static void
 +dsend(void)
 +{
@@ -130,13 +91,16 @@
 +	int i;
 +	uchar buf[HDRSZ+sizeof(doomdata_t)];
 +	doomdata_t d;
-+
+ 
+-	doomcom->numnodes = 1;	// this node for sure
 +	hnputl(&d.checksum, netbuffer->checksum);
 +	d.player = netbuffer->player;
 +	d.retransmitfrom = netbuffer->retransmitfrom;
 +	d.starttic = netbuffer->starttic;
 +	d.numtics = netbuffer->numtics;
-+
+ 
+-	doomcom->id = DOOMCOM_ID;
+-	doomcom->numplayers = doomcom->numnodes;
 +	for(i = 0; i < netbuffer->numtics; i++){
 +		d.cmds[i].forwardmove = netbuffer->cmds[i].forwardmove;
 +		d.cmds[i].sidemove = netbuffer->cmds[i].sidemove;
@@ -193,14 +157,30 @@
 -	doomcom->consoleplayer = 0;
 -	return;
 -    }
--
++	if(!raddr[doomcom->remotenode].ready){
++		conreq(&d);
++		return;
++	}
++	memcpy(buf, &raddr[doomcom->remotenode].h, HDRSZ);
++	memcpy(buf+HDRSZ, &d, sizeof d);
+ 
 -    netsend = PacketSend;
 -    netget = PacketGet;
 -    netgame = true;
--
++	i = doomcom->datalength + HDRSZ;
++	if(write(udfd, buf, i) != i)
++		sysfatal("dsend: %r");
++}
+ 
 -    // parse player number and host list
 -    doomcom->consoleplayer = myargv[i+1][0]-'1';
--
++static void
++drecv(void)
++{
++	int n;
++	ushort i;
++	doomdata_t d;
+ 
 -    doomcom->numnodes = 1;	// this node for sure
 -	
 -    i++;
@@ -212,29 +192,17 @@
 -	{
 -	    sendaddress[doomcom->numnodes].sin_addr.s_addr 
 -		= inet_addr (myargv[i]+1);
-+	if(!raddr[doomcom->remotenode].ready){
-+		conreq(&d);
-+		return;
- 	}
-+	memcpy(buf, &raddr[doomcom->remotenode].h, HDRSZ);
-+	memcpy(buf+HDRSZ, &d, sizeof d);
-+
-+	i = doomcom->datalength + HDRSZ;
-+	if(write(udfd, buf, i) != i)
-+		sysfatal("dsend: %r");
-+}
-+
-+static void
-+drecv(void)
-+{
-+	int n;
-+	ushort i;
-+	doomdata_t d;
-+
 +	if(filelength(upfd[1]) < 1){
 +		doomcom->remotenode = -1;
 +		return;
-+	}
+ 	}
+-	else
+-	{
+-	    hostentry = gethostbyname (myargv[i]);
+-	    if (!hostentry)
+-		I_Error ("gethostbyname: couldn't find %s", myargv[i]);
+-	    sendaddress[doomcom->numnodes].sin_addr.s_addr 
+-		= *(int *)hostentry->h_addr_list[0];
 +	if((n = read(upfd[1], &d, sizeof d)) <= 0
 +	|| read(upfd[1], &i, sizeof i) <= 0)
 +		sysfatal("drecv: %r");
@@ -255,17 +223,25 @@
 +		netbuffer->cmds[i].consistancy = nhgets(&d.cmds[i].consistancy);
 +		netbuffer->cmds[i].chatchar = d.cmds[i].chatchar;
 +		netbuffer->cmds[i].buttons = d.cmds[i].buttons;
-+	}
-+}
-+
+ 	}
+-	doomcom->numnodes++;
+-    }
+-	
+-    doomcom->id = DOOMCOM_ID;
+-    doomcom->numplayers = doomcom->numnodes;
+-*/
+ }
+ 
 +static void
-+uproc(void)
++uproc(void*)
 +{
 +	int n;
 +	ushort i;
 +	uchar buf[HDRSZ+sizeof(doomdata_t)];
 +	Udphdr h;
-+
+ 
+-void I_NetCmd (void)
++	upid = getpid();
 +	for(;;){
 +		if((n = read(udfd, buf, sizeof buf)) <= 0)
 +			break;
@@ -290,25 +266,24 @@
 +
 +void
 +I_NetCmd(void)
-+{
+ {
+-/*
+-    if (doomcom->command == CMD_SEND)
+-    {
+-	netsend ();
+-    }
+-    else if (doomcom->command == CMD_GET)
+-    {
+-	netget ();
+-    }
+-    else
+-	I_Error ("Bad net cmd: %i\n",doomcom->command);
+-*/
 +	if(doomcom->command == CMD_SEND)
 +		dsend();
 +	else if(doomcom->command == CMD_GET)
 +		drecv();
- 	else
--	{
--	    hostentry = gethostbyname (myargv[i]);
--	    if (!hostentry)
--		I_Error ("gethostbyname: couldn't find %s", myargv[i]);
--	    sendaddress[doomcom->numnodes].sin_addr.s_addr 
--		= *(int *)hostentry->h_addr_list[0];
--	}
--	doomcom->numnodes++;
--    }
--	
--    doomcom->id = DOOMCOM_ID;
--    doomcom->numplayers = doomcom->numnodes;
--*/
++	else
 +		I_Error("invalid netcmd %d", doomcom->command);
 +}
 +
@@ -325,7 +300,6 @@
 +static void
 +initudp(void)
 +{
-+	int pid;
 +	char data[64], adir[40];
 +
 +	/* FIXME */
@@ -342,11 +316,8 @@
 +
 +	if(pipe(upfd) < 0)
 +		sysfatal("pipe: %r");
-+	if((pid = rfork(RFPROC|RFMEM|RFFDG)) == 0){
-+		uproc();
-+		exits(nil);
-+	}
-+	upid = pid;
++	if(procrfork(uproc, nil, mainstacksize, RFFDG) < 0)
++		sysfatal("procrfork: %r");
 +}
 +
 +static void
@@ -420,8 +391,8 @@
 +	}
 +
 +	return 0;
- }
- 
++}
++
 +void
 +I_InitNetwork(void)
 +{
@@ -439,26 +410,11 @@
 +
 +	fmtinstall('I', eipfmt);
 +	initudp();
- 
--void I_NetCmd (void)
--{
--/*
--    if (doomcom->command == CMD_SEND)
--    {
--	netsend ();
--    }
--    else if (doomcom->command == CMD_GET)
--    {
--	netget ();
--    }
--    else
--	I_Error ("Bad net cmd: %i\n",doomcom->command);
--*/
++
 +	netgame = true;
  }
-diff -Naur a/sys/src/games/doom/i_net.h b/sys/src/games/doom/i_net.h
---- a/sys/src/games/doom/i_net.h	Wed Jan 18 01:13:23 2012
-+++ b/sys/src/games/doom/i_net.h	Wed Sep 16 06:36:09 2015
+--- a/sys/src/games/doom/i_net.h
++++ b/sys/src/games/doom/i_net.h
 @@ -35,6 +35,7 @@
  
  void I_InitNetwork (void);
@@ -467,9 +423,8 @@
  
  
  #endif
-diff -Naur a/sys/src/games/doom/i_system.c b/sys/src/games/doom/i_system.c
---- a/sys/src/games/doom/i_system.c	Wed Feb  5 08:58:15 2014
-+++ b/sys/src/games/doom/i_system.c	Wed Sep 16 06:36:09 2015
+--- a/sys/src/games/doom/i_system.c
++++ b/sys/src/games/doom/i_system.c
 @@ -6,6 +6,7 @@
  #include "i_system.h"
  #include "i_sound.h"
@@ -476,9 +431,9 @@
  #include "i_video.h"
 +#include "i_net.h"
  
+ #include "d_main.h"
  #include "d_net.h"
- #include "g_game.h"
-@@ -41,6 +42,7 @@
+@@ -42,6 +43,7 @@
  void I_Quit (void)
  {
  	D_QuitNetGame ();
@@ -486,7 +441,7 @@
  	I_ShutdownSound();
  	I_ShutdownMusic();
  	M_SaveDefaults ();
-@@ -85,6 +87,7 @@
+@@ -86,6 +88,7 @@
  	G_CheckDemoStatus();
  
      D_QuitNetGame ();
@@ -494,14 +449,14 @@
      I_ShutdownGraphics();
  
      exits("I_Error");
-diff -Naur a/sys/src/games/doom/w_wad.h b/sys/src/games/doom/w_wad.h
---- a/sys/src/games/doom/w_wad.h	Wed Jan 18 01:13:24 2012
-+++ b/sys/src/games/doom/w_wad.h	Wed Sep 16 06:38:33 2015
-@@ -67,6 +67,7 @@
+--- a/sys/src/games/doom/w_wad.h
++++ b/sys/src/games/doom/w_wad.h
+@@ -67,6 +67,8 @@
  void*	W_CacheLumpNum (int lump, int tag);
  void*	W_CacheLumpName (char* name, int tag);
  
 +vlong	filelength(int);
- 
- 
- 
++
+ #endif
+ //-----------------------------------------------------------------------------
+ //
--- a/file-mod
+++ /dev/null
@@ -1,11 +1,0 @@
-diff -r 121def0aed4d sys/src/cmd/file.c
---- a/sys/src/cmd/file.c	Thu Jul 12 09:33:33 2018 +0200
-+++ b/sys/src/cmd/file.c	Fri Jul 13 13:39:52 2018 +1200
-@@ -920,6 +920,7 @@
- } offstrs[] = {
- 	32*1024, "\001CD001\001",	"ISO9660 CD image",	7,	"application/x-iso9660-image",
- 	32*4, "DICM",	"DICOM medical imaging data",	4,	"application/dicom",
-+	1080, "M.K.",	"Amiga module",	4,	"audio/mod",
- 	0, 0, 0, 0, 0
- };
- 
--- a/file-opus
+++ /dev/null
@@ -1,58 +1,0 @@
-diff -r 19baa5600a90 sys/src/cmd/file.c
---- a/sys/src/cmd/file.c	Mon Apr 06 01:31:35 2020 +0200
-+++ b/sys/src/cmd/file.c	Mon Apr 06 04:34:43 2020 +0200
-@@ -153,6 +153,8 @@
- int	istga(void);
- int	ismp3(void);
- int	ismp4(void);
-+int	isoggvorbis(void);
-+int	isoggopus(void);
- int	ismung(void);
- int	isp9bit(void);
- int	isp9font(void);
-@@ -201,6 +203,8 @@
- 	isicocur,		/* windows icon or cursor file */
- 	isface,		/* ascii face file */
- 	istga,
-+	isoggvorbis,
-+	isoggopus,
- 	ismp4,
- 	ismp3,
- 
-@@ -838,7 +842,6 @@
- 	"\033%-12345X",		"HPJCL file",		9,	"application/hpjcl",
- 	"\033Lua",		"Lua bytecode",		4,	OCTET,
- 	"ID3",			"mp3 audio with id3",	3,	"audio/mpeg",
--	"OggS",			"ogg audio",		4,	"audio/ogg",
- 	".snd",			"sun audio",		4,	"audio/basic",
- 	"\211PNG",		"PNG image",		4,	"image/png",
- 	"P1\n",			"ppm",			3,	"image/ppm",
-@@ -1262,6 +1265,28 @@
- 	return 0;
- }
- 
-+int
-+isoggvorbis(void)
-+{
-+	if(memcmp(&buf[0], "OggS", 4) != 0)
-+		return 0;
-+	if(memcmp(&buf[29], "vorbis", 6) != 0)
-+		return 0;
-+	print("%s\n", mime ? "audio/ogg;codecs=vorbis" : "ogg audio");
-+	return 1;
-+}
-+
-+int
-+isoggopus(void)
-+{
-+	if(memcmp(&buf[0], "OggS", 4) != 0)
-+		return 0;
-+	if(memcmp(&buf[28], "OpusHead", 8) != 0)
-+		return 0;
-+	print("%s\n", mime ? "audio/ogg;codecs=opus" : "ogg audio");
-+	return 1;
-+}
-+
- /*
-  * low entropy means encrypted
-  */
--- a/troff-nchars
+++ /dev/null
@@ -1,18 +1,0 @@
-troff: inflate maximum size of character set
-
-this enables one to use fonts like unifont with troff.
-
-don't use fonts like unifont with troff.
-
-diff -r 79938a709ae3 sys/src/cmd/troff/tdef.h
---- a/sys/src/cmd/troff/tdef.h	Wed Jan 30 18:22:52 2019 +0100
-+++ b/sys/src/cmd/troff/tdef.h	Mon Feb 11 10:44:11 2019 +0100
-@@ -190,7 +190,7 @@
- 		unnamed ones and \N's)
- 	*/
- 
--#define	NCHARS	(8*1024)	/* maximum size of troff character set*/
-+#define	NCHARS	(64*1024)	/* maximum size of troff character set*/
- 
- 
- 	/* However for nroff you want only :
--- a/vdiff-col
+++ /dev/null
@@ -1,22 +1,0 @@
-diff ad909adf2b1c4d98b3e04698e9802a87ea9685d3 uncommitted
---- a/vdiff.c
-+++ b/vdiff.c
-@@ -177,12 +177,12 @@
- initcols(int black)
- {
- 	if(black){
--		initcol(&scrlcol,     0x22272EFF, 0xADBAC7FF);
--		initcol(&cols[Lfile], 0xADBAC7FF, 0x2D333BFF);
--		initcol(&cols[Lsep],  0xADBAC7FF, 0x263549FF);
--		initcol(&cols[Ladd],  0xADBAC7FF, 0x273732FF);
--		initcol(&cols[Ldel],  0xADBAC7FF, 0x3F2D32FF);
--		initcol(&cols[Lnone], 0xADBAC7FF, 0x22272EFF);
-+		initcol(&scrlcol,     DBlack, 0x777777FF);
-+		initcol(&cols[Lfile], 0xE7DA36FF, 0x222222FF);
-+		initcol(&cols[Lsep],  0xBEBEBEFF, 0x222222FF);
-+		initcol(&cols[Ladd],  0x55DD55FF, 0x061106FF);
-+		initcol(&cols[Ldel],  0xDD5555FF, 0x060606FF);
-+		initcol(&cols[Lnone], 0x777777FF, DBlack);
- 	}else{
- 		initcol(&scrlcol,     DWhite, 0x999999FF);
- 		initcol(&cols[Lfile], DBlack, 0xEFEFEFFF);
--- a/vdir-tweaks
+++ b/vdir-tweaks
@@ -1,104 +1,4 @@
-diff a50ea54acc46b5ee57b463ef3e881515cc962c00 uncommitted
---- a/alert.c
-+++ b/alert.c
-@@ -19,11 +19,11 @@
- alert(const char *title, const char *message, const char *err, Mousectl *mctl, Keyboardctl *kctl)
- {
- 	Alt alts[3];
--	Rectangle r, sc;
-+	Rectangle r;
- 	Point o, p;
--	Image *b, *save, *bg, *fg;
-+	Image *bg, *fg;
- 	Font *tf, *mf;
--	int done, h, w, tw, mw, ew;
-+	int i, h, w, tw, mw, ew;
- 	Mouse m;
- 	Rune k;
- 
-@@ -46,8 +46,6 @@
- 	mf = openfont(display, Messagefont);
- 	if(mf==nil)
- 		sysfatal("openfont: %r");
--	done = 0;
--	save = nil;
- 	h = Padding+tf->height+mf->height+Padding;
- 	if(err != nil)
- 		h += mf->height;
-@@ -55,56 +53,25 @@
- 	mw = stringwidth(mf, message);
- 	ew = err != nil ? stringwidth(mf, err) : 0;
- 	w = Padding+max(tw, max(mw, ew))+Padding;
--	b = screen;
--	sc = b->clipr;
--	replclipr(b, 0, b->r);
--	while(!done){
--		o = addpt(screen->r.min, Pt((Dx(screen->r)-w)/2, (Dy(screen->r)-h)/2));
--		r = Rect(o.x, o.y, o.x+w, o.y+h);
--		if(save==nil){
--			save = allocimage(display, r, b->chan, 0, DNofill);
--			if(save==nil)
--				break;
--			draw(save, r, b, nil, r.min);
--		}
--		draw(b, r, bg, nil, ZP);
--		border(b, r, 2, fg, ZP);
--		p = addpt(o, Pt(Padding, Padding));
--		string(b, p, fg, ZP, tf, title);
--		p.y += tf->height;
--		string(b, p, fg, ZP, mf, message);
--		if(err != nil){
--			p.x = o.x + Padding;
--			p.y += mf->height;
--			string(b, p, fg, ZP, mf, err);
--		}
--		flushimage(display, 1);
--		if(b!=screen || !eqrect(screen->clipr, sc)){
--			freeimage(save);
--			save = nil;
--		}
--		b = screen;
--		sc = b->clipr;
--		replclipr(b, 0, b->r);
--		switch(alt(alts)){
--		default:
--			continue;
-+	o = addpt(screen->r.min, Pt((Dx(screen->r)-w)/2, (Dy(screen->r)-h)/2));
-+	r = Rect(o.x, o.y, o.x+w, o.y+h);
-+	draw(screen, r, bg, nil, ZP);
-+	border(screen, r, 2, fg, ZP);
-+	p = addpt(o, Pt(Padding, Padding));
-+	string(screen, p, fg, ZP, tf, title);
-+	p.y += tf->height;
-+	string(screen, p, fg, ZP, mf, message);
-+	if(err != nil){
-+		p.x = o.x + Padding;
-+		p.y += mf->height;
-+		string(screen, p, fg, ZP, mf, err);
-+	}
-+	flushimage(display, 1);
-+	for(;;){
-+		i = alt(alts);
-+		if(i == 1 || i == 0 && m.buttons != 0)
- 			break;
--		case 1:
--			done = (k=='\n' || k==Kesc);
--			break;
--		case 0:
--			done = m.buttons&1 && ptinrect(m.xy, r);
--			break;
--		}
--		if(save){
--			draw(b, save->r, save, nil, save->r.min);
--			freeimage(save);
--			save = nil;
--		}
--			
- 	}
--	replclipr(b, 0, sc);
- 	freeimage(bg);
- 	freeimage(fg);
- 	freefont(tf);
+diff d57a09f05c237d004770493258c206bbe9916681 uncommitted
 --- a/icons.h
 +++ b/icons.h
 @@ -420,3 +420,181 @@
@@ -420,7 +320,7 @@
 +Image*	ereadcol(char*);
 --- a/vdir.c
 +++ b/vdir.c
-@@ -20,6 +20,13 @@
+@@ -21,6 +21,13 @@
  	Slowscroll = 10,
  };
  
@@ -434,7 +334,7 @@
  enum
  {
  	Emouse,
-@@ -47,6 +54,8 @@
+@@ -50,6 +57,8 @@
  Rectangle homer;
  Rectangle upr;
  Rectangle cdr;
@@ -443,7 +343,7 @@
  Rectangle newdirr;
  Rectangle newfiler;
  Rectangle viewr;
-@@ -60,6 +69,8 @@
+@@ -63,6 +72,8 @@
  Image *iup;
  Image *inewfile;
  Image *inewfolder;
@@ -452,15 +352,15 @@
  Image *toolbg;
  Image *toolfg;
  Image *viewbg;
-@@ -68,6 +79,7 @@
+@@ -71,6 +82,7 @@
  Image *selfg;
  Image *scrollbg;
  Image *scrollfg;
 +Image *fb;
+ Image *high;
  int sizew;
  int lineh;
- int nlines;
-@@ -121,8 +133,10 @@
+@@ -124,8 +136,10 @@
  	return 1;
  }
  
@@ -472,7 +372,7 @@
  {
  	int fd, i;
  	vlong m;
-@@ -135,14 +149,11 @@
+@@ -138,14 +152,11 @@
  	if(dirs!=nil)
  		free(dirs);
  	ndirs = dirreadall(fd, &dirs);
@@ -492,7 +392,7 @@
  	close(fd);
  	m = 1;
  	for(i=0; i < ndirs; i++){
-@@ -149,14 +160,47 @@
+@@ -152,14 +163,47 @@
  		if(dirs[i].length>m)
  			m=dirs[i].length;
  	}
@@ -542,15 +442,15 @@
  }
  
  void
-@@ -164,6 +208,7 @@
+@@ -167,6 +211,7 @@
  {
- 	char newpath[256] = {0};
+ 	char newpath[4096] = {0};
  
 +	pushback();
  	if(dir == nil)
- 		snprint(newpath, sizeof path, home);
+ 		snprint(newpath, sizeof newpath, home);
  	else if(dir[0] == '/')
-@@ -174,7 +219,7 @@
+@@ -177,7 +222,7 @@
  		showerrstr("Directory does not exist");
  	else
  		snprint(path, sizeof path, abspath(path, newpath));
@@ -559,7 +459,7 @@
  }
  
  void
-@@ -194,7 +239,7 @@
+@@ -197,7 +242,7 @@
  		goto cleanup;
  	}
  	close(fd);
@@ -568,7 +468,7 @@
  cleanup:
  	free(p);
  }
-@@ -216,7 +261,7 @@
+@@ -219,7 +264,7 @@
  		goto cleanup;
  	}
  	close(fd);
@@ -577,7 +477,12 @@
  cleanup:
  	free(p);
  }
-@@ -267,7 +312,7 @@
+@@ -272,11 +317,11 @@
+ 		return;
+ 	p = smprint("%s/%s", path, d.name);
+ 	qp = quotestrdup(p);
+-	snprint(cmd, sizeof cmd, "rm -r %s >/dev/null >[2=1]", qp);
++	snprint(cmd, sizeof cmd, "rm -r \'%s\' >/dev/null >[2=1]", qp);
  	if(doexec(cmd) < 0)
  		showerrstr("Cannot remove file/directory");
  	else
@@ -586,7 +491,12 @@
  	free(qp);
  	free(p);
  }
-@@ -287,7 +332,7 @@
+@@ -292,11 +337,11 @@
+ 	qfp = quotestrdup(fp);
+ 	qtp = quotestrdup(tp);
+ 
+-	snprint(cmd, sizeof cmd, "mv %s %s >/dev/null >[2=1]", qfp, qtp);
++	snprint(cmd, sizeof cmd, "mv \'%s\' \'%s\' >/dev/null >[2=1]", qfp, qtp);
  	if(doexec(cmd) < 0)
  		showerrstr("Cannot rename file/directory");
  	else
@@ -595,7 +505,7 @@
  	free(qtp);
  	free(qfp);
  	free(tp);
-@@ -295,7 +340,7 @@
+@@ -304,7 +349,7 @@
  }
  
  int
@@ -604,7 +514,7 @@
  {
  	char *f;
  	int e;
-@@ -302,11 +347,14 @@
+@@ -311,11 +356,14 @@
  
  	f = smprint("%s/%s", path, name);
  	e = access(f, 0)==0;
@@ -617,13 +527,13 @@
 +		else
 +			plumbsendtext(plumbfd, "vdir", nil, path, name);
 +	}else{
- 		alert("Error", "File does not exist anymore", nil, mctl, kctl);
+ 		alert("File does not exist anymore", nil, mctl, kctl);
 -		loaddirs();
 +		loaddirs(0);
  		redraw();
  	}
  	free(f);
-@@ -316,28 +364,21 @@
+@@ -325,30 +373,22 @@
  void
  initcolors(void)
  {
@@ -640,6 +550,7 @@
 -		selfg  = display->black;
 -		scrollbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF);
 -		scrollfg = display->white;
+-		high = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreygreen);
 -	}else{
 -		toolbg = theme->back;
 -		toolfg = theme->text;
@@ -649,6 +560,7 @@
 -		selfg  = theme->text;
 -		scrollbg = theme->border;
 -		scrollfg = theme->back;
+-		high = theme->high;
 -	}
 +	memset(&theme, 0, sizeof theme);
 +	theme.back = 0xEFEFEF;
@@ -663,10 +575,11 @@
 +	selfg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme.text << 8 | 0xff);
 +	scrollbg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme.border << 8 | 0xff);
 +	scrollfg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme.back << 8 | 0xff);
++	high = allocimage(display, Rect(0,0,1,1), screen->chan, 1, theme.high << 8 | 0xff);
  }
  
  Image*
-@@ -368,6 +409,8 @@
+@@ -379,6 +419,8 @@
  	iup    = loadicon(big, updata, sizeof updata);
  	inewfile = loadicon(big, newfiledata, sizeof newfiledata);
  	inewfolder = loadicon(big, newfolderdata, sizeof newfolderdata);
@@ -675,7 +588,7 @@
  }
  
  char*
-@@ -388,7 +431,7 @@
+@@ -399,7 +441,7 @@
  
  	p->x += Toolpadding;
  	r = Rect(p->x, p->y, p->x+16, p->y+16);
@@ -684,7 +597,7 @@
  	p->x += 16+Toolpadding;
  	return r;
  }
-@@ -401,12 +444,12 @@
+@@ -412,12 +454,12 @@
  
  	s = t;
  	if(*s && (p.x+stringwidth(font, s)) > n){
@@ -699,7 +612,7 @@
  	}
  	return p;
  }
-@@ -429,7 +472,7 @@
+@@ -440,7 +482,7 @@
  	p = addpt(viewr.min, Pt(Toolpadding, Toolpadding));
  	p.y += n*lineh;
  	r = Rpt(p, addpt(p, Pt(Dx(viewr)-2*Toolpadding, lineh)));
@@ -708,7 +621,7 @@
  	t = mdate(d);
  	snprint(buf, sizeof buf, "%*lld  %s", sizew, d.length, t);
  	free(t);
-@@ -436,12 +479,12 @@
+@@ -447,12 +489,12 @@
  	img = (d.qid.type&QTDIR) ? folder : file;
  	p.y -= Padding;
  	dy = (lineh-12)/2;
@@ -723,7 +636,7 @@
  }
  
  void
-@@ -462,22 +505,25 @@
+@@ -473,22 +515,25 @@
  	Point p;
  	int i, h, y;
  
@@ -757,7 +670,7 @@
  	if(ndirs>0){
  		h = ((double)nlines/ndirs)*Dy(scrollr);
  		y = ((double)offset/ndirs)*Dy(scrollr);
-@@ -484,10 +530,11 @@
+@@ -495,10 +540,11 @@
  		scrposr = Rect(scrollr.min.x, scrollr.min.y+y, scrollr.max.x-1, scrollr.min.y+y+h);
  	}else
  		scrposr = Rect(scrollr.min.x, scrollr.min.y, scrollr.max.x-1, scrollr.max.y);
@@ -770,7 +683,7 @@
  	flushimage(display, 1);
  }
  
-@@ -528,18 +575,42 @@
+@@ -539,18 +585,42 @@
  }
  
  void
@@ -816,7 +729,7 @@
  	viewr.min.x += Scrollwidth;
  	viewr.min.y = toolr.max.y+1;
  	nlines = Dy(viewr)/lineh;
-@@ -560,17 +631,38 @@
+@@ -571,17 +641,38 @@
  	case Kpgdown:
  		scrolldown(nlines);
  		break;
@@ -859,7 +772,7 @@
  	}
  }
  
-@@ -579,9 +671,8 @@
+@@ -590,9 +681,8 @@
  {
  	Point p;
  
@@ -871,7 +784,7 @@
  	return p;
  }
  
-@@ -601,66 +692,36 @@
+@@ -612,66 +702,36 @@
  void
  evtmouse(Mouse m)
  {
@@ -878,7 +791,7 @@
 -	int n, dy;
 +	int n;
  	Dir d;
- 	char buf[256] = {0};
+ 	char buf[4096] = {0};
  
 -	if(oldbuttons == 0 && m.buttons != 0 && ptinrect(m.xy, scrollr))
 +	m.xy = subpt(m.xy, screen->r.min);
@@ -902,7 +815,7 @@
 -			d = dirs[offset+n];
 -			switch(menuhit(2, mctl, &menu2, nil)){
 -			case Mdelete:
--				rm(d.name);
+-				rm(d);
 -				redraw();
 -				break;
 -			case Mrename:
@@ -952,7 +865,7 @@
  		}else if(ptinrect(m.xy, newdirr)){
  			m.xy = cept("Create directory");
  			if(enter("Create directory", buf, sizeof buf, mctl, kctl, nil)>0){
-@@ -681,11 +742,40 @@
+@@ -692,11 +752,40 @@
  			if(d.qid.type & QTDIR){
  				cd(d.name);
  				redraw();
@@ -970,7 +883,7 @@
 +			menu2.lasthit = 0;
 +			switch(menuhit(2, mctl, &menu2, nil)){
 +			case Mdelete:
-+				rm(d.name);
++				rm(d);
 +				redraw();
 +				break;
 +			case Mrename:
@@ -996,9 +909,9 @@
  	}else if(m.buttons&8)
  		scrollup(Slowscroll);
  	else if(m.buttons&16)
-@@ -761,7 +851,7 @@
- 	alts[Eresize].c = mctl->resizec;
- 	alts[Ekeyboard].c = kctl->c;
+@@ -795,7 +884,7 @@
+ 	alts[Eplumb].c = chancreate(sizeof(d), 1);
+ 	proccreate(plumbdir, alts[Eplumb].c, 4096);
  	readhome();
 -	loaddirs();
 +	loaddirs(1);