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);
}