Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial commit of v0.1

  • Loading branch information...
commit 47484320a4abc48667efe4c757c50fa0faeb42dc 0 parents
@gorlowski authored
1  .gitignore
@@ -0,0 +1 @@
+*.swp
39 Makefile
@@ -0,0 +1,39 @@
+AWESOME_CFG_DIR := $(HOME)/.config/awesome
+COUTH_INST_DIR := $(AWESOME_CFG_DIR)/couth
+
+help:
+ @echo '----------------------------------------------------'
+ @echo "To install, run: "
+ @echo " make install"
+ @echo '----------------------------------------------------'
+
+#
+# TODO: make the tests real unit tests
+#
+test:
+ lua test/test.lua
+
+install:
+ @if [ ! -d "$(AWESOME_CFG_DIR)" ]; then \
+ echo "ERROR: $(AWESOME_CFG_DIR) NOT FOUND! Aborting."; exit 1; \
+ fi
+ $(RM) -f "$(COUTH_INST_DIR)"
+ ln -s "$(PWD)/lib" "$(COUTH_INST_DIR)"
+ @echo '----------------------------------------------------'
+ @echo "Couth symlink created: $(COUTH_INST_DIR)"
+ @echo '----------------------------------------------------'
+ @echo
+ @echo " You should now edit your $(AWESOME_CFG_DIR)/rc.lua to require the couth"
+ @echo " modules that you want to use, and bind them to key bindings."
+ @echo
+ @echo " -- you MUST require this to use ANY couth modules: "
+ @echo " require('couth.couth') "
+ @echo
+ @echo " -- These are optional. Only require the ones that you want to use. "
+ @echo " require('couth.alsa') "
+ @echo " require('couth.mpc') "
+ @echo
+ @echo " Read the README.rst for more details."
+ @echo
+
+.PHONY: install help test
49 README.rst
@@ -0,0 +1,49 @@
+==========================================================
+couth -- a set of plugins for the awesome window manager
+==========================================================
+
+This is a set of plugins that I wrote for `awesome
+<http://awesome.naquadah.org/>`_.
+
+----------
+plugins
+----------
+
+couth.alsa:
+
+ allows you to get/set the volumes for all your alsa controls (*e.g.*,
+ Master volume, Headphone volume, PCM volume, etc.). When you view or change the
+ volume, an indicator can be displayed with awesome's `naughty
+ <http://awesome.naquadah.org/wiki/Naughty>`_ library. The indicator is a basic
+ bar/ascii indicator that looks something like like this::
+
+ Master : [ ] [||||||||||||||| ]
+ Headphone: [ ] [|||||||||||||| ]
+ PCM : [||||||||||||||||||||]
+ Front : [ ] [||||||||||||||||| ]
+
+couth.mpc:
+
+ This is similar to the couth.alsa library, but it allows you to get/set the
+ volume of an mpd server (either localhost or a remote mpd server). Here is
+ an example of the output::
+
+ localhost volume: [||||||||||||||||||| ]
+
+ The cool thing about couth.mpc is that you can map the volume +/- keys on a
+ laptop to control the volume on, e.g., your media server. I map a combination
+ of [meta, shift, XF86AudioRaiseVolume]/[meta, shift, XF86AudioLowerVolume]
+ on my laptop to raise/lower the volume on the mini-itx server plugged into
+ my living room stereo.
+
+---------------
+Installation
+---------------
+
+- Download the couth source tree (with git, from a tarball, or however else you
+ manage to get it) to some directory on your machine.
+
+- Run ``make install`` to create symlinks from ``$HOME/.config/awesome/couth``
+ to lib directory where you installed the actual files (``$PWD/lib``).
+
+- Configure your ``rc.lua`` to map keybindings to couth functions.
116 lib/alsa.lua
@@ -0,0 +1,116 @@
+---------------------------------------------------------------------------
+--
+-- couth alsa volume library
+--
+-- This only works with ALSA (not OSS). You must have amixer on your path
+-- for this to work.
+--
+-- Usage Examples:
+--
+-- -- Get the the volume for all alsa controls and return an indicator
+-- couth.alsa:getVolume()
+--
+-- -- Get the the volume for all alsa controls and return an indicator,
+-- -- highlighting the Master volume in green
+-- couth.alsa:getVolume('Master')
+--
+-- -- Set the the volume for CONTROL to NEW_VALUE, and
+-- -- return bar indicators that displays all volumes with
+-- -- the indicator for CONTROL highlighted.
+-- --
+-- -- NOTE: NEW_VALUE can be any string that "amixer" will
+-- -- accept as an argument, e.g., 3dB-, 3dB+, etc.
+-- couth.alsa:setVolume('localhost', NEW_VALUE)
+--
+--
+-- TODO: my examples:
+--
+---------------------------------------------------------------------------
+
+local M = {}
+
+M.__volume_pattern = 'Playback.*%[(%d+)%%%]'
+M.__mute_pattern = '%[(o[nf]+)%]'
+M.__control_pattern = "^Simple mixer control '(%a+)'"
+
+-- get all alsa volumes as a table:
+function M:getVolumes()
+ local fd = io.popen("amixer -c0 scontents")
+ local volumes = fd:read("*all")
+ fd:close()
+
+ local n=1
+ local ret = {}
+
+ local controls = {}
+ for i,v in pairs(couth.CONFIG.ALSA_CONTROLS) do controls[v]=1 end
+
+ local m, ctrl, vol, mute
+ for line in volumes:gmatch("[^\n]+") do
+ if couth.count_keys(controls) > 0 then
+ _,_,m = line:find(self.__control_pattern)
+ if m and controls[m] then
+ ctrl = m
+ else
+ _,_,vol = line:find(self.__volume_pattern)
+ if ctrl and vol and controls[ctrl] then
+ ret[ctrl] = {vol = vol}
+ _,_,mute=line:find(self.__mute_pattern)
+ if mute then ret[ctrl]['mute'] = mute end
+ controls[ctrl], vol, mute, ctrl = nil
+ end
+ end
+ end
+ end
+ return ret
+end
+
+function M:muteIndicator(isOrOff)
+ if not isOrOff then return ' ' end
+ if isOrOff == 'on' then
+ return '[ ]'
+ end
+ -- off means the ctrl is mute
+ return '[M]'
+end
+
+--
+-- ctrlToHighlight: the name of an alsa control that we want to highlight in
+-- the output. If this is nil then no controls will be
+-- highlighted in the output. Use this to signify the
+-- control that was just modified -- i.e., if we are
+-- adjusting the Master volume then Master will be
+-- highlighted and others will not be. This helps give us
+-- a visual indicator of the volume control we are adjusting
+-- so we know if we accidentally hit the wrong key.
+--
+function M:getVolume(ctrlToHighlight)
+ local ret = {}
+ local vol, mute
+ local volumes = self:getVolumes()
+ local pad_width = couth.string.maxLen(couth.CONFIG.ALSA_CONTROLS)
+
+ for _,ctrl in ipairs(couth.CONFIG.ALSA_CONTROLS) do
+ if volumes[ctrl] then
+ local prefix, suffix = '',''
+ if ctrl == ctrlToHighlight then
+ prefix,suffix = '<span color="green">',"</span>"
+ end
+ table.insert(ret, prefix .. couth.string.rpad(ctrl, pad_width) .. ': '
+ .. self:muteIndicator(volumes[ctrl]['mute']) .. ' '
+ .. couth.indicator.barIndicator(volumes[ctrl]['vol']) .. suffix)
+ end
+ end
+ return table.concat(ret,"\n")
+end
+
+--
+-- level can be "toggle" to toggle mute/unmute or any other string
+-- that amixer can recognize 3dB+
+--
+function M:setVolume(ctrl, level)
+ io.popen("amixer -c0 set " .. ctrl .. ' ' .. level):close()
+ return self:getVolume(ctrl)
+end
+
+couth.alsa = M
107 lib/couth.lua
@@ -0,0 +1,107 @@
+---------------------------------------------------------------------------
+--
+-- couth.lua -- shared libaries for the couth awesomewm library
+--
+-- @author Greg Orlowski
+-- @copyright 2011 Greg Orlowski
+--
+--
+--
+---------------------------------------------------------------------------
+
+require 'io'
+
+if not couth then couth = {} end
+--
+-- This is the default configuration for couth modules.
+-- Modify this table to change the defaults.
+--
+if not couth.CONFIG then
+ couth.CONFIG = {
+
+ INDICATOR_MAX_BARS = 20,
+
+ -- these are the alsa controls that can be controlled or displayed
+ -- by couth. To get a list of possible values, execute this in a shell:
+ --
+ -- amixer scontrols |sed -e "s/.* '//" -e "s/'.*//"
+ --
+ ALSA_CONTROLS = {
+ 'Master',
+ 'PCM',
+ },
+
+ NOTIFIER_FONT = 'mono 22',
+ NOTIFIER_POSITION = 'top_right',
+ NOTIFIER_TIMEOUT = 5,
+
+ }
+end
+
+--
+-- general functions
+--
+function couth.count_keys(t)
+ local n=0
+ for _,_ in pairs(t) do n=n+1 end
+ return n
+end
+
+
+--
+-- file path functions (like python os.path)
+--
+if not couth['path'] then couth.path = {} end
+function couth.path.file_exists(fileName)
+ doesExist = false
+ f = io.open(fileName, 'r')
+ if f then
+ doesExist = true
+ f:close()
+ end
+ return doesExist
+end
+
+--
+-- string functions
+--
+if not couth['string'] then couth.string = {} end
+function couth.string.maxLen(t)
+ local ret=0, l
+ for _,v in pairs(t) do
+ if v and type(v)=='string' then
+ l = v:len()
+ if l>ret then ret=l end
+ end
+ end
+ return ret
+end
+
+function couth.string.rpad(str, width)
+ return str .. string.rep(' ', width - str:len())
+end
+
+--
+-- indicator functions
+--
+if not couth['indicator'] then couth.indicator = {} end
+function couth.indicator.barIndicator(prct)
+ local maxBars = couth.CONFIG.INDICATOR_MAX_BARS
+ local num_bars = math.floor(maxBars * (prct / 100.0))
+ return '[' .. couth.string.rpad(string.rep('|', num_bars), maxBars) .. ']'
+end
+
+--
+-- notifier
+--
+if not couth['notifier'] then couth.notifier = {id=nil} end
+function couth.notifier:notify(msg)
+ self.id = naughty.notify({
+ text = msg,
+ font = couth.CONFIG.NOTIFIER_FONT,
+ position = couth.CONFIG.NOTIFIER_POSITION,
+ timeout = couth.CONFIG.NOTIFIER_TIMEOUT,
+ replaces_id = self.id
+ }).id
+end
+
65 lib/mpc.lua
@@ -0,0 +1,65 @@
+---------------------------------------------------------------------------
+--
+-- couth mpc/mpd volume indicator library.
+--
+-- In order for this to work, mpc must be on your path, and mpd must be
+-- running on the host (obviously)
+--
+-- Usage Examples:
+--
+-- -- Get the the volume from localhost and return an bar indicator
+-- -- for display
+-- couth.mpc:getVolume('localhost')
+--
+-- -- Set the the volume from localhost to NEW_VALUE, and
+-- -- return a bar indicator that displays the new value.
+-- -- NOTE: NEW_VALUE can be any string that "mpc volume" will
+-- -- accept as an argument, e.g.,
+-- -- "50" to set volume to 50%,
+-- -- "+5" to increase the volume by 5%,
+-- -- "-5" to decrease the volume by 5%,
+-- couth.mpc:setVolume('localhost', NEW_VALUE)
+--
+--
+-- I use this configuration in ~/.config/awesome/rc.lua to adjust the volume
+-- on my media server "pizza":
+--
+-- -- mpc volume on pizza
+-- awful.key({ modkey, "Shift" }, "XF86AudioLowerVolume", function () couth.notifier:notify( couth.mpc:setVolume('pizza','-5')) end),
+-- awful.key({ modkey, "Shift" }, "XF86AudioRaiseVolume", function () couth.notifier:notify( couth.mpc:setVolume('pizza','+5')) end),
+-- awful.key({ modkey, "Shift" }, "v", function () couth.notifier:notify( couth.mpc:getVolume('pizza') ) end)
+--
+---------------------------------------------------------------------------
+local M = {}
+M.__volume_pattern = '^volume:%s*(%d+)%%'
+
+function M:execMpcVolume(host, arg)
+ arg = arg or ''
+ local fd = io.popen('mpc -h ' .. host .. ' volume ' .. arg)
+ local mpc_ret = fd:read("*all")
+ fd:close()
+
+ local ret
+ for line in mpc_ret:gmatch("[^\n]+") do
+ local _,_,ret = line:find(self.__volume_pattern)
+ if ret then return ret end
+ end
+ return '0'
+end
+
+function M:renderVolumeDisplay(host, volume )
+ local prefix,suffix = '<span color="green">', "</span>"
+ local label = host .. ' volume: '
+ return prefix .. label .. couth.indicator.barIndicator(volume) .. suffix
+end
+
+-- get all alsa volumes as a table:
+function M:getVolume(host)
+ return self:renderVolumeDisplay(host, self:execMpcVolume(host) )
+end
+
+function M:setVolume(host, val)
+ return self:renderVolumeDisplay(host, self:execMpcVolume(host, val) )
+end
+
+couth.mpc = M
27 test/test.lua
@@ -0,0 +1,27 @@
+--
+-- TODO: make these real unit tests that verify assertions
+--
+require('lib/couth')
+
+--
+-- mpc volume
+--
+require('lib/mpc')
+
+print(couth.mpc:getVolume('pizza'))
+print(couth.mpc:getVolume('localhost'))
+
+--
+-- alsa volume
+--
+require('lib/alsa')
+couth.CONFIG.ALSA_CONTROLS = {
+ 'Master',
+ 'Headphone',
+ 'PCM',
+ 'Front'
+}
+
+print(couth.alsa:getVolume())
+print('--------')
+print(couth.alsa:getVolume('Master'))
Please sign in to comment.
Something went wrong with that request. Please try again.