]> git.tdb.fi Git - libs/gui.git/blob - source/input/linux/gamecontroller.cpp
Zero-initialize JsDevice name buffer to avoid valgrind warning
[libs/gui.git] / source / input / linux / gamecontroller.cpp
1 #include <fcntl.h>
2 #include <linux/joystick.h>
3 #include <msp/core/systemerror.h>
4 #include <msp/io/handle_private.h>
5 #include <msp/strings/format.h>
6 #include "gamecontroller.h"
7 #include "gamecontroller_platform.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace Input {
13
14 GameController::GameController(unsigned index):
15         priv(new Private)
16 {
17         priv->dev = new JsDevice(format("/dev/input/js%d", index));
18         name = priv->dev->get_name();
19         tick();
20 }
21
22 GameController::~GameController()
23 {
24         delete priv->dev;
25         delete priv;
26 }
27
28 void GameController::tick()
29 {
30         js_event events[16];
31         while(1)
32         {
33                 unsigned len = priv->dev->read(reinterpret_cast<char *>(events), sizeof(events));
34
35                 unsigned count = len/sizeof(js_event);
36                 for(unsigned i=0; i<count; ++i)
37                 {
38                         unsigned type = events[i].type&0x7F;
39                         bool init = events[i].type&JS_EVENT_INIT;
40                         if(type==JS_EVENT_AXIS)
41                                 set_axis_value(events[i].number, events[i].value/32768.0f, !init);
42                         else if(type==JS_EVENT_BUTTON)
43                                 set_button_state(events[i].number, events[i].value, !init);
44                 }
45
46                 if(len<sizeof(events))
47                         break;
48         }
49 }
50
51
52 JsDevice::JsDevice(const string &fn)
53 {
54         mode = IO::M_READ;
55         *handle = open(fn.c_str(), O_RDONLY|O_NONBLOCK);
56         if(!handle)
57                 throw system_error(format("open(%s)", fn));
58 }
59
60 string JsDevice::get_name() const
61 {
62         char buf[128] = { 0 };
63         int ret = ioctl(*handle, JSIOCGNAME(sizeof(buf)), buf);
64         if(ret<0)
65                 throw system_error("ioctl(JSIOCGNAME)");
66         return buf;
67 }
68
69 unsigned JsDevice::do_read(char *buf, unsigned size)
70 {
71         return IO::sys_read(handle, buf, size);
72 }
73
74 unsigned JsDevice::do_write(const char *, unsigned)
75 {
76         throw IO::invalid_access(IO::M_WRITE);
77 }
78
79 } // namespace Input
80 } // namespace Msp