shithub: zuke

Download patch

ref: 3ef22d5f5699f64f6d89fea1eaeb75b892633af5
parent: feeab3fe530af252f3e7062b9bc638fa72c4b348
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sat Feb 20 19:53:07 EST 2016

get rid of event(2); crappy cover images; fixes all around

--- a/mkplist.c
+++ b/mkplist.c
@@ -80,9 +80,12 @@
 			curr->track = strdup(v);
 		break;
 	case Timage:
-		curr->imageoffset = offset;
-		curr->imagesize = size;
-		curr->imagereader = f != nil;
+		if(curr->imagefmt == nil){
+			curr->imagefmt = strdup(v);
+			curr->imageoffset = offset;
+			curr->imagesize = size;
+			curr->imagereader = f != nil;
+		}
 		break;
 	}
 }
@@ -213,7 +216,7 @@
 	if(m->channels > 0)
 		s = seprint(s, buf+sizeof(buf), "%c %d\n", Pchannels, m->channels);
 	if(m->imagesize > 0)
-		s = seprint(s, buf+sizeof(buf), "%c %d %d %d\n", Pimage, m->imageoffset, m->imagesize, m->imagereader);
+		s = seprint(s, buf+sizeof(buf), "%c %d %d %d %s\n", Pimage, m->imageoffset, m->imagesize, m->imagereader, m->imagefmt);
 	s = seprint(s, buf+sizeof(buf), "%c %s\n", Ppath, m->path);
 
 	if(buf[sizeof(buf)-2] != 0)
--- a/plist.h
+++ b/plist.h
@@ -35,6 +35,7 @@
 	char *date;
 	char *track;
 	char *path;
+	char *imagefmt;
 	int numartist;
 	int duration;
 	int samplerate;
--- a/zuke.c
+++ b/zuke.c
@@ -1,9 +1,8 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
-#include <event.h>
+#include <mouse.h>
 #include <keyboard.h>
-#include <bio.h>
 #include <thread.h>
 #include <ctype.h>
 #include "plist.h"
@@ -16,7 +15,7 @@
 	Cstop,
 	Ctoggle,
 
-	Relbufsz = 65536,
+	Relbufsz = 8192,
 };
 
 static Meta *pl;
@@ -26,7 +25,7 @@
 
 struct Player
 {
-	Channel *ctl, *ev;
+	Channel *ctl;
 	int pcur;
 };
 
@@ -38,7 +37,10 @@
 static int scroll, scrollsz;
 static Image *cola, *colb;
 static Font *f;
+static Image *cover;
 static Channel *ev;
+static Mousectl *mctl;
+static Keyboardctl *kctl;
 
 static void
 redraw(Image *screen, int new)
@@ -45,12 +47,18 @@
 {
 	char tmp[256];
 	Point p, sp;
+	Rectangle sel;
 	int i;
 
-	sp.x = sp.y = 0;
-	if(new)
+	if(new && getwindow(display, Refnone) < 0)
+		sysfatal("getwindow: %r");
+	else
 		draw(screen, screen->r, cola, nil, ZP);
+	sp.x = sp.y = 0;
 
+	if(cover != nil)
+		draw(screen, screen->r, cover, nil, ZP);
+
 	p.x = screen->r.min.x + 2;
 	p.y = screen->r.min.y + 2;
 	scrollsz = Dy(screen->r) / f->height - 1;
@@ -70,7 +78,6 @@
 
 		snprint(tmp, sizeof(tmp), "%s  -  %s  -  %s", pl[i].artist[0], pl[i].album, pl[i].title);
 		if(pcur == i){
-			Rectangle sel;
 			sel = screen->r;
 			sel.min.y = p.y;
 			sel.max.y = p.y + f->height;
@@ -86,17 +93,63 @@
 }
 
 static void
+coverload(void *m_)
+{
+	int p[2], fd, pid;
+	char *prog;
+	Meta *m;
+
+	threadsetname("cover");
+	m = m_;
+	freeimage(cover);
+	cover = nil;
+	redraw(screen, 0);
+	if(m->imagefmt == nil || m->imagereader != 0)
+		return;
+	if(strcmp(m->imagefmt, "image/png") == 0)
+		prog = "/bin/png";
+	else if(strcmp(m->imagefmt, "image/jpeg") == 0)
+		prog = "/bin/jpg";
+	else
+		return;
+
+	if((fd = open(m->path, OREAD)) < 0)
+		return;
+	if(seek(fd, m->imageoffset, 0) != m->imageoffset){
+		close(fd);
+		return;
+	}
+
+	pipe(p);
+	if((pid = rfork(RFPROC|RFFDG|RFREND|RFNOTEG)) == 0){
+		dup(fd, 0);
+		dup(p[0], 1);
+		close(fd);
+		close(p[0]);
+		close(p[1]);
+		execl(prog, prog, "-9t", nil);
+		sysfatal("execl: %r");
+	}
+	close(fd);
+	close(p[0]);
+	if(pid > 0){
+		cover = readimage(display, p[1], 0);
+		postnote(PNGROUP, pid, "kill");
+		redraw(screen, 0);
+	}
+	close(p[1]);
+}
+
+static void
 playerthread(void *player_)
 {
 	char *buf;
-	Ioproc *io;
 	Player *player;
 	ulong c;
-	int p[2], pid, n, noinit;
+	int p[2], fd, pid, n, noinit;
 
 	player = player_;
 	noinit = 0;
-	io = nil;
 	buf = nil;
 
 next:
@@ -103,11 +156,16 @@
 	pipe(p);
 	if((pid = rfork(RFPROC|RFFDG|RFREND|RFNOTEG)) == 0){
 		dup(p[0], 1);
+		if((fd = open(pl[player->pcur].path, OREAD)) < 0){
+			fprint(2, "%r\n");
+			exits(nil);
+		}
+		dup(fd, 0);
+		close(fd);
 		close(p[0]);
 		close(p[1]);
-		close(0);
 		close(2);
-		execl("/bin/play", "/bin/play", "-o", "/fd/1", pl[player->pcur].path, nil);
+		execl("/bin/play", "/bin/play", "-o", "/fd/1", nil);
 		sysfatal("execl: %r");
 	}
 	if(pid < 0)
@@ -116,19 +174,18 @@
 
 	if(!noinit){
 		threadsetname("player");
-		sendp(player->ev, nil); /* "ready to start" */
 		c = recvul(player->ctl);
 		if(c != Cstart)
 			return;
-		io = ioproc();
 		buf = malloc(Relbufsz);
 		byteswritten = 0;
 	}
 
 	pcurplaying = player->pcur;
-	redraw(screen, 1);
+	redraw(screen, 0);
+	threadcreate(coverload, &pl[pcurplaying], 4096);
 
-	while((n = ioread(io, p[1], buf, Relbufsz)) > 0){
+	while((n = readn(p[1], buf, Relbufsz)) > 0){
 		c = nbrecvul(player->ctl);
 		if(c == Cstop)
 			goto stop;
@@ -137,7 +194,7 @@
 			if(c == Cstop)
 				goto stop;
 		}
-		if(iowrite(io, audio, buf, n) != n)
+		if(write(audio, buf, n) != n)
 			break;
 		byteswritten += n;
 	}
@@ -151,10 +208,8 @@
 
 stop:
 	close(p[1]);
-	postnote(PNGROUP, pid, "interrupt");
+	postnote(PNGROUP, pid, "kill");
 	free(buf);
-	closeioproc(io);
-	sendp(player->ev, nil); /* "finished" */
 }
 
 static Player *
@@ -164,11 +219,9 @@
 
 	player = malloc(sizeof(*player));
 	player->ctl = chancreate(sizeof(ulong), 0);
-	player->ev = chancreate(sizeof(void*), 0);
 	player->pcur = pcur;
 
 	proccreate(playerthread, player, mainstacksize);
-	recvp(player->ev); /* wait for it to become ready */
 
 	return player;
 }
@@ -180,8 +233,6 @@
 		return;
 
 	sendul(player->ctl, Cstop);
-	recvp(player->ev); /* wait until it dies */
-	chanfree(player->ev);
 	chanfree(player->ctl);
 	free(player);
 }
@@ -252,7 +303,8 @@
 				m->imageoffset = strtol(s+2, &e, 10);
 				m->imagesize = strtol(e+1, &s, 10);
 				m->imagereader = strtol(s+1, &e, 10);
-				s = e + 1;
+				m->imagefmt = e + 1;
+				s = strchr(e+2, '\n') + 1;
 			}else if(s[0] == Pchannels || s[0] == Pduration || s[0] == Psamplerate){
 				intval = strtol(s+2, &e, 10);
 				if(s[0] == Pchannels) m->channels = intval;
@@ -292,7 +344,7 @@
 
 	inc = (d == '/' || d == 'n') ? 1 : -1;
 	if(d == '/' || d == '?')
-		sz = eenter(inc > 0 ? "forward:" : "backward:", buf, sizeof(buf), nil);
+		sz = enter(inc > 0 ? "forward:" : "backward:", buf, sizeof(buf), mctl, kctl, nil);
 	if(sz < 1 || (inc > 0 && pcur >= plnum-1) || (inc < 0 && pcur < 1))
 		return;
 
@@ -327,18 +379,19 @@
 }
 
 void
-eresized(int new)
-{
-	if(getwindow(display, Refnone) < 0)
-		sysfatal("can't reattach to window: %r");
-	redraw(screen, new);
-}
-
-void
 threadmain(int argc, char **argv)
 {
-	int inv;
+	int inv, oldpcur;
 	Player *player;
+	Rune key;
+	Mouse m;
+	Alt a[] =
+	{
+		{ nil, &m,   CHANRCV },
+		{ nil, nil,  CHANRCV },
+		{ nil, &key, CHANRCV },
+		{ nil, nil,  CHANEND },
+	};
 
 	inv = 0;
 	ARGBEGIN{
@@ -360,12 +413,19 @@
 	}
 
 	if(initdraw(0, 0, "zuke") < 0)
-		sysfatal("initdraw failed");
+		sysfatal("initdraw: %r");
+	if((mctl = initmouse(nil, screen)) == nil)
+		sysfatal("initmouse: %r");
+	if((kctl = initkeyboard(nil)) == nil)
+		sysfatal("initkeyboard: %r");
 
+	a[0].c = mctl->c;
+	a[1].c = mctl->resizec;
+	a[2].c = kctl->c;
+
 	f = display->defaultfont;
 	cola = inv ? display->black : display->white;
 	colb = inv ? display->white : display->black;
-	einit(Emouse | Ekeyboard);
 	srand(time(0));
 	pcurplaying = -1;
 	player = nil;
@@ -374,52 +434,66 @@
 	redraw(screen, 1);
 
 	for(;;){
-		int oldpcur, key;
-		Event e;
-
 		oldpcur = pcur;
-		key = event(&e);
 
-		if(key == Emouse){
-			if(e.mouse.buttons > 0){
-				pcur = scroll + (e.mouse.xy.y - screen->r.min.y)/f->height;
-				if(e.mouse.buttons == 4){
+		switch(alt(a)){
+		case 0:
+			if(m.buttons > 0){
+				pcur = scroll + (m.xy.y - screen->r.min.y)/f->height;
+				if(m.buttons == 4){
 					stop(player);
 					player = newplayer(pcur);
 					start(player);
 				}
 			}
-		}
-		else if(key == Ekeyboard){
-			if(e.kbdc == Kup){
+			break;
+		case 1:
+			redraw(screen, 1);
+			break;
+		case 2:
+			switch(key){
+			case Kup:
 				pcur--;
-			}else if(e.kbdc == Kpgup){
+				break;
+			case Kpgup:
 				pcur -= scrollsz;
-			}else if(e.kbdc == Kdown){
+				break;
+			case Kdown:
 				pcur++;
-			}else if(e.kbdc == Kpgdown){
+				break;
+			case Kpgdown:
 				pcur += scrollsz;
-			}else if(e.kbdc == Kend){
+				break;
+			case Kend:
 				pcur = plnum-1;
-			}else if(e.kbdc == Khome){
+				break;
+			case Khome:
 				pcur = 0;
-			}else if(e.kbdc == 0x0a){
+				break;
+			case 10:
 				stop(player);
 				player = newplayer(pcur);
 				start(player);
-			}else if(e.kbdc == 'q' || e.kbdc == Kesc){
+				break;
+			case 'q': case Kdel:
 				stop(player);
+				goto end;
+			case 'o':
+				pcur = pcurplaying;
 				break;
-			}else if(e.kbdc == 'o'){
+			case '>':
+				if(player == nil)
+					break;
 				pcur = pcurplaying;
-			}else if(e.kbdc == '>' && pcurplaying >= 0){
-				pcur = pcurplaying;
 				if(++pcur >= plnum)
 					pcur = 0;
 				stop(player);
 				player = newplayer(pcur);
 				start(player);
-			}else if(e.kbdc == '<' && pcurplaying >= 0){
+				break;
+			case '<':
+				if(player == nil)
+					break;
 				pcur = pcurplaying;
 				if(--pcur < 0)
 					pcur = plnum-1;
@@ -426,13 +500,17 @@
 				stop(player);
 				player = newplayer(pcur);
 				start(player);
-			}else if(e.kbdc == 's' && player != nil){
+				break;
+			case 's':
 				stop(player);
 				player = nil;
-			}else if(e.kbdc == 'p'){
+				break;
+			case 'p':
 				toggle(player);
-			}else if(e.kbdc == '/' || e.kbdc == '?' || e.kbdc == 'n' || e.kbdc == 'N'){
-				search(e.kbdc);
+				break;
+			case '/': case '?': case 'n': case 'N':
+				search(key);
+				break;
 			}
 		}
 
@@ -453,9 +531,15 @@
 				scroll = 0;
 
 			if(pcur != oldpcur)
-				redraw(screen, 1);
+				redraw(screen, 0);
 		}
 	}
 
+end:
+	closemouse(mctl);
+	closekeyboard(kctl);
+	chanclose(a[0].c);
+	chanclose(a[1].c);
+	chanclose(a[2].c);
 	threadexitsall(nil);
 }