First attempt at code for raw mice under Linux

This commit is contained in:
Josh Yelon 2007-03-23 19:42:19 +00:00
parent 125414bdd9
commit d3b05dc48c
5 changed files with 169 additions and 3 deletions

View File

@ -201,7 +201,7 @@ class ShowBase(DirectObject.DirectObject):
# Open the default rendering window. # Open the default rendering window.
if self.windowType != 'none': if self.windowType != 'none':
props = WindowProperties.getDefault() props = WindowProperties.getDefault()
if (self.config.GetBool('read-raw-mice', 1)): if (self.config.GetBool('read-raw-mice', 0)):
props.setRawMice(1) props.setRawMice(1)
self.openDefaultWindow(startDirect = False, props=props) self.openDefaultWindow(startDirect = False, props=props)

View File

@ -1627,6 +1627,7 @@ DEFAULT_SETTINGS=[
("HAVE_GETOPT", 'UNDEF', '1'), ("HAVE_GETOPT", 'UNDEF', '1'),
("HAVE_GETOPT_LONG_ONLY", 'UNDEF', '1'), ("HAVE_GETOPT_LONG_ONLY", 'UNDEF', '1'),
("HAVE_GETOPT_H", 'UNDEF', '1'), ("HAVE_GETOPT_H", 'UNDEF', '1'),
("HAVE_LINUX_INPUT_H", 'UNDEF', '1'),
("IOCTL_TERMINAL_WIDTH", 'UNDEF', '1'), ("IOCTL_TERMINAL_WIDTH", 'UNDEF', '1'),
("HAVE_STREAMSIZE", '1', '1'), ("HAVE_STREAMSIZE", '1', '1'),
("HAVE_IOS_TYPEDEFS", '1', '1'), ("HAVE_IOS_TYPEDEFS", '1', '1'),
@ -1857,8 +1858,8 @@ if (sys.platform != "win32"):
confautoprc = confautoprc.replace("aux-display pandadx8","") confautoprc = confautoprc.replace("aux-display pandadx8","")
confautoprc = confautoprc.replace("aux-display pandadx7","") confautoprc = confautoprc.replace("aux-display pandadx7","")
ConditionalWriteFile("built/etc/Confauto.prc", confautoprc)
ConditionalWriteFile("built/etc/Config.prc", configprc) ConditionalWriteFile("built/etc/Config.prc", configprc)
ConditionalWriteFile("built/etc/Confauto.prc", confautoprc)
########################################################################################## ##########################################################################################
# #

View File

@ -182,6 +182,9 @@ add_properties(const WindowProperties &other) {
if (other.has_minimized()) { if (other.has_minimized()) {
set_minimized(other.get_minimized()); set_minimized(other.get_minimized());
} }
if (other.has_raw_mice()) {
set_raw_mice(other.get_raw_mice());
}
if (other.has_open()) { if (other.has_open()) {
set_open(other.get_open()); set_open(other.get_open());
} }
@ -241,6 +244,9 @@ output(ostream &out) const {
if (has_minimized()) { if (has_minimized()) {
out << (get_minimized() ? "minimized " : "!minimized "); out << (get_minimized() ? "minimized " : "!minimized ");
} }
if (has_raw_mice()) {
out << (get_raw_mice() ? "raw_mice " : "!raw_mice ");
}
if (has_open()) { if (has_open()) {
out << (get_open() ? "open " : "!open "); out << (get_open() ? "open " : "!open ");
} }

View File

@ -37,8 +37,14 @@
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#ifdef HAVE_LINUX_INPUT_H
#include <linux/input.h>
#endif
TypeHandle glxGraphicsWindow::_type_handle; TypeHandle glxGraphicsWindow::_type_handle;
#define test_bit(bit, array) ((array)[(bit)/8] & (1<<((bit)&7)))
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: glxGraphicsWindow::Constructor // Function: glxGraphicsWindow::Constructor
// Access: Public // Access: Public
@ -236,6 +242,8 @@ process_events() {
return; return;
} }
poll_raw_mice();
XEvent event; XEvent event;
XKeyEvent keyrelease_event; XKeyEvent keyrelease_event;
bool got_keyrelease_event = false; bool got_keyrelease_event = false;
@ -683,6 +691,13 @@ open_window() {
XMapWindow(_display, _xwindow); XMapWindow(_display, _xwindow);
if (_properties.get_raw_mice()) {
open_raw_mice();
} else {
glxdisplay_cat.error() <<
"Raw mice not requested.\n";
}
return true; return true;
} }
@ -1003,6 +1018,140 @@ setup_colormap(XVisualInfo *visual) {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsWindow::open_raw_mice
// Access: Private
// Description: Adds raw mice to the _input_devices list.
////////////////////////////////////////////////////////////////////
void glxGraphicsWindow::
open_raw_mice()
{
#ifdef HAVE_LINUX_INPUT_H
bool any_present = false;
bool any_mice = false;
for (int i=0; i<64; i++) {
uint8_t evtypes[EV_MAX/8 + 1];
ostringstream fnb;
fnb << "/dev/input/event" << i;
string fn = fnb.str();
int fd = open(fn.c_str(), O_RDONLY | O_NONBLOCK, 0);
if (fd >= 0) {
any_present = true;
char name[256];
char phys[256];
char uniq[256];
if ((ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0)||
(ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) < 0)||
(ioctl(fd, EVIOCGPHYS(sizeof(uniq)), uniq) < 0)||
(ioctl(fd, EVIOCGBIT(0, EV_MAX), &evtypes) < 0)) {
close(fd);
glxdisplay_cat.error() <<
"Opening raw mice: ioctl failed on " << fn << "\n";
} else {
if (test_bit(EV_REL, evtypes) || test_bit(EV_ABS, evtypes)) {
string full_id = ((string)name) + " " + uniq;
MouseDeviceInfo inf;
inf._fd = fd;
inf._input_device_index = _input_devices.size();
inf._io_buffer = "";
_mouse_device_info.push_back(inf);
GraphicsWindowInputDevice device =
GraphicsWindowInputDevice::pointer_only(full_id);
_input_devices.push_back(device);
any_mice = true;
} else {
close(fd);
}
}
} else {
if ((errno == ENOENT)||(errno == ENOTDIR)) {
break;
} else {
any_present = true;
glxdisplay_cat.error() <<
"Opening raw mice: " << strerror(errno) << " " << fn << "\n";
}
}
}
if (!any_present) {
glxdisplay_cat.error() <<
"Opening raw mice: files not found: /dev/input/event*\n";
} else if (!any_mice) {
glxdisplay_cat.error() <<
"Opening raw mice: no mouse devices detected in /dev/input/event*\n";
}
#else
glxdisplay_cat.error() <<
"Opening raw mice: panda not compiled with raw mouse support.\n";
#endif
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsWindow::poll_raw_mice
// Access: Private
// Description: Reads events from the raw mouse device files.
////////////////////////////////////////////////////////////////////
void glxGraphicsWindow::
poll_raw_mice()
{
#ifdef HAVE_LINUX_INPUT_H
for (int dev=0; dev<_mouse_device_info.size(); dev++) {
MouseDeviceInfo &inf = _mouse_device_info[dev];
// Read all bytes into buffer.
if (inf._fd >= 0) {
while (1) {
char tbuf[1024];
int nread = read(inf._fd, tbuf, sizeof(tbuf));
if (nread > 0) {
inf._io_buffer += string(tbuf, nread);
} else {
if ((nread < 0)&&((errno == EWOULDBLOCK) || (errno==EAGAIN))) {
break;
}
close(inf._fd);
inf._fd = -1;
break;
}
}
}
// Process events.
int nevents = inf._io_buffer.size() / sizeof(struct input_event);
if (nevents == 0) {
continue;
}
const input_event *events = (const input_event *)(inf._io_buffer.c_str());
GraphicsWindowInputDevice &dev = _input_devices[inf._input_device_index];
int x = dev.get_pointer().get_x();
int y = dev.get_pointer().get_y();
for (int i=0; i<nevents; i++) {
if (events[i].type == EV_REL) {
if (events[i].code == REL_X) x += events[i].value;
if (events[i].code == REL_Y) y += events[i].value;
} else if (events[i].type == EV_ABS) {
if (events[i].code == ABS_X) x = events[i].value;
if (events[i].code == ABS_Y) y = events[i].value;
} else if (events[i].type == EV_KEY) {
if ((events[i].code >= BTN_MOUSE)&&(events[i].code < BTN_MOUSE+8)) {
int btn = events[i].code - BTN_MOUSE;
dev.set_pointer_in_window(x,y);
if (events[i].value) {
dev.button_down(MouseButton::button(btn));
} else {
dev.button_up(MouseButton::button(btn));
}
}
}
}
inf._io_buffer.erase(0,nevents*sizeof(struct input_event));
dev.set_pointer_in_window(x,y);
}
#endif
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: glxGraphicsWindow::handle_keystroke // Function: glxGraphicsWindow::handle_keystroke
// Access: Private // Access: Private

View File

@ -70,6 +70,9 @@ private:
static Bool check_event(Display *display, XEvent *event, char *arg); static Bool check_event(Display *display, XEvent *event, char *arg);
void open_raw_mice();
void poll_raw_mice();
private: private:
Display *_display; Display *_display;
int _screen; int _screen;
@ -90,6 +93,13 @@ private:
Atom _net_wm_state_add; Atom _net_wm_state_add;
Atom _net_wm_state_remove; Atom _net_wm_state_remove;
struct MouseDeviceInfo {
int _fd;
int _input_device_index;
string _io_buffer;
};
pvector<MouseDeviceInfo> _mouse_device_info;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;