bool CGUIDialogIgnoreInput::AddPrimitive(const JOYSTICK::CDriverPrimitive& primitive) { bool bValid = false; if (primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::BUTTON || primitive.Type() == JOYSTICK::PRIMITIVE_TYPE::SEMIAXIS) { auto PrimitiveMatch = [&primitive](const JOYSTICK::CDriverPrimitive& other) { return primitive.Type() == other.Type() && primitive.Index() == other.Index(); }; bValid = std::find_if(m_capturedPrimitives.begin(), m_capturedPrimitives.end(), PrimitiveMatch) == m_capturedPrimitives.end(); } if (bValid) { m_capturedPrimitives.emplace_back(primitive); return true; } return false; }
bool CAddonButtonMap::GetAnalogStick(const FeatureName& feature, JOYSTICK::ANALOG_STICK_DIRECTION direction, JOYSTICK::CDriverPrimitive& primitive) { bool retVal(false); CSingleLock lock(m_mutex); FeatureMap::const_iterator it = m_features.find(feature); if (it != m_features.end()) { const ADDON::JoystickFeature& addonFeature = it->second; if (addonFeature.Type() == JOYSTICK_FEATURE_TYPE_ANALOG_STICK) { primitive = CPeripheralAddonTranslator::TranslatePrimitive(addonFeature.Primitive(GetPrimitiveIndex(direction))); retVal = primitive.IsValid(); } } return retVal; }
bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap, IKeymap* keymap, const JOYSTICK::CDriverPrimitive& primitive) { using namespace JOYSTICK; bool bHandled = false; // Handle esc key separately if (!m_deviceName.empty() && m_deviceName != buttonMap->DeviceName()) { bool bIsCancelAction = false; //! @todo This only succeeds for game.controller.default; no actions are // currently defined for other controllers if (keymap) { std::string feature; if (buttonMap->GetFeature(primitive, feature)) { const auto &actions = keymap->GetActions(CJoystickUtils::MakeKeyName(feature)).actions; if (!actions.empty()) { //! @todo Handle multiple actions mapped to the same key switch (actions.begin()->actionId) { case ACTION_NAV_BACK: case ACTION_PREVIOUS_MENU: bIsCancelAction = true; break; default: break; } } } } if (bIsCancelAction) { CLog::Log(LOGDEBUG, "%s: device \"%s\" is cancelling prompt", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str()); Abort(false); } else CLog::Log(LOGDEBUG, "%s: ignoring input for device \"%s\"", buttonMap->ControllerID().c_str(), buttonMap->DeviceName().c_str()); // Discard input bHandled = true; } else if (primitive.Type() == PRIMITIVE_TYPE::BUTTON && primitive.Index() == ESC_KEY_CODE) { // Handle esc key bHandled = Abort(false); } else if (m_history.find(primitive) != m_history.end()) { // Primitive has already been mapped this round, ignore it bHandled = true; } else if (buttonMap->IsIgnored(primitive)) { bHandled = true; } else { // Get the current state of the thread IFeatureButton* currentButton; ANALOG_STICK_DIRECTION currentDirection; { CSingleLock lock(m_stateMutex); currentButton = m_currentButton; currentDirection = m_currentDirection; } if (currentButton) { const CControllerFeature& feature = currentButton->Feature(); CLog::Log(LOGDEBUG, "%s: mapping feature \"%s\" for device %s", m_strControllerId.c_str(), feature.Name().c_str(), buttonMap->DeviceName().c_str()); switch (feature.Type()) { case FEATURE_TYPE::SCALAR: { buttonMap->AddScalar(feature.Name(), primitive); bHandled = true; break; } case FEATURE_TYPE::ANALOG_STICK: { buttonMap->AddAnalogStick(feature.Name(), currentDirection, primitive); bHandled = true; break; } case FEATURE_TYPE::RELPOINTER: { buttonMap->AddRelativePointer(feature.Name(), currentDirection, primitive); bHandled = true; break; } default: break; } if (bHandled) { m_history.insert(primitive); OnMotion(buttonMap); m_inputEvent.Set(); m_deviceName = buttonMap->DeviceName(); } } } return bHandled; }
bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap, const JOYSTICK::CDriverPrimitive& primitive) { using namespace JOYSTICK; bool bHandled = false; // Handle esc key separately if (primitive.Type() == PRIMITIVE_TYPE::BUTTON && primitive.Index() == ESC_KEY_CODE) { bHandled = Abort(false); } else if (m_history.find(primitive) != m_history.end()) { // Primitive has already been mapped this round, ignore it bHandled = true; } else { // Get the current state of the thread IFeatureButton* currentButton; CARDINAL_DIRECTION currentDirection; { CSingleLock lock(m_stateMutex); currentButton = m_currentButton; currentDirection = m_currentDirection; } if (currentButton) { const CControllerFeature& feature = currentButton->Feature(); switch (feature.Type()) { case FEATURE_TYPE::SCALAR: { bHandled = buttonMap->AddScalar(feature.Name(), primitive); break; } case FEATURE_TYPE::ANALOG_STICK: { CDriverPrimitive up; CDriverPrimitive down; CDriverPrimitive right; CDriverPrimitive left; buttonMap->GetAnalogStick(feature.Name(), up, down, right, left); switch (currentDirection) { case CARDINAL_DIRECTION::UP: up = primitive; break; case CARDINAL_DIRECTION::DOWN: down = primitive; break; case CARDINAL_DIRECTION::RIGHT: right = primitive; break; case CARDINAL_DIRECTION::LEFT: left = primitive; break; default: break; } bHandled = buttonMap->AddAnalogStick(feature.Name(), up, down, right, left); break; } default: break; } if (bHandled) { m_history.insert(primitive); m_inputEvent.Set(); } } } return bHandled; }
bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap, IKeymap* keymap, const JOYSTICK::CDriverPrimitive& primitive) { using namespace INPUT; using namespace JOYSTICK; bool bHandled = false; // Abort if another controller cancels the prompt if (IsMapping() && !IsMapping(buttonMap->DeviceName())) { //! @todo This only succeeds for game.controller.default; no actions are // currently defined for other controllers if (keymap) { std::string feature; if (buttonMap->GetFeature(primitive, feature)) { const auto &actions = keymap->GetActions(CJoystickUtils::MakeKeyName(feature)).actions; if (!actions.empty()) { //! @todo Handle multiple actions mapped to the same key OnAction(actions.begin()->actionId); } } } // Discard input bHandled = true; } else if (m_history.find(primitive) != m_history.end()) { // Primitive has already been mapped this round, ignore it bHandled = true; } else if (buttonMap->IsIgnored(primitive)) { bHandled = true; } else { // Get the current state of the thread IFeatureButton* currentButton; CARDINAL_DIRECTION cardinalDirection; WHEEL_DIRECTION wheelDirection; THROTTLE_DIRECTION throttleDirection; { CSingleLock lock(m_stateMutex); currentButton = m_currentButton; cardinalDirection = m_cardinalDirection; wheelDirection = m_wheelDirection; throttleDirection = m_throttleDirection; } if (currentButton) { // Check if we were expecting a keyboard key if (currentButton->NeedsKey()) { if (primitive.Type() == PRIMITIVE_TYPE::KEY) { auto it = m_keyMap.find(primitive.Keycode()); if (it != m_keyMap.end()) { const CControllerFeature &key = it->second; currentButton->SetKey(key); m_inputEvent.Set(); } } else { //! @todo Check if primitive is a cancel or motion action } bHandled = true; } else { const CControllerFeature& feature = currentButton->Feature(); if (primitive.Type() == PRIMITIVE_TYPE::RELATIVE_POINTER && feature.Type() != FEATURE_TYPE::RELPOINTER) { // Don't allow relative pointers to map to other features } else { CLog::Log(LOGDEBUG, "%s: mapping feature \"%s\" for device %s", m_strControllerId.c_str(), feature.Name().c_str(), buttonMap->DeviceName().c_str()); switch (feature.Type()) { case FEATURE_TYPE::SCALAR: { buttonMap->AddScalar(feature.Name(), primitive); bHandled = true; break; } case FEATURE_TYPE::ANALOG_STICK: { buttonMap->AddAnalogStick(feature.Name(), cardinalDirection, primitive); bHandled = true; break; } case FEATURE_TYPE::RELPOINTER: { buttonMap->AddRelativePointer(feature.Name(), cardinalDirection, primitive); bHandled = true; break; } case FEATURE_TYPE::WHEEL: { buttonMap->AddWheel(feature.Name(), wheelDirection, primitive); bHandled = true; break; } case FEATURE_TYPE::THROTTLE: { buttonMap->AddThrottle(feature.Name(), throttleDirection, primitive); bHandled = true; break; } case FEATURE_TYPE::KEY: { buttonMap->AddKey(feature.Name(), primitive); bHandled = true; break; } default: break; } } if (bHandled) { m_history.insert(primitive); // Don't record motion for relative pointers if (primitive.Type() != PRIMITIVE_TYPE::RELATIVE_POINTER) OnMotion(buttonMap); m_inputEvent.Set(); if (m_deviceName.empty()) { m_deviceName = buttonMap->DeviceName(); m_bIsKeyboard = (primitive.Type() == PRIMITIVE_TYPE::KEY); } } } } } return bHandled; }
bool CGUIConfigurationWizard::MapPrimitive(JOYSTICK::IButtonMap* buttonMap, JOYSTICK::IActionMap* actionMap, const JOYSTICK::CDriverPrimitive& primitive) { using namespace JOYSTICK; bool bHandled = false; // Handle esc key separately if (primitive.Type() == PRIMITIVE_TYPE::BUTTON && primitive.Index() == ESC_KEY_CODE) { bHandled = Abort(false); } else if (m_history.find(primitive) != m_history.end()) { // Primitive has already been mapped this round, ignore it bHandled = true; } else if (buttonMap->IsIgnored(primitive)) { bHandled = true; } else { // Get the current state of the thread IFeatureButton* currentButton; ANALOG_STICK_DIRECTION currentDirection; { CSingleLock lock(m_stateMutex); currentButton = m_currentButton; currentDirection = m_currentDirection; } if (currentButton) { const CControllerFeature& feature = currentButton->Feature(); CLog::Log(LOGDEBUG, "%s: mapping feature \"%s\" for device %s", m_strControllerId.c_str(), feature.Name().c_str(), buttonMap->DeviceName().c_str()); switch (feature.Type()) { case FEATURE_TYPE::SCALAR: { buttonMap->AddScalar(feature.Name(), primitive); bHandled = true; break; } case FEATURE_TYPE::ANALOG_STICK: { buttonMap->AddAnalogStick(feature.Name(), currentDirection, primitive); bHandled = true; break; } default: break; } if (bHandled) { m_history.insert(primitive); OnMotion(buttonMap); m_inputEvent.Set(); } } } return bHandled; }