summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/joypad_linux.cpp25
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp65
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h5
3 files changed, 65 insertions, 30 deletions
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 342cff82e9..5d636240b7 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -56,6 +56,14 @@
static const char *ignore_str = "/dev/input/js";
#endif
+// On Linux with Steam Input Xbox 360 devices have an index appended to their device name, this index is
+// the Steam Input gamepad index
+#define VALVE_GAMEPAD_NAME_PREFIX "Microsoft X-Box 360 pad "
+// IDs used by Steam Input virtual controllers.
+// See https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices
+#define VALVE_GAMEPAD_VID 0x28DE
+#define VALVE_GAMEPAD_PID 0x11FF
+
JoypadLinux::Joypad::~Joypad() {
for (int i = 0; i < MAX_ABS; i++) {
if (abs_info[i]) {
@@ -411,8 +419,23 @@ void JoypadLinux::open_joypad(const char *p_path) {
setup_joypad_properties(joypad);
sprintf(uid, "%04x%04x", BSWAP16(inpid.bustype), 0);
if (inpid.vendor && inpid.product && inpid.version) {
+ Dictionary joypad_info;
+ joypad_info["vendor_id"] = inpid.vendor;
+ joypad_info["product_id"] = inpid.product;
+ joypad_info["raw_name"] = name;
+
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);
+
+ if (inpid.vendor == VALVE_GAMEPAD_VID && inpid.product == VALVE_GAMEPAD_PID) {
+ if (name.begins_with(VALVE_GAMEPAD_NAME_PREFIX)) {
+ String idx_str = name.substr(strlen(VALVE_GAMEPAD_NAME_PREFIX));
+ if (idx_str.is_valid_int()) {
+ joypad_info["steam_input_index"] = idx_str.to_int();
+ }
+ }
+ }
+
+ input->joy_connection_changed(joy_num, true, name, uid, joypad_info);
} else {
String uidname = uid;
int uidlen = MIN(name.length(), 11);
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 2643cd3b1a..f0864f5134 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -379,7 +379,11 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
if (show_cursor && !previously_shown) {
WindowID window_id = get_window_at_screen_position(mouse_get_position());
- if (window_id != INVALID_WINDOW_ID) {
+ if (window_id != INVALID_WINDOW_ID && window_mouseover_id != window_id) {
+ if (window_mouseover_id != INVALID_WINDOW_ID) {
+ _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+ window_mouseover_id = window_id;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
}
@@ -744,7 +748,7 @@ int DisplayServerX11::get_screen_count() const {
// Using Xinerama Extension
int event_base, error_base;
- if (XineramaQueryExtension(x11_display, &event_base, &error_base)) {
+ if (xinerama_ext_ok && XineramaQueryExtension(x11_display, &event_base, &error_base)) {
XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
XFree(xsi);
} else {
@@ -756,7 +760,7 @@ int DisplayServerX11::get_screen_count() const {
int DisplayServerX11::get_primary_screen() const {
int event_base, error_base;
- if (XineramaQueryExtension(x11_display, &event_base, &error_base)) {
+ if (xinerama_ext_ok && XineramaQueryExtension(x11_display, &event_base, &error_base)) {
return 0;
} else {
return XDefaultScreen(x11_display);
@@ -809,7 +813,7 @@ Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const {
// Using Xinerama Extension.
int event_base, error_base;
- if (XineramaQueryExtension(x11_display, &event_base, &error_base)) {
+ if (xinerama_ext_ok && XineramaQueryExtension(x11_display, &event_base, &error_base)) {
int count;
XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
@@ -1244,7 +1248,7 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {
XImage *image = nullptr;
int event_base, error_base;
- if (XineramaQueryExtension(x11_display, &event_base, &error_base)) {
+ if (xinerama_ext_ok && XineramaQueryExtension(x11_display, &event_base, &error_base)) {
int xin_count;
XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &xin_count);
if (p_screen < xin_count) {
@@ -1449,6 +1453,11 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
DEBUG_LOG_X11("delete_sub_window: %lu (%u) \n", wd.x11_window, p_id);
+ if (window_mouseover_id == p_id) {
+ window_mouseover_id = INVALID_WINDOW_ID;
+ _send_window_event(windows[p_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+
window_set_rect_changed_callback(Callable(), p_id);
window_set_window_event_callback(Callable(), p_id);
window_set_input_event_callback(Callable(), p_id);
@@ -1586,6 +1595,7 @@ void DisplayServerX11::window_set_mouse_passthrough(const Vector<Vector2> &p_reg
void DisplayServerX11::_update_window_mouse_passthrough(WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window));
+ ERR_FAIL_COND(!xshaped_ext_ok);
const Vector<Vector2> region_path = windows[p_window].mpath;
@@ -3957,7 +3967,7 @@ bool DisplayServerX11::mouse_process_popups() {
// Find top popup to close.
while (E) {
// Popup window area.
- Rect2i win_rect = Rect2i(window_get_position(E->get()), window_get_size(E->get()));
+ Rect2i win_rect = Rect2i(window_get_position_with_decorations(E->get()), window_get_size_with_decorations(E->get()));
// Area of the parent window, which responsible for opening sub-menu.
Rect2i safe_rect = window_get_popup_safe_rect(E->get());
if (win_rect.has_point(pos)) {
@@ -4291,7 +4301,8 @@ void DisplayServerX11::process_events() {
break;
}
- if (!mouse_mode_grab) {
+ if (!mouse_mode_grab && window_mouseover_id == window_id) {
+ window_mouseover_id = INVALID_WINDOW_ID;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
}
@@ -4303,7 +4314,11 @@ void DisplayServerX11::process_events() {
break;
}
- if (!mouse_mode_grab) {
+ if (!mouse_mode_grab && window_mouseover_id != window_id) {
+ if (window_mouseover_id != INVALID_WINDOW_ID) {
+ _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+ window_mouseover_id = window_id;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
} break;
@@ -5461,13 +5476,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
if (initialize_xinerama(dylibloader_verbose) != 0) {
- r_error = ERR_UNAVAILABLE;
- ERR_FAIL_MSG("Can't load Xinerama dynamically.");
+ xinerama_ext_ok = false;
}
if (initialize_xrandr(dylibloader_verbose) != 0) {
- r_error = ERR_UNAVAILABLE;
- ERR_FAIL_MSG("Can't load Xrandr dynamically.");
+ xrandr_ext_ok = false;
}
if (initialize_xrender(dylibloader_verbose) != 0) {
@@ -5537,42 +5550,36 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
return;
}
- {
+ if (xshaped_ext_ok) {
int version_major = 0;
int version_minor = 0;
int rc = XShapeQueryVersion(x11_display, &version_major, &version_minor);
print_verbose(vformat("Xshape %d.%d detected.", version_major, version_minor));
if (rc != 1 || version_major < 1) {
- ERR_PRINT("Unsupported Xshape library version.");
- r_error = ERR_UNAVAILABLE;
- XCloseDisplay(x11_display);
- return;
+ xshaped_ext_ok = false;
+ print_verbose("Unsupported Xshape library version.");
}
}
- {
+ if (xinerama_ext_ok) {
int version_major = 0;
int version_minor = 0;
int rc = XineramaQueryVersion(x11_display, &version_major, &version_minor);
print_verbose(vformat("Xinerama %d.%d detected.", version_major, version_minor));
if (rc != 1 || version_major < 1) {
- ERR_PRINT("Unsupported Xinerama library version.");
- r_error = ERR_UNAVAILABLE;
- XCloseDisplay(x11_display);
- return;
+ xinerama_ext_ok = false;
+ print_verbose("Unsupported Xinerama library version.");
}
}
- {
+ if (xrandr_ext_ok) {
int version_major = 0;
int version_minor = 0;
int rc = XRRQueryVersion(x11_display, &version_major, &version_minor);
print_verbose(vformat("Xrandr %d.%d detected.", version_major, version_minor));
if (rc != 1 || (version_major == 1 && version_minor < 3) || (version_major < 1)) {
- ERR_PRINT("Unsupported Xrandr library version.");
- r_error = ERR_UNAVAILABLE;
- XCloseDisplay(x11_display);
- return;
+ xrandr_ext_ok = false;
+ print_verbose("Unsupported Xrandr library version.");
}
}
@@ -5638,7 +5645,9 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
if (!xrandr_handle) {
fprintf(stderr, "could not load libXrandr.so.2, Error: %s\n", err);
}
- } else {
+ }
+
+ if (xrandr_handle) {
XRRQueryVersion(x11_display, &xrandr_major, &xrandr_minor);
if (((xrandr_major << 8) | xrandr_minor) >= 0x0105) {
xrr_get_monitors = (xrr_get_monitors_t)dlsym(xrandr_handle, "XRRGetMonitors");
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index 70703d42c3..cce44a92de 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -225,6 +225,7 @@ class DisplayServerX11 : public DisplayServer {
List<WindowID> popup_list;
+ WindowID window_mouseover_id = INVALID_WINDOW_ID;
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID window_id_counter = MAIN_WINDOW_ID;
@@ -322,7 +323,9 @@ class DisplayServerX11 : public DisplayServer {
xrr_get_monitors_t xrr_get_monitors = nullptr;
xrr_free_monitors_t xrr_free_monitors = nullptr;
void *xrandr_handle = nullptr;
- Bool xrandr_ext_ok;
+ bool xrandr_ext_ok = true;
+ bool xinerama_ext_ok = true;
+ bool xshaped_ext_ok = true;
struct Property {
unsigned char *data;