diff options
author | John Rennie <renniej@ratix.(none)> | 2011-05-19 10:35:05 +0100 |
---|---|---|
committer | John Rennie <renniej@ratix.(none)> | 2011-05-19 10:35:05 +0100 |
commit | 37b72cc9b34733a40db82fa78ab02243abe9725e (patch) | |
tree | 1459bed841c258364569c59c8a45ec1e5e0dab2a | |
parent | a339fc658d6a4f5f1bf20ebd402332cd97e25d85 (diff) |
Move Linux specific multimedia key code to WinEventsSDL.cpp
-rw-r--r-- | xbmc/input/KeyboardStat.cpp | 165 | ||||
-rw-r--r-- | xbmc/input/KeyboardStat.h | 4 | ||||
-rw-r--r-- | xbmc/input/XBMC_keysym.h | 2 | ||||
-rw-r--r-- | xbmc/windowing/WinEventsSDL.cpp | 180 |
4 files changed, 182 insertions, 169 deletions
diff --git a/xbmc/input/KeyboardStat.cpp b/xbmc/input/KeyboardStat.cpp index b9b35eab27..19117c90c6 100644 --- a/xbmc/input/KeyboardStat.cpp +++ b/xbmc/input/KeyboardStat.cpp @@ -37,127 +37,10 @@ CKeyboardStat g_Keyboard; -struct XBMC_KeyMapping -{ - int source; - BYTE VKey; - char Ascii; - WCHAR Unicode; -}; - -// based on the evdev mapped scancodes in /user/share/X11/xkb/keycodes -static XBMC_KeyMapping g_mapping_evdev[] = -{ { 121, 0xad } // Volume mute -, { 122, 0xae } // Volume down -, { 123, 0xaf } // Volume up -, { 127, 0x20 } // Pause -, { 135, 0x5d } // Right click -, { 136, 0xb2 } // Stop -, { 138, 0x49 } // Info -, { 147, 0x4d } // Menu -, { 150, 0x9f } // Sleep -, { 152, 0xb8 } // Launch file browser -, { 163, 0xb4 } // Launch Mail -, { 164, 0xab } // Browser favorites -, { 166, 0x08 } // Back -, { 167, 0xa7 } // Browser forward -, { 171, 0xb0 } // Next track -, { 172, 0xb3 } // Play_Pause -, { 173, 0xb1 } // Prev track -, { 174, 0xb2 } // Stop -, { 176, 0x52 } // Rewind -, { 179, 0xb9 } // Launch media center -, { 180, 0xac } // Browser home -, { 181, 0xa8 } // Browser refresh -, { 214, 0x1B } // Close -, { 215, 0xb3 } // Play_Pause -, { 216, 0x46 } // Forward -//, {167, 0xb3 } // Record -}; - -// following scancode infos are -// 1. from ubuntu keyboard shortcut (hex) -> predefined -// 2. from unix tool xev and my keyboards (decimal) -// m_VKey infos from CharProbe tool -// Can we do the same for XBoxKeyboard and DirectInputKeyboard? Can we access the scancode of them? By the way how does SDL do it? I can't find it. (Automagically? But how exactly?) -// Some pairs of scancode and virtual keys are only known half - -// special "keys" above F1 till F12 on my MS natural keyboard mapped to virtual keys "F13" till "F24"): -static XBMC_KeyMapping g_mapping_ubuntu[] = -{ { 0xf5, 0x7c } // F13 Launch help browser -, { 0x87, 0x7d } // F14 undo -, { 0x8a, 0x7e } // F15 redo -, { 0x89, 0x7f } // F16 new -, { 0xbf, 0x80 } // F17 open -, { 0xaf, 0x81 } // F18 close -, { 0xe4, 0x82 } // F19 reply -, { 0x8e, 0x83 } // F20 forward -, { 0xda, 0x84 } // F21 send -//, { 0x, 0x85 } // F22 check spell (doesn't work for me with ubuntu) -, { 0xd5, 0x86 } // F23 save -, { 0xb9, 0x87 } // 0x2a?? F24 print - // end of special keys above F1 till F12 - -, { 234, 0xa6 } // Browser back -, { 233, 0xa7 } // Browser forward -, { 231, 0xa8 } // Browser refresh -//, { , 0xa9 } // Browser stop -, { 122, 0xaa } // Browser search -, { 0xe5, 0xaa } // Browser search -, { 230, 0xab } // Browser favorites -, { 130, 0xac } // Browser home -, { 0xa0, 0xad } // Volume mute -, { 0xae, 0xae } // Volume down -, { 0xb0, 0xaf } // Volume up -, { 0x99, 0xb0 } // Next track -, { 0x90, 0xb1 } // Prev track -, { 0xa4, 0xb2 } // Stop -, { 0xa2, 0xb3 } // Play_Pause -, { 0xec, 0xb4 } // Launch mail -, { 129, 0xb5 } // Launch media_select -, { 198, 0xb6 } // Launch App1/PC icon -, { 0xa1, 0xb7 } // Launch App2/Calculator -, { 34, 0xba } // OEM 1: [ on us keyboard -, { 51, 0xbf } // OEM 2: additional key on european keyboards between enter and ' on us keyboards -, { 47, 0xc0 } // OEM 3: ; on us keyboards -, { 20, 0xdb } // OEM 4: - on us keyboards (between 0 and =) -, { 49, 0xdc } // OEM 5: ` on us keyboards (below ESC) -, { 21, 0xdd } // OEM 6: =??? on us keyboards (between - and backspace) -, { 48, 0xde } // OEM 7: ' on us keyboards (on right side of ;) -//, { 0, 0xdf } // OEM 8 -, { 94, 0xe2 } // OEM 102: additional key on european keyboards between left shift and z on us keyboards -//, { 0xb2, 0x } // Ubuntu default setting for launch browser -//, { 0x76, 0x } // Ubuntu default setting for launch music player -//, { 0xcc, 0x } // Ubuntu default setting for eject -, { 117, 0x5d } // right click -}; - -static bool LookupKeyMapping(BYTE* VKey, char* Ascii, WCHAR* Unicode, int source, XBMC_KeyMapping* map, int count) -{ - for(int i = 0; i < count; i++) - { - if(source == map[i].source) - { - if(VKey) - *VKey = map[i].VKey; - if(Ascii) - *Ascii = map[i].Ascii; - if(Unicode) - *Unicode = map[i].Unicode; - return true; - } - } - return false; -} - CKeyboardStat::CKeyboardStat() { memset(&m_lastKeysym, 0, sizeof(m_lastKeysym)); m_lastKeyTime = 0; - - // In Linux the codes (numbers) for multimedia keys differ depending on - // what driver is used and the evdev bool switches between the two. - m_bEvdev = true; } CKeyboardStat::~CKeyboardStat() @@ -166,39 +49,6 @@ CKeyboardStat::~CKeyboardStat() void CKeyboardStat::Initialize() { -/* this stuff probably doesn't belong here * - * but in some x11 specific WinEvents file * - * but for some reason the code to map keys * - * to specific xbmc vkeys is here */ -#if defined(_LINUX) && !defined(__APPLE__) - Display* dpy = XOpenDisplay(NULL); - if (!dpy) - return; - - XkbDescPtr desc; - char* symbols; - - desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd); - if(!desc) - { - XCloseDisplay(dpy); - return; - } - - symbols = XGetAtomName(dpy, desc->names->symbols); - if(symbols) - { - CLog::Log(LOGDEBUG, "CKeyboardStat::Initialize - XKb symbols %s", symbols); - if(strstr(symbols, "(evdev)")) - m_bEvdev = true; - else - m_bEvdev = false; - } - - XFree(symbols); - XkbFreeKeyboard(desc, XkbAllComponentsMask, True); - XCloseDisplay(dpy); -#endif } const CKey CKeyboardStat::ProcessKeyDown(XBMC_keysym& keysym) @@ -264,21 +114,6 @@ const CKey CKeyboardStat::ProcessKeyDown(XBMC_keysym& keysym) { if (!vkey && !ascii) { - /* Check for linux defined non printable keys */ - if(m_bEvdev) - LookupKeyMapping(&vkey, NULL, NULL - , keysym.scancode - , g_mapping_evdev - , sizeof(g_mapping_evdev)/sizeof(g_mapping_evdev[0])); - else - LookupKeyMapping(&vkey, NULL, NULL - , keysym.scancode - , g_mapping_ubuntu - , sizeof(g_mapping_ubuntu)/sizeof(g_mapping_ubuntu[0])); - } - - if (!vkey && !ascii) - { if (keysym.mod & XBMCKMOD_LSHIFT) vkey = 0xa0; else if (keysym.mod & XBMCKMOD_RSHIFT) vkey = 0xa1; else if (keysym.mod & XBMCKMOD_LALT) vkey = 0xa4; diff --git a/xbmc/input/KeyboardStat.h b/xbmc/input/KeyboardStat.h index b391df0bde..9d00809e83 100644 --- a/xbmc/input/KeyboardStat.h +++ b/xbmc/input/KeyboardStat.h @@ -57,10 +57,6 @@ public: private: XBMC_keysym m_lastKeysym; unsigned int m_lastKeyTime; - - // In Linux the codes (numbers) for multimedia keys differ depending on - // what driver is used and the evdev bool switches between the two. - bool m_bEvdev; }; extern CKeyboardStat g_Keyboard; diff --git a/xbmc/input/XBMC_keysym.h b/xbmc/input/XBMC_keysym.h index 64cee57d19..5c0136fe09 100644 --- a/xbmc/input/XBMC_keysym.h +++ b/xbmc/input/XBMC_keysym.h @@ -133,6 +133,8 @@ typedef enum { XBMCK_LAUNCH_MEDIA_SELECT = 0xB5, XBMCK_LAUNCH_APP1 = 0xB6, XBMCK_LAUNCH_APP2 = 0xB7, + XBMCK_LAUNCH_FILE_BROWSER = 0xB8, + XBMCK_LAUNCH_MEDIA_CENTER = 0xB9, // Numeric keypad XBMCK_KP0 = 0x100, diff --git a/xbmc/windowing/WinEventsSDL.cpp b/xbmc/windowing/WinEventsSDL.cpp index 6461492d0e..e9bab4e723 100644 --- a/xbmc/windowing/WinEventsSDL.cpp +++ b/xbmc/windowing/WinEventsSDL.cpp @@ -31,10 +31,184 @@ #include "osx/CocoaInterface.h" #endif +#if defined(_LINUX) && !defined(__APPLE__) +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include "input/XBMC_keysym.h" +#include "utils/log.h" +#endif + #ifdef HAS_SDL_WIN_EVENTS PHANDLE_EVENT_FUNC CWinEventsBase::m_pEventFunc = NULL; +#if defined(_LINUX) && !defined(__APPLE__) +// The following chunk of code is Linux specific. For keys that have +// with keysym.sym set to zero it checks the scan code, and sets the sym +// for some known scan codes. This is mostly the multimedia keys. +// Note that the scan code to sym mapping is different with and without +// the evdev driver so we need to check if evdev is loaded. + +// m_bEvdev == true if evdev is loaded +static bool m_bEvdev = true; +// We need to initialise some local storage once. Set m_bEvdevInit to true +// once the initialisation has been done +static bool m_bEvdevInit = false; + +// Mappings of scancodes to syms for the evdev driver +static uint16_t SymMappingsEvdev[][2] = +{ { 121, XBMCK_VOLUME_MUTE } // Volume mute +, { 122, XBMCK_VOLUME_DOWN } // Volume down +, { 123, XBMCK_VOLUME_UP } // Volume up +, { 127, XBMCK_SPACE } // Pause +, { 135, XBMCK_MENU } // Right click +, { 136, XBMCK_MEDIA_STOP } // Stop +, { 138, 0x49 /* 'I' */} // Info +, { 147, 0x4d /* 'M' */} // Menu +, { 148, XBMCK_LAUNCH_APP2 } // Launch app 2 +, { 150, 0x9f } // Sleep +, { 152, XBMCK_LAUNCH_APP1 } // Launch app 1 +, { 163, XBMCK_LAUNCH_MAIL } // Launch Mail +, { 164, XBMCK_BROWSER_FAVORITES } // Browser favorites +, { 166, XBMCK_BROWSER_BACK } // Back +, { 167, XBMCK_BROWSER_FORWARD } // Browser forward +, { 171, XBMCK_MEDIA_NEXT_TRACK } // Next track +, { 172, XBMCK_MEDIA_PLAY_PAUSE } // Play_Pause +, { 173, XBMCK_MEDIA_PREV_TRACK } // Prev track +, { 174, XBMCK_MEDIA_STOP } // Stop +, { 176, 0x52 /* 'R' */} // Rewind +, { 179, XBMCK_LAUNCH_MEDIA_SELECT } // Launch media select +, { 180, XBMCK_BROWSER_HOME } // Browser home +, { 181, XBMCK_BROWSER_REFRESH } // Browser refresh +, { 214, XBMCK_ESCAPE } // Close +, { 215, XBMCK_MEDIA_PLAY_PAUSE } // Play_Pause +, { 216, 0x46 /* 'F' */} // Forward +//, {167, 0xb3 } // Record +}; + +// The non-evdev mappings need to be checked. At the moment XBMC will never +// use them anyway. +static uint16_t SymMappingsUbuntu[][2] = +{ { 0xf5, XBMCK_F13 } // F13 Launch help browser +, { 0x87, XBMCK_F14 } // F14 undo +, { 0x8a, XBMCK_F15 } // F15 redo +, { 0x89, 0x7f } // F16 new +, { 0xbf, 0x80 } // F17 open +, { 0xaf, 0x81 } // F18 close +, { 0xe4, 0x82 } // F19 reply +, { 0x8e, 0x83 } // F20 forward +, { 0xda, 0x84 } // F21 send +//, { 0x, 0x85 } // F22 check spell (doesn't work for me with ubuntu) +, { 0xd5, 0x86 } // F23 save +, { 0xb9, 0x87 } // 0x2a?? F24 print + // end of special keys above F1 till F12 + +, { 234, XBMCK_BROWSER_BACK } // Browser back +, { 233, XBMCK_BROWSER_FORWARD } // Browser forward +, { 231, XBMCK_BROWSER_REFRESH } // Browser refresh +//, { , XBMCK_BROWSER_STOP } // Browser stop +, { 122, XBMCK_BROWSER_SEARCH } // Browser search +, { 0xe5, XBMCK_BROWSER_SEARCH } // Browser search +, { 230, XBMCK_BROWSER_FAVORITES } // Browser favorites +, { 130, XBMCK_BROWSER_HOME } // Browser home +, { 0xa0, XBMCK_VOLUME_MUTE } // Volume mute +, { 0xae, XBMCK_VOLUME_DOWN } // Volume down +, { 0xb0, XBMCK_VOLUME_UP } // Volume up +, { 0x99, XBMCK_MEDIA_NEXT_TRACK } // Next track +, { 0x90, XBMCK_MEDIA_PREV_TRACK } // Prev track +, { 0xa4, XBMCK_MEDIA_STOP } // Stop +, { 0xa2, XBMCK_MEDIA_PLAY_PAUSE } // Play_Pause +, { 0xec, XBMCK_LAUNCH_MAIL } // Launch mail +, { 129, XBMCK_LAUNCH_MEDIA_SELECT } // Launch media_select +, { 198, XBMCK_LAUNCH_APP1 } // Launch App1/PC icon +, { 0xa1, XBMCK_LAUNCH_APP2 } // Launch App2/Calculator +, { 34, 0x3b /* vkey 0xba */} // OEM 1: [ on us keyboard +, { 51, 0x2f /* vkey 0xbf */} // OEM 2: additional key on european keyboards between enter and ' on us keyboards +, { 47, 0x60 /* vkey 0xc0 */} // OEM 3: ; on us keyboards +, { 20, 0xdb } // OEM 4: - on us keyboards (between 0 and =) +, { 49, 0xdc } // OEM 5: ` on us keyboards (below ESC) +, { 21, 0xdd } // OEM 6: =??? on us keyboards (between - and backspace) +, { 48, 0xde } // OEM 7: ' on us keyboards (on right side of ;) +//, { 0, 0xdf } // OEM 8 +, { 94, 0xe2 } // OEM 102: additional key on european keyboards between left shift and z on us keyboards +//, { 0xb2, 0x } // Ubuntu default setting for launch browser +//, { 0x76, 0x } // Ubuntu default setting for launch music player +//, { 0xcc, 0x } // Ubuntu default setting for eject +, { 117, 0x5d } // right click +}; + +// Called once. Checks whether evdev is loaded and sets m_bEvdev accordingly. +void InitEvdev(void) +{ + // Set m_bEvdevInit to indicate we have been initialised + m_bEvdevInit = true; + + Display* dpy = XOpenDisplay(NULL); + if (!dpy) + { + CLog::Log(LOGERROR, "CWinEventsSDL::CWinEventsSDL - XOpenDisplay failed"); + return; + } + + XkbDescPtr desc; + char* symbols; + + desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd); + if(!desc) + { + XCloseDisplay(dpy); + CLog::Log(LOGERROR, "CWinEventsSDL::CWinEventsSDL - XkbGetKeyboard failed"); + return; + } + + symbols = XGetAtomName(dpy, desc->names->symbols); + if(symbols) + { + CLog::Log(LOGDEBUG, "CWinEventsSDL::CWinEventsSDL - XKb symbols %s", symbols); + if(strstr(symbols, "(evdev)")) + m_bEvdev = true; + else + m_bEvdev = false; + } + + XFree(symbols); + XkbFreeKeyboard(desc, XkbAllComponentsMask, True); + XCloseDisplay(dpy); + + CLog::Log(LOGDEBUG, "CWinEventsSDL::CWinEventsSDL - m_bEvdev = %d", m_bEvdev); +} + +// Check the scan code and return the matching sym, or zero if the scan code +// is unknown. +uint16_t SymFromScancode(uint16_t scancode) +{ + int i; + + // We need to initialise m_bEvdev once + if (!m_bEvdevInit) + InitEvdev(); + + // If evdev is loaded look up the scan code in SymMappingsEvdev + if (m_bEvdev) + { + for (i = 0; i < sizeof(SymMappingsEvdev)/4; i++) + if (scancode == SymMappingsEvdev[i][0]) + return SymMappingsEvdev[i][1]; + } + + // If evdev is not loaded look up the scan code in SymMappingsUbuntu + else + { + for (i = 0; i < sizeof(SymMappingsUbuntu)/4; i++) + if (scancode == SymMappingsUbuntu[i][0]) + return SymMappingsUbuntu[i][1]; + } + + // Scan code wasn't found, return zero + return 0; +} +#endif // End of checks for keysym.sym == 0 + bool CWinEventsSDL::MessagePump() { SDL_Event event; @@ -94,6 +268,12 @@ bool CWinEventsSDL::MessagePump() newEvent.key.type = event.key.type; newEvent.key.which = event.key.which; +#if defined(_LINUX) && !defined(__APPLE__) + // If the keysym.sym is zero try to get it from the scan code + if (newEvent.key.keysym.sym == 0) + newEvent.key.keysym.sym = (XBMCKey) SymFromScancode(newEvent.key.keysym.scancode); +#endif + // don't handle any more messages in the queue until we've handled keydown, // if a keyup is in the queue it will reset the keypress before it is handled. ret |= g_application.OnEvent(newEvent); |