shithub: mpl

Download patch

ref: 140b16cb7ae7c8dbe6c28f196e4dad10dc6890dc
parent: b7a4f1e6e70cb97de31ec684d243825e395fe001
author: Jacob Moody <jsmoody@iastate.edu>
date: Tue Sep 24 05:32:24 EDT 2019

Add volume controls
volume is done in in new thread under mainproc
Minor bug fixes regarding album drawing and dir parsing

--- a/dir.c
+++ b/dir.c
@@ -160,7 +160,7 @@
 	uint n, i;
 	uint numdirs = 0;
 	uint alcount = 0;
-	char buf[512];
+	char buf[1024];
 
 	fd = open(path, OREAD);
 	if(fd < 0)
--- a/draw.c
+++ b/draw.c
@@ -164,7 +164,10 @@
 		runestring(screen, p, i == cursong ? active : textcolor, ZP, f, tracktitle);
 		p.y += f->height;
 	}
-	start.y+=256;
+	if(p.y > start.y+256)
+		start.y = p.y;
+	else
+		start.y+=256;
 	return start;
 }
 
@@ -178,5 +181,20 @@
 	stop+=1;
 
 	for(;start!=stop;start++)
-		p = drawalbum(start, textcolor, active, p, start ==  cur ? cursong : -1);
+		p = drawalbum(start, textcolor, active, p, start == cur ? cursong : -1);
+	flushimage(display, Refnone);
+}
+
+void
+drawvolume(int level, Image* color)
+{
+	Point p;
+	char buf[128];
+	Font *f = screen->display->defaultfont;
+	int n = snprint(buf, sizeof buf, "Vol: %d%%", level);
+	p.y = screen->r.min.y;
+	p.x = screen->r.max.x;
+	p.x-=(n*f->width);
+	string(screen, p, color, ZP, f, buf);
+	flushimage(display, Refnone);
 }
\ No newline at end of file
--- a/fncs.h
+++ b/fncs.h
@@ -27,6 +27,7 @@
 Image*	convpic(int, char*);
 Image*	convpicbuf(uchar*, uvlong, char*);
 void	drawlibrary(Album*, Album*, Album*, Image*, Image*, int);
+void	drawvolume(int, Image*);
 
 /* dir.c */
 void	dir2album(Album*,char*);
--- a/mpl.c
+++ b/mpl.c
@@ -17,12 +17,21 @@
 	NONE
 };
 
+enum volmsg{
+	UP,
+	DOWN,
+	MUTE,
+	UNMUTE,
+	DRAW,
+};
 
+
 Mousectl 	*mctl;
 Keyboardctl *kctl;
 Channel		*queuein;
 Channel		*queueout;
 Channel		*ctl;
+Channel		*vctl;
 Album		*start, *cur, *stop;
 int			cursong;
 int			decpid;
@@ -31,8 +40,6 @@
 Image *red;
 Image *background;
 
-enum decmsg msg;
-
 void
 quit(char *err)
 {
@@ -45,12 +52,13 @@
 void
 eresized(int isnew)
 {
+	enum volmsg vmsg = DRAW;
 	if(isnew && getwindow(display, Refnone) < 0)
 		quit("eresized: Can't reattach to window");
 
 	draw(screen, screen->r, background, nil, ZP);
 	drawlibrary(cur, stop, cur, black, red, cursong);
-	flushimage(display, Refnone);
+	send(vctl, &vmsg);
 }
 
 char*
@@ -74,6 +82,8 @@
 void
 handleaction(Rune kbd)
 {
+	enum volmsg vmsg;
+	enum decmsg msg;
 	switch(kbd){
 		case Kbs:
 		case Kdel:
@@ -103,6 +113,16 @@
 			sendp(queuein, nextsong());
 			eresized(0);
 			break;
+		case '9':
+			vmsg = DOWN;
+			send(vctl, &vmsg);
+			eresized(0);
+			break;
+		case '0':
+			vmsg = UP;
+			send(vctl, &vmsg);
+			eresized(0);
+			break;
 	}
 }
 
@@ -113,7 +133,87 @@
 	sysfatal("usage");
 }
 
+
 void
+readvol(int fd, int *level)
+{
+	int n;
+	char *dot;
+	char buf[512];
+	n = pread(fd, buf, (sizeof buf) - 1, 0);
+	buf[n] = '\0';
+	dot = strchr(buf, '\n');
+	if(dot == nil)
+		goto error;
+
+	*dot = '\0';
+	dot = strstr(buf, "left");
+	if(dot != nil){
+		*level = atoi(dot+4+1);
+		return;
+	}
+
+	dot = strstr(buf, "out");
+	if(dot == nil)
+		goto error;
+
+	*level = atoi(dot+3);
+	return;
+
+error:
+	*level = -1;
+}
+
+void
+writevol(int fd, int level)
+{
+	char buf[16];
+	int n = snprint(buf, sizeof buf, "%d", level);
+	write(fd, buf, n);
+}
+
+
+void
+volthread(void *arg)
+{
+	Channel *ctl = arg;
+	int fd;
+	int mlevel, level;
+	enum volmsg vmsg;
+
+	if((fd = open("/dev/volume", ORDWR))<0){
+		/* Make volume controls NOP */
+		chanclose(ctl);
+		return;
+	}
+	for(;;){
+		recv(ctl, &vmsg);
+		readvol(fd, &level);
+		switch(vmsg){
+		case UP:
+			level+=5;
+			writevol(fd, level);
+			break;
+		case DOWN:
+			level-=5;
+			writevol(fd, level);
+			break;
+		case MUTE:
+			mlevel = level;
+			level = 0;
+			writevol(fd, level);
+			break;
+		case UNMUTE:
+			level = mlevel;
+			writevol(fd, level);
+			break;
+		case DRAW:
+			drawvolume(level, black);
+		}
+	}
+}
+
+void
 threadmain(int argc, char *argv[])
 {
 	Mouse mouse;
@@ -121,7 +221,7 @@
 	int resize[2];
 	int nalbum;
 	cursong = 0;
-	queuein = queueout = ctl = nil;
+	queuein = queueout = ctl = vctl = nil;
 
 	//TODO: Use ARGBEGIN
 	argv0 = argv[0];	
@@ -135,6 +235,9 @@
 		sysfatal("initmouse: %r");
 	if((kctl = initkeyboard(nil)) == nil)
 		sysfatal("initkeyboard: %r");
+
+	vctl = chancreate(sizeof(enum volmsg), 0);
+	threadcreate(volthread, vctl, 8192);
 
 	red = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DBlue);
 	black = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DBlack);