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"
11
12#include "mythmainwindow.h"
14
15#if CONFIG_JOYSTICK_MENU
16#include "devices/jsmenu.h"
17#include "devices/jsmenuevent.h"
18#endif
19
20#if CONFIG_APPLEREMOTE
22#endif
23
24#if CONFIG_LIRC
25#include "devices/lirc.h"
26#endif
27
28#if defined CONFIG_LIRC || CONFIG_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#if CONFIG_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 {
71 m_lircThread->start();
72 }
73 else
74 {
75 m_lircThread->deleteLater();
76 m_lircThread = nullptr;
77 }
78 }
79#endif
80
81#if CONFIG_JOYSTICK_MENU
82 if (!m_joystickThread)
83 {
84 QString config = GetConfDir() + "/joystickmenurc";
85 m_joystickThread = new JoystickMenuThread(this);
86 if (m_joystickThread->Init(config))
87 m_joystickThread->start();
88 }
89#endif
90
91#if CONFIG_APPLEREMOTE
92 if (!m_appleRemoteListener)
93 {
94 m_appleRemoteListener = new AppleRemoteListener(this);
95 m_appleRemote = AppleRemote::Get();
96
97 m_appleRemote->setListener(m_appleRemoteListener);
98 m_appleRemote->startListening();
99 if (m_appleRemote->isListeningToRemote())
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
115void MythInputDeviceHandler::Stop([[maybe_unused]] bool Finishing /* = true */)
116{
117 LOG(VB_GENERAL, LOG_INFO, LOC + "Stopping");
118
119#if CONFIG_LIBCEC
120 if (Finishing)
121 m_cecAdapter.Close();
122#endif
123
124#if CONFIG_APPLEREMOTE
125 if (Finishing)
126 {
127 delete m_appleRemote;
128 delete m_appleRemoteListener;
129 m_appleRemote = nullptr;
130 m_appleRemoteListener = nullptr;
131 }
132#endif
133
134#if CONFIG_JOYSTICK_MENU
135 if (m_joystickThread && Finishing)
136 {
137 if (m_joystickThread->isRunning())
138 {
139 m_joystickThread->Stop();
140 m_joystickThread->wait();
141 }
142 delete m_joystickThread;
143 m_joystickThread = nullptr;
144 }
145#endif
146
147#if CONFIG_LIRC
148 if (m_lircThread)
149 {
150 m_lircThread->deleteLater();
151 m_lircThread = nullptr;
152 }
153#endif
154}
155
157{
158 Stop(false);
159 Start();
160}
161
162// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
164{
165 if (!Event)
166 return;
167
168#if CONFIG_APPLEREMOTE
169 if (m_appleRemote)
170 {
171 if (Event->type() == QEvent::WindowActivate)
172 m_appleRemote->startListening();
173 if (Event->type() == QEvent::WindowDeactivate)
174 m_appleRemote->stopListening();
175 }
176#endif
177}
178
179void MythInputDeviceHandler::Action([[maybe_unused]] const QString &Action)
180{
181#if CONFIG_LIBCEC
182 m_cecAdapter.Action(Action);
183#endif
184}
185
187{
188 if (Ignore)
189 LOG(VB_GENERAL, LOG_INFO, LOC + "Locking input devices");
190 else
191 LOG(VB_GENERAL, LOG_INFO, LOC + "Unlocking input devices");
192 m_ignoreKeys = Ignore;
193#if CONFIG_LIBCEC
194 m_cecAdapter.IgnoreKeys(Ignore);
195#endif
196}
197
199{
200#if CONFIG_LIBCEC
201 // Open any adapter after the window has been created to ensure we capture
202 // the EDID if available - and hence get a more accurate Physical Address.
203 // This will close any existing adapter in the event that the window has been re-init'ed.
204 m_cecAdapter.Open(m_parent);
205#endif
206}
207
208void MythInputDeviceHandler::customEvent([[maybe_unused]] QEvent* Event)
209{
210 if (m_ignoreKeys)
211 return;
212
213 QScopedPointer<QKeyEvent> key { new QKeyEvent(QEvent::KeyPress, 0, Qt::NoModifier) };
214 QObject* target = nullptr;
215 QString error;
216
217#if CONFIG_JOYSTICK_MENU
219 {
220 auto *jke = dynamic_cast<JoystickKeycodeEvent *>(Event);
221 if (!jke)
222 return;
223
224 int keycode = jke->key();
225 if (keycode)
226 {
227 key.reset(new QKeyEvent(jke->keyAction(), keycode, jke->keyModifiers()));
228 target = m_parent->GetTarget(*key);
229 }
230 else
231 {
232 error = jke->getJoystickMenuText();
233 }
234 }
235#endif
236
237#if CONFIG_LIRC || CONFIG_APPLEREMOTE
238 if (Event->type() == LircKeycodeEvent::kEventType)
239 {
240 auto *lke = dynamic_cast<LircKeycodeEvent *>(Event);
241 if (!lke)
242 return;
243
244 if (LircKeycodeEvent::kLIRCInvalidKeyCombo == lke->modifiers())
245 {
246 error = lke->lirctext();
247 }
248 else
249 {
250 key.reset(new QKeyEvent(lke->keytype(), lke->key(), lke->modifiers(), lke->text()));
251 target = m_parent->GetTarget(*key);
252 }
253 }
254#endif
255
256 if (!error.isEmpty())
257 {
258 LOG(VB_GENERAL, LOG_WARNING, LOC +
259 QString("Attempt to convert key sequence '%1' to a Qt key sequence failed.").arg(error));
260 }
261 else if (target)
262 {
265 return;
266 QCoreApplication::sendEvent(target, key.data());
267 }
268}
An action (for this plugin) consists of a description, and a set of key sequences.
Definition: action.h:41
static AppleRemote * Get()
Definition: AppleRemote.cpp:42
Event details.
Definition: zmdefines.h:28
static const Type kEventType
Definition: jsmenuevent.h:32
Main object for injecting key strokes based on joystick movements.
Definition: jsmenu.h:88
Interface between mythtv and lircd.
Definition: lirc.h:26
static const Type kEventType
Definition: lircevent.h:27
static const unsigned kLIRCInvalidKeyCombo
Definition: lircevent.h:29
void customEvent(QEvent *Event) override
MythInputDeviceHandler(MythMainWindow *Parent)
void Action(const QString &Action)
void Event(QEvent *Event) const
void Stop(bool Finishing=true)
static void ResetScreensaver()
static bool IsScreensaverAsleep()
QObject * GetTarget(QKeyEvent &Key)
MythDB * GetMythDB(void)
Definition: mythdb.cpp:51
QString GetConfDir(void)
Definition: mythdirs.cpp:263
#define LOC
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
def error(message)
Definition: smolt.py:409
bool exists(str path)
Definition: xbmcvfs.py:51