8
#include <linux/uinput.h>
11
#include <log4cplus/logger.h>
12
#include <log4cplus/loggingmacros.h>
14
using namespace log4cplus;
16
// Various uinput files we try and open
17
static const char *uinput_filename[] = {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput"};
19
static Logger logger = Logger::getInstance("uinput");
21
UInput::UInput(const char *dev_name, const std::vector< std::list<__u16> > & keys) : fd(-1) {
23
setup(dev_name, keys);
31
int UInput::open(const char *uinput_path) {
32
this->fd = ::open(uinput_path, O_WRONLY | O_NONBLOCK);
40
* Try each uinput until one works
42
void UInput::openAll() {
44
for (int i = 0; i < 3; i++) {
45
ret = open(uinput_filename[i]);
47
// If all things worked, then bail
49
LOG4CPLUS_INFO(logger, "Opened " << uinput_filename[i]);
53
// If the device isn't found, try the next one
58
LOG4CPLUS_ERROR(logger, "Permission denied. Check you have permission to uinput.");
60
LOG4CPLUS_ERROR(logger, errno << " " << strerror(errno));
63
throw std::runtime_error("Failed to open uinput");
67
LOG4CPLUS_ERROR(logger, "uinput was not found. Is the uinput module loaded?");
68
throw std::runtime_error("Failed to open uinput");
72
void UInput::setup(const char *dev_name, const std::vector< std::list<__u16> > & keys) {
75
struct uinput_user_dev uidev;
76
memset(&uidev, 0, sizeof(uidev));
78
strncpy(uidev.name, dev_name, UINPUT_MAX_NAME_SIZE);
79
uidev.id.bustype = BUS_USB;
80
uidev.id.vendor = 1337;
81
uidev.id.product = 1337;
82
uidev.id.version = 1337;
84
ret = write(this->fd, &uidev, sizeof(uidev));
85
if (ret != sizeof(uidev)) {
86
throw std::runtime_error("Failed to setup uinput");
87
//cerr << "Failed to setup uinput: " << errno << " " << strerror(errno) << endl;
90
// We only want to send keypresses
91
ret = ioctl(this->fd, UI_SET_EVBIT, EV_KEY);
93
// Add all the keys we might use
94
for (std::vector< std::list<__u16> >::const_iterator i = keys.begin(); i != keys.end(); ++i) {
95
const std::list<__u16> & kk = *i;
96
for (std::list<__u16>::const_iterator k = kk.begin(); k != kk.end(); ++k) {
98
if (ukey != KEY_RESERVED)
99
ret |= ioctl(this->fd, UI_SET_KEYBIT, ukey);
104
throw std::runtime_error("Failed to setup uinput");
105
//cerr << "Failed to setup uinput" " << errno << " " << strerror(errno) << endl;
109
void UInput::create() {
110
int ret = ioctl(this->fd, UI_DEV_CREATE);
112
throw std::runtime_error("Failed to create uinput");
115
LOG4CPLUS_INFO(logger, "Created uinput device");
117
// This sleep is here, because (for some reason) you need to wait before
118
// sending you first uinput event.
122
void UInput::send_event(__u16 type, __u16 code, __s32 value) const {
123
struct input_event ev;
124
memset(&ev, 0, sizeof(ev));
130
int ret = write(this->fd, &ev, sizeof(ev));
131
if (ret != sizeof(ev)) {
132
throw std::runtime_error("Failed to send_event");
136
void UInput::sync() const {
137
send_event(EV_SYN, SYN_REPORT, 0);
141
void UInput::destroy() {
142
ioctl(this->fd, UI_DEV_DESTROY);