bool CGameClientKeyboard::OnKeyPress(const CKey& key) { // Only allow activated input in fullscreen game if (!m_gameClient->AcceptsInput()) { CLog::Log(LOGDEBUG, "GAME: key press ignored, not in fullscreen game"); return false; } bool bHandled = false; game_input_event event; event.type = GAME_INPUT_EVENT_KEY; event.port = GAME_INPUT_PORT_KEYBOARD; event.controller_id = ""; //! @todo event.feature_name = ""; //! @todo event.key.pressed = true; event.key.character = static_cast<XBMCVKey>(key.GetButtonCode() & BUTTON_INDEX_MASK); event.key.modifiers = CGameClientTranslator::GetModifiers(static_cast<CKey::Modifier>(key.GetModifiers())); if (event.key.character != 0) { try { bHandled = m_dllStruct->InputEvent(&event); } catch (...) { CLog::Log(LOGERROR, "GAME: %s: exception caught in InputEvent()", m_gameClient->ID().c_str()); } } return bHandled; }
void CGameClientKeyboard::OnKeyRelease(const CKey& key) { game_input_event event; event.type = GAME_INPUT_EVENT_KEY; event.port = GAME_INPUT_PORT_KEYBOARD; event.controller_id = ""; //! @todo event.feature_name = ""; //! @todo event.key.pressed = false; event.key.character = static_cast<XBMCVKey>(key.GetButtonCode() & BUTTON_INDEX_MASK); event.key.modifiers = CGameClientTranslator::GetModifiers(static_cast<CKey::Modifier>(key.GetModifiers())); if (event.key.character != 0) { try { m_dllStruct->InputEvent(&event); } catch (...) { CLog::Log(LOGERROR, "GAME: %s: exception caught in InputEvent()", m_gameClient->ID().c_str()); } } }
bool CInputManager::OnKey(const CKey& key) { for (std::vector<KEYBOARD::IKeyboardHandler*>::iterator it = m_keyboardHandlers.begin(); it != m_keyboardHandlers.end(); ++it) { if ((*it)->OnKeyPress(key)) return true; } // Turn the mouse off, as we've just got a keypress from controller or remote m_Mouse.SetActive(false); // get the current active window int iWin = g_windowManager.GetActiveWindowID(); // this will be checked for certain keycodes that need // special handling if the screensaver is active CAction action = m_buttonTranslator->GetAction(iWin, key); // a key has been pressed. // reset Idle Timer g_application.ResetSystemIdleTimer(); bool processKey = AlwaysProcess(action); if (StringUtils::StartsWithNoCase(action.GetName(), "CECToggleState") || StringUtils::StartsWithNoCase(action.GetName(), "CECStandby")) { // do not wake up the screensaver right after switching off the playing device if (StringUtils::StartsWithNoCase(action.GetName(), "CECToggleState")) { CLog::LogF(LOGDEBUG, "action %s [%d], toggling state of playing device", action.GetName().c_str(), action.GetID()); bool result; CApplicationMessenger::GetInstance().SendMsg(TMSG_CECTOGGLESTATE, 0, 0, static_cast<void*>(&result)); if (!result) return true; } else { CApplicationMessenger::GetInstance().PostMsg(TMSG_CECSTANDBY); return true; } } g_application.ResetScreenSaver(); // allow some keys to be processed while the screensaver is active if (g_application.WakeUpScreenSaverAndDPMS(processKey) && !processKey) { CLog::LogF(LOGDEBUG, "%s pressed, screen saver/dpms woken up", m_Keyboard.GetKeyName((int)key.GetButtonCode()).c_str()); return true; } if (iWin != WINDOW_FULLSCREEN_VIDEO) { // current active window isnt the fullscreen window // just use corresponding section from keymap.xml // to map key->action // first determine if we should use keyboard input directly bool useKeyboard = key.FromKeyboard() && (iWin == WINDOW_DIALOG_KEYBOARD || iWin == WINDOW_DIALOG_NUMERIC); CGUIWindow *window = g_windowManager.GetWindow(iWin); if (window) { CGUIControl *control = window->GetFocusedControl(); if (control) { // If this is an edit control set usekeyboard to true. This causes the // keypress to be processed directly not through the key mappings. if (control->GetControlType() == CGUIControl::GUICONTROL_EDIT) useKeyboard = true; // If the key pressed is shift-A to shift-Z set usekeyboard to true. // This causes the keypress to be used for list navigation. if (control->IsContainer() && key.GetModifiers() == CKey::MODIFIER_SHIFT && key.GetVKey() >= XBMCVK_A && key.GetVKey() <= XBMCVK_Z) useKeyboard = true; } } if (useKeyboard) { // use the virtualkeyboard section of the keymap, and send keyboard-specific or navigation // actions through if that's what they are CAction action = m_buttonTranslator->GetAction(WINDOW_DIALOG_KEYBOARD, key); if (!(action.GetID() == ACTION_MOVE_LEFT || action.GetID() == ACTION_MOVE_RIGHT || action.GetID() == ACTION_MOVE_UP || action.GetID() == ACTION_MOVE_DOWN || action.GetID() == ACTION_SELECT_ITEM || action.GetID() == ACTION_ENTER || action.GetID() == ACTION_PREVIOUS_MENU || action.GetID() == ACTION_NAV_BACK || action.GetID() == ACTION_VOICE_RECOGNIZE)) { // the action isn't plain navigation - check for a keyboard-specific keymap action = m_buttonTranslator->GetAction(WINDOW_DIALOG_KEYBOARD, key, false); if (!(action.GetID() >= REMOTE_0 && action.GetID() <= REMOTE_9) || action.GetID() == ACTION_BACKSPACE || action.GetID() == ACTION_SHIFT || action.GetID() == ACTION_SYMBOLS || action.GetID() == ACTION_CURSOR_LEFT || action.GetID() == ACTION_CURSOR_RIGHT) action = CAction(0); // don't bother with this action } // else pass the keys through directly if (!action.GetID()) { if (key.GetFromService()) action = CAction(key.GetButtonCode() != KEY_INVALID ? key.GetButtonCode() : 0, key.GetUnicode()); else { // Check for paste keypress #ifdef TARGET_WINDOWS // In Windows paste is ctrl-V if (key.GetVKey() == XBMCVK_V && key.GetModifiers() == CKey::MODIFIER_CTRL) #elif defined(TARGET_LINUX) // In Linux paste is ctrl-V if (key.GetVKey() == XBMCVK_V && key.GetModifiers() == CKey::MODIFIER_CTRL) #elif defined(TARGET_DARWIN_OSX) // In OSX paste is cmd-V if (key.GetVKey() == XBMCVK_V && key.GetModifiers() == CKey::MODIFIER_META) #else // Placeholder for other operating systems if (false) #endif action = CAction(ACTION_PASTE); // If the unicode is non-zero the keypress is a non-printing character else if (key.GetUnicode()) action = CAction(key.GetAscii() | KEY_ASCII, key.GetUnicode()); // The keypress is a non-printing character else action = CAction(key.GetVKey() | KEY_VKEY); } } CLog::LogF(LOGDEBUG, "%s pressed, trying keyboard action %x", m_Keyboard.GetKeyName((int)key.GetButtonCode()).c_str(), action.GetID()); if (g_application.OnAction(action)) return true; // failed to handle the keyboard action, drop down through to standard action } if (key.GetFromService()) { if (key.GetButtonCode() != KEY_INVALID) action = m_buttonTranslator->GetAction(iWin, key); } else action = m_buttonTranslator->GetAction(iWin, key); } if (!key.IsAnalogButton()) CLog::LogF(LOGDEBUG, "%s pressed, action is %s", m_Keyboard.GetKeyName((int)key.GetButtonCode()).c_str(), action.GetName().c_str()); return ExecuteInputAction(action); }