InputComponent.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "QsLog.h"
  2. #include "InputComponent.h"
  3. #include "settings/SettingsComponent.h"
  4. #include "system/SystemComponent.h"
  5. #include "power/PowerComponent.h"
  6. #include "InputKeyboard.h"
  7. #include "InputSocket.h"
  8. #ifdef Q_OS_MAC
  9. #include "apple/InputAppleRemote.h"
  10. #include "apple/InputAppleMediaKeys.h"
  11. #endif
  12. #ifdef HAVE_SDL
  13. #include "InputSDL.h"
  14. #endif
  15. #ifdef HAVE_LIRC
  16. #include "InputLIRC.h"
  17. #endif
  18. #ifdef HAVE_CEC
  19. #include "InputCEC.h"
  20. #endif
  21. ///////////////////////////////////////////////////////////////////////////////////////////////////
  22. InputComponent::InputComponent(QObject* parent) : ComponentBase(parent)
  23. {
  24. m_mappings = new InputMapping(this);
  25. }
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. bool InputComponent::addInput(InputBase* base)
  28. {
  29. if (!base->initInput())
  30. {
  31. QLOG_WARN() << "Failed to init input:" << base->inputName();
  32. return false;
  33. }
  34. QLOG_INFO() << "Successfully inited input:" << base->inputName();
  35. m_inputs.push_back(base);
  36. // we connect to the provider receivedInput signal, then we check if the name
  37. // needs to be remaped in remapInput and then finally send it out to JS land.
  38. //
  39. connect(base, &InputBase::receivedInput, this, &InputComponent::remapInput);
  40. return true;
  41. }
  42. ///////////////////////////////////////////////////////////////////////////////////////////////////
  43. bool InputComponent::componentInitialize()
  44. {
  45. // load our input mappings
  46. m_mappings->loadMappings();
  47. addInput(&InputKeyboard::Get());
  48. addInput(new InputSocket(this));
  49. #ifdef Q_OS_MAC
  50. addInput(new InputAppleRemote(this));
  51. addInput(new InputAppleMediaKeys(this));
  52. #endif
  53. #ifdef HAVE_SDL
  54. addInput(new InputSDL(this));
  55. #endif
  56. #ifdef HAVE_LIRC
  57. addInput(new InputLIRC(this));
  58. #endif
  59. #ifdef HAVE_CEC
  60. if (SettingsComponent::Get().value(SETTINGS_SECTION_CEC, "enable").toBool())
  61. addInput(new InputCEC(this));
  62. #endif
  63. return true;
  64. }
  65. ///////////////////////////////////////////////////////////////////////////////////////////////////
  66. void InputComponent::remapInput(const QString &source, const QString &keycode, float amount)
  67. {
  68. // hide mouse if it's visible.
  69. SystemComponent::Get().setCursorVisibility(false);
  70. QLOG_DEBUG() << "Input received: source:" << source << "keycode:" << keycode;
  71. QString action = m_mappings->mapToAction(source, keycode);
  72. if (!action.isEmpty())
  73. {
  74. if (action.startsWith("host:"))
  75. {
  76. QStringList argList = action.mid(5).split(" ");
  77. QString hostCommand = argList.value(0);
  78. QString hostArguments;
  79. if (argList.size() > 1)
  80. {
  81. argList.pop_front();
  82. hostArguments = argList.join(" ");
  83. }
  84. QLOG_DEBUG() << "Got host command:" << hostCommand << "arguments:" << hostArguments;
  85. if (m_hostCommands.contains(hostCommand))
  86. {
  87. ReceiverSlot* recvSlot = m_hostCommands.value(hostCommand);
  88. if (recvSlot)
  89. {
  90. QLOG_DEBUG() << "Invoking slot" << qPrintable(recvSlot->slot.data());
  91. QGenericArgument arg0 = QGenericArgument();
  92. if (recvSlot->hasArguments)
  93. arg0 = Q_ARG(const QString&, hostArguments);
  94. QMetaObject::invokeMethod(recvSlot->receiver, recvSlot->slot.data(),
  95. Qt::AutoConnection, arg0);
  96. }
  97. }
  98. else
  99. {
  100. QLOG_WARN() << "No such host command:" << hostCommand;
  101. }
  102. }
  103. else
  104. {
  105. emit receivedAction(action);
  106. }
  107. }
  108. else
  109. {
  110. QLOG_WARN() << "Could not map:" << source << keycode << "to any useful action";
  111. }
  112. }
  113. /////////////////////////////////////////////////////////////////////////////////////////
  114. void InputComponent::registerHostCommand(const QString& command, QObject* receiver, const char* slot)
  115. {
  116. ReceiverSlot* recvSlot = new ReceiverSlot;
  117. recvSlot->receiver = receiver;
  118. recvSlot->slot = QMetaObject::normalizedSignature(slot);
  119. recvSlot->hasArguments = false;
  120. QLOG_DEBUG() << "Adding host command:" << qPrintable(command) << "mapped to" << qPrintable(QString(receiver->metaObject()->className()) + "::" + recvSlot->slot);
  121. m_hostCommands.insert(command, recvSlot);
  122. auto slotWithArgs = QString("%1(QString)").arg(QString::fromLatin1(recvSlot->slot)).toLatin1().data();
  123. auto slotWithoutArgs = QString("%1()").arg(QString::fromLatin1(recvSlot->slot)).toLatin1().data();
  124. if (recvSlot->receiver->metaObject()->indexOfMethod(slotWithArgs) != -1)
  125. {
  126. QLOG_DEBUG() << "Host command maps to method with an argument.";
  127. recvSlot->hasArguments = true;
  128. }
  129. else if (recvSlot->receiver->metaObject()->indexOfMethod(slotWithoutArgs) != -1)
  130. {
  131. QLOG_DEBUG() << "Host command maps to method without arguments.";
  132. }
  133. else
  134. {
  135. QLOG_ERROR() << "Slot for host command missing, or has incorrect signature!";
  136. }
  137. }