From 55ae7c05bc335be404d2e88dde60fdedec540a1e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 2 Jun 2009 08:56:32 +0000 Subject: [PATCH] Refactored the adaption of X11 key symbols into OSG key events to fix problems with handling wide range of locales. --- src/osgViewer/GraphicsWindowX11.cpp | 319 +++++++++++++++------------- 1 file changed, 173 insertions(+), 146 deletions(-) diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index 83e12f94d..29e47f3ac 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -44,163 +44,184 @@ class X11KeyboardMap X11KeyboardMap() { - _keymap[XK_Escape ] = osgGA::GUIEventAdapter::KEY_Escape; - _keymap[XK_F1 ] = osgGA::GUIEventAdapter::KEY_F1; - _keymap[XK_F2 ] = osgGA::GUIEventAdapter::KEY_F2; - _keymap[XK_F3 ] = osgGA::GUIEventAdapter::KEY_F3; - _keymap[XK_F4 ] = osgGA::GUIEventAdapter::KEY_F4; - _keymap[XK_F5 ] = osgGA::GUIEventAdapter::KEY_F5; - _keymap[XK_F6 ] = osgGA::GUIEventAdapter::KEY_F6; - _keymap[XK_F7 ] = osgGA::GUIEventAdapter::KEY_F7; - _keymap[XK_F8 ] = osgGA::GUIEventAdapter::KEY_F8; - _keymap[XK_F9 ] = osgGA::GUIEventAdapter::KEY_F9; - _keymap[XK_F10 ] = osgGA::GUIEventAdapter::KEY_F10; - _keymap[XK_F11 ] = osgGA::GUIEventAdapter::KEY_F11; - _keymap[XK_F12 ] = osgGA::GUIEventAdapter::KEY_F12; - _keymap[XK_quoteleft ] = '"'; - _keymap[XK_1 ] = '1'; - _keymap[XK_2 ] = '2'; - _keymap[XK_3 ] = '3'; - _keymap[XK_4 ] = '4'; - _keymap[XK_5 ] = '5'; - _keymap[XK_6 ] = '6'; - _keymap[XK_7 ] = '7'; - _keymap[XK_8 ] = '8'; - _keymap[XK_9 ] = '9'; - _keymap[XK_0 ] = '0'; - _keymap[XK_minus ] = '-'; - _keymap[XK_equal ] = '='; - _keymap[XK_BackSpace ] = osgGA::GUIEventAdapter::KEY_BackSpace; - _keymap[XK_Tab ] = osgGA::GUIEventAdapter::KEY_Tab; - _keymap[XK_A ] = 'A'; - _keymap[XK_B ] = 'B'; - _keymap[XK_C ] = 'C'; - _keymap[XK_D ] = 'D'; - _keymap[XK_E ] = 'E'; - _keymap[XK_F ] = 'F'; - _keymap[XK_G ] = 'G'; - _keymap[XK_H ] = 'H'; - _keymap[XK_I ] = 'I'; - _keymap[XK_J ] = 'J'; - _keymap[XK_K ] = 'K'; - _keymap[XK_L ] = 'L'; - _keymap[XK_M ] = 'M'; - _keymap[XK_N ] = 'N'; - _keymap[XK_O ] = 'O'; - _keymap[XK_P ] = 'P'; - _keymap[XK_Q ] = 'Q'; - _keymap[XK_R ] = 'R'; - _keymap[XK_S ] = 'S'; - _keymap[XK_T ] = 'T'; - _keymap[XK_U ] = 'U'; - _keymap[XK_V ] = 'V'; - _keymap[XK_W ] = 'W'; - _keymap[XK_X ] = 'X'; - _keymap[XK_Y ] = 'Y'; - _keymap[XK_Z ] = 'Z'; - _keymap[XK_a ] = 'a'; - _keymap[XK_b ] = 'b'; - _keymap[XK_c ] = 'c'; - _keymap[XK_d ] = 'd'; - _keymap[XK_e ] = 'e'; - _keymap[XK_f ] = 'f'; - _keymap[XK_g ] = 'g'; - _keymap[XK_h ] = 'h'; - _keymap[XK_i ] = 'i'; - _keymap[XK_j ] = 'j'; - _keymap[XK_k ] = 'k'; - _keymap[XK_l ] = 'l'; - _keymap[XK_m ] = 'm'; - _keymap[XK_n ] = 'n'; - _keymap[XK_o ] = 'o'; - _keymap[XK_p ] = 'p'; - _keymap[XK_q ] = 'q'; - _keymap[XK_r ] = 'r'; - _keymap[XK_s ] = 's'; - _keymap[XK_t ] = 't'; - _keymap[XK_u ] = 'u'; - _keymap[XK_v ] = 'v'; - _keymap[XK_w ] = 'w'; - _keymap[XK_x ] = 'x'; - _keymap[XK_y ] = 'y'; - _keymap[XK_z ] = 'z'; - _keymap[XK_bracketleft ] = '('; - _keymap[XK_bracketright ] = ')'; - _keymap[XK_backslash ] = '\\'; - _keymap[XK_Caps_Lock ] = osgGA::GUIEventAdapter::KEY_Caps_Lock; - _keymap[XK_semicolon ] = ';'; - _keymap[XK_apostrophe ] = '\''; - _keymap[XK_Return ] = osgGA::GUIEventAdapter::KEY_Return; - _keymap[XK_comma ] = ','; - _keymap[XK_period ] = '.'; - _keymap[XK_slash ] = '/'; - _keymap[XK_space ] = ' '; - _keymap[XK_Shift_L ] = osgGA::GUIEventAdapter::KEY_Shift_L; - _keymap[XK_Shift_R ] = osgGA::GUIEventAdapter::KEY_Shift_R; - _keymap[XK_Control_L ] = osgGA::GUIEventAdapter::KEY_Control_L; - _keymap[XK_Control_R ] = osgGA::GUIEventAdapter::KEY_Control_R; - _keymap[XK_Meta_L ] = osgGA::GUIEventAdapter::KEY_Meta_L; - _keymap[XK_Meta_R ] = osgGA::GUIEventAdapter::KEY_Meta_R; - _keymap[XK_Alt_L ] = osgGA::GUIEventAdapter::KEY_Alt_L; - _keymap[XK_Alt_R ] = osgGA::GUIEventAdapter::KEY_Alt_R; - _keymap[XK_Super_L ] = osgGA::GUIEventAdapter::KEY_Super_L; - _keymap[XK_Super_R ] = osgGA::GUIEventAdapter::KEY_Super_R; - _keymap[XK_Hyper_L ] = osgGA::GUIEventAdapter::KEY_Hyper_L; - _keymap[XK_Hyper_R ] = osgGA::GUIEventAdapter::KEY_Hyper_R; - _keymap[XK_Menu ] = osgGA::GUIEventAdapter::KEY_Menu; - _keymap[XK_Print ] = osgGA::GUIEventAdapter::KEY_Print; - _keymap[XK_Scroll_Lock ] = osgGA::GUIEventAdapter::KEY_Scroll_Lock; - _keymap[XK_Pause ] = osgGA::GUIEventAdapter::KEY_Pause; - _keymap[XK_Home ] = osgGA::GUIEventAdapter::KEY_Home; - _keymap[XK_Page_Up ] = osgGA::GUIEventAdapter::KEY_Page_Up; - _keymap[XK_End ] = osgGA::GUIEventAdapter::KEY_End; - _keymap[XK_Page_Down ] = osgGA::GUIEventAdapter::KEY_Page_Down; - _keymap[XK_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; - _keymap[XK_Insert ] = osgGA::GUIEventAdapter::KEY_Insert; - _keymap[XK_Left ] = osgGA::GUIEventAdapter::KEY_Left; - _keymap[XK_Up ] = osgGA::GUIEventAdapter::KEY_Up; - _keymap[XK_Right ] = osgGA::GUIEventAdapter::KEY_Right; - _keymap[XK_Down ] = osgGA::GUIEventAdapter::KEY_Down; - _keymap[XK_Num_Lock ] = osgGA::GUIEventAdapter::KEY_Num_Lock; - _keymap[XK_KP_Divide ] = osgGA::GUIEventAdapter::KEY_KP_Divide; - _keymap[XK_KP_Multiply ] = osgGA::GUIEventAdapter::KEY_KP_Multiply; - _keymap[XK_KP_Subtract ] = osgGA::GUIEventAdapter::KEY_KP_Subtract; - _keymap[XK_KP_Add ] = osgGA::GUIEventAdapter::KEY_KP_Add; - _keymap[XK_KP_Home ] = osgGA::GUIEventAdapter::KEY_KP_Home; - _keymap[XK_KP_Up ] = osgGA::GUIEventAdapter::KEY_KP_Up; - _keymap[XK_KP_Page_Up ] = osgGA::GUIEventAdapter::KEY_KP_Page_Up; - _keymap[XK_KP_Left ] = osgGA::GUIEventAdapter::KEY_KP_Left; - _keymap[XK_KP_Begin ] = osgGA::GUIEventAdapter::KEY_KP_Begin; - _keymap[XK_KP_Right ] = osgGA::GUIEventAdapter::KEY_KP_Right; - _keymap[XK_KP_End ] = osgGA::GUIEventAdapter::KEY_KP_End; - _keymap[XK_KP_Down ] = osgGA::GUIEventAdapter::KEY_KP_Down; - _keymap[XK_KP_Page_Down ] = osgGA::GUIEventAdapter::KEY_KP_Page_Down; - _keymap[XK_KP_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert; - _keymap[XK_KP_Delete ] = osgGA::GUIEventAdapter::KEY_KP_Delete; - _keymap[XK_KP_Enter ] = osgGA::GUIEventAdapter::KEY_KP_Enter; - +#if 0 + _extendKeymap[8 ] = osgGA::GUIEventAdapter::KEY_BackSpace; + _extendKeymap[127 ] = osgGA::GUIEventAdapter::KEY_Delete; + _extendKeymap[27 ] = osgGA::GUIEventAdapter::KEY_Escape; + // _extendKeymap[13 ] = osgGA::GUIEventAdapter::KEY_Enter; +#endif + _extendedKeymap[XK_Escape ] = osgGA::GUIEventAdapter::KEY_Escape; + _extendedKeymap[XK_F1 ] = osgGA::GUIEventAdapter::KEY_F1; + _extendedKeymap[XK_F2 ] = osgGA::GUIEventAdapter::KEY_F2; + _extendedKeymap[XK_F3 ] = osgGA::GUIEventAdapter::KEY_F3; + _extendedKeymap[XK_F4 ] = osgGA::GUIEventAdapter::KEY_F4; + _extendedKeymap[XK_F5 ] = osgGA::GUIEventAdapter::KEY_F5; + _extendedKeymap[XK_F6 ] = osgGA::GUIEventAdapter::KEY_F6; + _extendedKeymap[XK_F7 ] = osgGA::GUIEventAdapter::KEY_F7; + _extendedKeymap[XK_F8 ] = osgGA::GUIEventAdapter::KEY_F8; + _extendedKeymap[XK_F9 ] = osgGA::GUIEventAdapter::KEY_F9; + _extendedKeymap[XK_F10 ] = osgGA::GUIEventAdapter::KEY_F10; + _extendedKeymap[XK_F11 ] = osgGA::GUIEventAdapter::KEY_F11; + _extendedKeymap[XK_F12 ] = osgGA::GUIEventAdapter::KEY_F12; + _extendedKeymap[XK_quoteleft ] = '`'; + _extendedKeymap[XK_minus ] = '-'; + _extendedKeymap[XK_equal ] = '='; + _extendedKeymap[XK_BackSpace ] = osgGA::GUIEventAdapter::KEY_BackSpace; + _extendedKeymap[XK_Tab ] = osgGA::GUIEventAdapter::KEY_Tab; + _extendedKeymap[XK_bracketleft ] = '('; + _extendedKeymap[XK_bracketright ] = ')'; + _extendedKeymap[XK_backslash ] = '\\'; + _extendedKeymap[XK_Caps_Lock ] = osgGA::GUIEventAdapter::KEY_Caps_Lock; + _extendedKeymap[XK_semicolon ] = ';'; + _extendedKeymap[XK_apostrophe ] = '\''; + _extendedKeymap[XK_Return ] = osgGA::GUIEventAdapter::KEY_Return; + _extendedKeymap[XK_comma ] = ','; + _extendedKeymap[XK_period ] = '.'; + _extendedKeymap[XK_slash ] = '/'; + _extendedKeymap[XK_space ] = ' '; + _extendedKeymap[XK_Shift_L ] = osgGA::GUIEventAdapter::KEY_Shift_L; + _extendedKeymap[XK_Shift_R ] = osgGA::GUIEventAdapter::KEY_Shift_R; + _extendedKeymap[XK_Control_L ] = osgGA::GUIEventAdapter::KEY_Control_L; + _extendedKeymap[XK_Control_R ] = osgGA::GUIEventAdapter::KEY_Control_R; + _extendedKeymap[XK_Meta_L ] = osgGA::GUIEventAdapter::KEY_Meta_L; + _extendedKeymap[XK_Meta_R ] = osgGA::GUIEventAdapter::KEY_Meta_R; + _extendedKeymap[XK_Alt_L ] = osgGA::GUIEventAdapter::KEY_Alt_L; + _extendedKeymap[XK_Alt_R ] = osgGA::GUIEventAdapter::KEY_Alt_R; + _extendedKeymap[XK_Super_L ] = osgGA::GUIEventAdapter::KEY_Super_L; + _extendedKeymap[XK_Super_R ] = osgGA::GUIEventAdapter::KEY_Super_R; + _extendedKeymap[XK_Hyper_L ] = osgGA::GUIEventAdapter::KEY_Hyper_L; + _extendedKeymap[XK_Hyper_R ] = osgGA::GUIEventAdapter::KEY_Hyper_R; + _extendedKeymap[XK_Menu ] = osgGA::GUIEventAdapter::KEY_Menu; + _extendedKeymap[XK_Print ] = osgGA::GUIEventAdapter::KEY_Print; + _extendedKeymap[XK_Scroll_Lock ] = osgGA::GUIEventAdapter::KEY_Scroll_Lock; + _extendedKeymap[XK_Pause ] = osgGA::GUIEventAdapter::KEY_Pause; + _extendedKeymap[XK_Home ] = osgGA::GUIEventAdapter::KEY_Home; + _extendedKeymap[XK_Page_Up ] = osgGA::GUIEventAdapter::KEY_Page_Up; + _extendedKeymap[XK_End ] = osgGA::GUIEventAdapter::KEY_End; + _extendedKeymap[XK_Page_Down ] = osgGA::GUIEventAdapter::KEY_Page_Down; + _extendedKeymap[XK_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; + _extendedKeymap[XK_Insert ] = osgGA::GUIEventAdapter::KEY_Insert; + _extendedKeymap[XK_Left ] = osgGA::GUIEventAdapter::KEY_Left; + _extendedKeymap[XK_Up ] = osgGA::GUIEventAdapter::KEY_Up; + _extendedKeymap[XK_Right ] = osgGA::GUIEventAdapter::KEY_Right; + _extendedKeymap[XK_Down ] = osgGA::GUIEventAdapter::KEY_Down; + _extendedKeymap[XK_Num_Lock ] = osgGA::GUIEventAdapter::KEY_Num_Lock; + _extendedKeymap[XK_KP_Divide ] = osgGA::GUIEventAdapter::KEY_KP_Divide; + _extendedKeymap[XK_KP_Multiply ] = osgGA::GUIEventAdapter::KEY_KP_Multiply; + _extendedKeymap[XK_KP_Subtract ] = osgGA::GUIEventAdapter::KEY_KP_Subtract; + _extendedKeymap[XK_KP_Add ] = osgGA::GUIEventAdapter::KEY_KP_Add; + _extendedKeymap[XK_KP_Home ] = osgGA::GUIEventAdapter::KEY_KP_Home; + _extendedKeymap[XK_KP_Up ] = osgGA::GUIEventAdapter::KEY_KP_Up; + _extendedKeymap[XK_KP_Page_Up ] = osgGA::GUIEventAdapter::KEY_KP_Page_Up; + _extendedKeymap[XK_KP_Left ] = osgGA::GUIEventAdapter::KEY_KP_Left; + _extendedKeymap[XK_KP_Begin ] = osgGA::GUIEventAdapter::KEY_KP_Begin; + _extendedKeymap[XK_KP_Right ] = osgGA::GUIEventAdapter::KEY_KP_Right; + _extendedKeymap[XK_KP_End ] = osgGA::GUIEventAdapter::KEY_KP_End; + _extendedKeymap[XK_KP_Down ] = osgGA::GUIEventAdapter::KEY_KP_Down; + _extendedKeymap[XK_KP_Page_Down ] = osgGA::GUIEventAdapter::KEY_KP_Page_Down; + _extendedKeymap[XK_KP_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert; + _extendedKeymap[XK_KP_Delete ] = osgGA::GUIEventAdapter::KEY_KP_Delete; + _extendedKeymap[XK_KP_Enter ] = osgGA::GUIEventAdapter::KEY_KP_Enter; + + _standardKeymap[XK_1 ] = '1'; + _standardKeymap[XK_2 ] = '2'; + _standardKeymap[XK_3 ] = '3'; + _standardKeymap[XK_4 ] = '4'; + _standardKeymap[XK_5 ] = '5'; + _standardKeymap[XK_6 ] = '6'; + _standardKeymap[XK_7 ] = '7'; + _standardKeymap[XK_8 ] = '8'; + _standardKeymap[XK_9 ] = '9'; + _standardKeymap[XK_0 ] = '0'; + _standardKeymap[XK_A ] = 'A'; + _standardKeymap[XK_B ] = 'B'; + _standardKeymap[XK_C ] = 'C'; + _standardKeymap[XK_D ] = 'D'; + _standardKeymap[XK_E ] = 'E'; + _standardKeymap[XK_F ] = 'F'; + _standardKeymap[XK_G ] = 'G'; + _standardKeymap[XK_H ] = 'H'; + _standardKeymap[XK_I ] = 'I'; + _standardKeymap[XK_J ] = 'J'; + _standardKeymap[XK_K ] = 'K'; + _standardKeymap[XK_L ] = 'L'; + _standardKeymap[XK_M ] = 'M'; + _standardKeymap[XK_N ] = 'N'; + _standardKeymap[XK_O ] = 'O'; + _standardKeymap[XK_P ] = 'P'; + _standardKeymap[XK_Q ] = 'Q'; + _standardKeymap[XK_R ] = 'R'; + _standardKeymap[XK_S ] = 'S'; + _standardKeymap[XK_T ] = 'T'; + _standardKeymap[XK_U ] = 'U'; + _standardKeymap[XK_V ] = 'V'; + _standardKeymap[XK_W ] = 'W'; + _standardKeymap[XK_X ] = 'X'; + _standardKeymap[XK_Y ] = 'Y'; + _standardKeymap[XK_Z ] = 'Z'; + _standardKeymap[XK_a ] = 'a'; + _standardKeymap[XK_b ] = 'b'; + _standardKeymap[XK_c ] = 'c'; + _standardKeymap[XK_d ] = 'd'; + _standardKeymap[XK_e ] = 'e'; + _standardKeymap[XK_f ] = 'f'; + _standardKeymap[XK_g ] = 'g'; + _standardKeymap[XK_h ] = 'h'; + _standardKeymap[XK_i ] = 'i'; + _standardKeymap[XK_j ] = 'j'; + _standardKeymap[XK_k ] = 'k'; + _standardKeymap[XK_l ] = 'l'; + _standardKeymap[XK_m ] = 'm'; + _standardKeymap[XK_n ] = 'n'; + _standardKeymap[XK_o ] = 'o'; + _standardKeymap[XK_p ] = 'p'; + _standardKeymap[XK_q ] = 'q'; + _standardKeymap[XK_r ] = 'r'; + _standardKeymap[XK_s ] = 's'; + _standardKeymap[XK_t ] = 't'; + _standardKeymap[XK_u ] = 'u'; + _standardKeymap[XK_v ] = 'v'; + _standardKeymap[XK_w ] = 'w'; + _standardKeymap[XK_x ] = 'x'; + _standardKeymap[XK_y ] = 'y'; + _standardKeymap[XK_z ] = 'z'; } ~X11KeyboardMap() {} int remapKey(int key) { - KeyMap::iterator itr = _keymap.find(key); - if (itr == _keymap.end()) return key; - else return itr->second; + KeyMap::iterator itr = _extendedKeymap.find(key); + if (itr != _extendedKeymap.end()) return itr->second; + + itr = _standardKeymap.find(key); + if (itr != _standardKeymap.end()) return itr->second; + + return key; } - + + bool remapExtendedKey(int& key) + { + KeyMap::iterator itr = _extendedKeymap.find(key); + if (itr != _extendedKeymap.end()) + { + key = itr->second; + return true; + } + else return false; + } + protected: - typedef std::map KeyMap; - KeyMap _keymap; + KeyMap _extendedKeymap; + KeyMap _standardKeymap; }; -static int remapX11Key(int key) +static bool remapExtendedX11Key(int& key) { static X11KeyboardMap s_x11KeyboardMap; - return s_x11KeyboardMap.remapKey(key); + return s_x11KeyboardMap.remapExtendedKey(key); } // Functions to handle key maps of type char[32] as contained in @@ -1333,10 +1354,16 @@ void GraphicsWindowX11::transformMouseXY(float& x, float& y) void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol) { - Display* display = _eventDisplay; - KeySym ks = XKeycodeToKeysym( display, keyevent.keycode, 0 ); + unsigned char buffer_return[32]; + int bytes_buffer = 32; + KeySym keysym_return; - keySymbol = remapX11Key(ks); + int numChars = XLookupString(&keyevent, reinterpret_cast(buffer_return), bytes_buffer, &keysym_return, NULL); + keySymbol = keysym_return; + if (!remapExtendedX11Key(keySymbol) && (numChars==1)) + { + keySymbol = buffer_return[0]; + } } // Function to inject artificial key presses/releases.