///////////////////////////////////////////////////////////////////////////// // Name: ckeyboardcode.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 "ckeyboardcode.h" #include #include #include #if defined(__WXGTK__) #include #include #define XK_MISCELLANY #include #endif #include "simplelog.h" // Make sure that m_virtualKeyCode is wide enough to store a KeySym // On windows it seems that virtual-key codes are 16bit wide, so no problem. #if defined(__WXGTK__) wxCOMPILE_TIME_ASSERT( sizeof(KeySym)== sizeof(unsigned long), KeySymDifferentThanLongError ); wxCOMPILE_TIME_ASSERT( sizeof(KeyCode)<= sizeof(unsigned int), KeyCodeGreaterThanIntError ); #endif // Default constructor. Initializes internal keycode to a invalid value CKeyboardCode::CKeyboardCode() : m_virtualKeyCode(0) { } // Private constructor which initializes to the internal // state given virtual key code or KeySym CKeyboardCode::CKeyboardCode (unsigned long vkCode) { m_virtualKeyCode= vkCode; } const char* CKeyboardCode::GetName() const { #if defined(__WXGTK__) return XKeysymToString((KeySym) m_virtualKeyCode); #else // Still not available for Windows return ""; #endif } void CKeyboardCode::SendKey() { #if defined(__WXGTK__) KeyCode k= XKeysymToKeycode((Display *) wxGetDisplay(), (KeySym) m_virtualKeyCode); XTestFakeKeyEvent((Display *) wxGetDisplay(), k, true, 0); XTestFakeKeyEvent((Display *) wxGetDisplay(), k, false, 0); #else // Still not available for Windows assert(0); #endif } // Reads a keycode from keyboard and returns a CKeyboardCode object CKeyboardCode CKeyboardCode::ReadKeyCode() { #if defined(__WXGTK__) char keys_return[32]; unsigned char keys; unsigned int kc = 0; XQueryKeymap(((Display *) wxGetDisplay()), keys_return); // TODO: implement this correctly for(int i=0; i<32; i++) { 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 // Still not available for Windows assert(0); return CKeyboardCode(); #endif } // Given an scan code returns the corresponding CKeyboardCode object CKeyboardCode CKeyboardCode::FromScanCode (unsigned int scanCode) { #if defined(__WXGTK__) return CKeyboardCode (static_cast (XKeycodeToKeysym( (Display *) wxGetDisplay(), (KeyCode) scanCode, 0))); #else // Still not available for Windows wxUnusedVar(scanCode); assert(false); return CKeyboardCode(); #endif } // Given a platform dependent virtual-key or KeySym returns the // corresponding CKeyboardCode object CKeyboardCode CKeyboardCode::FromVirtualKeyCode (unsigned long vkCode) { return CKeyboardCode (vkCode); } // Given an ASCII code returns the corresponding CKeyboardCode object CKeyboardCode CKeyboardCode::FromASCII (char ascii) { #if defined(__WXGTK__) char c[2]= { ascii, '\0'}; return CKeyboardCode (static_cast(XStringToKeysym(c))); #else // Still not available for Windows assert(0); wxUnusedVar(ascii); return CKeyboardCode(); #endif } void CKeyboardCode::Dump() const { #if !defined(WIN32) slog_write (SLOG_PRIO_DEBUG, "KeySym: %lu KeyCode: %u Name: %s\n", m_virtualKeyCode, XKeysymToKeycode((Display *) wxGetDisplay(), m_virtualKeyCode), GetName()); #endif } // Given an wxKeyCode code returns the corresponding CKeyboardCode object CKeyboardCode CKeyboardCode::FromWXKeyCode (wxKeyCode kc) { #if defined(__WXGTK__) switch (kc) { case WXK_BACK: return CKeyboardCode(XK_BackSpace); case WXK_TAB: return CKeyboardCode(XK_Tab); case WXK_RETURN: return CKeyboardCode(XK_Return); case WXK_ESCAPE: return CKeyboardCode(XK_Escape); case WXK_DELETE: return CKeyboardCode(XK_Delete); case WXK_CLEAR: return CKeyboardCode(XK_Clear); case WXK_SHIFT: return CKeyboardCode(XK_Shift_L); case WXK_ALT: return CKeyboardCode(XK_Alt_L); case WXK_CONTROL: return CKeyboardCode(XK_Control_L); case WXK_MENU: return CKeyboardCode(XK_Menu); case WXK_PAUSE: return CKeyboardCode(XK_Pause); case WXK_END: return CKeyboardCode(XK_End); case WXK_HOME: return CKeyboardCode(XK_Home); case WXK_LEFT: return CKeyboardCode(XK_Left); case WXK_UP: return CKeyboardCode(XK_Up); case WXK_RIGHT: return CKeyboardCode(XK_Right); case WXK_DOWN: return CKeyboardCode(XK_Down); case WXK_SELECT: return CKeyboardCode(XK_Select); case WXK_PRINT: return CKeyboardCode(XK_Print); case WXK_EXECUTE: return CKeyboardCode(XK_Execute); case WXK_SNAPSHOT: return CKeyboardCode(XK_Print); case WXK_INSERT: return CKeyboardCode(XK_Insert); case WXK_HELP: return CKeyboardCode(XK_Help); case WXK_NUMPAD0: return CKeyboardCode(XK_KP_0); case WXK_NUMPAD1: return CKeyboardCode(XK_KP_1); case WXK_NUMPAD2: return CKeyboardCode(XK_KP_2); case WXK_NUMPAD3: return CKeyboardCode(XK_KP_3); case WXK_NUMPAD4: return CKeyboardCode(XK_KP_4); case WXK_NUMPAD5: return CKeyboardCode(XK_KP_5); case WXK_NUMPAD6: return CKeyboardCode(XK_KP_6); case WXK_NUMPAD7: return CKeyboardCode(XK_KP_7); case WXK_NUMPAD8: return CKeyboardCode(XK_KP_8); case WXK_NUMPAD9: return CKeyboardCode(XK_KP_9); case WXK_MULTIPLY: return CKeyboardCode(XK_KP_Multiply); case WXK_ADD: return CKeyboardCode(XK_KP_Add); case WXK_SEPARATOR: return CKeyboardCode(XK_KP_Separator); case WXK_SUBTRACT: return CKeyboardCode(XK_KP_Subtract); case WXK_DECIMAL: return CKeyboardCode(XK_KP_Decimal); case WXK_DIVIDE: return CKeyboardCode(XK_KP_Divide); case WXK_F1: return CKeyboardCode(XK_F1); case WXK_F2: return CKeyboardCode(XK_F2); case WXK_F3: return CKeyboardCode(XK_F3); case WXK_F4: return CKeyboardCode(XK_F4); case WXK_F5: return CKeyboardCode(XK_F5); case WXK_F6: return CKeyboardCode(XK_F6); case WXK_F7: return CKeyboardCode(XK_F7); case WXK_F8: return CKeyboardCode(XK_F8); case WXK_F9: return CKeyboardCode(XK_F9); case WXK_F10: return CKeyboardCode(XK_F10); case WXK_F11: return CKeyboardCode(XK_F11); case WXK_F12: return CKeyboardCode(XK_F12); case WXK_F13: return CKeyboardCode(XK_F13); case WXK_F14: return CKeyboardCode(XK_F14); case WXK_F15: return CKeyboardCode(XK_F15); case WXK_F16: return CKeyboardCode(XK_F16); case WXK_F17: return CKeyboardCode(XK_F17); case WXK_F18: return CKeyboardCode(XK_F18); case WXK_F19: return CKeyboardCode(XK_F19); case WXK_F20: return CKeyboardCode(XK_F20); case WXK_F21: return CKeyboardCode(XK_F21); case WXK_F22: return CKeyboardCode(XK_F22); case WXK_F23: return CKeyboardCode(XK_F23); case WXK_F24: return CKeyboardCode(XK_F24); case WXK_NUMLOCK: return CKeyboardCode(XK_Num_Lock); case WXK_SCROLL: return CKeyboardCode(XK_Scroll_Lock); case WXK_PAGEUP: return CKeyboardCode(XK_Page_Up); case WXK_PAGEDOWN: return CKeyboardCode(XK_Page_Down); case WXK_NUMPAD_SPACE: return CKeyboardCode(XK_KP_Space); case WXK_NUMPAD_TAB: return CKeyboardCode(XK_KP_Tab); case WXK_NUMPAD_ENTER: return CKeyboardCode(XK_KP_Enter); case WXK_NUMPAD_F1: return CKeyboardCode(XK_KP_F1); case WXK_NUMPAD_F2: return CKeyboardCode(XK_KP_F2); case WXK_NUMPAD_F3: return CKeyboardCode(XK_KP_F3); case WXK_NUMPAD_F4: return CKeyboardCode(XK_KP_F4); case WXK_NUMPAD_HOME: return CKeyboardCode(XK_KP_Home); case WXK_NUMPAD_LEFT: return CKeyboardCode(XK_KP_Left); case WXK_NUMPAD_UP: return CKeyboardCode(XK_KP_Up); case WXK_NUMPAD_RIGHT: return CKeyboardCode(XK_KP_Right); case WXK_NUMPAD_DOWN: return CKeyboardCode(XK_KP_Down); case WXK_NUMPAD_PAGEUP: return CKeyboardCode(XK_KP_Page_Up); case WXK_NUMPAD_PAGEDOWN: return CKeyboardCode(XK_KP_Page_Down); case WXK_NUMPAD_END: return CKeyboardCode(XK_KP_End); case WXK_NUMPAD_BEGIN: return CKeyboardCode(XK_KP_Begin); case WXK_NUMPAD_INSERT: return CKeyboardCode(XK_KP_Insert); case WXK_NUMPAD_DELETE: return CKeyboardCode(XK_KP_Delete); case WXK_NUMPAD_EQUAL: return CKeyboardCode(XK_KP_Equal); case WXK_NUMPAD_MULTIPLY: return CKeyboardCode(XK_KP_Multiply); case WXK_NUMPAD_ADD: return CKeyboardCode(XK_KP_Add); case WXK_NUMPAD_SEPARATOR: return CKeyboardCode(XK_KP_Separator); case WXK_NUMPAD_SUBTRACT: return CKeyboardCode(XK_KP_Subtract); case WXK_NUMPAD_DECIMAL: return CKeyboardCode(XK_KP_Decimal); case WXK_NUMPAD_DIVIDE: return CKeyboardCode(XK_KP_Divide); // the following key codes are only generated under Windows currently case WXK_WINDOWS_LEFT: return CKeyboardCode(XK_Super_L); case WXK_WINDOWS_RIGHT: return CKeyboardCode(XK_Super_R); case WXK_WINDOWS_MENU: return CKeyboardCode(XK_Menu); // // Untranslated codes // case WXK_SPACE: case WXK_START: case WXK_LBUTTON: case WXK_RBUTTON: case WXK_CANCEL: case WXK_MBUTTON: // Hardware-specific buttons case WXK_SPECIAL1: case WXK_SPECIAL2: case WXK_SPECIAL3: case WXK_SPECIAL4: case WXK_SPECIAL5: case WXK_SPECIAL6: case WXK_SPECIAL7: case WXK_SPECIAL8: case WXK_SPECIAL9: case WXK_SPECIAL10: case WXK_SPECIAL11: case WXK_SPECIAL12: case WXK_SPECIAL13: case WXK_SPECIAL14: case WXK_SPECIAL15: case WXK_SPECIAL16: case WXK_SPECIAL17: case WXK_SPECIAL18: case WXK_SPECIAL19: case WXK_SPECIAL20: case WXK_CAPITAL: assert (false); return CKeyboardCode(0); break; } // If the code reaches this point it means that wxKeyCode kc carries // an unicode character (see wxKeyEvent::GetUnicodeKey) // TODO: translate these unicode char to a keysym return CKeyboardCode(kc); #else // Still not available for Windows // assert(0); wxUnusedVar(kc); return CKeyboardCode(); #endif } CKeyboardCode CKeyboardCode::FromRawValue (unsigned long kc) { return CKeyboardCode(kc); } // Get the internal raw value. NOTE: intended only // for storage purposes not to work with unsigned long CKeyboardCode::GetRawValue() const { return m_virtualKeyCode; }