Pierre Ossman wrote: > As I recently bought an ATI remote control, I felt that Freevo really > lacked good support for Linux event devices. So I decided to add it. :) > > Included is a patch that adds that support, relevant configuration > options and a default key map that should handle most devices out there. > > Comparison with using SDL keyboard: > > Pros: > * You can use specific devices instead of all. > * You get all fancy special buttons (like stop, play, etc.) working by > default. > * You can handle devices that might not show up as keyboards. > > Cons: > * As it uses local device nodes, it only works for locally connected > devices. Only a problem if you run freevo through X11 to another machine. > * You need to explicitly configure which devices to use (I plan to make > it easier by mapping on device name instead of device node). > > This input system could in theory replace both keyboard and joystick > support. > > Comment away!
I shouldn't apply this patch in 1.6, but it may be too important to exclude. So I have done. Please put this in the tracker as a new feature and add a description of how to use it, when it is used, how to configure it, etc. Many thanks Duncan > > Rgds > > > ------------------------------------------------------------------------ > > Index: local_conf.py.example > =================================================================== > --- local_conf.py.example (revision 8396) > +++ local_conf.py.example (working copy) > @@ -241,11 +241,32 @@ > # MENU_ARROW_NAVIGATION = 0 > > # > +# Process keyboard events from SDL. You want this unless you use only lirc > +# or event devices below. > +# > +# USE_SDL_KEYBOARD = 1 > + > +# > # Keymap to map keyboard keys to event strings. You can also add new keys > # here, e.g. KEYMAP[key.K_x] = 'SUBTITLE'. The K_-names are defined by > pygame. > # > > # > +# List of /dev/input/event# devices to monitor. If you monitor your keyboard > +# both here and with USE_SDL_KEYBOARD, then you will get duplicate events. > +# > +# > +# EVENT_DEVS = [] > + > +# > +# Keymap to map input events to event strings. You can change current > mappings > +# and add new ones here, e.g. EVENTMAP['KEY_COFFEE'] = 'SUBTITLE'. Key names > +# are defined by the Linux input layer (input.h). An axis is described by a > +# pair, one for positive and one for negative movement, e.g. > +# EVENTMAP['REL_Z'] = ('LEFT', 'RIGHT') > +# > + > +# > # Use Internet resources to fetch information? > # For example, Freevo can use CDDB for album information, > # the IMDB movie database for movie info, and Amazon for cover searches. > Index: src/evfallback.py > =================================================================== > --- src/evfallback.py (revision 0) > +++ src/evfallback.py (revision 0) > @@ -0,0 +1,572 @@ > +# -*- coding: iso-8859-1 -*- > +# ----------------------------------------------------------------------- > +# evfallback.py - Default mappings for event interface module > +# ----------------------------------------------------------------------- > +# $Id$ > +# > +# Notes: > +# Todo: > +# > +# ----------------------------------------------------------------------- > +# $Log$ > +# ----------------------------------------------------------------------- > +# Freevo - A Home Theater PC framework > +# Copyright (C) 2002 Krister Lagerstrom, et al. > +# Please see the file freevo/Docs/CREDITS for a complete list of authors. > +# > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, but > +# WITHOUT ANY WARRANTY; without even the implied warranty of MER- > +# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General > +# Public License for more details. > +# > +# You should have received a copy of the GNU General Public License along > +# with this program; if not, write to the Free Software Foundation, Inc., > +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +# > +# ----------------------------------------------------------------------- */ > + > +_types = { > + 0:'EV_SYN', > + 1:'EV_KEY', > + 2:'EV_REL', > + 3:'EV_ABS', > + 4:'EV_MSC', > + 5:'EV_SW', > + 17:'EV_LED', > + 18:'EV_SND', > + 20:'EV_REP', > + 21:'EV_FF', > + 22:'EV_PWR', > + 23:'EV_FF_STATUS', > + 31:'EV_MAX', > + } > + > +_events = { > + 0:{ # EV_SYN > + 0:'SYN_REPORT', > + 1:'SYN_CONFIG', > + }, > + 1:{ # EV_KEY > + 0:'KEY_RESERVED', > + 1:'KEY_ESC', > + 2:'KEY_1', > + 3:'KEY_2', > + 4:'KEY_3', > + 5:'KEY_4', > + 6:'KEY_5', > + 7:'KEY_6', > + 8:'KEY_7', > + 9:'KEY_8', > + 10:'KEY_9', > + 11:'KEY_0', > + 12:'KEY_MINUS', > + 13:'KEY_EQUAL', > + 14:'KEY_BACKSPACE', > + 15:'KEY_TAB', > + 16:'KEY_Q', > + 17:'KEY_W', > + 18:'KEY_E', > + 19:'KEY_R', > + 20:'KEY_T', > + 21:'KEY_Y', > + 22:'KEY_U', > + 23:'KEY_I', > + 24:'KEY_O', > + 25:'KEY_P', > + 26:'KEY_LEFTBRACE', > + 27:'KEY_RIGHTBRACE', > + 28:'KEY_ENTER', > + 29:'KEY_LEFTCTRL', > + 30:'KEY_A', > + 31:'KEY_S', > + 32:'KEY_D', > + 33:'KEY_F', > + 34:'KEY_G', > + 35:'KEY_H', > + 36:'KEY_J', > + 37:'KEY_K', > + 38:'KEY_L', > + 39:'KEY_SEMICOLON', > + 40:'KEY_APOSTROPHE', > + 41:'KEY_GRAVE', > + 42:'KEY_LEFTSHIFT', > + 43:'KEY_BACKSLASH', > + 44:'KEY_Z', > + 45:'KEY_X', > + 46:'KEY_C', > + 47:'KEY_V', > + 48:'KEY_B', > + 49:'KEY_N', > + 50:'KEY_M', > + 51:'KEY_COMMA', > + 52:'KEY_DOT', > + 53:'KEY_SLASH', > + 54:'KEY_RIGHTSHIFT', > + 55:'KEY_KPASTERISK', > + 56:'KEY_LEFTALT', > + 57:'KEY_SPACE', > + 58:'KEY_CAPSLOCK', > + 59:'KEY_F1', > + 60:'KEY_F2', > + 61:'KEY_F3', > + 62:'KEY_F4', > + 63:'KEY_F5', > + 64:'KEY_F6', > + 65:'KEY_F7', > + 66:'KEY_F8', > + 67:'KEY_F9', > + 68:'KEY_F10', > + 69:'KEY_NUMLOCK', > + 70:'KEY_SCROLLLOCK', > + 71:'KEY_KP7', > + 72:'KEY_KP8', > + 73:'KEY_KP9', > + 74:'KEY_KPMINUS', > + 75:'KEY_KP4', > + 76:'KEY_KP5', > + 77:'KEY_KP6', > + 78:'KEY_KPPLUS', > + 79:'KEY_KP1', > + 80:'KEY_KP2', > + 81:'KEY_KP3', > + 82:'KEY_KP0', > + 83:'KEY_KPDOT', > + 85:'KEY_ZENKAKUHANKAKU', > + 86:'KEY_102ND', > + 87:'KEY_F11', > + 88:'KEY_F12', > + 89:'KEY_RO', > + 90:'KEY_KATAKANA', > + 91:'KEY_HIRAGANA', > + 92:'KEY_HENKAN', > + 93:'KEY_KATAKANAHIRAGANA', > + 94:'KEY_MUHENKAN', > + 95:'KEY_KPJPCOMMA', > + 96:'KEY_KPENTER', > + 97:'KEY_RIGHTCTRL', > + 98:'KEY_KPSLASH', > + 99:'KEY_SYSRQ', > + 100:'KEY_RIGHTALT', > + 101:'KEY_LINEFEED', > + 102:'KEY_HOME', > + 103:'KEY_UP', > + 104:'KEY_PAGEUP', > + 105:'KEY_LEFT', > + 106:'KEY_RIGHT', > + 107:'KEY_END', > + 108:'KEY_DOWN', > + 109:'KEY_PAGEDOWN', > + 110:'KEY_INSERT', > + 111:'KEY_DELETE', > + 112:'KEY_MACRO', > + 113:'KEY_MUTE', > + 114:'KEY_VOLUMEDOWN', > + 115:'KEY_VOLUMEUP', > + 116:'KEY_POWER', > + 117:'KEY_KPEQUAL', > + 118:'KEY_KPPLUSMINUS', > + 119:'KEY_PAUSE', > + 121:'KEY_KPCOMMA', > + 122:'KEY_HANGEUL', > + 123:'KEY_HANJA', > + 124:'KEY_YEN', > + 125:'KEY_LEFTMETA', > + 126:'KEY_RIGHTMETA', > + 127:'KEY_COMPOSE', > + 128:'KEY_STOP', > + 129:'KEY_AGAIN', > + 130:'KEY_PROPS', > + 131:'KEY_UNDO', > + 132:'KEY_FRONT', > + 133:'KEY_COPY', > + 134:'KEY_OPEN', > + 135:'KEY_PASTE', > + 136:'KEY_FIND', > + 137:'KEY_CUT', > + 138:'KEY_HELP', > + 139:'KEY_MENU', > + 140:'KEY_CALC', > + 141:'KEY_SETUP', > + 142:'KEY_SLEEP', > + 143:'KEY_WAKEUP', > + 144:'KEY_FILE', > + 145:'KEY_SENDFILE', > + 146:'KEY_DELETEFILE', > + 147:'KEY_XFER', > + 148:'KEY_PROG1', > + 149:'KEY_PROG2', > + 150:'KEY_WWW', > + 151:'KEY_MSDOS', > + 152:'KEY_COFFEE', > + 153:'KEY_DIRECTION', > + 154:'KEY_CYCLEWINDOWS', > + 155:'KEY_MAIL', > + 156:'KEY_BOOKMARKS', > + 157:'KEY_COMPUTER', > + 158:'KEY_BACK', > + 159:'KEY_FORWARD', > + 160:'KEY_CLOSECD', > + 161:'KEY_EJECTCD', > + 162:'KEY_EJECTCLOSECD', > + 163:'KEY_NEXTSONG', > + 164:'KEY_PLAYPAUSE', > + 165:'KEY_PREVIOUSSONG', > + 166:'KEY_STOPCD', > + 167:'KEY_RECORD', > + 168:'KEY_REWIND', > + 169:'KEY_PHONE', > + 170:'KEY_ISO', > + 171:'KEY_CONFIG', > + 172:'KEY_HOMEPAGE', > + 173:'KEY_REFRESH', > + 174:'KEY_EXIT', > + 175:'KEY_MOVE', > + 176:'KEY_EDIT', > + 177:'KEY_SCROLLUP', > + 178:'KEY_SCROLLDOWN', > + 179:'KEY_KPLEFTPAREN', > + 180:'KEY_KPRIGHTPAREN', > + 181:'KEY_NEW', > + 182:'KEY_REDO', > + 183:'KEY_F13', > + 184:'KEY_F14', > + 185:'KEY_F15', > + 186:'KEY_F16', > + 187:'KEY_F17', > + 188:'KEY_F18', > + 189:'KEY_F19', > + 190:'KEY_F20', > + 191:'KEY_F21', > + 192:'KEY_F22', > + 193:'KEY_F23', > + 194:'KEY_F24', > + 200:'KEY_PLAYCD', > + 201:'KEY_PAUSECD', > + 202:'KEY_PROG3', > + 203:'KEY_PROG4', > + 205:'KEY_SUSPEND', > + 206:'KEY_CLOSE', > + 207:'KEY_PLAY', > + 208:'KEY_FASTFORWARD', > + 209:'KEY_BASSBOOST', > + 210:'KEY_PRINT', > + 211:'KEY_HP', > + 212:'KEY_CAMERA', > + 213:'KEY_SOUND', > + 214:'KEY_QUESTION', > + 215:'KEY_EMAIL', > + 216:'KEY_CHAT', > + 217:'KEY_SEARCH', > + 218:'KEY_CONNECT', > + 219:'KEY_FINANCE', > + 220:'KEY_SPORT', > + 221:'KEY_SHOP', > + 222:'KEY_ALTERASE', > + 223:'KEY_CANCEL', > + 224:'KEY_BRIGHTNESSDOWN', > + 225:'KEY_BRIGHTNESSUP', > + 226:'KEY_MEDIA', > + 227:'KEY_SWITCHVIDEOMODE', > + 228:'KEY_KBDILLUMTOGGLE', > + 229:'KEY_KBDILLUMDOWN', > + 230:'KEY_KBDILLUMUP', > + 231:'KEY_SEND', > + 232:'KEY_REPLY', > + 233:'KEY_FORWARDMAIL', > + 234:'KEY_SAVE', > + 235:'KEY_DOCUMENTS', > + 236:'KEY_BATTERY', > + 240:'KEY_UNKNOWN', > + 256:'BTN_0', > + 257:'BTN_1', > + 258:'BTN_2', > + 259:'BTN_3', > + 260:'BTN_4', > + 261:'BTN_5', > + 262:'BTN_6', > + 263:'BTN_7', > + 264:'BTN_8', > + 265:'BTN_9', > + 272:'BTN_LEFT', > + 273:'BTN_RIGHT', > + 274:'BTN_MIDDLE', > + 275:'BTN_SIDE', > + 276:'BTN_EXTRA', > + 277:'BTN_FORWARD', > + 278:'BTN_BACK', > + 279:'BTN_TASK', > + 288:'BTN_TRIGGER', > + 289:'BTN_THUMB', > + 290:'BTN_THUMB2', > + 291:'BTN_TOP', > + 292:'BTN_TOP2', > + 293:'BTN_PINKIE', > + 294:'BTN_BASE', > + 295:'BTN_BASE2', > + 296:'BTN_BASE3', > + 297:'BTN_BASE4', > + 298:'BTN_BASE5', > + 299:'BTN_BASE6', > + 303:'BTN_DEAD', > + 304:'BTN_A', > + 305:'BTN_B', > + 306:'BTN_C', > + 307:'BTN_X', > + 308:'BTN_Y', > + 309:'BTN_Z', > + 310:'BTN_TL', > + 311:'BTN_TR', > + 312:'BTN_TL2', > + 313:'BTN_TR2', > + 314:'BTN_SELECT', > + 315:'BTN_START', > + 316:'BTN_MODE', > + 317:'BTN_THUMBL', > + 318:'BTN_THUMBR', > + 320:'BTN_TOOL_PEN', > + 321:'BTN_TOOL_RUBBER', > + 322:'BTN_TOOL_BRUSH', > + 323:'BTN_TOOL_PENCIL', > + 324:'BTN_TOOL_AIRBRUSH', > + 325:'BTN_TOOL_FINGER', > + 326:'BTN_TOOL_MOUSE', > + 327:'BTN_TOOL_LENS', > + 330:'BTN_TOUCH', > + 331:'BTN_STYLUS', > + 332:'BTN_STYLUS2', > + 333:'BTN_TOOL_DOUBLETAP', > + 334:'BTN_TOOL_TRIPLETAP', > + 336:'BTN_GEAR_DOWN', > + 337:'BTN_GEAR_UP', > + 352:'KEY_OK', > + 353:'KEY_SELECT', > + 354:'KEY_GOTO', > + 355:'KEY_CLEAR', > + 356:'KEY_POWER2', > + 357:'KEY_OPTION', > + 358:'KEY_INFO', > + 359:'KEY_TIME', > + 360:'KEY_VENDOR', > + 361:'KEY_ARCHIVE', > + 362:'KEY_PROGRAM', > + 363:'KEY_CHANNEL', > + 364:'KEY_FAVORITES', > + 365:'KEY_EPG', > + 366:'KEY_PVR', > + 367:'KEY_MHP', > + 368:'KEY_LANGUAGE', > + 369:'KEY_TITLE', > + 370:'KEY_SUBTITLE', > + 371:'KEY_ANGLE', > + 372:'KEY_ZOOM', > + 373:'KEY_MODE', > + 374:'KEY_KEYBOARD', > + 375:'KEY_SCREEN', > + 376:'KEY_PC', > + 377:'KEY_TV', > + 378:'KEY_TV2', > + 379:'KEY_VCR', > + 380:'KEY_VCR2', > + 381:'KEY_SAT', > + 382:'KEY_SAT2', > + 383:'KEY_CD', > + 384:'KEY_TAPE', > + 385:'KEY_RADIO', > + 386:'KEY_TUNER', > + 387:'KEY_PLAYER', > + 388:'KEY_TEXT', > + 389:'KEY_DVD', > + 390:'KEY_AUX', > + 391:'KEY_MP3', > + 392:'KEY_AUDIO', > + 393:'KEY_VIDEO', > + 394:'KEY_DIRECTORY', > + 395:'KEY_LIST', > + 396:'KEY_MEMO', > + 397:'KEY_CALENDAR', > + 398:'KEY_RED', > + 399:'KEY_GREEN', > + 400:'KEY_YELLOW', > + 401:'KEY_BLUE', > + 402:'KEY_CHANNELUP', > + 403:'KEY_CHANNELDOWN', > + 404:'KEY_FIRST', > + 405:'KEY_LAST', > + 406:'KEY_AB', > + 407:'KEY_NEXT', > + 408:'KEY_RESTART', > + 409:'KEY_SLOW', > + 410:'KEY_SHUFFLE', > + 411:'KEY_BREAK', > + 412:'KEY_PREVIOUS', > + 413:'KEY_DIGITS', > + 414:'KEY_TEEN', > + 415:'KEY_TWEN', > + 448:'KEY_DEL_EOL', > + 449:'KEY_DEL_EOS', > + 450:'KEY_INS_LINE', > + 451:'KEY_DEL_LINE', > + 464:'KEY_FN', > + 465:'KEY_FN_ESC', > + 466:'KEY_FN_F1', > + 467:'KEY_FN_F2', > + 468:'KEY_FN_F3', > + 469:'KEY_FN_F4', > + 470:'KEY_FN_F5', > + 471:'KEY_FN_F6', > + 472:'KEY_FN_F7', > + 473:'KEY_FN_F8', > + 474:'KEY_FN_F9', > + 475:'KEY_FN_F10', > + 476:'KEY_FN_F11', > + 477:'KEY_FN_F12', > + 478:'KEY_FN_1', > + 479:'KEY_FN_2', > + 480:'KEY_FN_D', > + 481:'KEY_FN_E', > + 482:'KEY_FN_F', > + 483:'KEY_FN_S', > + 484:'KEY_FN_B', > + 497:'KEY_BRL_DOT1', > + 498:'KEY_BRL_DOT2', > + 499:'KEY_BRL_DOT3', > + 500:'KEY_BRL_DOT4', > + 501:'KEY_BRL_DOT5', > + 502:'KEY_BRL_DOT6', > + 503:'KEY_BRL_DOT7', > + 504:'KEY_BRL_DOT8', > + 511:'KEY_MAX', > + }, > + 2:{ # EV_REL > + 0:'REL_X', > + 1:'REL_Y', > + 2:'REL_Z', > + 3:'REL_RX', > + 4:'REL_RY', > + 5:'REL_RZ', > + 6:'REL_HWHEEL', > + 7:'REL_DIAL', > + 8:'REL_WHEEL', > + 9:'REL_MISC', > + 15:'REL_MAX', > + }, > + 3:{ # EV_ABS > + 0:'ABS_X', > + 1:'ABS_Y', > + 2:'ABS_Z', > + 3:'ABS_RX', > + 4:'ABS_RY', > + 5:'ABS_RZ', > + 6:'ABS_THROTTLE', > + 7:'ABS_RUDDER', > + 8:'ABS_WHEEL', > + 9:'ABS_GAS', > + 10:'ABS_BRAKE', > + 16:'ABS_HAT0X', > + 17:'ABS_HAT0Y', > + 18:'ABS_HAT1X', > + 19:'ABS_HAT1Y', > + 20:'ABS_HAT2X', > + 21:'ABS_HAT2Y', > + 22:'ABS_HAT3X', > + 23:'ABS_HAT3Y', > + 24:'ABS_PRESSURE', > + 25:'ABS_DISTANCE', > + 26:'ABS_TILT_X', > + 27:'ABS_TILT_Y', > + 28:'ABS_TOOL_WIDTH', > + 32:'ABS_VOLUME', > + 40:'ABS_MISC', > + 63:'ABS_MAX', > + }, > + 4:{ # EV_MSC > + 0:'MSC_SERIAL', > + 1:'MSC_PULSELED', > + 2:'MSC_GESTURE', > + 3:'MSC_RAW', > + 4:'MSC_SCAN', > + 7:'MSC_MAX', > + }, > + 5:{ # EV_SW > + 0:'SW_LID', > + 1:'SW_TABLET_MODE', > + 2:'SW_HEADPHONE_INSERT', > + 15:'SW_MAX', > + }, > + 17:{ # EV_LED > + 0:'LED_NUML', > + 1:'LED_CAPSL', > + 2:'LED_SCROLLL', > + 3:'LED_COMPOSE', > + 4:'LED_KANA', > + 5:'LED_SLEEP', > + 6:'LED_SUSPEND', > + 7:'LED_MUTE', > + 8:'LED_MISC', > + 9:'LED_MAIL', > + 10:'LED_CHARGING', > + 15:'LED_MAX', > + }, > + 18:{ # EV_SND > + 0:'SND_CLICK', > + 1:'SND_BELL', > + 2:'SND_TONE', > + 7:'SND_MAX', > + }, > + 20:{ # EV_REP > + 0:'REP_DELAY', > + 1:'REP_MAX', > + }, > + 21:{ # EV_FF > + 0:'FF_STATUS_STOPPED', > + 1:'FF_STATUS_MAX', > + 97:'FF_AUTOCENTER', > + 96:'FF_GAIN', > + 80:'FF_RUMBLE', > + 81:'FF_PERIODIC', > + 82:'FF_CONSTANT', > + 83:'FF_SPRING', > + 84:'FF_FRICTION', > + 85:'FF_DAMPER', > + 86:'FF_INERTIA', > + 87:'FF_RAMP', > + 88:'FF_SQUARE', > + 89:'FF_TRIANGLE', > + 90:'FF_SINE', > + 91:'FF_SAW_UP', > + 92:'FF_SAW_DOWN', > + 93:'FF_CUSTOM', > + 127:'FF_MAX', > + }, > + } > + > +_ids = { > + 0:'ID_BUS', > + 1:'ID_VENDOR', > + 2:'ID_PRODUCT', > + 3:'ID_VERSION', > + } > + > +_buses = { > + 1:'BUS_PCI', > + 2:'BUS_ISAPNP', > + 3:'BUS_USB', > + 4:'BUS_HIL', > + 5:'BUS_BLUETOOTH', > + 16:'BUS_ISA', > + 17:'BUS_I8042', > + 18:'BUS_XTKBD', > + 19:'BUS_RS232', > + 20:'BUS_GAMEPORT', > + 21:'BUS_PARPORT', > + 22:'BUS_AMIGA', > + 23:'BUS_ADB', > + 24:'BUS_I2C', > + 25:'BUS_HOST', > + 26:'BUS_GSC', > + } > Index: src/rc.py > =================================================================== > --- src/rc.py (revision 8396) > +++ src/rc.py (working copy) > @@ -60,6 +60,7 @@ > import types > > import config > +import evdev > > from event import Event, BUTTON > > @@ -323,7 +324,46 @@ > # No data available > return None > > +# > -------------------------------------------------------------------------------- > > +class Evdev: > + """ > + Class to handle evdev events > + """ > + def __init__(self): > + """ > + init all specified devices > + """ > + self._devs = [] > + > + for dev in config.EVENT_DEVS: > + try: > + e = evdev.evdev(dev) > + print "Added input device '%s': %s" % (dev, e.get_name()) > + self._devs.append(e) > + except: > + print "Problem opening event device '%s'" % dev > + > + def poll(self, rc): > + """ > + return next event > + """ > + for dev in self._devs: > + event = dev.read() > + if event is None: > + continue > + > + if config.EVENTMAP.has_key(event[2]): > + if event[1] == 'EV_KEY': > + # 0 = release, 1 = press, 2 = repeat > + if event[3] > 0: > + return config.EVENTMAP[event[2]] > + elif event[1] == 'EV_REL': > + if event[3] < -10: > + return config.EVENTMAP[event[2]][0] > + elif event[3] > 10: > + return config.EVENTMAP[event[2]][1] > + > # > -------------------------------------------------------------------------------- > > class EventHandler: > @@ -340,8 +380,14 @@ > except: > pass > > + if config.USE_SDL_KEYBOARD: > + try: > + self.inputs.append(Keyboard()) > + except: > + pass > + > try: > - self.inputs.append(Keyboard()) > + self.inputs.append(Evdev()) > except: > pass > > Index: src/evdev.py > =================================================================== > --- src/evdev.py (revision 0) > +++ src/evdev.py (revision 0) > @@ -0,0 +1,335 @@ > +# -*- coding: iso-8859-1 -*- > +# ----------------------------------------------------------------------- > +# evdev.py - Linux /dev/input/event# interface library > +# ----------------------------------------------------------------------- > +# $Id$ > +# > +# Notes: > +# Todo: > +# > +# ----------------------------------------------------------------------- > +# $Log$ > +# ----------------------------------------------------------------------- > +# Freevo - A Home Theater PC framework > +# Copyright (C) 2002 Krister Lagerstrom, et al. > +# Please see the file freevo/Docs/CREDITS for a complete list of authors. > +# > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, but > +# WITHOUT ANY WARRANTY; without even the implied warranty of MER- > +# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General > +# Public License for more details. > +# > +# You should have received a copy of the GNU General Public License along > +# with this program; if not, write to the Free Software Foundation, Inc., > +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +# > +# ----------------------------------------------------------------------- */ > + > +import os > +import re > +from fcntl import ioctl > +import struct > + > +_types = {} > +_events = {} > + > +_ids = {} > +_buses = {} > + > +def _convert_value(s): > + if s.startswith("0x"): > + return int(s, 16) > + return int(s, 10) > + > +def parse_input_h(path): > + global _types, _events, _ids, _buses > + > + f = file(path) > + > + types = {} > + events = {} > + > + ids = {} > + buses = {} > + > + for line in f.readlines(): > + m = re.search("#define > (?P<name>EV_[A-Za-z0-9_]+)\s+(?P<value>(0x)?[0-9A-Fa-f]+)", line) > + if m: > + if m.group("name") != "EV_VERSION": > + types[_convert_value(m.group("value"))] = m.group("name") > + continue > + > + m = re.search("#define > (?P<name>ID_[A-Za-z0-9_]+)\s+(?P<value>(0x)?[0-9A-Fa-f]+)", line) > + if m: > + ids[_convert_value(m.group("value"))] = m.group("name") > + continue > + > + m = re.search("#define > (?P<name>BUS_[A-Za-z0-9_]+)\s+(?P<value>(0x)?[0-9A-Fa-f]+)", line) > + if m: > + buses[_convert_value(m.group("value"))] = m.group("name") > + continue > + > + m = re.search("#define > (?P<name>(?P<type>[A-Za-z0-9]+)_[A-Za-z0-9_]+)\s+(?P<value>(0x)?[0-9A-Fa-f]+)", > line) > + if m: > + t = m.group("type") > + > + # The naming is a bit off in input.h > + if t == "BTN": > + t = "KEY" > + > + for k in types.keys(): > + if types[k] == "EV_" + t: > + break > + else: > + raise Exception("Invalid type: %s" % m.group("type")) > + > + if not events.has_key(k): > + events[k] = {} > + > + events[k][_convert_value(m.group("value"))] = m.group("name") > + > + _types = types > + _events = events > + > + _ids = ids > + _buses = buses > + > +def _print_tables(): > + print "_types = {" > + > + keys = _types.keys() > + keys.sort() > + for key in keys: > + print " %2d:%s," % (key, repr(_types[key])) > + > + print " }" > + > + print "" > + > + print "_events = {" > + > + keys = _events.keys() > + keys.sort() > + for key in keys: > + print " %2d:{ # %s" % (key, _types[key]) > + > + subkeys = _events[key].keys() > + for subkey in subkeys: > + print " %3d:%s," % (subkey, repr(_events[key][subkey])) > + > + print " }," > + > + print " }" > + > + print "" > + > + print "_ids = {" > + > + keys = _ids.keys() > + keys.sort() > + for key in keys: > + print " %2d:%s," % (key, repr(_ids[key])) > + > + print " }" > + > + print "" > + > + print "_buses = {" > + > + keys = _buses.keys() > + keys.sort() > + for key in keys: > + print " %2d:%s," % (key, repr(_buses[key])) > + > + print " }" > + > +# Copied from asm-generic/ioctl.h > + > +_IOC_NRBITS = 8 > +_IOC_TYPEBITS = 8 > +_IOC_SIZEBITS = 14 > +_IOC_DIRBITS = 2 > + > +_IOC_NRMASK = ((1 << _IOC_NRBITS)-1) > +_IOC_TYPEMASK = ((1 << _IOC_TYPEBITS)-1) > +_IOC_SIZEMASK = ((1 << _IOC_SIZEBITS)-1) > +_IOC_DIRMASK = ((1 << _IOC_DIRBITS)-1) > + > +_IOC_NRSHIFT = 0 > +_IOC_TYPESHIFT = (_IOC_NRSHIFT+_IOC_NRBITS) > +_IOC_SIZESHIFT = (_IOC_TYPESHIFT+_IOC_TYPEBITS) > +_IOC_DIRSHIFT = (_IOC_SIZESHIFT+_IOC_SIZEBITS) > + > +_IOC_NONE = 0 > +_IOC_WRITE = 1 > +_IOC_READ = 2 > + > +def _IOC(dir,type,nr,size): > + ioc = (((dir) << _IOC_DIRSHIFT) | \ > + (ord(type) << _IOC_TYPESHIFT) | \ > + ((nr) << _IOC_NRSHIFT) | \ > + ((size) << _IOC_SIZESHIFT)) > + if ioc >= 2**31: > + ioc = int(ioc - 2**32) > + return ioc > + > +def _IO(type,nr): > + return _IOC(_IOC_NONE,(type),(nr),0) > +def _IOR(type,nr,size): > + return _IOC(_IOC_READ,(type),(nr),(size)) > +def _IOW(type,nr,size): > + return _IOC(_IOC_WRITE,(type),(nr),(size)) > +def _IOWR(type,nr,size): > + return _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(size)) > + > + > +EVIOCGVERSION = _IOR('E', 0x01, 4) # get driver version > +EVIOCGID = _IOR('E', 0x02, 8) # get device ID > + > +def EVIOCGNAME(len): return _IOR('E', 0x06, len) # get device name > +def EVIOCGPHYS(len): return _IOR('E', 0x07, len) # get physical location > +def EVIOCGUNIQ(len): return _IOR('E', 0x08, len) # get unique identifier > + > +def EVIOCGBIT(ev,len):return _IOR('E', 0x20 + ev, len) # get event bits > +def EVIOCGABS(abs): return _IOR('E', 0x40 + abs, 20) # get abs value/limits > +def EVIOCSABS(abs): return _IOW('E', 0xc0 + abs, 20) # set abs value/limits > + > +class evdev: > + def __init__(self, dev, blocking = False): > + self._fd = None > + if blocking: > + self._fd = os.open(dev, os.O_RDONLY) > + else: > + self._fd = os.open(dev, os.O_RDONLY | os.O_NDELAY) > + self.get_events() > + > + def __del__(self): > + self.close() > + > + def close(self): > + if self._fd is not None: > + os.close(self._fd) > + self._fd = None > + > + def print_info(self): > + print "Input driver version %d.%d.%d" % self.get_version() > + > + devid = self.get_id() > + print "Device ID: bus %s vendor 0x%04x product 0x%04x version > 0x%04x" % \ > + (devid["bus"], devid["vendor"], devid["product"], > devid["version"]) > + > + print 'Device name: "' + self.get_name() + '"' > + print 'Device location: "' + self.get_location() + '"' > + > + def print_events(self): > + print "Supported events:" > + > + keys = self._events.keys() > + keys.sort() > + for key in keys: > + print " Event type %s (%d):" % (_types[key], key) > + > + self._events[key].sort() > + for event in self._events[key]: > + try: > + print " Event %s (%d)" % (_events[key][event], > event) > + except KeyError: > + print " Event ??? (%d)" % event > + > + def get_version(self): > + buf = ioctl(self._fd, EVIOCGVERSION, " ") > + l, = struct.unpack("L", buf) > + return (l >> 16, (l >> 8) & 0xff, l & 0xff) > + > + def get_id(self): > + buf = ioctl(self._fd, EVIOCGID, " " * 8) > + bus, vendor, product, version = struct.unpack("HHHH", buf) > + return { "bus":_buses[bus], "vendor":vendor, > + "product":product, "version":version } > + > + def get_name(self): > + buf = ioctl(self._fd, EVIOCGNAME(1024), " " * 1024) > + null = buf.find("\0") > + return buf[:null] > + > + def get_location(self): > + buf = ioctl(self._fd, EVIOCGPHYS(1024), " " * 1024) > + null = buf.find("\0") > + return buf[:null] > + > + def get_events(self): > + keys = _types.keys() > + keys.sort() > + > + # We need one bit per type, rounded up to even 4 bytes > + l = ((keys[-1] + 7) / 8 + 3) & ~0x3 > + > + buf = ioctl(self._fd, EVIOCGBIT(0, l), " " * l) > + array = struct.unpack("L" * (l/4), buf) > + > + self._events = {} > + > + for i in xrange(l * 8): > + if not array[i / 32] & (1 << i % 32): > + continue > + > + self._events[i] = [] > + > + subkeys = _events[i].keys() > + subkeys.sort() > + > + # We need one bit per type, rounded up to even 4 bytes > + sl = ((subkeys[-1] + 7) / 8 + 3) & ~0x3 > + > + try: > + buf = ioctl(self._fd, EVIOCGBIT(i, sl), " " * sl) > + except IOError: > + # No events for a type results in Errno 22 (EINVAL) > + break > + subarray = struct.unpack("L" * (sl/4), buf) > + > + for j in xrange(sl * 8): > + if not subarray[j / 32] & (1 << j % 32): > + continue > + > + self._events[i].append(j) > + > + def has_event(self, test_event): > + for type in self._events.keys(): > + for event in self._events[type]: > + if _events[type][event] == test_event: > + return True > + return False > + > + def read(self): > + try: > + buf = os.read(self._fd, 16) > + except OSError, (errno, str): > + if errno == 11: > + return None > + raise > + > + sec, usec, type, code, value = struct.unpack("LLHHl", buf) > + > + return (float(sec) + float(usec)/1000000.0, _types[type], > _events[type][code], value) > + > +if os.path.exists("/usr/include/linux/input.h"): > + parse_input_h("/usr/include/linux/input.h") > +else: > + from evfallback import _types, _events, _ids, _buses > + > +if __name__ == "__main__": > + e = evdev("/dev/input/event1", True) > + e.print_info() > + e.print_events() > + > + try: > + while True: > + print e.read() > + except KeyboardInterrupt: > + pass > Index: src/event.py > =================================================================== > --- src/event.py (revision 8396) > +++ src/event.py (working copy) > @@ -538,7 +538,77 @@ > } > > > +DEFAULT_EVENTMAP = { > + 'KEY_F1' : 'SLEEP', > + 'KEY_HOME' : 'MENU', > + 'KEY_G' : 'GUIDE', > + 'KEY_ESC' : 'EXIT', > + 'KEY_UP' : 'UP', > + 'KEY_DOWN' : 'DOWN', > + 'KEY_LEFT' : 'LEFT', > + 'KEY_RIGHT' : 'RIGHT', > + 'KEY_OK' : 'SELECT', > + 'KEY_SPACE' : 'SELECT', > + 'KEY_ENTER' : 'SELECT', > + 'KEY_KPENTER' : 'SELECT', > + 'KEY_POWER' : 'POWER', > + 'KEY_F2' : 'POWER', > + 'KEY_MUTE' : 'MUTE', > + 'KEY_F3' : 'MUTE', > + 'KEY_VOLUMEDOWN' : 'VOL-', > + 'KEY_KPMINUS' : 'VOL-', > + 'KEY_N' : 'VOL-', > + 'KEY_VOLUMEUP' : 'VOL+', > + 'KEY_KPPLUS' : 'VOL+', > + 'KEY_M' : 'VOL+', > + 'KEY_CHANNELUP' : 'CH+', > + 'KEY_C' : 'CH+', > + 'KEY_CHANNELDOWN' : 'CH-', > + 'KEY_V' : 'CH-', > + 'KEY_1' : '1', > + 'KEY_2' : '2', > + 'KEY_3' : '3', > + 'KEY_4' : '4', > + 'KEY_5' : '5', > + 'KEY_6' : '6', > + 'KEY_7' : '7', > + 'KEY_8' : '8', > + 'KEY_9' : '9', > + 'KEY_0' : '0', > + 'KEY_VENDOR' : 'DISPLAY', > + 'KEY_D' : 'DISPLAY', > + 'KEY_MENU' : 'ENTER', > + 'KEY_E' : 'ENTER', > + 'KEY_MINUS' : 'PREV_CH', > + 'KEY_O' : 'PIP_ONOFF', > + 'KEY_W' : 'PIP_SWAP', > + 'KEY_I' : 'PIP_MOVE', > + 'KEY_F4' : 'TV_VCR', > + 'KEY_REWIND' : 'REW', > + 'KEY_R' : 'REW', > + 'KEY_PLAY' : 'PLAY', > + 'KEY_P' : 'PLAY', > + 'KEY_FORWARD' : 'FFWD', > + 'KEY_F' : 'FFWD', > + 'KEY_PAUSE' : 'PAUSE', > + 'KEY_U' : 'PAUSE', > + 'KEY_STOP' : 'STOP', > + 'KEY_S' : 'STOP', > + 'KEY_RECORD' : 'RECORD', > + 'KEY_F6' : 'REC', > + 'KEY_PERIOD' : 'EJECT', > + 'KEY_L' : 'SUBTITLE', > + 'KEY_A' : 'LANG', > > + 'REL_X' : ('LEFT', 'RIGHT'), > + 'REL_Y' : ('UP', 'DOWN'), > + > + 'BTN_LEFT' : 'SELECT', > + 'BTN_RIGHT' : 'EXIT', > + } > + > + > + > # > # Internal events, don't map any button on them > # > Index: Docs/CREDITS > =================================================================== > --- Docs/CREDITS (revision 8396) > +++ Docs/CREDITS (working copy) > @@ -92,8 +92,11 @@ > o fxdimdb class + rewrite of the plugin & helper > o the df plugin > > +Pierre Ossman <[EMAIL PROTECTED]> > +o Linux event device input handler > > > + > Special Copyright Notice: > ------------------------- > > Index: freevo_config.py > =================================================================== > --- freevo_config.py (revision 8396) > +++ freevo_config.py (working copy) > @@ -235,7 +235,9 @@ > Added TV_RECORDFILE_OKLETTERS for characters allowed in recording > filenames. > Added AUTOSHUTDOWN_ settings to turn off and on the machine > automatically > Added Multi-tuner support to allow recording and watching at the same > time > - Added plug-in "upsoon" to stop the player when a recording is about to > start''' ), > + Added plug-in "upsoon" to stop the player when a recording is about to > start > + Added USE_SDL_KEYBOARD to specify if generic keyboard handler should be > used > + Added EVENT_DEVS and EVENTMAP for the new Linux event device handler''' > ), > ] > > > @@ -486,12 +488,35 @@ > MENU_ARROW_NAVIGATION = 0 > > # > +# Process keyboard events from SDL. You want this unless you use only lirc > +# or event devices below. > +# > +USE_SDL_KEYBOARD = 1 > + > +# > # Keymap to map keyboard keys to event strings. You can also add new keys > # here, e.g. KEYMAP[key.K_x] = 'SUBTITLE'. The K_-names are defined by > pygame. > # > KEYMAP = DEFAULT_KEYMAP > > # > +# List of /dev/input/event# devices to monitor. If you monitor your keyboard > +# both here and with USE_SDL_KEYBOARD, then you will get duplicate events. > +# > + > +EVENT_DEVS = [] > + > +# > +# Keymap to map input events to event strings. You can change current > mappings > +# and add new ones here, e.g. EVENTMAP['KEY_COFFEE'] = 'SUBTITLE'. Key names > +# are defined by the Linux input layer (input.h). An axis is described by a > +# pair, one for positive and one for negative movement, e.g. > +# EVENTMAP['REL_Z'] = ('LEFT', 'RIGHT') > +# > + > +EVENTMAP = DEFAULT_EVENTMAP > + > +# > # Use Internet resources to fetch information? > # For example, Freevo can use CDDB for album information, > # the IMDB movie database for movie info, and Amazon for cover searches. > > > ------------------------------------------------------------------------ > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > > > ------------------------------------------------------------------------ > > _______________________________________________ > Freevo-devel mailing list > Freevo-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/freevo-devel ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Freevo-devel mailing list Freevo-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/freevo-devel