This repository was archived by the owner on Jun 24, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathchumbybuttonhandler.cpp
More file actions
152 lines (119 loc) · 4.66 KB
/
chumbybuttonhandler.cpp
File metadata and controls
152 lines (119 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) 2011 Stefan A. van der Meer
// See "LICENSE" file included with source code for terms and conditions.
#include "chumbybuttonhandler.h"
#include <QApplication>
#include <QKeyEvent>
// Keyboard socket access
#include <QSocketNotifier>
#include <linux/input.h>
#include <fcntl.h>
// There should be no reason to change the sockets on Chumby One (Falconwing),
// but just in case: they can be easily modified with -D compile flags
#ifndef SOCKET_CHUMBY_TOPBUTTON
#define SOCKET_CHUMBY_TOPBUTTON "/dev/input/by-id/soc-noserial-event-kbd"
#endif
#ifndef SOCKET_CHUMBY_WHEELBUTTON
#define SOCKET_CHUMBY_WHEELBUTTON "/dev/input/by-id/soc-noserial-event-joystick"
#endif
int ChumbyButtonHandler::fdevice_top = -1;
int ChumbyButtonHandler::fdevice_wheel = -1;
ChumbyButtonHandler::ChumbyButtonHandler(QObject *parent)
:QObject(parent)
{
//
// Button presses are detected by reading the socket in which the device
// generates the input events. Simpler than a keyboard driver.
//
// Hook up key handler for top button events.
fdevice_top = ::open(SOCKET_CHUMBY_TOPBUTTON, O_RDONLY|O_NDELAY, 0);
if (fdevice_top >= 0) {
QSocketNotifier *notifier_top = new QSocketNotifier(fdevice_top, QSocketNotifier::Read, this);
connect(notifier_top, SIGNAL(activated(int)), this, SLOT(readButton()));
qDebug("Connected fdevice_top slot.");
} else {
qWarning("Failed to connect to top button socket at %s", SOCKET_CHUMBY_TOPBUTTON);
}
// Hook up key handler for volume wheel events.
fdevice_wheel = ::open(SOCKET_CHUMBY_WHEELBUTTON, O_RDONLY|O_NDELAY, 0);
if (fdevice_wheel >= 0) {
QSocketNotifier *notifier_wheel = new QSocketNotifier(fdevice_wheel, QSocketNotifier::Read, this);
connect(notifier_wheel, SIGNAL(activated(int)), this, SLOT(readWheel()));
qDebug("Connected fdevice_wheel slot");
} else {
qWarning("Failed to connect to top button socket at %s", SOCKET_CHUMBY_WHEELBUTTON);
}
}
ChumbyButtonHandler::~ChumbyButtonHandler()
{
if (fdevice_top >= 0) {
::close(fdevice_top);
fdevice_top = -1;
}
if (fdevice_wheel >= 0) {
::close(fdevice_wheel);
fdevice_wheel = -1;
}
}
//
// Input handling
//
// Because Qt's keyboard driver infrastructure was a hassle, we manually read
// keypresses and generate events that we post to the browser widget. Ugly!
//
// Process a top button press/release. Generates a keypress event of the HOME
// key in the webview widget, where a loaded page can detect it as a DOM event.
void ChumbyButtonHandler::handleTopButtonPress(bool pressed) {
QKeyEvent *ev = new QKeyEvent(pressed ? QEvent::KeyPress : QEvent::KeyRelease,
Qt::Key_Home,
0);
qApp->postEvent(parent(), ev);
}
// Process a wheel rotation. The rotation parameter is positive for up, negative
// for down. Normal rotation gives a magnitude of 1, while very fast rotation
// gives magnitudes between 2-4.
//
// Currently this handler simply generates a keypress event in the webview of
// the arrow key that matches the rotation direction (up/down). This keypress
// can be detected as a DOM event in javascript loaded in the webview.
void ChumbyButtonHandler::handleWheelEvent(int rotation) {
QKeyEvent *ev = new QKeyEvent(QEvent::KeyPress,
rotation > 0 ? Qt::Key_Up : Qt::Key_Down,
0);
qApp->postEvent(parent(), ev);
}
// Read all events from the top button socket. For every button press or release,
// call handleTopButtonPress (there is usually only one event).
void ChumbyButtonHandler::readButton()
{
struct input_event event;
const int event_size = sizeof(struct input_event);
int rb = 0;
while (true) {
rb = ::read(fdevice_top, &event, event_size);
if (rb != event_size) break;
if (event.type != EV_KEY) continue;
// This magic number is the key code the Chumby top button generates.
if (event.code == 0x82) {
handleTopButtonPress(event.value == 1);
}
}
}
// Read all events from the wheel button socket. For every rotation event
// call handleWheelEvent.
//
// The event value varies with the rotation direction and
// speed.
void ChumbyButtonHandler::readWheel()
{
struct input_event event;
const int event_size = sizeof(struct input_event);
int rb = 0;
while (true) {
rb = ::read(fdevice_wheel, &event, event_size);
if (rb != event_size) break;
if (event.type != EV_REL) continue;
if (event.code == REL_WHEEL) {
handleWheelEvent(event.value);
}
}
}