///////////////////////////////////////////////////////////////////////////// // Name: keyboardcode.cpp // Purpose: // Author: Cesar Mauri Loba (cesar at crea-si dot com) // Modified by: // Created: 28/09/2010 // Copyright: (C) 2008 Cesar Mauri Loba - CREA Software Systems // // 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 3 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 // MERCHANTABILITY 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, see . ///////////////////////////////////////////////////////////////////////////// #include "keyboardcode.h" #include #include #include #if defined(WIN32) #define _WIN32_WINNT 0x0500 #include #else #include #include #define XK_MISCELLANY #include #include #endif #include "simplelog.h" wxString KeyboardCode::GetName() const { #if defined(__WXGTK__) return wxString(XKeysymToString((KeySym) m_nativeKeyCode), wxConvLocal); #else UINT scanCode= ::MapVirtualKeyW(m_nativeKeyCode, MAPVK_VK_TO_VSC); scanCode= scanCode << 16; char buffer[100] = { 0 }; ::GetKeyNameTextA (scanCode, buffer, sizeof(buffer)); buffer[sizeof(buffer)-1]= 0; return wxString(buffer, wxConvLocal); #endif } void KeyboardCode::SendKey() { #if defined(__WXGTK__) KeyCode k= XKeysymToKeycode((Display *) wxGetDisplay(), (KeySym) m_nativeKeyCode); XTestFakeKeyEvent((Display *) wxGetDisplay(), k, true, 0); XTestFakeKeyEvent((Display *) wxGetDisplay(), k, false, 0); #else // It seems that, to work properly, SendInput() need both the virtual-key // code and the scan code. Note that KEYEVENTF_EXTENDEDKEY flag is not used. UINT scanCode = ::MapVirtualKey(m_nativeKeyCode, MAPVK_VK_TO_VSC); INPUT ip; memset(&ip, 0, sizeof(ip)); ip.type= INPUT_KEYBOARD; ip.ki.wVk= m_nativeKeyCode; ip.ki.wScan= (WORD) scanCode; // Key press SendInput(1, &ip, sizeof(ip)); // Key release ip.ki.dwFlags|= KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(ip)); #endif } KeyboardCode KeyboardCode::ReadKeyCode() { #if defined(__WXGTK__) char keys_return[32]; XQueryKeymap(((Display *) wxGetDisplay()), keys_return); // Given the keyboard state bitmap, return the scan code // of the key is pressed down // BUG: when multiple keys are pressed simultaneously // the scan code is undefined unsigned int kc = 0; for(int i=0; i<32; i++) { unsigned char keys = (unsigned char) keys_return[i]; if (keys > 0) { switch (keys) { case 1: kc = 0; break; case 2: kc = 1; break; case 4: kc = 2; break; case 8: kc = 3; break; case 16: kc = 4; break; case 32: kc = 5; break; case 64: kc = 6; break; case 128: kc = 7; break; } kc += 8 * i; } } return FromScanCode (kc); #else // NOT implemented for Windows. This method is used to poll // the keyboard to implement hotkeys. On Windows RegisterHotKey is used assert(0); return KeyboardCode(); #endif } KeyboardCode KeyboardCode::FromChar (char c) { #if defined(__WXGTK__) // Try to translate the one char string to a valid KeySym. If no // suitable conversion is available, XStringToKeysym returns // NoSymbol which equals to 0. char str[2]= { c, '\0'}; KeySym ks = XStringToKeysym(str); return KeyboardCode (static_cast(ks)); #else // VkKeyScan translates a character to the corresponding virtual-key // code and shift state for the current keyboard. If the function // succeeds, the low-order byte of the return value contains the // virtual-key code and the high-order byte contains the shift state short vkey = VkKeyScanA(c); // Clean shift state return KeyboardCode(vkey & 0xFF); #endif } // Given an scan code returns the corresponding CKeyboardCode object KeyboardCode KeyboardCode::FromScanCode (int scanCode) { #if defined(__WXGTK__) KeySym ks= XkbKeycodeToKeysym( static_cast(wxGetDisplay()), static_cast(scanCode), 0, 0); return KeyboardCode(static_cast(ks)); #else UINT vKCode= ::MapVirtualKey(scanCode, MAPVK_VSC_TO_VK_EX); assert (vKCode< 0xFFFF); return KeyboardCode(vKCode); #endif } // Given an wxKeyCode code returns the corresponding CKeyboardCode object KeyboardCode KeyboardCode::FromWXK (wxKeyCode kc) { // If the value is between 0..255 corresponds to the characters of the // current locale, in particular the 32..127 subrange is for the ASCII // symbols. Therefore, try to translate as such. if (kc>= 0 && kc <= 255) { return FromChar(static_cast(kc)); } // Otherwise the translation is platform dependent #if defined(__WXGTK__) switch (kc) { case WXK_BACK: return KeyboardCode(XK_BackSpace); case WXK_TAB: return KeyboardCode(XK_Tab); case WXK_RETURN: return KeyboardCode(XK_Return); case WXK_ESCAPE: return KeyboardCode(XK_Escape); case WXK_DELETE: return KeyboardCode(XK_Delete); case WXK_CLEAR: return KeyboardCode(XK_Clear); case WXK_SHIFT: return KeyboardCode(XK_Shift_L); case WXK_ALT: return KeyboardCode(XK_Alt_L); case WXK_CONTROL: return KeyboardCode(XK_Control_L); case WXK_MENU: return KeyboardCode(XK_Menu); case WXK_PAUSE: return KeyboardCode(XK_Pause); case WXK_END: return KeyboardCode(XK_End); case WXK_HOME: return KeyboardCode(XK_Home); case WXK_LEFT: return KeyboardCode(XK_Left); case WXK_UP: return KeyboardCode(XK_Up); case WXK_RIGHT: return KeyboardCode(XK_Right); case WXK_DOWN: return KeyboardCode(XK_Down); case WXK_SELECT: return KeyboardCode(XK_Select); case WXK_PRINT: return KeyboardCode(XK_Print); case WXK_EXECUTE: return KeyboardCode(XK_Execute); case WXK_SNAPSHOT: return KeyboardCode(XK_Print); case WXK_INSERT: return KeyboardCode(XK_Insert); case WXK_HELP: return KeyboardCode(XK_Help); case WXK_NUMPAD0: return KeyboardCode(XK_KP_0); case WXK_NUMPAD1: return KeyboardCode(XK_KP_1); case WXK_NUMPAD2: return KeyboardCode(XK_KP_2); case WXK_NUMPAD3: return KeyboardCode(XK_KP_3); case WXK_NUMPAD4: return KeyboardCode(XK_KP_4); case WXK_NUMPAD5: return KeyboardCode(XK_KP_5); case WXK_NUMPAD6: return KeyboardCode(XK_KP_6); case WXK_NUMPAD7: return KeyboardCode(XK_KP_7); case WXK_NUMPAD8: return KeyboardCode(XK_KP_8); case WXK_NUMPAD9: return KeyboardCode(XK_KP_9); case WXK_MULTIPLY: return KeyboardCode(XK_KP_Multiply); case WXK_ADD: return KeyboardCode(XK_KP_Add); case WXK_SEPARATOR: return KeyboardCode(XK_KP_Separator); case WXK_SUBTRACT: return KeyboardCode(XK_KP_Subtract); case WXK_DECIMAL: return KeyboardCode(XK_KP_Decimal); case WXK_DIVIDE: return KeyboardCode(XK_KP_Divide); case WXK_F1: return KeyboardCode(XK_F1); case WXK_F2: return KeyboardCode(XK_F2); case WXK_F3: return KeyboardCode(XK_F3); case WXK_F4: return KeyboardCode(XK_F4); case WXK_F5: return KeyboardCode(XK_F5); case WXK_F6: return KeyboardCode(XK_F6); case WXK_F7: return KeyboardCode(XK_F7); case WXK_F8: return KeyboardCode(XK_F8); case WXK_F9: return KeyboardCode(XK_F9); case WXK_F10: return KeyboardCode(XK_F10); case WXK_F11: return KeyboardCode(XK_F11); case WXK_F12: return KeyboardCode(XK_F12); case WXK_F13: return KeyboardCode(XK_F13); case WXK_F14: return KeyboardCode(XK_F14); case WXK_F15: return KeyboardCode(XK_F15); case WXK_F16: return KeyboardCode(XK_F16); case WXK_F17: return KeyboardCode(XK_F17); case WXK_F18: return KeyboardCode(XK_F18); case WXK_F19: return KeyboardCode(XK_F19); case WXK_F20: return KeyboardCode(XK_F20); case WXK_F21: return KeyboardCode(XK_F21); case WXK_F22: return KeyboardCode(XK_F22); case WXK_F23: return KeyboardCode(XK_F23); case WXK_F24: return KeyboardCode(XK_F24); case WXK_NUMLOCK: return KeyboardCode(XK_Num_Lock); case WXK_SCROLL: return KeyboardCode(XK_Scroll_Lock); case WXK_PAGEUP: return KeyboardCode(XK_Page_Up); case WXK_PAGEDOWN: return KeyboardCode(XK_Page_Down); case WXK_NUMPAD_SPACE: return KeyboardCode(XK_KP_Space); case WXK_NUMPAD_TAB: return KeyboardCode(XK_KP_Tab); case WXK_NUMPAD_ENTER: return KeyboardCode(XK_KP_Enter); case WXK_NUMPAD_F1: return KeyboardCode(XK_KP_F1); case WXK_NUMPAD_F2: return KeyboardCode(XK_KP_F2); case WXK_NUMPAD_F3: return KeyboardCode(XK_KP_F3); case WXK_NUMPAD_F4: return KeyboardCode(XK_KP_F4); case WXK_NUMPAD_HOME: return KeyboardCode(XK_KP_Home); case WXK_NUMPAD_LEFT: return KeyboardCode(XK_KP_Left); case WXK_NUMPAD_UP: return KeyboardCode(XK_KP_Up); case WXK_NUMPAD_RIGHT: return KeyboardCode(XK_KP_Right); case WXK_NUMPAD_DOWN: return KeyboardCode(XK_KP_Down); case WXK_NUMPAD_PAGEUP: return KeyboardCode(XK_KP_Page_Up); case WXK_NUMPAD_PAGEDOWN: return KeyboardCode(XK_KP_Page_Down); case WXK_NUMPAD_END: return KeyboardCode(XK_KP_End); case WXK_NUMPAD_BEGIN: return KeyboardCode(XK_KP_Begin); case WXK_NUMPAD_INSERT: return KeyboardCode(XK_KP_Insert); case WXK_NUMPAD_DELETE: return KeyboardCode(XK_KP_Delete); case WXK_NUMPAD_EQUAL: return KeyboardCode(XK_KP_Equal); case WXK_NUMPAD_MULTIPLY: return KeyboardCode(XK_KP_Multiply); case WXK_NUMPAD_ADD: return KeyboardCode(XK_KP_Add); case WXK_NUMPAD_SEPARATOR: return KeyboardCode(XK_KP_Separator); case WXK_NUMPAD_SUBTRACT: return KeyboardCode(XK_KP_Subtract); case WXK_NUMPAD_DECIMAL: return KeyboardCode(XK_KP_Decimal); case WXK_NUMPAD_DIVIDE: return KeyboardCode(XK_KP_Divide); // the following key codes are only generated under Windows currently case WXK_WINDOWS_LEFT: return KeyboardCode(XK_Super_L); case WXK_WINDOWS_RIGHT: return KeyboardCode(XK_Super_R); case WXK_WINDOWS_MENU: return KeyboardCode(XK_Menu); default: return KeyboardCode(0); } #else switch (kc) { case WXK_BACK: return KeyboardCode(VK_BACK); case WXK_TAB: return KeyboardCode(VK_TAB); case WXK_RETURN: return KeyboardCode(VK_RETURN); case WXK_ESCAPE: return KeyboardCode(VK_ESCAPE); case WXK_DELETE: return KeyboardCode(VK_DELETE); case WXK_CLEAR: return KeyboardCode(VK_CLEAR); case WXK_SHIFT: return KeyboardCode(VK_SHIFT); case WXK_ALT: return KeyboardCode(VK_MENU); case WXK_CONTROL: return KeyboardCode(VK_CONTROL); case WXK_MENU: return KeyboardCode(VK_MENU); case WXK_PAUSE: return KeyboardCode(VK_PAUSE); case WXK_END: return KeyboardCode(VK_END); case WXK_HOME: return KeyboardCode(VK_HOME); case WXK_LEFT: return KeyboardCode(VK_LEFT); case WXK_UP: return KeyboardCode(VK_UP); case WXK_RIGHT: return KeyboardCode(VK_RIGHT); case WXK_DOWN: return KeyboardCode(VK_DOWN); case WXK_SELECT: return KeyboardCode(VK_SELECT); case WXK_PRINT: return KeyboardCode(VK_PRINT); case WXK_EXECUTE: return KeyboardCode(VK_EXECUTE); case WXK_SNAPSHOT: return KeyboardCode(VK_SNAPSHOT); case WXK_INSERT: return KeyboardCode(VK_INSERT); case WXK_HELP: return KeyboardCode(VK_HELP); case WXK_NUMPAD0: return KeyboardCode(VK_NUMPAD0); case WXK_NUMPAD1: return KeyboardCode(VK_NUMPAD1); case WXK_NUMPAD2: return KeyboardCode(VK_NUMPAD2); case WXK_NUMPAD3: return KeyboardCode(VK_NUMPAD3); case WXK_NUMPAD4: return KeyboardCode(VK_NUMPAD4); case WXK_NUMPAD5: return KeyboardCode(VK_NUMPAD5); case WXK_NUMPAD6: return KeyboardCode(VK_NUMPAD6); case WXK_NUMPAD7: return KeyboardCode(VK_NUMPAD7); case WXK_NUMPAD8: return KeyboardCode(VK_NUMPAD8); case WXK_NUMPAD9: return KeyboardCode(VK_NUMPAD9); case WXK_MULTIPLY: return KeyboardCode(VK_MULTIPLY); case WXK_ADD: return KeyboardCode(VK_ADD); case WXK_SEPARATOR: return KeyboardCode(VK_SEPARATOR); case WXK_SUBTRACT: return KeyboardCode(VK_SUBTRACT); case WXK_DECIMAL: return KeyboardCode(VK_DECIMAL); case WXK_DIVIDE: return KeyboardCode(VK_DIVIDE); case WXK_F1: return KeyboardCode(VK_F1); case WXK_F2: return KeyboardCode(VK_F2); case WXK_F3: return KeyboardCode(VK_F3); case WXK_F4: return KeyboardCode(VK_F4); case WXK_F5: return KeyboardCode(VK_F5); case WXK_F6: return KeyboardCode(VK_F6); case WXK_F7: return KeyboardCode(VK_F7); case WXK_F8: return KeyboardCode(VK_F8); case WXK_F9: return KeyboardCode(VK_F9); case WXK_F10: return KeyboardCode(VK_F10); case WXK_F11: return KeyboardCode(VK_F11); case WXK_F12: return KeyboardCode(VK_F12); case WXK_F13: return KeyboardCode(VK_F13); case WXK_F14: return KeyboardCode(VK_F14); case WXK_F15: return KeyboardCode(VK_F15); case WXK_F16: return KeyboardCode(VK_F16); case WXK_F17: return KeyboardCode(VK_F17); case WXK_F18: return KeyboardCode(VK_F18); case WXK_F19: return KeyboardCode(VK_F19); case WXK_F20: return KeyboardCode(VK_F20); case WXK_F21: return KeyboardCode(VK_F21); case WXK_F22: return KeyboardCode(VK_F22); case WXK_F23: return KeyboardCode(VK_F23); case WXK_F24: return KeyboardCode(VK_F24); case WXK_NUMLOCK: return KeyboardCode(VK_NUMLOCK); case WXK_SCROLL: return KeyboardCode(VK_SCROLL); case WXK_PAGEUP: return KeyboardCode(VK_PRIOR); case WXK_PAGEDOWN: return KeyboardCode(VK_NEXT); case WXK_NUMPAD_SPACE: return KeyboardCode(VK_SPACE); case WXK_NUMPAD_TAB: return KeyboardCode(VK_TAB); case WXK_NUMPAD_ENTER: return KeyboardCode(VK_RETURN); case WXK_NUMPAD_F1: return KeyboardCode(VK_F1); case WXK_NUMPAD_F2: return KeyboardCode(VK_F2); case WXK_NUMPAD_F3: return KeyboardCode(VK_F3); case WXK_NUMPAD_F4: return KeyboardCode(VK_F4); case WXK_NUMPAD_HOME: return KeyboardCode(VK_HOME); case WXK_NUMPAD_LEFT: return KeyboardCode(VK_LEFT); case WXK_NUMPAD_UP: return KeyboardCode(VK_UP); case WXK_NUMPAD_RIGHT: return KeyboardCode(VK_RIGHT); case WXK_NUMPAD_DOWN: return KeyboardCode(VK_DOWN); case WXK_NUMPAD_PAGEUP: return KeyboardCode(VK_PRIOR); case WXK_NUMPAD_PAGEDOWN: return KeyboardCode(VK_NEXT); case WXK_NUMPAD_END: return KeyboardCode(VK_END); case WXK_NUMPAD_BEGIN: return KeyboardCode(VK_NUMPAD5); case WXK_NUMPAD_INSERT: return KeyboardCode(VK_INSERT); case WXK_NUMPAD_DELETE: return KeyboardCode(VK_DELETE); case WXK_NUMPAD_MULTIPLY: return KeyboardCode(VK_MULTIPLY); case WXK_NUMPAD_ADD: return KeyboardCode(VK_ADD); case WXK_NUMPAD_SEPARATOR: return KeyboardCode(VK_SEPARATOR); case WXK_NUMPAD_SUBTRACT: return KeyboardCode(VK_SUBTRACT); case WXK_NUMPAD_DECIMAL: return KeyboardCode(VK_DECIMAL); case WXK_NUMPAD_DIVIDE: return KeyboardCode(VK_DIVIDE); // the following key codes are only generated under Windows currently case WXK_WINDOWS_LEFT: return KeyboardCode(VK_LWIN); case WXK_WINDOWS_RIGHT: return KeyboardCode(VK_RWIN); case WXK_WINDOWS_MENU: return KeyboardCode(VK_APPS); case WXK_SPACE: return KeyboardCode(VK_SPACE); case WXK_CANCEL: return KeyboardCode(VK_CANCEL); case WXK_CAPITAL: return KeyboardCode(VK_CAPITAL); default: return KeyboardCode(0); } #endif } #if defined(DEBUG) void KeyboardCode::Dump() const { #if !defined(WIN32) slog_write (SLOG_PRIO_DEBUG, "KeySym: %d, KeyCode: %u Name: %s\n", m_nativeKeyCode, XKeysymToKeycode((Display *) wxGetDisplay(), m_nativeKeyCode), static_cast(GetName().mb_str())); #endif } #endif