MythTV  master
mythinputdevicehandler.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QCoreApplication>
3 #include <QKeyEvent>
4 #include <QDir>
5 
6 // MythTV
7 #include "libmythbase/mythconfig.h"
8 #include "libmythbase/mythdb.h"
9 #include "libmythbase/mythdirs.h"
11 
12 #include "mythmainwindow.h"
13 #include "mythinputdevicehandler.h"
14 
15 #ifdef USE_JOYSTICK_MENU
16 #include "devices/jsmenu.h"
17 #include "devices/jsmenuevent.h"
18 #endif
19 
20 #ifdef USING_APPLEREMOTE
22 #endif
23 
24 #ifdef USE_LIRC
25 #include "devices/lirc.h"
26 #endif
27 
28 #if defined (USE_LIRC) || defined (USING_APPLEREMOTE)
29 #include "devices/lircevent.h"
30 #endif
31 
32 #define LOC QString("InputHandler: ")
33 
42  : m_parent(Parent)
43 {
45 }
46 
48 {
50 }
51 
53 {
54  LOG(VB_GENERAL, LOG_INFO, LOC + "Starting");
55 
56 #ifdef USE_LIRC
57  if (!m_lircThread)
58  {
59  QString config = GetConfDir() + "/lircrc";
60  if (!QFile::exists(config))
61  config = QDir::homePath() + "/.lircrc";
62 
63  // lircd socket moved from /dev/ to /var/run/lirc/ in lirc 0.8.6
64  QString socket = "/dev/lircd";
65  if (!QFile::exists(socket))
66  socket = "/var/run/lirc/lircd";
67 
68  m_lircThread = new LIRC(this, GetMythDB()->GetSetting("LircSocket", socket), "mythtv", config);
69  if (m_lircThread->Init())
70  {
72  }
73  else
74  {
76  m_lircThread = nullptr;
77  }
78  }
79 #endif
80 
81 #ifdef USE_JOYSTICK_MENU
82  if (!m_joystickThread)
83  {
84  QString config = GetConfDir() + "/joystickmenurc";
86  if (m_joystickThread->Init(config))
88  }
89 #endif
90 
91 #ifdef USING_APPLEREMOTE
93  {
96 
100  {
101  m_appleRemote->start();
102  }
103  else
104  {
105  // start listening failed, no remote receiver present
106  delete m_appleRemote;
107  delete m_appleRemoteListener;
108  m_appleRemote = nullptr;
109  m_appleRemoteListener = nullptr;
110  }
111  }
112 #endif
113 }
114 
115 void MythInputDeviceHandler::Stop(bool Finishing /* = true */)
116 {
117  Q_UNUSED(Finishing) // depending on #ifdefs
118  LOG(VB_GENERAL, LOG_INFO, LOC + "Stopping");
119 
120 #ifdef USING_LIBCEC
121  if (Finishing)
122  m_cecAdapter.Close();
123 #endif
124 
125 #ifdef USING_APPLEREMOTE
126  if (Finishing)
127  {
128  delete m_appleRemote;
129  delete m_appleRemoteListener;
130  m_appleRemote = nullptr;
131  m_appleRemoteListener = nullptr;
132  }
133 #endif
134 
135 #ifdef USE_JOYSTICK_MENU
136  if (m_joystickThread && Finishing)
137  {
139  {
142  }
143  delete m_joystickThread;
144  m_joystickThread = nullptr;
145  }
146 #endif
147 
148 #ifdef USE_LIRC
149  if (m_lircThread)
150  {
152  m_lircThread = nullptr;
153  }
154 #endif
155 }
156 
158 {
159  Stop(false);
160  Start();
161 }
162 
163 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
165 {
166  if (!Event)
167  return;
168 
169 #ifdef USING_APPLEREMOTE
170  if (m_appleRemote)
171  {
172  if (Event->type() == QEvent::WindowActivate)
174  if (Event->type() == QEvent::WindowDeactivate)
176  }
177 #endif
178 }
179 
181 {
182 #ifdef USING_LIBCEC
183  m_cecAdapter.Action(Action);
184 #else
185  (void) Action;
186 #endif
187 }
188 
190 {
191  if (Ignore)
192  LOG(VB_GENERAL, LOG_INFO, LOC + "Locking input devices");
193  else
194  LOG(VB_GENERAL, LOG_INFO, LOC + "Unlocking input devices");
195  m_ignoreKeys = Ignore;
196 #ifdef USING_LIBCEC
197  m_cecAdapter.IgnoreKeys(Ignore);
198 #endif
199 }
200 
202 {
203 #ifdef USING_LIBCEC
204  // Open any adapter after the window has been created to ensure we capture
205  // the EDID if available - and hence get a more accurate Physical Address.
206  // This will close any existing adapter in the event that the window has been re-init'ed.
207  m_cecAdapter.Open(m_parent);
208 #endif
209 }
210 
212 {
213  Q_UNUSED(Event) // depending on #ifdefs
214 
215  if (m_ignoreKeys)
216  return;
217 
218  QScopedPointer<QKeyEvent> key { new QKeyEvent(QEvent::KeyPress, 0, Qt::NoModifier) };
219  QObject* target = nullptr;
220  QString error;
221 
222 #ifdef USE_JOYSTICK_MENU
224  {
225  auto *jke = dynamic_cast<JoystickKeycodeEvent *>(Event);
226  if (!jke)
227  return;
228 
229  int keycode = jke->key();
230  if (keycode)
231  {
232  key.reset(new QKeyEvent(jke->keyAction(), keycode, jke->keyModifiers()));
233  target = m_parent->GetTarget(*key);
234  }
235  else
236  {
237  error = jke->getJoystickMenuText();
238  }
239  }
240 #endif
241 
242 #if defined(USE_LIRC) || defined(USING_APPLEREMOTE)
243  if (Event->type() == LircKeycodeEvent::kEventType)
244  {
245  auto *lke = dynamic_cast<LircKeycodeEvent *>(Event);
246  if (!lke)
247  return;
248 
249  if (LircKeycodeEvent::kLIRCInvalidKeyCombo == lke->modifiers())
250  {
251  error = lke->lirctext();
252  }
253  else
254  {
255  key.reset(new QKeyEvent(lke->keytype(), lke->key(), lke->modifiers(), lke->text()));
256  target = m_parent->GetTarget(*key);
257  }
258  }
259 #endif
260 
261  if (!error.isEmpty())
262  {
263  LOG(VB_GENERAL, LOG_WARNING, LOC +
264  QString("Attempt to convert key sequence '%1' to a Qt key sequence failed.").arg(error));
265  }
266  else if (target)
267  {
270  return;
271  QCoreApplication::sendEvent(target, key.data());
272  }
273 }
AppleRemote::Get
static AppleRemote * Get()
Definition: AppleRemote.cpp:41
AppleRemoteListener
Definition: AppleRemoteListener.h:6
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:283
LOC
#define LOC
Definition: mythinputdevicehandler.cpp:32
MythInputDeviceHandler::MainWindowReady
void MainWindowReady(void)
Definition: mythinputdevicehandler.cpp:201
MythInputDeviceHandler::customEvent
void customEvent(QEvent *Event) override
Definition: mythinputdevicehandler.cpp:211
jsmenu.h
error
static void error(const char *str,...)
Definition: vbi.cpp:36
mythdb.h
MythInputDeviceHandler::MythInputDeviceHandler
MythInputDeviceHandler(MythMainWindow *Parent)
Definition: mythinputdevicehandler.cpp:41
MThread::wait
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:300
jsmenuevent.h
MythInputDeviceHandler::Action
void Action(const QString &Action)
Definition: mythinputdevicehandler.cpp:180
MythInputDeviceHandler::Start
void Start(void)
Definition: mythinputdevicehandler.cpp:52
JoystickKeycodeEvent
Definition: jsmenuevent.h:16
MythInputDeviceHandler::m_ignoreKeys
bool m_ignoreKeys
Definition: mythinputdevicehandler.h:41
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
mythinputdevicehandler.h
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
mythdirs.h
MythInputDeviceHandler::Stop
void Stop(bool Finishing=true)
Definition: mythinputdevicehandler.cpp:115
Action
An action (for this plugin) consists of a description, and a set of key sequences.
Definition: action.h:40
JoystickKeycodeEvent::key
int key() const
Definition: jsmenuevent.h:28
mythlogging.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:224
Event
Event details.
Definition: zmdefines.h:26
LIRC::deleteLater
virtual void deleteLater(void)
Definition: lirc.cpp:101
AppleRemoteListener.h
MythInputDeviceHandler::m_appleRemoteListener
AppleRemoteListener * m_appleRemoteListener
Definition: mythinputdevicehandler.h:56
MythInputDeviceHandler::Reset
void Reset(void)
Definition: mythinputdevicehandler.cpp:157
LircKeycodeEvent::kLIRCInvalidKeyCombo
static const unsigned kLIRCInvalidKeyCombo
Definition: lircevent.h:29
JoystickMenuThread::Stop
void Stop(void)
Definition: jsmenu.h:99
MythInputDeviceHandler::m_joystickThread
JoystickMenuThread * m_joystickThread
Definition: mythinputdevicehandler.h:52
MythInputDeviceHandler::m_appleRemote
AppleRemote * m_appleRemote
Definition: mythinputdevicehandler.h:57
MythInputDeviceHandler::~MythInputDeviceHandler
~MythInputDeviceHandler() override
Definition: mythinputdevicehandler.cpp:47
AppleRemote::startListening
void startListening()
Definition: AppleRemote.cpp:73
LircKeycodeEvent
Definition: lircevent.h:12
MythMainWindow::GetTarget
QObject * GetTarget(QKeyEvent &Key)
Definition: mythmainwindow.cpp:2074
MythMainWindow::IsScreensaverAsleep
static bool IsScreensaverAsleep()
Definition: mythmainwindow.cpp:592
lirc.h
JoystickKeycodeEvent::kEventType
static Type kEventType
Definition: jsmenuevent.h:32
MThread::isRunning
bool isRunning(void) const
Definition: mthread.cpp:263
LIRC::Init
bool Init(void)
Definition: lirc.cpp:166
LircKeycodeEvent::kEventType
static Type kEventType
Definition: lircevent.h:27
AppleRemote::stopListening
void stopListening()
Definition: AppleRemote.cpp:95
JoystickMenuThread::Init
bool Init(QString &config_file)
Initialise the class variables with values from the config file.
Definition: jsmenu.cpp:77
JoystickMenuThread
Main object for injecting key strokes based on joystick movements.
Definition: jsmenu.h:87
MythMainWindow::ResetScreensaver
static void ResetScreensaver()
Definition: mythmainwindow.cpp:586
MythInputDeviceHandler::Event
void Event(QEvent *Event) const
Definition: mythinputdevicehandler.cpp:164
AppleRemote::isListeningToRemote
bool isListeningToRemote()
Definition: AppleRemote.cpp:63
LIRC
Interface between mythtv and lircd.
Definition: lirc.h:27
mythmainwindow.h
MythInputDeviceHandler::m_lircThread
LIRC * m_lircThread
Definition: mythinputdevicehandler.h:44
AppleRemote::setListener
void setListener(Listener *listener)
Definition: AppleRemote.cpp:68
MythMainWindow
Definition: mythmainwindow.h:28
lircevent.h
LIRC::start
virtual void start(void)
Definition: lirc.cpp:325
MythInputDeviceHandler::IgnoreKeys
void IgnoreKeys(bool Ignore)
Definition: mythinputdevicehandler.cpp:189
MythInputDeviceHandler::m_parent
MythMainWindow * m_parent
Definition: mythinputdevicehandler.h:40