aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Rennie <renniej@ratix.(none)>2011-05-19 10:35:05 +0100
committerJohn Rennie <renniej@ratix.(none)>2011-05-19 10:35:05 +0100
commit37b72cc9b34733a40db82fa78ab02243abe9725e (patch)
tree1459bed841c258364569c59c8a45ec1e5e0dab2a
parenta339fc658d6a4f5f1bf20ebd402332cd97e25d85 (diff)
Move Linux specific multimedia key code to WinEventsSDL.cpp
-rw-r--r--xbmc/input/KeyboardStat.cpp165
-rw-r--r--xbmc/input/KeyboardStat.h4
-rw-r--r--xbmc/input/XBMC_keysym.h2
-rw-r--r--xbmc/windowing/WinEventsSDL.cpp180
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);