fix for the no-posix detection patch (thanks to Ian Ward)
[wmiirc-lua.git] / plugins / volume.lua
blobbef540dfad595e577bd77f1364ca051f4125f7fc
1 --[[
2 =pod
4 =head1 NAME
6 volume.lua - wmiirc-lua plugin for volume control
8 =head1 SYNOPSIS
10 -- in your wmiirc.lua:
11 wmii.load_plugin("volume")
13 -- If you also want keybindings for volume control, you might want to add:
14 wmii.add_key_handler('Mod1-minus', function (key)
15 volume.update_volume(-1)
16 end
17 wmii.add_key_handler('Mod1-plus', function (key)
18 volume.update_volume(1)
19 end
22 =head1 DESCRIPTION
24 This plugin module provides a volume control widget that uses I<amixer> to view and control volume.
26 The following controls are available:
28 =over 4
30 =item left mouse click
32 Spawns a mixer (TODO: not implemented yet)
34 =item right mouse click
36 Mutes master volume
38 =item scroll wheel up/down
40 Adjusts volume up/down
42 =back
44 =head1 CONFIGURATION AND ENVIRONMENT
46 There are two configurable options at the moment, modifiable via wmii.set_conf():
48 =over 4
50 =item volume.update
52 Interval in seconds for polling the mixer, to determine current volume level.
53 Without this, your volume display can get out of sync with reality if other
54 apps adjust the mixer volume.
56 Default value is 10.
58 =item volume.mixer
60 The name of the mixer setting to adjust. Default is 'Master', which should
61 work fine for most, but if you have a more complex audio setup, you may wish to
62 change this.
64 =back
66 =head1 MIXER API
68 One public method is provided. It can be used in your own plugins, in
69 keybindings, etc.
71 =over 4
73 =item update_volume ( val )
75 Updates the volume, and changes the plugin display.
77 If 'val' is numeric and positive, volume is increased by that many steps
78 (volume controls currently work against "exact hardware value" as described in
79 the L<amixer(1)> manual. The scale varies from hardware to hardware -- pinal
80 Tap's goes to 11. Mine goes to 2^5 - 1.).
82 If 'val' is negative, volume is decremented that many steps.
84 If 'val' is set to the string 'mute', volume is muted. If set to 'unmute',
85 volume is unmuted.
87 =back
89 =head1 BUGS AND LIMITATIONS
91 Please report problems to the author.
92 Patches are welcome.
94 Current known issues and TODO items:
96 =over 4
98 =item left-click does not spawn a mixer app
100 =item validity and bounds-checking on update_volume()
102 =item rather than using hardware values, increment/decrement with percentages?
104 =back
106 =head1 SEE ALSO
108 L<wmii(1)>, L<lua(1)>
110 =head1 AUTHOR
112 Dave O'Neill <dmo@dmo.ca>
114 =head1 LICENCE AND COPYRIGHT
116 Copyright (c) 2007, Dave O'Neill <dmo@dmo.ca>
118 This is free software. You may redistribute copies of it under the terms of
119 the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>. There
120 is NO WARRANTY, to the extent permitted by law.
122 =cut
123 --]]
125 local wmii = require("wmii")
126 local os = require("os")
127 local io = require("io")
128 local math = require("math")
129 local type = type
130 local error = error
132 module("volume")
133 api_version = 0.1
135 -- ------------------------------------------------------------
136 -- VOLUME CONFIGURATION VARIABLES
138 -- these can be overridden by wmiirc
140 wmii.set_conf ("volume.update", 10);
141 wmii.set_conf ("volume.mixer", "Master");
143 -- ------------------------------------------------------------
144 -- MODULE VARIABLES
145 local widget = nil
146 local timer = nil
148 widget = wmii.widget:new ("999_volume")
150 local function _amixer_command ( cmd )
152 wmii.log( "about to run " .. cmd)
153 local file = io.popen( cmd )
154 local status = file:read("*a")
155 file:close()
157 local volume
158 -- omfg. lua regexes are uuuugly
159 volume = status:match("%[(%d+%%)%]");
160 if status:match("%[off%]") then
161 volume = "OFF"
164 return volume
167 local function mixer_set_volume (value)
168 wmii.log( "mixer_set_volume(" .. value .. ")")
169 local mixer = wmii.get_conf("volume.mixer")
170 return _amixer_command("amixer set \"" .. mixer .. ",0\" " .. value)
173 local function mixer_get_volume ( )
174 wmii.log( "mixer_get_volume")
175 local mixer = wmii.get_conf("volume.mixer")
176 return _amixer_command("amixer get \"" .. mixer .. ",0\"")
179 function update_volume ( new_vol )
181 wmii.log("update_volume(" .. new_vol .. ")")
182 local value
184 if type( new_vol ) == "number" then
185 local sign
187 if new_vol < 0 then
188 sign = "-"
189 else
190 sign = "+"
192 value = math.abs( new_vol ) .. sign
193 else
194 value = new_vol
198 local volume = mixer_set_volume( value )
200 widget:show("VOL [" .. volume .. "]")
203 local function button_handler (ev, button)
205 wmii.log("button_handler(" .. ev .. "," .. button .. ")")
206 if button == 1 then
207 -- left click
208 elseif button == 2 then
209 -- middle click
210 elseif button == 3 then
211 -- right click
212 local action
213 local cur_volume = mixer_get_volume()
214 if cur_volume == "OFF" then
215 action = "unmute"
216 else
217 action = "mute"
219 update_volume( action )
220 elseif button == 4 then
221 -- scroll up
222 update_volume( 1 )
223 elseif button == 5 then
224 -- scroll down
225 update_volume( -1 )
229 widget:add_event_handler("RightBarClick", button_handler)
232 local function volume_timer ( timer )
234 wmii.log("volume_timer()")
235 update_volume(0)
237 -- returning a positive number of seconds before next wakeup, or
238 -- nil (or no return at all) repeats the last schedule, or
239 -- -1 to stop the timer
240 return 10
243 timer = wmii.timer:new (volume_timer, 1)