28 #include <QCoreApplication> 30 #include <QKeySequence> 31 #include <QTextStream> 32 #include <QStringList> 39 #include <sys/types.h> 44 #include <linux/joystick.h> 52 #define LOC QString("JoystickMenuThread: ") 86 LOG(VB_GENERAL, LOG_ERR,
LOC +
87 QString(
"Joystick disabled - Failed to open device %1")
95 LOG(VB_GENERAL, LOG_ERR,
LOC +
96 "Joystick disabled - ioctl JSIOCGAXES failed");
103 LOG(VB_GENERAL, LOG_ERR,
LOC +
104 "Joystick disabled - ioctl JSIOCGBUTTONS failed");
117 LOG(VB_GENERAL, LOG_INFO,
LOC +
118 QString(
"Initialization of %1 succeeded using config file %2")
138 if (!QFile::exists(config_file))
140 LOG(VB_GENERAL, LOG_INFO,
"No joystick configuration found, not enabling joystick control");
144 FILE *fp = fopen(qPrintable(config_file),
"r");
147 LOG(VB_GENERAL, LOG_ERR,
LOC +
148 QString(
"Joystick disabled - Failed to open %1") .arg(config_file));
152 QTextStream istream(fp);
153 for (
int line = 1; ! istream.atEnd(); line++)
155 QString rawline = istream.readLine();
156 QString simple_line = rawline.simplified();
157 if (simple_line.isEmpty() || simple_line.startsWith(
'#'))
160 QStringList tokens = simple_line.split(
" ");
161 if (tokens.count() < 1)
164 QString firstTok = tokens[0].toLower();
166 if (firstTok.startsWith(
"devicename") && tokens.count() == 2)
168 else if (firstTok.startsWith(
"button") && tokens.count() == 3)
170 else if (firstTok.startsWith(
"axis") && tokens.count() == 5)
172 tokens[3].toInt(), tokens[4]);
173 else if (firstTok.startsWith(
"chord") && tokens.count() == 4)
176 LOG(VB_GENERAL, LOG_WARNING,
LOC +
177 QString(
"ReadConfig(%1) unrecognized or malformed line \"%2\" ")
178 .arg(line) .arg(rawline));
195 struct js_event js {};
206 FD_SET(
m_fd, &readfds);
212 int rc = select(
m_fd + 1, &readfds,
nullptr,
nullptr, &
timeout);
219 LOG(VB_GENERAL, LOG_ERR,
"select: " +
ENO);
229 if (rc !=
sizeof(js))
231 LOG(VB_GENERAL, LOG_ERR,
"error reading js:" +
ENO);
240 if (js.type & JS_EVENT_INIT)
245 if (js.type & JS_EVENT_AXIS && js.number <
m_axesCount)
246 m_axes[js.number] = js.value;
263 if (js.value == 0 &&
m_buttons[js.number] == 1)
269 if (js.type & JS_EVENT_AXIS && js.number <
m_axesCount)
272 m_axes[js.number] = js.value;
289 QKeySequence a(code);
300 for (
int i = 0; i < a.count(); i++)
323 JoystickMap::button_map_t::const_iterator bmap;
327 if (button == bmap->button && bmap->chord != -1
342 if (button == bmap->button && bmap->chord == -1)
352 JoystickMap::axis_map_t::const_iterator amap;
355 if (axis == amap->axis)
359 if (
m_axes[axis] < amap->from ||
m_axes[axis] > amap->to)
360 if (value >= amap->from && value <= amap->to)
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
void AddAxis(int in_axis, int in_from, int in_to, QString in_keystr)
def read(device=None, features=[])
#define ENO
This can be appended to the LOG args with "+".
const axis_map_t & axisMap() const
#define LOG(_MASK_, _LEVEL_, _STRING_)
void AddButton(int in_button, QString in_keystr, int in_chord=-1)
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
const button_map_t & buttonMap() const