diff --git a/examples/osgkeyboard/osgkeyboard.cpp b/examples/osgkeyboard/osgkeyboard.cpp index 27e2eed83..e5c5b1dfa 100644 --- a/examples/osgkeyboard/osgkeyboard.cpp +++ b/examples/osgkeyboard/osgkeyboard.cpp @@ -42,14 +42,13 @@ public: osg::Group* getScene() { return _scene.get(); } - void keyChange(int key,int value); + void keyChange(int key, int virtualKey, int value); protected: ~KeyboardModel() {} osg::Switch* addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height); - osg::Switch* addKey(int key,osg::Switch* sw); void createKeyboard(); @@ -61,12 +60,12 @@ protected: }; -void KeyboardModel::keyChange(int key,int value) +void KeyboardModel::keyChange(int key, int virtualKey, int value) { osg::notify(osg::INFO) << "key value change, code="<',addKey(pos,'.',".",1.0f,1.0f)); - addKey('?',addKey(pos,'/',"/",1.0f,1.0f)); + addKey(pos,osgGA::GUIEventAdapter::KEY_Backslash,"\\",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Z,"Z",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_X,"X",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_C,"C",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_V,"V",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_B,"B",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_N,"N",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_M,"M",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Comma,",",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Period,".",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Slash,"/",1.0f,1.0f); addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_R,"Shift",2.0f,0.5f); pos.x() = 0.0f; pos.z() += 1.0f; addKey(pos,osgGA::GUIEventAdapter::KEY_Caps_Lock,"Caps",2.0f,0.5f); - addKey('A',addKey(pos,'a',"A",1.0f,1.0f)); - addKey('S',addKey(pos,'s',"S",1.0f,1.0f)); - addKey('D',addKey(pos,'d',"D",1.0f,1.0f)); - addKey('F',addKey(pos,'f',"F",1.0f,1.0f)); - addKey('G',addKey(pos,'g',"G",1.0f,1.0f)); - addKey('H',addKey(pos,'h',"H",1.0f,1.0f)); - addKey('J',addKey(pos,'j',"J",1.0f,1.0f)); - addKey('K',addKey(pos,'k',"K",1.0f,1.0f)); - addKey('L',addKey(pos,'l',"L",1.0f,1.0f)); - addKey(':',addKey(pos,';',";",1.0f,1.0f)); - addKey('@',addKey(pos,'\'',"'",1.0f,1.0f)); - addKey('~',addKey(pos,'#',"#",1.0f,1.0f)); + addKey(pos,osgGA::GUIEventAdapter::KEY_A,"A",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_S,"S",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_D,"D",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_F,"F",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_G,"G",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_H,"H",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_J,"J",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_K,"K",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_L,"L",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Semicolon,";",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Quote,"'",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Hash,"#",1.0f,1.0f); addKey(pos,osgGA::GUIEventAdapter::KEY_Return,"Return",4.0f,0.5f); pos.x() = 0.0f; pos.z() += 1.0f; addKey(pos,osgGA::GUIEventAdapter::KEY_Tab,"Tab",2.0f,0.5f); - addKey('Q',addKey(pos,'q',"Q",1.0f,1.0f)); - addKey('W',addKey(pos,'w',"W",1.0f,1.0f)); - addKey('E',addKey(pos,'e',"E",1.0f,1.0f)); - addKey('R',addKey(pos,'r',"R",1.0f,1.0f)); - addKey('T',addKey(pos,'t',"T",1.0f,1.0f)); - addKey('Y',addKey(pos,'y',"Y",1.0f,1.0f)); - addKey('U',addKey(pos,'u',"U",1.0f,1.0f)); - addKey('I',addKey(pos,'i',"I",1.0f,1.0f)); - addKey('O',addKey(pos,'o',"O",1.0f,1.0f)); - addKey('P',addKey(pos,'p',"P",1.0f,1.0f)); - addKey('{',addKey(pos,'[',"[",1.0f,1.0f)); - addKey('}',addKey(pos,']',"]",1.0f,1.0f)); + addKey(pos,osgGA::GUIEventAdapter::KEY_Q,"Q",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_W,"W",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_E,"E",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_R,"R",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_T,"T",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Y,"Y",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_U,"U",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_I,"I",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_O,"O",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_P,"P",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Leftbracket,"[",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Rightbracket,"]",1.0f,1.0f); pos.x() = 0.0f; pos.z() += 1.0f; - addKey(pos,'`',"`",1.0f,1.0f); - addKey(pos,'1',"1",1.0f,1.0f); - addKey(pos,'2',"2",1.0f,1.0f); - addKey(pos,'3',"3",1.0f,1.0f); - addKey(pos,'4',"4",1.0f,1.0f); - addKey(pos,'5',"5",1.0f,1.0f); - addKey(pos,'6',"6",1.0f,1.0f); - addKey(pos,'7',"7",1.0f,1.0f); - addKey(pos,'8',"8",1.0f,1.0f); - addKey(pos,'9',"9",1.0f,1.0f); - addKey(pos,'0',"0",1.0f,1.0f); - addKey(pos,'-',"-",1.0f,1.0f); - addKey(pos,'=',"=",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Backquote,"`",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_1,"1",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_2,"2",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_3,"3",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_4,"4",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_5,"5",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_6,"6",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_7,"7",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_8,"8",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_9,"9",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_0,"0",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Minus,"-",1.0f,1.0f); + addKey(pos,osgGA::GUIEventAdapter::KEY_Equals,"=",1.0f,1.0f); addKey(pos,osgGA::GUIEventAdapter::KEY_BackSpace,"Backspace",3.0f,0.5f); pos.x() = 0.0f; @@ -405,12 +398,12 @@ public: { case(osgGA::GUIEventAdapter::KEYDOWN): { - _keyboardModel->keyChange(ea.getKey(),1); + _keyboardModel->keyChange(ea.getKey(), ea.getUnmodifiedKey(),1); return true; } case(osgGA::GUIEventAdapter::KEYUP): { - _keyboardModel->keyChange(ea.getKey(),0); + _keyboardModel->keyChange(ea.getKey(), ea.getUnmodifiedKey(),0); return true; } diff --git a/include/osgGA/EventQueue b/include/osgGA/EventQueue index b88427a40..1b518aa2b 100644 --- a/include/osgGA/EventQueue +++ b/include/osgGA/EventQueue @@ -146,17 +146,17 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced /** Method for adapting keyboard press events. Note, special keys such as Ctrl/Function keys should be adapted to GUIEventAdapter::KeySymbol mappings.*/ - void keyPress(int key) { keyPress(key, getTime()); } + void keyPress(int key, int unmodifiedKey = 0) { keyPress(key, getTime(), unmodifiedKey); } /** Method for adapting keyboard press events. Note, special keys such as Ctrl/Function keys should be adapted to GUIEventAdapter::KeySymbol mappings, with specified time.*/ - void keyPress(int key, double time); + void keyPress(int key, double time, int unmodifiedKey = 0); /** Method for adapting keyboard press events. Note, special keys such as Ctrl/Function keys should be adapted to GUIEventAdapter::KeySymbol mappings.*/ - void keyRelease(int key) { keyRelease(key, getTime()); } + void keyRelease(int key, int unmodifiedKey = 0) { keyRelease(key, getTime(), unmodifiedKey); } /** Method for adapting keyboard press events. Note, special keys such as Ctrl/Function keys should be adapted to GUIEventAdapter::KeySymbol mappings, with specified time.*/ - void keyRelease(int key, double time); + void keyRelease(int key, double time, int unmodifiedKey = 0); GUIEventAdapter* touchBegan(unsigned int id, GUIEventAdapter::TouchPhase phase, float x, float y, double time); GUIEventAdapter* touchBegan(unsigned int id, GUIEventAdapter::TouchPhase phase, float x, float y) { diff --git a/include/osgGA/GUIEventAdapter b/include/osgGA/GUIEventAdapter index e6867ea6a..0c1613e94 100644 --- a/include/osgGA/GUIEventAdapter +++ b/include/osgGA/GUIEventAdapter @@ -58,7 +58,72 @@ public: enum KeySymbol { KEY_Space = 0x20, - + + KEY_0 = '0', + 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_A = 'a', + KEY_B = 'b', + KEY_C = 'c', + KEY_D = 'd', + KEY_E = 'e', + KEY_F = 'f', + KEY_G = 'g', + KEY_H = 'h', + KEY_I = 'i', + KEY_J = 'j', + KEY_K = 'k', + KEY_L = 'l', + KEY_M = 'm', + KEY_N = 'n', + KEY_O = 'o', + KEY_P = 'p', + KEY_Q = 'q', + KEY_R = 'r', + KEY_S = 's', + KEY_T = 't', + KEY_U = 'u', + KEY_V = 'v', + KEY_W = 'w', + KEY_X = 'x', + KEY_Y = 'y', + KEY_Z = 'z', + + KEY_Exclaim = 0x21, + KEY_Quotedbl = 0x22, + KEY_Hash = 0x23, + KEY_Dollar = 0x24, + KEY_Ampersand = 0x26, + KEY_Quote = 0x27, + KEY_Leftparen = 0x28, + KEY_Rightparen = 0x29, + KEY_Asterisk = 0x2A, + KEY_Plus = 0x2B, + KEY_Comma = 0x2C, + KEY_Minus = 0x2D, + KEY_Period = 0x2E, + KEY_Slash = 0x2F, + KEY_Colon = 0x3A, + KEY_Semicolon = 0x3B, + KEY_Less = 0x3C, + KEY_Equals = 0x3D, + KEY_Greater = 0x3E, + KEY_Question = 0x3F, + KEY_At = 0x40, + KEY_Leftbracket = 0x5B, + KEY_Backslash = 0x5C, + KEY_Rightbracket = 0x5D, + KEY_Caret = 0x5E, + KEY_Underscore = 0x5F, + KEY_Backquote = 0x60, + KEY_BackSpace = 0xFF08, /* back space, back char */ KEY_Tab = 0xFF09, KEY_Linefeed = 0xFF0A, /* Linefeed, LF */ @@ -374,6 +439,12 @@ public: /** get key pressed, return -1 if inappropriate for this GUIEventAdapter. */ virtual int getKey() const { return _key; } + /** set virtual key pressed. */ + void setUnmodifiedKey(int key) { _unmodifiedKey = key; } + + /** get virtual key pressed. */ + int getUnmodifiedKey() const { return _unmodifiedKey; } + /** set button pressed/released.*/ void setButton(int button) { _button = button; } @@ -519,6 +590,7 @@ public: int _windowWidth; int _windowHeight; int _key; + int _unmodifiedKey; int _button; float _Xmin,_Xmax; float _Ymin,_Ymax; diff --git a/include/osgViewer/api/Win32/GraphicsWindowWin32 b/include/osgViewer/api/Win32/GraphicsWindowWin32 index e359bd940..b10790958 100644 --- a/include/osgViewer/api/Win32/GraphicsWindowWin32 +++ b/include/osgViewer/api/Win32/GraphicsWindowWin32 @@ -135,7 +135,7 @@ class OSGVIEWER_EXPORT GraphicsWindowWin32 : public osgViewer::GraphicsWindow, p bool setPixelFormat(); - void adaptKey( WPARAM wParam, LPARAM lParam, int& keySymbol, unsigned int& modifierMask ); + void adaptKey( WPARAM wParam, LPARAM lParam, int& keySymbol, unsigned int& modifierMask, int& unmodifiedKeySymbol ); void transformMouseXY(float& x, float& y); @@ -178,7 +178,7 @@ class OSGVIEWER_EXPORT GraphicsWindowWin32 : public osgViewer::GraphicsWindow, p std::map _mouseCursorMap; - std::map _keyMap; + std::map, bool> _keyMap; bool _applyWorkaroundForMultimonitorMultithreadNVidiaWin32Issues; }; diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index f580cd41a..47593e361 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -163,7 +163,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub void transformMouseXY(float& x, float& y); - void adaptKey(XKeyEvent& keyevent, int& keySymbol); + void adaptKey(XKeyEvent& keyevent, int& keySymbol, int& unmodifiedKeySymbol); void forceKey(int key, double time, bool state); void rescanModifierMapping(); void getModifierMap(char* keymap) const; diff --git a/src/osgGA/EventQueue.cpp b/src/osgGA/EventQueue.cpp index c2dfd6710..7e61f4907 100644 --- a/src/osgGA/EventQueue.cpp +++ b/src/osgGA/EventQueue.cpp @@ -274,7 +274,7 @@ void EventQueue::mouseButtonRelease(float x, float y, unsigned int button, doubl addEvent(event); } -void EventQueue::keyPress(int key, double time) +void EventQueue::keyPress(int key, double time, int unmodifiedKey) { switch(key) { @@ -312,12 +312,13 @@ void EventQueue::keyPress(int key, double time) GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState); event->setEventType(GUIEventAdapter::KEYDOWN); event->setKey(key); + event->setUnmodifiedKey(unmodifiedKey); event->setTime(time); addEvent(event); } -void EventQueue::keyRelease(int key, double time) +void EventQueue::keyRelease(int key, double time, int unmodifiedKey) { switch(key) { @@ -339,6 +340,7 @@ void EventQueue::keyRelease(int key, double time) GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState); event->setEventType(GUIEventAdapter::KEYUP); event->setKey(key); + event->setUnmodifiedKey(unmodifiedKey); event->setTime(time); addEvent(event); diff --git a/src/osgGA/GUIEventAdapter.cpp b/src/osgGA/GUIEventAdapter.cpp index 6697e8d53..2b51cf04c 100644 --- a/src/osgGA/GUIEventAdapter.cpp +++ b/src/osgGA/GUIEventAdapter.cpp @@ -31,6 +31,7 @@ GUIEventAdapter::GUIEventAdapter(): _windowWidth(1280), _windowHeight(1024), _key(0), + _unmodifiedKey(0), _button(0), _Xmin(-1.0), _Xmax(1.0), @@ -57,6 +58,7 @@ GUIEventAdapter::GUIEventAdapter(const GUIEventAdapter& rhs,const osg::CopyOp& c _windowWidth(rhs._windowWidth), _windowHeight(rhs._windowHeight), _key(rhs._key), + _unmodifiedKey(rhs._unmodifiedKey), _button(rhs._button), _Xmin(rhs._Xmin), _Xmax(rhs._Xmax), diff --git a/src/osgViewer/GraphicsWindowWin32.cpp b/src/osgViewer/GraphicsWindowWin32.cpp index 62aba011f..ea1941dba 100644 --- a/src/osgViewer/GraphicsWindowWin32.cpp +++ b/src/osgViewer/GraphicsWindowWin32.cpp @@ -401,62 +401,62 @@ class Win32KeyboardMap _keymap[VK_F10 ] = osgGA::GUIEventAdapter::KEY_F10; _keymap[VK_F11 ] = osgGA::GUIEventAdapter::KEY_F11; _keymap[VK_F12 ] = osgGA::GUIEventAdapter::KEY_F12; - _keymap[0xc0 ] = '`'; - _keymap['0' ] = '0'; - _keymap['1' ] = '1'; - _keymap['2' ] = '2'; - _keymap['3' ] = '3'; - _keymap['4' ] = '4'; - _keymap['5' ] = '5'; - _keymap['6' ] = '6'; - _keymap['7' ] = '7'; - _keymap['8' ] = '8'; - _keymap['9' ] = '9'; - _keymap[0xbd ] = '-'; - _keymap[0xbb ] = '='; + _keymap[0xc0 ] = osgGA::GUIEventAdapter::KEY_Backquote; + _keymap['0' ] = osgGA::GUIEventAdapter::KEY_0; + _keymap['1' ] = osgGA::GUIEventAdapter::KEY_1; + _keymap['2' ] = osgGA::GUIEventAdapter::KEY_2; + _keymap['3' ] = osgGA::GUIEventAdapter::KEY_3; + _keymap['4' ] = osgGA::GUIEventAdapter::KEY_4; + _keymap['5' ] = osgGA::GUIEventAdapter::KEY_5; + _keymap['6' ] = osgGA::GUIEventAdapter::KEY_6; + _keymap['7' ] = osgGA::GUIEventAdapter::KEY_7; + _keymap['8' ] = osgGA::GUIEventAdapter::KEY_8; + _keymap['9' ] = osgGA::GUIEventAdapter::KEY_9; + _keymap[0xbd ] = osgGA::GUIEventAdapter::KEY_Minus; + _keymap[0xbb ] = osgGA::GUIEventAdapter::KEY_Equals; _keymap[VK_BACK ] = osgGA::GUIEventAdapter::KEY_BackSpace; _keymap[VK_TAB ] = osgGA::GUIEventAdapter::KEY_Tab; - _keymap['A' ] = 'A'; - _keymap['B' ] = 'B'; - _keymap['C' ] = 'C'; - _keymap['D' ] = 'D'; - _keymap['E' ] = 'E'; - _keymap['F' ] = 'F'; - _keymap['G' ] = 'G'; - _keymap['H' ] = 'H'; - _keymap['I' ] = 'I'; - _keymap['J' ] = 'J'; - _keymap['K' ] = 'K'; - _keymap['L' ] = 'L'; - _keymap['M' ] = 'M'; - _keymap['N' ] = 'N'; - _keymap['O' ] = 'O'; - _keymap['P' ] = 'P'; - _keymap['Q' ] = 'Q'; - _keymap['R' ] = 'R'; - _keymap['S' ] = 'S'; - _keymap['T' ] = 'T'; - _keymap['U' ] = 'U'; - _keymap['V' ] = 'V'; - _keymap['W' ] = 'W'; - _keymap['X' ] = 'X'; - _keymap['Y' ] = 'Y'; - _keymap['Z' ] = 'Z'; - _keymap[0xdb ] = '['; - _keymap[0xdd ] = ']'; - _keymap[0xdc ] = '\\'; + _keymap['A' ] = osgGA::GUIEventAdapter::KEY_A; + _keymap['B' ] = osgGA::GUIEventAdapter::KEY_B; + _keymap['C' ] = osgGA::GUIEventAdapter::KEY_C; + _keymap['D' ] = osgGA::GUIEventAdapter::KEY_D; + _keymap['E' ] = osgGA::GUIEventAdapter::KEY_E; + _keymap['F' ] = osgGA::GUIEventAdapter::KEY_F; + _keymap['G' ] = osgGA::GUIEventAdapter::KEY_G; + _keymap['H' ] = osgGA::GUIEventAdapter::KEY_H; + _keymap['I' ] = osgGA::GUIEventAdapter::KEY_I; + _keymap['J' ] = osgGA::GUIEventAdapter::KEY_J; + _keymap['K' ] = osgGA::GUIEventAdapter::KEY_K; + _keymap['L' ] = osgGA::GUIEventAdapter::KEY_L; + _keymap['M' ] = osgGA::GUIEventAdapter::KEY_M; + _keymap['N' ] = osgGA::GUIEventAdapter::KEY_N; + _keymap['O' ] = osgGA::GUIEventAdapter::KEY_O; + _keymap['P' ] = osgGA::GUIEventAdapter::KEY_P; + _keymap['Q' ] = osgGA::GUIEventAdapter::KEY_Q; + _keymap['R' ] = osgGA::GUIEventAdapter::KEY_R; + _keymap['S' ] = osgGA::GUIEventAdapter::KEY_S; + _keymap['T' ] = osgGA::GUIEventAdapter::KEY_T; + _keymap['U' ] = osgGA::GUIEventAdapter::KEY_U; + _keymap['V' ] = osgGA::GUIEventAdapter::KEY_V; + _keymap['W' ] = osgGA::GUIEventAdapter::KEY_W; + _keymap['X' ] = osgGA::GUIEventAdapter::KEY_X; + _keymap['Y' ] = osgGA::GUIEventAdapter::KEY_Y; + _keymap['Z' ] = osgGA::GUIEventAdapter::KEY_Z; + _keymap[0xdb ] = osgGA::GUIEventAdapter::KEY_Leftbracket; + _keymap[0xdd ] = osgGA::GUIEventAdapter::KEY_Rightbracket; + _keymap[0xdc ] = osgGA::GUIEventAdapter::KEY_Backslash; _keymap[VK_CAPITAL ] = osgGA::GUIEventAdapter::KEY_Caps_Lock; - _keymap[0xba ] = ';'; - _keymap[0xde ] = '\''; + _keymap[0xba ] = osgGA::GUIEventAdapter::KEY_Semicolon; + _keymap[0xde ] = osgGA::GUIEventAdapter::KEY_Quote; _keymap[VK_RETURN ] = osgGA::GUIEventAdapter::KEY_Return; _keymap[VK_LSHIFT ] = osgGA::GUIEventAdapter::KEY_Shift_L; - _keymap[0xbc ] = ','; - _keymap[0xbe ] = '.'; - _keymap[0xbf ] = '/'; + _keymap[0xbc ] = osgGA::GUIEventAdapter::KEY_Comma; + _keymap[0xbe ] = osgGA::GUIEventAdapter::KEY_Period; + _keymap[0xbf ] = osgGA::GUIEventAdapter::KEY_Slash; _keymap[VK_RSHIFT ] = osgGA::GUIEventAdapter::KEY_Shift_R; _keymap[VK_LCONTROL ] = osgGA::GUIEventAdapter::KEY_Control_L; _keymap[VK_LWIN ] = osgGA::GUIEventAdapter::KEY_Super_L; - _keymap[VK_SPACE ] = ' '; + _keymap[VK_SPACE ] = osgGA::GUIEventAdapter::KEY_Space; _keymap[VK_LMENU ] = osgGA::GUIEventAdapter::KEY_Alt_L; _keymap[VK_RMENU ] = osgGA::GUIEventAdapter::KEY_Alt_R; _keymap[VK_RWIN ] = osgGA::GUIEventAdapter::KEY_Super_R; @@ -2237,7 +2237,7 @@ void GraphicsWindowWin32::setSyncToVBlank( bool on ) #endif } -void GraphicsWindowWin32::adaptKey( WPARAM wParam, LPARAM lParam, int& keySymbol, unsigned int& modifierMask ) +void GraphicsWindowWin32::adaptKey( WPARAM wParam, LPARAM lParam, int& keySymbol, unsigned int& modifierMask, int& unmodifiedKeySymbol) { modifierMask = 0; @@ -2303,7 +2303,10 @@ void GraphicsWindowWin32::adaptKey( WPARAM wParam, LPARAM lParam, int& keySymbol { keySymbol = osgGA::GUIEventAdapter::KEY_KP_Enter; } - else if ((keySymbol & 0xff00)==0) + + unmodifiedKeySymbol = keySymbol; + + if ((keySymbol & 0xff00)==0) { char asciiKey[2]; int numChars = ::ToAscii(wParam, (lParam>>16)&0xff, keyState, reinterpret_cast(asciiKey), 0); @@ -2479,11 +2482,12 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W { int keySymbol = 0; + int unmodifiedKeySymbol = 0; unsigned int modifierMask = 0; - adaptKey(wParam, lParam, keySymbol, modifierMask); - _keyMap[keySymbol] = true; + adaptKey(wParam, lParam, keySymbol, modifierMask, unmodifiedKeySymbol); + _keyMap[std::make_pair(keySymbol,unmodifiedKeySymbol)] = true; //getEventQueue()->getCurrentEventState()->setModKeyMask(modifierMask); - getEventQueue()->keyPress(keySymbol, eventTime); + getEventQueue()->keyPress(keySymbol, eventTime, unmodifiedKeySymbol); } break; @@ -2494,11 +2498,12 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W { int keySymbol = 0; + int unmodifiedKeySymbol = 0; unsigned int modifierMask = 0; - adaptKey(wParam, lParam, keySymbol, modifierMask); - _keyMap[keySymbol] = false; + adaptKey(wParam, lParam, keySymbol, modifierMask, unmodifiedKeySymbol); + _keyMap[std::make_pair(keySymbol, unmodifiedKeySymbol)] = false; //getEventQueue()->getCurrentEventState()->setModKeyMask(modifierMask); - getEventQueue()->keyRelease(keySymbol, eventTime); + getEventQueue()->keyRelease(keySymbol, eventTime, unmodifiedKeySymbol); } break; @@ -2538,12 +2543,12 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W /////////////////// // Release all keys that were pressed when the window lost focus. - for (std::map::iterator key = _keyMap.begin(); + for (std::map, bool>::iterator key = _keyMap.begin(); key != _keyMap.end(); ++key) { if (key->second) { - getEventQueue()->keyRelease(key->first); + getEventQueue()->keyRelease(key->first.first, key->first.second); key->second = false; } } diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index 10bd3cfb6..7ce1c8c84 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -1414,9 +1414,10 @@ void GraphicsWindowX11::checkEvents() _modifierState = ev.xkey.state; keyMapSetKey(_keyMap, ev.xkey.keycode); int keySymbol = 0; - adaptKey(ev.xkey, keySymbol); + int unmodifiedKeySymbol = 0; + adaptKey(ev.xkey, keySymbol, unmodifiedKeySymbol); - getEventQueue()->keyPress(keySymbol, eventTime); + getEventQueue()->keyPress(keySymbol, eventTime, unmodifiedKeySymbol); break; } @@ -1445,9 +1446,10 @@ void GraphicsWindowX11::checkEvents() _modifierState = ev.xkey.state; keyMapClearKey(_keyMap, ev.xkey.keycode); int keySymbol = 0; - adaptKey(ev.xkey, keySymbol); + int unmodifiedKeySymbol = 0; + adaptKey(ev.xkey, keySymbol, unmodifiedKeySymbol); - getEventQueue()->keyRelease(keySymbol, eventTime); + getEventQueue()->keyRelease(keySymbol, eventTime, unmodifiedKeySymbol); break; } @@ -1518,7 +1520,7 @@ void GraphicsWindowX11::transformMouseXY(float& x, float& y) } } -void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol) +void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, int& unmodifiedKeySymbol) { unsigned char buffer_return[32]; int bytes_buffer = 32; @@ -1530,6 +1532,8 @@ void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol) { keySymbol = buffer_return[0]; } + + unmodifiedKeySymbol = XKeycodeToKeysym(keyevent.display, keyevent.keycode, 0); } // Function to inject artificial key presses/releases. @@ -1553,18 +1557,19 @@ void GraphicsWindowX11::forceKey(int key, double time, bool state) event.same_screen = True; int keySymbol = 0; + int unmodifiedKeySymbol = 0; if (state) { event.type = KeyPress; - adaptKey(event, keySymbol); - getEventQueue()->keyPress(keySymbol, time); + adaptKey(event, keySymbol, unmodifiedKeySymbol); + getEventQueue()->keyPress(keySymbol, time, unmodifiedKeySymbol); keyMapSetKey(_keyMap, key); } else { event.type = KeyRelease; - adaptKey(event, keySymbol); - getEventQueue()->keyRelease(keySymbol, time); + adaptKey(event, keySymbol, unmodifiedKeySymbol); + getEventQueue()->keyRelease(keySymbol, time, unmodifiedKeySymbol); keyMapClearKey(_keyMap, key); } }