Skip to content
This repository was archived by the owner on Apr 21, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,30 @@ to that group. E.g.,

Otherwise, just run mopidy as root to avoid any additional configuration requirements.


You can define your own key using following options in configuration file::


[evtdev]
#same configuration as before
...
#define the play/pause button on key A
play_pause_btn = KEY_A
#define the stop button on key space
stop_btn = KEY_SPACE
#define mute button on key F12
mute_btn = KEY_F12
#define next track button on key '-' from the keypad
next_track_btn = KEY_KPPLUS
#define next track button on key '+' from the keypad
prev_track_btn = KEY_KPMINUS
#define volume up button on the page up key
volume_up_btn = KEY_PAGEUP
#define volume up button on the page down key
volume_down_btn = KEY_PAGEDOWN

the list of available keys is defined in linux/input.h

Project resources
=================

Expand Down
7 changes: 7 additions & 0 deletions mopidy_evtdev/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ def get_config_schema(self):
schema['devices'] = config.List(optional=True)
schema['refresh'] = config.Integer(minimum=1)
schema['vol_step_size'] = config.Integer(minimum=1, maximum=25)
schema['play_pause_btn'] = config.String(optional=True)
schema['stop_btn'] = config.String(optional=True)
schema['next_track_btn'] = config.String(optional=True)
schema['prev_track_btn'] = config.String(optional=True)
schema['volume_up_btn'] = config.String(optional=True)
schema['volume_down_btn'] = config.String(optional=True)
schema['mute_btn'] = config.String(optional=True)
return schema

def validate_environment(self):
Expand Down
23 changes: 22 additions & 1 deletion mopidy_evtdev/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class EvtDevAgent(object):

MAX_TIME_INTERVAL = 5.0 # Maximum number of seconds between events

def __init__(self, core, dev_dir, devices, vol_step_size, refresh):
def __init__(self, core, dev_dir, devices, vol_step_size, refresh, btn):

self.core = core
self.dev_dir = dev_dir
Expand Down Expand Up @@ -41,6 +41,27 @@ def __init__(self, core, dev_dir, devices, vol_step_size, refresh):
evdev.ecodes.KEY_MUTE: self._mute
}

for key, value in btn.iteritems():
if value is None:
continue
code = getattr(evdev.ecodes, value, None)
if code is None:
continue
if key == 'play_pause_btn':
self.ecode_map[code] = self._play_pause
elif key == 'stop_btn':
self.ecode_map[code] = self._play_pause
elif key == 'next_track_btn':
self.ecode_map[code] = self._next_track
elif key == 'prev_track_btn':
self.ecode_map[code] = self._prev_track
elif key == 'volume_up_btn':
self.ecode_map[code] = self._volume_up
elif key == 'volume_down_btn':
self.ecode_map[code] = self._volume_down
elif key == 'mute_btn':
self.ecode_map[code] = self._mute

# This will initiate a refresh of all attached devices and
# initiate timeouts
self._refresh_timeout_callback()
Expand Down
7 changes: 7 additions & 0 deletions mopidy_evtdev/ext.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@ dev_dir = /dev/input
devices =
refresh = 10
vol_step_size = 10
play_pause_btn =
prev_track_btn =
next_track_btn =
stop_btn =
volume_up_btn =
volume_down_btn =
mute_btn =
11 changes: 10 additions & 1 deletion mopidy_evtdev/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,19 @@ def __init__(self, config, core):
vol_step_size = config['evtdev']['vol_step_size']
refresh = config['evtdev']['refresh']

btn = {}
btn['play_pause_btn'] = config['evtdev']['play_pause_btn']
btn['stop_btn'] = config['evtdev']['stop_btn']
btn['next_track_btn'] = config['evtdev']['next_track_btn']
btn['prev_track_btn'] = config['evtdev']['prev_track_btn']
btn['volume_up_btn'] = config['evtdev']['volume_up_btn']
btn['volume_down_btn'] = config['evtdev']['volume_down_btn']
btn['mute_btn'] = config['evtdev']['mute_btn']

# EvtDevAgent performs all the handling of device
# key presses on our behalf
self.agent = EvtDevAgent(core, dev_dir, devices,
vol_step_size, refresh)
vol_step_size, refresh, btn)
logger.info('EvtDevAgent started')

def on_stop(self):
Expand Down
9 changes: 5 additions & 4 deletions tests/test_agent_mocked_uinput.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_cleanup_on_stale_device(self, input_device, source_remove,
mock_device.name = 'Mock Device'
input_device.return_value = mock_device
a = agent.EvtDevAgent(self.core, self.path, [], self.vol_step_size,
self.refresh_period)
self.refresh_period, {})
list_devices.assert_called_with(self.path)
input_device.assert_called_with(self.dev)
list_devices.return_value = []
Expand All @@ -73,7 +73,7 @@ def test_cleanup_on_stop(self, input_device, source_remove,
mock_device.name = 'Mock Device'
input_device.return_value = mock_device
a = agent.EvtDevAgent(self.core, self.path, [],
self.vol_step_size, self.refresh_period)
self.vol_step_size, self.refresh_period, {})
input_device.assert_called_with(self.dev)
a.stop()
mock_device.close.assert_called_with()
Expand All @@ -93,7 +93,7 @@ def test_fd_io_error(self, input_device, source_remove,
mock_device.name = 'Mock Device'
input_device.return_value = mock_device
a = agent.EvtDevAgent(self.core, self.path, [],
self.vol_step_size, self.refresh_period)
self.vol_step_size, self.refresh_period, {})
io_add_watch.assert_called()
io_callback = io_add_watch.call_args_list[0][0][2]
io_exception = IOError('Mocked IO Error')
Expand Down Expand Up @@ -125,7 +125,8 @@ def setUp(self):
self.devices = map(ProxyInputDevice, self.device_names)
self.agent = agent.EvtDevAgent(self.core, self.dev_dir,
self.device_names, self.vol_step_size,
self.refresh)
self.refresh,
{})

def tearDown(self):
self.agent.stop()
Expand Down