1 /*
2  *  OpenSCAD (www.openscad.org)
3  *  Copyright (C) 2009-2015 Clifford Wolf <clifford@clifford.at> and
4  *                          Marius Kintel <marius@kintel.net>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  As a special exception, you have permission to link this program
12  *  with the CGAL library and distribute executables, as long as you
13  *  follow the requirements of the GNU GPL in regard to all of the
14  *  software in the executable aside from CGAL.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  *
25  */
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 
30 #include "InputDriverManager.h"
31 #include "JoystickInputDriver.h"
32 
33 #include <linux/input.h>
34 #include <linux/joystick.h>
35 
run()36 void JoystickInputDriver::run()
37 {
38 	struct js_event js;
39 
40 	while (!stopRequest) {
41 		ssize_t len = read(fd, &js, sizeof(struct js_event));
42 		if (len < 0) {
43 			break;
44 		}
45 		if (len != sizeof(struct js_event)) {
46 			continue;
47 		}
48 		switch (js.type & ~JS_EVENT_INIT) {
49 		case JS_EVENT_BUTTON:
50 			InputDriverManager::instance()->sendEvent(new InputEventButtonChanged(js.number, js.value != 0));
51 			break;
52 		case JS_EVENT_AXIS:
53 			InputDriverManager::instance()->sendEvent(new InputEventAxisChanged(js.number, js.value / 32767.0));
54 			break;
55 		}
56 	}
57 	::close(fd);
58 }
59 
JoystickInputDriver()60 JoystickInputDriver::JoystickInputDriver() : fd(-1), version(0), axes(0), buttons(0), stopRequest(false)
61 {
62 
63 }
64 
~JoystickInputDriver()65 JoystickInputDriver::~JoystickInputDriver()
66 {
67 
68 }
69 
open()70 bool JoystickInputDriver::open()
71 {
72     stopRequest = false;
73 
74     auto path = boost::format("/dev/input/js%d") % this->nr;
75     this->fd = ::open(path.str().c_str(), O_RDONLY);
76 
77     if (fd < 0) {
78         return false;
79     }
80 
81     version = 0;
82     ioctl(fd, JSIOCGVERSION, &version);
83     if (version < 0x010000) {
84         return false;
85     }
86 
87     ioctl(fd, JSIOCGAXES, &axes);
88     ioctl(fd, JSIOCGBUTTONS, &buttons);
89     ioctl(fd, JSIOCGNAME(sizeof(name)), name);
90 
91     start();
92     return true;
93 }
94 
close()95 void JoystickInputDriver::close()
96 {
97     stopRequest=true;
98 }
99 
get_name() const100 const std::string & JoystickInputDriver::get_name() const
101 {
102     static std::string name = "JoystickInputDriver";
103     return name;
104 }
105 
get_info() const106 std::string JoystickInputDriver::get_info() const
107 {
108 	return STR(
109 		get_name() << " " << (isOpen() ? "open" : "not open") << " " <<
110 		"Name: " << name << " " <<
111 		"Axis: " << (int) axes << " " <<
112 		"Buttons: " << (int) buttons << " "
113 	);
114 }
115 
setJoystickNr(std::string jnr)116 void JoystickInputDriver::setJoystickNr(std::string jnr)
117 {
118     this->nr=jnr;
119 }
120