~moody/mpl

mpl/vol.c -rw-r--r-- 1.6 KiB
7309e0f2 — Jacob Moody Archive and point to zuke 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>

#include "dat.h"
#include "fncs.h"

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 **chans = arg;
	Channel *ctl = chans[0];
	Channel *out = chans[1];
	free(chans);

	int fd;
	int level;
	int muted = 0;
	enum volmsg vmsg;

	if((fd = open("/dev/volume", ORDWR))<0){
		/* Make volume controls NOP */
		chanclose(ctl);
		chanclose(out);
		return;
	}

	Alt alts[] = {
		{ctl, &vmsg, CHANRCV},
		{out, &level, CHANSND},
		{nil, nil, CHANEND},
	};

	readvol(fd, &level);
	for(;;){
		if(alt(alts) != 0)
			continue;
		readvol(fd, &level);
		switch(vmsg){
		case UP:
			level+=5;
			level = level > 100 ? 100 : level;
			writevol(fd, muted == 0 ? level : 0);
			break;
		case DOWN:
			level-=5;
			level = level < 0 ? 0 : level;
			writevol(fd, muted == 0 ? level : 0);
			break;
		case MUTE:
			muted = 1;
			writevol(fd, 0);
			break;
		case UNMUTE:
			muted = 0;
			writevol(fd, level);
			break;
		}
	}
}

void
spawnvol(Channel *ctl, Channel *out)
{
	Channel **chans;
	chans = emalloc(sizeof(Channel*)*2);
	chans[0] = ctl;
	chans[1] = out;
	threadcreate(volthread, chans, 8192);
}