summaryrefslogtreecommitdiff
path: root/platform/x11
diff options
context:
space:
mode:
Diffstat (limited to 'platform/x11')
-rw-r--r--platform/x11/SCsub1
-rw-r--r--platform/x11/context_gl_x11.cpp2
-rw-r--r--platform/x11/context_gl_x11.h2
-rw-r--r--platform/x11/detect.py39
-rw-r--r--platform/x11/godot_x11.cpp2
-rw-r--r--platform/x11/joystick_linux.cpp416
-rw-r--r--platform/x11/joystick_linux.h92
-rw-r--r--platform/x11/key_mapping_x11.cpp2
-rw-r--r--platform/x11/key_mapping_x11.h2
-rw-r--r--platform/x11/os_x11.cpp230
-rw-r--r--platform/x11/os_x11.h37
-rw-r--r--platform/x11/platform_config.h5
12 files changed, 595 insertions, 235 deletions
diff --git a/platform/x11/SCsub b/platform/x11/SCsub
index 7a6f02daa5..80fd347ded 100644
--- a/platform/x11/SCsub
+++ b/platform/x11/SCsub
@@ -5,6 +5,7 @@ common_x11=[\
"context_gl_x11.cpp",\
"os_x11.cpp",\
"key_mapping_x11.cpp",\
+ "joystick_linux.cpp",\
]
env.Program('#bin/godot',['godot_x11.cpp']+common_x11)
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp
index 3db1f6da25..89bd5f58ff 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/x11/context_gl_x11.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index 8b81db9160..56404d0fae 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 9a52a7c92b..e035c72993 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -1,6 +1,7 @@
import os
import sys
+import platform
def is_active():
@@ -44,7 +45,7 @@ def can_build():
print("xinerama not found.. x11 disabled.")
return False
-
+
return True # X11 enabled
def get_opts():
@@ -54,6 +55,7 @@ def get_opts():
('use_sanitizer','Use llvm compiler sanitize address','no'),
('use_leak_sanitizer','Use llvm compiler sanitize memory leaks','no'),
('pulseaudio','Detect & Use pulseaudio','yes'),
+ ('gamepad','Gamepad support, requires libudev and libevdev','yes'),
('new_wm_api', 'Use experimental window management API','no'),
('debug_release', 'Add debug symbols to release version','no'),
]
@@ -118,6 +120,8 @@ def configure(env):
elif (env["target"]=="release_debug"):
env.Append(CCFLAGS=['-O2','-ffast-math','-DDEBUG_ENABLED'])
+ if (env["debug_release"]=="yes"):
+ env.Append(CCFLAGS=['-g2'])
elif (env["target"]=="debug"):
@@ -142,10 +146,33 @@ def configure(env):
env.Append(CPPPATH=['#tools/freetype/freetype/include'])
-
-
env.Append(CPPFLAGS=['-DOPENGL_ENABLED','-DGLEW_ENABLED'])
- env.Append(CPPFLAGS=["-DALSA_ENABLED"])
+
+ if os.system("pkg-config --exists alsa")==0:
+ print("Enabling ALSA")
+ env.Append(CPPFLAGS=["-DALSA_ENABLED"])
+ env.Append(LIBS=['asound'])
+ else:
+ print("ALSA libraries not found, disabling driver")
+
+ if (env["gamepad"]=="yes" and platform.system() == "Linux"):
+ # pkg-config returns 0 when the lib exists...
+ found_udev = not os.system("pkg-config --exists libudev")
+ found_evdev = not os.system("pkg-config --exists libevdev")
+
+ if (found_udev and found_evdev):
+ print("Enabling gamepad support with udev/evdev")
+ env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])
+ env.ParseConfig('pkg-config libudev --cflags --libs')
+ env.ParseConfig('pkg-config libevdev --cflags --libs')
+ else:
+ if (not found_udev):
+ print("libudev development libraries not found")
+ if (not found_evdev):
+ print("libevdev development libraries not found")
+ print("Some libraries are missing for the required gamepad support, aborting!")
+ print("Install the mentioned libraries or build with 'gamepad=no' to disable gamepad support.")
+ sys.exit(255)
if (env["pulseaudio"]=="yes"):
if not os.system("pkg-config --exists libpulse-simple"):
@@ -156,7 +183,7 @@ def configure(env):
print("PulseAudio development libraries not found, disabling driver")
env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES_OVER_GL'])
- env.Append(LIBS=['GL', 'GLU', 'pthread','asound','z']) #TODO detect linux/BSD!
+ env.Append(LIBS=['GL', 'GLU', 'pthread', 'z'])
#env.Append(CPPFLAGS=['-DMPC_FIXED_POINT'])
#host compiler is default..
@@ -180,3 +207,5 @@ def configure(env):
env.Append(CPPFLAGS=['-DNEW_WM_API'])
env.ParseConfig('pkg-config xinerama --cflags --libs')
+ env["x86_opt_gcc"]=True
+
diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp
index f90d40fa5c..ee83da25c1 100644
--- a/platform/x11/godot_x11.cpp
+++ b/platform/x11/godot_x11.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/x11/joystick_linux.cpp b/platform/x11/joystick_linux.cpp
new file mode 100644
index 0000000000..6eb3671bc0
--- /dev/null
+++ b/platform/x11/joystick_linux.cpp
@@ -0,0 +1,416 @@
+/*************************************************************************/
+/* joystick_linux.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+//author: Andreas Haas <hondres, liugam3@gmail.com>
+#ifdef JOYDEV_ENABLED
+
+#include "joystick_linux.h"
+#include "print_string.h"
+
+#include <libevdev/libevdev.h>
+#include <libudev.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <cstring>
+
+static const char* ignore_str = "/dev/input/js";
+
+joystick_linux::Joystick::Joystick() {
+ fd = -1;
+ dpad = 0;
+ dev = NULL;
+ devpath = "";
+}
+
+void joystick_linux::Joystick::reset() {
+ dpad = 0;
+ fd = -1;
+
+ InputDefault::JoyAxis jx;
+ jx.min = -1;
+ jx.value = 0.0f;
+ for (int i=0; i < MAX_ABS; i++) {
+ abs_map[i] = -1;
+ curr_axis[i] = jx;
+ }
+}
+
+joystick_linux::joystick_linux(InputDefault *in)
+{
+ exit_udev = false;
+ input = in;
+ joy_mutex = Mutex::create();
+ joy_thread = Thread::create(joy_thread_func, this);
+}
+
+joystick_linux::~joystick_linux() {
+ exit_udev = true;
+ Thread::wait_to_finish(joy_thread);
+ close_joystick();
+}
+
+void joystick_linux::joy_thread_func(void *p_user) {
+
+ if (p_user) {
+ joystick_linux* joy = (joystick_linux*) p_user;
+ joy->run_joystick_thread();
+ }
+ return;
+}
+
+void joystick_linux::run_joystick_thread() {
+
+ udev *_udev = udev_new();
+ ERR_FAIL_COND(!_udev);
+ enumerate_joysticks(_udev);
+ monitor_joysticks(_udev);
+ udev_unref(_udev);
+}
+
+void joystick_linux::enumerate_joysticks(udev *p_udev) {
+
+ udev_enumerate *enumerate;
+ udev_list_entry *devices, *dev_list_entry;
+ udev_device *dev;
+
+ enumerate = udev_enumerate_new(p_udev);
+ udev_enumerate_add_match_subsystem(enumerate,"input");
+ udev_enumerate_add_match_property(enumerate, "ID_INPUT_JOYSTICK", "1");
+
+ udev_enumerate_scan_devices(enumerate);
+ devices = udev_enumerate_get_list_entry(enumerate);
+ udev_list_entry_foreach(dev_list_entry, devices) {
+
+ const char* path = udev_list_entry_get_name(dev_list_entry);
+ dev = udev_device_new_from_syspath(p_udev, path);
+ const char* devnode = udev_device_get_devnode(dev);
+
+ if (devnode != NULL && strstr(devnode, ignore_str) == NULL) {
+ joy_mutex->lock();
+ open_joystick(devnode);
+ joy_mutex->unlock();
+ }
+ udev_device_unref(dev);
+ }
+ udev_enumerate_unref(enumerate);
+}
+
+void joystick_linux::monitor_joysticks(udev *p_udev) {
+
+ udev_device *dev = NULL;
+ udev_monitor *mon = udev_monitor_new_from_netlink(p_udev, "udev");
+ udev_monitor_filter_add_match_subsystem_devtype(mon, "input", NULL);
+ udev_monitor_enable_receiving(mon);
+ int fd = udev_monitor_get_fd(mon);
+
+ while (!exit_udev) {
+
+ fd_set fds;
+ struct timeval tv;
+ int ret;
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ ret = select(fd+1, &fds, NULL, NULL, &tv);
+
+ /* Check if our file descriptor has received data. */
+ if (ret > 0 && FD_ISSET(fd, &fds)) {
+ /* Make the call to receive the device.
+ select() ensured that this will not block. */
+ dev = udev_monitor_receive_device(mon);
+
+ if (dev && udev_device_get_devnode(dev) != 0) {
+
+ joy_mutex->lock();
+ const char* action = udev_device_get_action(dev);
+ const char* devnode = udev_device_get_devnode(dev);
+
+ if (strstr(devnode, ignore_str) == NULL) {
+
+ if (strcmp(action, "add") == 0)
+ open_joystick(devnode);
+
+ else if (strcmp(action, "remove") == 0)
+ close_joystick(get_joy_from_path(devnode));
+ }
+
+ udev_device_unref(dev);
+ joy_mutex->unlock();
+ }
+ }
+ usleep(50000);
+ }
+ //printf("exit udev\n");
+ udev_monitor_unref(mon);
+}
+
+int joystick_linux::get_free_joy_slot() const {
+
+ for (int i = 0; i < JOYSTICKS_MAX; i++) {
+
+ if (joysticks[i].fd == -1) return i;
+ }
+ return -1;
+}
+
+int joystick_linux::get_joy_from_path(String p_path) const {
+
+ for (int i = 0; i < JOYSTICKS_MAX; i++) {
+
+ if (joysticks[i].devpath == p_path) {
+ return i;
+ }
+ }
+ return -2;
+}
+
+void joystick_linux::close_joystick(int p_id) {
+ if (p_id == -1) {
+ for (int i=0; i<JOYSTICKS_MAX; i++) {
+
+ close_joystick(i);
+ };
+ return;
+ }
+ else if (p_id < 0) return;
+
+ Joystick &joy = joysticks[p_id];
+
+ if (joy.fd != -1) {
+
+ libevdev_free(joy.dev);
+ close(joy.fd);
+ joy.fd = -1;
+ input->joy_connection_changed(p_id, false, "");
+ };
+};
+
+static String _hex_str(uint8_t p_byte) {
+
+ static const char* dict = "0123456789abcdef";
+ char ret[3];
+ ret[2] = 0;
+
+ ret[0] = dict[p_byte>>4];
+ ret[1] = dict[p_byte & 0xF];
+
+ return ret;
+};
+
+void joystick_linux::setup_joystick_properties(int p_id) {
+
+ Joystick* joy = &joysticks[p_id];
+ libevdev* dev = joy->dev;
+
+ int num_buttons = 0;
+ int num_axes = 0;
+
+ for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
+
+ if (libevdev_has_event_code(dev, EV_KEY, i)) {
+
+ joy->key_map[i] = num_buttons++;
+ }
+ }
+ for (int i = BTN_MISC; i < BTN_JOYSTICK; ++i) {
+
+ if (libevdev_has_event_code(dev, EV_KEY, i)) {
+
+ joy->key_map[i] = num_buttons++;
+ }
+ }
+ for (int i = 0; i < ABS_MISC; ++i) {
+ /* Skip hats */
+ if (i == ABS_HAT0X) {
+ i = ABS_HAT3Y;
+ continue;
+ }
+ if (libevdev_has_event_code(dev, EV_ABS, i)) {
+
+ joy->abs_map[i] = num_axes++;
+ }
+ }
+}
+
+void joystick_linux::open_joystick(const char *p_path) {
+
+ int joy_num = get_free_joy_slot();
+ int fd = open(p_path, O_RDONLY | O_NONBLOCK);
+ if (fd != -1 && joy_num != -1) {
+
+ int rc = libevdev_new_from_fd(fd, &joysticks[joy_num].dev);
+ if (rc < 0) {
+
+ fprintf(stderr, "Failed to init libevdev (%s)\n", strerror(-rc));
+ return;
+ }
+
+ libevdev *dev = joysticks[joy_num].dev;
+
+ //check if the device supports basic gamepad events, prevents certain keyboards from
+ //being detected as joysticks
+ if (libevdev_has_event_type(dev, EV_ABS) && libevdev_has_event_type(dev, EV_KEY) &&
+ (libevdev_has_event_code(dev, EV_KEY, BTN_A) || libevdev_has_event_code(dev, EV_KEY, BTN_THUMBL) || libevdev_has_event_code(dev, EV_KEY, BTN_TOP))) {
+
+ char uid[128];
+ String name = libevdev_get_name(dev);
+ uint16_t bus = __bswap_16(libevdev_get_id_bustype(dev));
+ uint16_t vendor = __bswap_16(libevdev_get_id_vendor(dev));
+ uint16_t product = __bswap_16(libevdev_get_id_product(dev));
+ uint16_t version = __bswap_16(libevdev_get_id_version(dev));
+
+ joysticks[joy_num].reset();
+
+ Joystick &joy = joysticks[joy_num];
+ joy.fd = fd;
+ joy.devpath = String(p_path);
+ setup_joystick_properties(joy_num);
+ sprintf(uid, "%04x%04x", bus, 0);
+ if (vendor && product && version) {
+
+ sprintf(uid + String(uid).length(), "%04x%04x%04x%04x%04x%04x", vendor,0,product,0,version,0);
+ input->joy_connection_changed(joy_num, true, name, uid);
+ }
+ else {
+ String uidname = uid;
+ int uidlen = MIN(name.length(), 11);
+ for (int i=0; i<uidlen; i++) {
+
+ uidname = uidname + _hex_str(name[i]);
+ }
+ uidname += "00";
+ input->joy_connection_changed(joy_num, true, name, uidname);
+
+ }
+ }
+ else {
+ //device is not a gamepad, clean up
+ libevdev_free(dev);
+ close(fd);
+ }
+ }
+}
+
+InputDefault::JoyAxis joystick_linux::axis_correct(const input_absinfo *p_abs, int p_value) const {
+
+ int min = p_abs->minimum;
+ int max = p_abs->maximum;
+ InputDefault::JoyAxis jx;
+
+ if (min < 0) {
+ jx.min = -1;
+ if (p_value < 0) {
+ jx.value = (float) -p_value / min;
+ }
+ jx.value = (float) p_value / max;
+ }
+ if (min == 0) {
+ jx.min = 0;
+ jx.value = 0.0f + (float) p_value / max;
+ }
+ return jx;
+}
+
+uint32_t joystick_linux::process_joysticks(uint32_t p_event_id) {
+
+ if (joy_mutex->try_lock() != OK) {
+ return p_event_id;
+ }
+ for (int i=0; i<JOYSTICKS_MAX; i++) {
+
+ if (joysticks[i].fd == -1) continue;
+
+ input_event ev;
+ Joystick* joy = &joysticks[i];
+ libevdev* dev = joy->dev;
+ int rc = 1;
+
+ rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+
+ if (rc < 0 && rc != -EAGAIN) {
+ continue;
+ }
+
+ while (rc == LIBEVDEV_READ_STATUS_SYNC || rc == LIBEVDEV_READ_STATUS_SUCCESS) {
+
+ switch (ev.type) {
+ case EV_KEY:
+ p_event_id = input->joy_button(p_event_id, i, joy->key_map[ev.code], ev.value);
+ break;
+
+ case EV_ABS:
+
+ switch (ev.code) {
+ case ABS_HAT0X:
+ if (ev.value != 0) {
+ if (ev.value < 0) joy->dpad |= InputDefault::HAT_MASK_LEFT;
+ else joy->dpad |= InputDefault::HAT_MASK_RIGHT;
+
+ }
+ else joy->dpad &= ~(InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_RIGHT);
+
+ p_event_id = input->joy_hat(p_event_id, i, joy->dpad);
+ break;
+
+ case ABS_HAT0Y:
+ if (ev.value != 0) {
+ if (ev.value < 0) joy->dpad |= InputDefault::HAT_MASK_UP;
+ else joy->dpad |= InputDefault::HAT_MASK_DOWN;
+ }
+ else joy->dpad &= ~(InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_DOWN);
+
+ p_event_id = input->joy_hat(p_event_id, i, joy->dpad);
+ break;
+
+ default:
+ if (joy->abs_map[ev.code] != -1) {
+ InputDefault::JoyAxis value = axis_correct(libevdev_get_abs_info(dev, ev.code), ev.value);
+ joy->curr_axis[joy->abs_map[ev.code]] = value;
+ }
+ break;
+ }
+ break;
+ }
+ rc = libevdev_next_event(dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+ }
+ for (int j = 0; j < MAX_ABS; j++) {
+ int index = joy->abs_map[j];
+ if (index != -1) {
+ p_event_id = input->joy_axis(p_event_id, i, index, joy->curr_axis[index]);
+ }
+ }
+ }
+ joy_mutex->unlock();
+ return p_event_id;
+}
+#endif
diff --git a/platform/x11/joystick_linux.h b/platform/x11/joystick_linux.h
new file mode 100644
index 0000000000..ee9bd0352a
--- /dev/null
+++ b/platform/x11/joystick_linux.h
@@ -0,0 +1,92 @@
+/*************************************************************************/
+/* joystick_linux.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+//author: Andreas Haas <hondres, liugam3@gmail.com>
+#ifndef JOYSTICK_LINUX_H
+#define JOYSTICK_LINUX_H
+#ifdef JOYDEV_ENABLED
+#include "main/input_default.h"
+#include "os/thread.h"
+#include "os/mutex.h"
+
+struct input_absinfo;
+
+class joystick_linux
+{
+public:
+ joystick_linux(InputDefault *in);
+ ~joystick_linux();
+ uint32_t process_joysticks(uint32_t p_event_id);
+private:
+
+ enum {
+ JOYSTICKS_MAX = 16,
+ MAX_ABS = 63,
+ MAX_KEY = 767, // Hack because <linux/input.h> can't be included here
+ BT_MISC = 256,
+ HAT_MAX = 4,
+ };
+
+ struct Joystick {
+ InputDefault::JoyAxis curr_axis[MAX_ABS];
+ int key_map[MAX_KEY - BT_MISC];
+ int abs_map[MAX_ABS];
+ int dpad;
+ int fd;
+
+ String devpath;
+ struct libevdev *dev;
+
+ Joystick();
+ void reset();
+ };
+
+ bool exit_udev;
+ Mutex *joy_mutex;
+ Thread *joy_thread;
+ InputDefault *input;
+ Joystick joysticks[JOYSTICKS_MAX];
+
+ static void joy_thread_func(void *p_user);
+
+ int get_joy_from_path(String path) const;
+ int get_free_joy_slot() const;
+
+ void setup_joystick_properties(int p_id);
+ void close_joystick(int p_id = -1);
+ void enumerate_joysticks(struct udev *_udev);
+ void monitor_joysticks(struct udev *_udev);
+ void run_joystick_thread();
+ void open_joystick(const char* path);
+
+ InputDefault::JoyAxis axis_correct(const input_absinfo *abs, int value) const;
+};
+
+#endif
+#endif // JOYSTICK_LINUX_H
diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp
index 9c68ac1a2c..48f415a730 100644
--- a/platform/x11/key_mapping_x11.cpp
+++ b/platform/x11/key_mapping_x11.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h
index 7ab883878f..979d8a112f 100644
--- a/platform/x11/key_mapping_x11.h
+++ b/platform/x11/key_mapping_x11.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 74ebad748a..f42e93b93f 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,6 +32,7 @@
#include "key_mapping_x11.h"
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "print_string.h"
#include "servers/physics/physics_server_sw.h"
#include "errno.h"
@@ -57,10 +58,6 @@
#include <fcntl.h>
#include <unistd.h>
-#ifdef __linux__
-#include <linux/joystick.h>
-#endif
-
//stupid linux.h
#ifdef KEY_TAB
#undef KEY_TAB
@@ -81,7 +78,7 @@ const char * OS_X11::get_video_driver_name(int p_driver) const {
}
OS::VideoMode OS_X11::get_default_video_mode() const {
- return OS::VideoMode(800,600,false);
+ return OS::VideoMode(1024,600,false);
}
int OS_X11::get_audio_driver_count() const {
@@ -98,8 +95,6 @@ const char *OS_X11::get_audio_driver_name(int p_driver) const {
void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
last_button_state=0;
- dpad_last[0]=0;
- dpad_last[1]=0;
xmbstring=NULL;
event_id=0;
@@ -431,9 +426,9 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
physics_2d_server->init();
input = memnew( InputDefault );
-
- probe_joystick();
-
+#ifdef JOYDEV_ENABLED
+ joystick = memnew( joystick_linux(input));
+#endif
_ensure_data_dir();
}
@@ -452,6 +447,11 @@ void OS_X11::finalize() {
// memdelete(debugger_connection_console);
//}
+#ifdef JOYDEV_ENABLED
+ memdelete(joystick);
+#endif
+ memdelete(input);
+
memdelete(sample_manager);
audio_server->finish();
@@ -467,8 +467,6 @@ void OS_X11::finalize() {
physics_2d_server->finish();
memdelete(physics_2d_server);
- memdelete(input);
-
XUnmapWindow( x11_display, x11_window );
XDestroyWindow( x11_display, x11_window );
@@ -621,6 +619,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
xev.xclient.data.l[2] = 0;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+
}
int OS_X11::get_screen_count() const {
@@ -889,7 +888,16 @@ void OS_X11::set_window_maximized(bool p_enabled) {
XGetWindowAttributes(x11_display,DefaultRootWindow(x11_display),&xwa);
current_videomode.width = xwa.width;
current_videomode.height = xwa.height;
-*/
+//*/
+
+// current_videomode.width = wm_max_horz;
+// current_videomode.height = wm_max_vert;
+
+ //Size2 ss = get_screen_size(get_current_screen());
+ //current_videomode.width=ss.width;
+ //current_videomode.height=ss.height;
+
+
maximized = p_enabled;
}
@@ -1652,193 +1660,11 @@ String OS_X11::get_system_dir(SystemDir p_dir) const {
return pipe.strip_edges();
}
-
-void OS_X11::close_joystick(int p_id) {
-
- if (p_id == -1) {
- for (int i=0; i<JOYSTICKS_MAX; i++) {
-
- close_joystick(i);
- };
- return;
- };
-
-
- if (joysticks[p_id].fd != -1) {
- close(joysticks[p_id].fd);
- joysticks[p_id].fd = -1;
- };
- input->joy_connection_changed(p_id, false, "");
-};
-
-void OS_X11::probe_joystick(int p_id) {
- #ifndef __FreeBSD__
-
- if (p_id == -1) {
-
- for (int i=0; i<JOYSTICKS_MAX; i++) {
-
- probe_joystick(i);
- };
- return;
- };
-
- if (joysticks[p_id].fd != -1)
- close_joystick(p_id);
-
- const char *joy_names[] = {
- "/dev/input/js%d",
- "/dev/js%d",
- NULL
- };
-
- int i=0;
- while(joy_names[i]) {
-
- char fname[64];
- sprintf(fname, joy_names[i], p_id);
- int fd = open(fname, O_RDONLY|O_NONBLOCK);
- if (fd != -1) {
-
- //fcntl( fd, F_SETFL, O_NONBLOCK );
- joysticks[p_id] = Joystick(); // this will reset the axis array
- joysticks[p_id].fd = fd;
-
- String name;
- char namebuf[255] = {0};
- if (ioctl(fd, JSIOCGNAME(sizeof(namebuf)), namebuf) >= 0) {
- name = namebuf;
- } else {
- name = "error";
- };
-
- input->joy_connection_changed(p_id, true, name);
- break; // don't try the next name
- };
-
- ++i;
- };
- #endif
-};
-
void OS_X11::move_window_to_foreground() {
XRaiseWindow(x11_display,x11_window);
}
-void OS_X11::process_joysticks() {
- #ifndef __FreeBSD__
- int bytes;
- js_event events[32];
- InputEvent ievent;
- for (int i=0; i<JOYSTICKS_MAX; i++) {
-
- if (joysticks[i].fd == -1) {
- probe_joystick(i);
- if (joysticks[i].fd == -1)
- continue;
- };
- ievent.device = i;
-
- while ( (bytes = read(joysticks[i].fd, &events, sizeof(events))) > 0) {
-
- int ev_count = bytes / sizeof(js_event);
- for (int j=0; j<ev_count; j++) {
-
- js_event& event = events[j];
-
- //printf("got event on joystick %i, %i, %i, %i, %i\n", i, joysticks[i].fd, event.type, event.number, event.value);
- if (event.type & JS_EVENT_INIT)
- continue;
-
- switch (event.type & ~JS_EVENT_INIT) {
-
- case JS_EVENT_AXIS:
-
- //if (joysticks[i].last_axis[event.number] != event.value) {
-
- /*
- if (event.number==5 || event.number==6) {
-
- int axis=event.number-5;
- int val = event.value;
- if (val<0)
- val=-1;
- if (val>0)
- val=+1;
-
- InputEvent ev;
- ev.type = InputEvent::JOYSTICK_BUTTON;
- ev.ID = ++event_id;
-
-
- if (val!=dpad_last[axis]) {
-
- int prev_val = dpad_last[axis];
- if (prev_val!=0) {
-
- ev.joy_button.pressed=false;
- ev.joy_button.pressure=0.0;
- if (event.number==5)
- ev.joy_button.button_index=JOY_DPAD_LEFT+(prev_val+1)/2;
- if (event.number==6)
- ev.joy_button.button_index=JOY_DPAD_UP+(prev_val+1)/2;
-
- input->parse_input_event( ev );
- }
- }
-
- if (val!=0) {
-
- ev.joy_button.pressed=true;
- ev.joy_button.pressure=1.0;
- if (event.number==5)
- ev.joy_button.button_index=JOY_DPAD_LEFT+(val+1)/2;
- if (event.number==6)
- ev.joy_button.button_index=JOY_DPAD_UP+(val+1)/2;
-
- input->parse_input_event( ev );
- }
-
-
- dpad_last[axis]=val;
-
- }
- */
- //print_line("ev: "+itos(event.number)+" val: "+ rtos((float)event.value / (float)MAX_JOY_AXIS));
- //if (event.number >= JOY_AXIS_MAX)
- // break;
- //ERR_FAIL_COND(event.number >= JOY_AXIS_MAX);
- ievent.type = InputEvent::JOYSTICK_MOTION;
- ievent.ID = ++event_id;
- ievent.joy_motion.axis = event.number; //_pc_joystick_get_native_axis(event.number);
- ievent.joy_motion.axis_value = (float)event.value / (float)MAX_JOY_AXIS;
- if (event.number < JOY_AXIS_MAX)
- joysticks[i].last_axis[event.number] = event.value;
- input->parse_input_event( ievent );
- //};
- break;
-
- case JS_EVENT_BUTTON:
-
-
- ievent.type = InputEvent::JOYSTICK_BUTTON;
- ievent.ID = ++event_id;
- ievent.joy_button.button_index = event.number; // _pc_joystick_get_native_button(event.number);
- ievent.joy_button.pressed = event.value;
- input->parse_input_event( ievent );
- break;
- };
- };
- };
- if (bytes == 0 || (bytes < 0 && errno != EAGAIN)) {
- close_joystick(i);
- };
- };
- #endif
-};
-
-
void OS_X11::set_cursor_shape(CursorShape p_shape) {
ERR_FAIL_INDEX(p_shape,CURSOR_MAX);
@@ -1938,7 +1764,9 @@ void OS_X11::run() {
while (!force_quit) {
process_xevents(); // get rid of pending events
- process_joysticks();
+#ifdef JOYDEV_ENABLED
+ event_id = joystick->process_joysticks(event_id);
+#endif
if (Main::iteration()==true)
break;
};
@@ -1946,6 +1774,14 @@ void OS_X11::run() {
main_loop->finish();
}
+bool OS_X11::is_joy_known(int p_device) {
+ return input->is_joy_mapped(p_device);
+}
+
+String OS_X11::get_joy_guid(int p_device) const {
+ return input->get_joy_guid_remapped(p_device);
+}
+
OS_X11::OS_X11() {
#ifdef RTAUDIO_ENABLED
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index ed61df8f0e..91dbeac284 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,6 +47,7 @@
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "main/input_default.h"
+#include "joystick_linux.h"
#include <X11/keysym.h>
#include <X11/Xlib.h>
@@ -113,7 +114,6 @@ class OS_X11 : public OS_Unix {
bool force_quit;
bool minimized;
- int dpad_last[2];
bool do_mouse_warp;
@@ -126,6 +126,10 @@ class OS_X11 : public OS_Unix {
InputDefault *input;
+#ifdef JOYDEV_ENABLED
+ joystick_linux *joystick;
+#endif
+
#ifdef RTAUDIO_ENABLED
AudioDriverRtAudio driver_rtaudio;
#endif
@@ -138,26 +142,7 @@ class OS_X11 : public OS_Unix {
AudioDriverPulseAudio driver_pulseaudio;
#endif
- enum {
- JOYSTICKS_MAX = 8,
- MAX_JOY_AXIS = 32768, // I've no idea
- };
-
- struct Joystick {
-
- int fd;
- int last_axis[JOY_AXIS_MAX];
-
- Joystick() {
- fd = -1;
- for (int i=0; i<JOY_AXIS_MAX; i++) {
-
- last_axis[i] = 0;
- };
- };
- };
- int joystick_count;
- Joystick joysticks[JOYSTICKS_MAX];
+ Atom net_wm_icon;
int audio_driver_index;
unsigned int capture_idle;
@@ -180,10 +165,6 @@ protected:
virtual void set_main_loop( MainLoop * p_main_loop );
- void probe_joystick(int p_id = -1);
- void process_joysticks();
- void close_joystick(int p_id = -1);
-
public:
@@ -241,6 +222,10 @@ public:
virtual void move_window_to_foreground();
virtual void alert(const String& p_alert,const String& p_title="ALERT!");
+
+ virtual bool is_joy_known(int p_device);
+ virtual String get_joy_guid(int p_device) const;
+
void run();
OS_X11();
diff --git a/platform/x11/platform_config.h b/platform/x11/platform_config.h
index c01d0aa380..aac50c27c2 100644
--- a/platform/x11/platform_config.h
+++ b/platform/x11/platform_config.h
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,8 +29,9 @@
#ifdef __linux__
#include <alloca.h>
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
#include <stdlib.h>
+#define PTHREAD_BSD_SET_NAME
#endif
#define GLES2_INCLUDE_H "gl_context/glew.h"