summaryrefslogtreecommitdiffstats
path: root/dwl-patches/patches/spawninfo/pamixerc
blob: 91a41c4c82753e717ad474c5e68dc6a4a79bf7ec (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/awk -f

function get_parent(pid,   cmd, ppid, arr) {
	cmd = sprintf("/proc/%d/stat", pid)
	ppid = ""
	if ((getline line < cmd) > 0) {
		split(line, arr)
		ppid = arr[4]
	}
	close(cmd)
	return ppid
}

function proc_clients(line,   arr) {
	if (match(line, /^Client #(.*)/, arr)) {
		store_client()
		client_index = arr[1]
		return
	}
	else if (match(line, /^\s*application\.process\.id = "(.*)"/, arr)) {
		process_id = arr[1]
		return
	}
	else if (match(line, /^\s*application\.name = "(.*)"/, arr)) {
		application_name = arr[1]
		return
	}
}

function store_client() {
	if (client_index == "")
		return

	clients[client_index] = 1
	clients[client_index, "pid"] = process_id
	clients[client_index, "parent_pid"] = get_parent(process_id)
	clients[client_index, "name"] = application_name
	client_index = ""
	process_id = ""
}

function proc_sink_inputs(line,   arr) {
	if (match(line, /^Sink Input #(.*)/, arr)) {
		apply_sink_input()
		sink_index = arr[1]
		return
	}
	else if (match(line, /^\s*application\.process\.id = "(.*)"/, arr)) {
		process_id = arr[1]
		return
	}
	else if (match(line, /^\s*Client: (.*)/, arr)) {
		client_index = arr[1]
		return
	}
	else if (match(line, /^\s*Mute: (.*)/, arr)) {
		muted = (arr[1] == "yes")
		return
	}
	else if (match(line, /^\s*Volume:.* ([0-9]+)%/, arr)) {
		volume = strtonum(arr[1])
		return
	}
}

function apply_sink_input(   cmd, header, msg, inc) {
	if (sink_index == "")
		return

	# Do stuff if PID matches
	if (PID == clients[client_index, "pid"] || PID == clients[client_index, "parent_pid"]) {
		switch (ACTION) {
			case "-i":
			case "-d":
				inc = strtonum(ARG)
				if (ACTION == "-i")
					volume += inc
				else
					volume -= inc
				volume = volume > 100 ? 100 : volume
				volume = volume < 0   ? 0   : volume
				cmd = sprintf("pactl set-sink-input-volume '%d' '%d'%", sink_index, volume)
				system(cmd)
                print cmd
				break
			case "-t":
				muted = !muted
				cmd = sprintf("pactl set-sink-input-mute '%d' '%s'", sink_index, muted ? "true" : "false")
				system(cmd)
				print cmd
				break
		}
		# Display a "popup" with new volume
		header = sprintf("Client Volume: %d%%%s", volume, muted ? " MUTED" : "")
		msg = clients[client_index, "name"]
		system(sprintf("notify-send -r 101 -u low -h 'int:value:%d' '%s' '%s'", volume, header, msg))
	}

	sink_index = ""
}

BEGIN {
	# Get arguments
	# ACTION: -d, -i or -t (like pamixer)
	# ARG:    num arg for -d or -i
	ACTION = ARGV[1]
	ARG    = ARGV[2]
	for (i = 1; i < ARGC; i++)
		delete ARGV[i]

	# Get client info
	getline PID
	getline TITLE     # Not used
	getline APPID     # Not used
	getline TAGS      # Not used
	getline GEOMETRY  # Not used

	if (PID == "")
		exit 1

	# Process PulseAudio clients list and store PIDs for each
	cmd = "pactl list clients"
	while ((cmd | getline line) > 0)
		proc_clients(line)
	close(cmd)
	store_client()

	# Process PulseAudio sink inputs list and run apply_sink_input() for each
	cmd = "pactl list sink-inputs"
	while ((cmd | getline line) > 0)
		proc_sink_inputs(line)
	close(cmd)
	apply_sink_input()
}