forked from jjackowski/screentouch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Evdev.cpp
137 lines (119 loc) · 3.21 KB
/
Evdev.cpp
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
/*
* This file is part of the Screentouch project. It is subject to the GPLv3
* license terms in the LICENSE file found in the top-level directory of this
* distribution and at
* https://github.com/jjackowski/screentouch/blob/master/LICENSE.
* No part of the Screentouch project, including this file, may be copied,
* modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*
* Copyright (C) 2018 Jeff Jackowski
*/
#include "Evdev.hpp"
#include <boost/exception/errinfo_file_name.hpp>
#include <boost/exception/errinfo_errno.hpp>
// for open() and related items; may be more than needed
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
const char *EventTypeCode::typeName() const {
return libevdev_event_type_get_name(type);
}
const char *EventTypeCode::codeName() const {
return libevdev_event_code_get_name(type, code);
}
//Evdev::Evdev() : dev(nullptr), fd(-1) { }
Evdev::Evdev(const std::string &path) {
fd = open(path.c_str(), O_RDONLY);
if (fd < 0) {
BOOST_THROW_EXCEPTION(EvdevFileOpenError() <<
boost::errinfo_file_name(path)
);
}
int result = libevdev_new_from_fd(fd, &dev);
if (result < 0) {
close(fd);
BOOST_THROW_EXCEPTION(EvdevInitError() <<
boost::errinfo_errno(-result) <<
// the file may have nothing to do with the error, but it will
// add context
boost::errinfo_file_name(path)
);
}
}
Evdev::Evdev(Evdev &&e) : dev(e.dev), fd(e.fd) {
e.dev = nullptr;
e.fd = -1;
}
Evdev::~Evdev() {
if (dev) {
libevdev_free(dev);
}
if (fd > 0) {
close(fd);
}
}
Evdev &Evdev::operator=(Evdev &&old) {
dev = old.dev;
old.dev = nullptr;
fd = old.fd;
old.fd = -1;
return *this;
}
void Evdev::respond(int) {
input_event ie;
int result;
do {
result = libevdev_next_event(
dev,
LIBEVDEV_READ_FLAG_NORMAL | LIBEVDEV_READ_FLAG_BLOCKING,
&ie
);
if (result == LIBEVDEV_READ_STATUS_SUCCESS) {
EventTypeCode etc(ie.type, ie.code);
InputMap::const_iterator iter = receivers.find(etc);
if (iter != receivers.end()) {
iter->second(etc, ie.value);
}
}
} while ((result >= 0) && (libevdev_has_event_pending(dev) > 0));
}
std::string Evdev::name() const {
return libevdev_get_name(dev);
}
bool Evdev::grab() {
return libevdev_grab(dev, LIBEVDEV_GRAB) == 0;
}
bool Evdev::hasEventType(unsigned int et) const {
return libevdev_has_event_type(dev, et) == 1;
}
bool Evdev::hasEventCode(unsigned int et, unsigned int ec) const {
return libevdev_has_event_code(dev, et, ec) == 1;
}
bool Evdev::hasEvent(EventTypeCode etc) const {
return libevdev_has_event_code(dev, etc.type, etc.code) == 1;
}
int Evdev::numSlots() const {
return libevdev_get_num_slots(dev);
}
int Evdev::value(unsigned int et, unsigned int ec) const {
int val;
if (!libevdev_fetch_event_value(dev, et, ec, &val)) {
BOOST_THROW_EXCEPTION(EvdevUnsupportedEvent() <<
EvdevEventType(et) << EvdevEventCode(ec)
);
}
return val;
}
void Evdev::usePoller(Poller &p) {
p.add(shared_from_this(), fd);
}
const input_absinfo *Evdev::absInfo(unsigned int absEc) const {
const input_absinfo *ia = libevdev_get_abs_info(dev, absEc);
if (!ia) {
BOOST_THROW_EXCEPTION(EvdevUnsupportedEvent() <<
EvdevEventType(EV_ABS) << EvdevEventCode(absEc)
);
}
return ia;
}