summaryrefslogtreecommitdiff
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/README.md11
-rw-r--r--platform/linuxbsd/SCsub1
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp10
-rw-r--r--platform/linuxbsd/detect.py56
-rw-r--r--platform/linuxbsd/display_server_x11.cpp341
-rw-r--r--platform/linuxbsd/display_server_x11.h172
-rw-r--r--platform/linuxbsd/export/export.cpp8
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.cpp125
-rw-r--r--platform/linuxbsd/freedesktop_screensaver.h47
-rw-r--r--platform/linuxbsd/joypad_linux.cpp20
-rw-r--r--platform/linuxbsd/key_mapping_x11.cpp28
-rw-r--r--platform/linuxbsd/key_mapping_x11.h5
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp80
-rw-r--r--platform/linuxbsd/os_linuxbsd.h4
-rw-r--r--platform/linuxbsd/vulkan_context_x11.cpp12
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h2
16 files changed, 611 insertions, 311 deletions
diff --git a/platform/linuxbsd/README.md b/platform/linuxbsd/README.md
new file mode 100644
index 0000000000..0d3fb37be5
--- /dev/null
+++ b/platform/linuxbsd/README.md
@@ -0,0 +1,11 @@
+# Linux/*BSD platform port
+
+This folder contains the C++ code for the Linux/*BSD platform port.
+
+## Artwork license
+
+[`logo.png`](logo.png) is derived from the [Linux logo](https://isc.tamu.edu/~lewing/linux/):
+
+> Permission to use and/or modify this image is granted provided you acknowledge me
+ <lewing@isc.tamu.edu> and [The GIMP](https://isc.tamu.edu/~lewing/gimp/)
+ if someone asks.
diff --git a/platform/linuxbsd/SCsub b/platform/linuxbsd/SCsub
index 1751d56e71..8aebd57fd2 100644
--- a/platform/linuxbsd/SCsub
+++ b/platform/linuxbsd/SCsub
@@ -9,6 +9,7 @@ common_linuxbsd = [
"crash_handler_linuxbsd.cpp",
"os_linuxbsd.cpp",
"joypad_linux.cpp",
+ "freedesktop_screensaver.cpp",
]
if "x11" in env and env["x11"]:
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index ea0222cb19..0e98af71fa 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -32,6 +32,8 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
+#include "core/version.h"
+#include "core/version_hash.gen.h"
#include "main/main.h"
#ifdef DEBUG_ENABLED
@@ -61,12 +63,19 @@ static void handle_crash(int sig) {
}
// Dump the backtrace to stderr with a message to the user
+ fprintf(stderr, "\n================================================================\n");
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
}
+ // Print the engine version just before, so that people are reminded to include the version in backtrace reports.
+ if (String(VERSION_HASH).length() != 0) {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n");
+ } else {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n");
+ }
fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data());
char **strings = backtrace_symbols(bt_buffer, size);
if (strings) {
@@ -115,6 +124,7 @@ static void handle_crash(int sig) {
free(strings);
}
fprintf(stderr, "-- END OF BACKTRACE --\n");
+ fprintf(stderr, "================================================================\n");
// Abort to pass the error to the OS
abort();
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 1487210174..8eb22c1c72 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -18,40 +18,42 @@ def can_build():
# Check the minimal dependencies
x11_error = os.system("pkg-config --version > /dev/null")
if x11_error:
+ print("Error: pkg-config not found. Aborting.")
return False
- x11_error = os.system("pkg-config x11 --modversion > /dev/null ")
+ x11_error = os.system("pkg-config x11 --modversion > /dev/null")
if x11_error:
+ print("Error: X11 libraries not found. Aborting.")
return False
- x11_error = os.system("pkg-config xcursor --modversion > /dev/null ")
+ x11_error = os.system("pkg-config xcursor --modversion > /dev/null")
if x11_error:
- print("xcursor not found.. x11 disabled.")
+ print("Error: Xcursor library not found. Aborting.")
return False
- x11_error = os.system("pkg-config xinerama --modversion > /dev/null ")
+ x11_error = os.system("pkg-config xinerama --modversion > /dev/null")
if x11_error:
- print("xinerama not found.. x11 disabled.")
+ print("Error: Xinerama library not found. Aborting.")
return False
- x11_error = os.system("pkg-config xext --modversion > /dev/null ")
+ x11_error = os.system("pkg-config xext --modversion > /dev/null")
if x11_error:
- print("xext not found.. x11 disabled.")
+ print("Error: Xext library not found. Aborting.")
return False
- x11_error = os.system("pkg-config xrandr --modversion > /dev/null ")
+ x11_error = os.system("pkg-config xrandr --modversion > /dev/null")
if x11_error:
- print("xrandr not found.. x11 disabled.")
+ print("Error: XrandR library not found. Aborting.")
return False
- x11_error = os.system("pkg-config xrender --modversion > /dev/null ")
+ x11_error = os.system("pkg-config xrender --modversion > /dev/null")
if x11_error:
- print("xrender not found.. x11 disabled.")
+ print("Error: XRender library not found. Aborting.")
return False
- x11_error = os.system("pkg-config xi --modversion > /dev/null ")
+ x11_error = os.system("pkg-config xi --modversion > /dev/null")
if x11_error:
- print("xi not found.. Aborting.")
+ print("Error: Xi library not found. Aborting.")
return False
return True
@@ -72,6 +74,7 @@ def get_opts():
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False),
BoolVariable("pulseaudio", "Detect and use PulseAudio", True),
+ BoolVariable("dbus", "Detect and use D-Bus to handle screensaver", True),
BoolVariable("udev", "Use udev for gamepad connection callbacks", True),
BoolVariable("x11", "Enable X11 display", True),
BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
@@ -137,7 +140,7 @@ def configure(env):
# A convenience so you don't need to write use_lto too when using SCons
env["use_lto"] = True
else:
- print("Using LLD with GCC is not supported yet, try compiling with 'use_llvm=yes'.")
+ print("Using LLD with GCC is not supported yet. Try compiling with 'use_llvm=yes'.")
sys.exit(255)
if env["use_coverage"]:
@@ -200,11 +203,6 @@ def configure(env):
env.Append(CCFLAGS=["-pipe"])
env.Append(LINKFLAGS=["-pipe"])
- # -fpie and -no-pie is supported on GCC 6+ and Clang 4+, both below our
- # minimal requirements.
- env.Append(CCFLAGS=["-fpie"])
- env.Append(LINKFLAGS=["-no-pie"])
-
## Dependencies
env.ParseConfig("pkg-config x11 --cflags --libs")
@@ -333,28 +331,32 @@ def configure(env):
## Flags
if os.system("pkg-config --exists alsa") == 0: # 0 means found
- print("Enabling ALSA")
env["alsa"] = True
env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"])
else:
- print("ALSA libraries not found, disabling driver")
+ print("Warning: ALSA libraries not found. Disabling the ALSA audio driver.")
if env["pulseaudio"]:
if os.system("pkg-config --exists libpulse") == 0: # 0 means found
- print("Enabling PulseAudio")
env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"])
env.ParseConfig("pkg-config --cflags libpulse")
else:
- print("PulseAudio development libraries not found, disabling driver")
+ print("Warning: PulseAudio development libraries not found. Disabling the PulseAudio audio driver.")
+
+ if env["dbus"]:
+ if os.system("pkg-config --exists dbus-1") == 0: # 0 means found
+ env.Append(CPPDEFINES=["DBUS_ENABLED"])
+ env.ParseConfig("pkg-config --cflags --libs dbus-1")
+ else:
+ print("Warning: D-Bus development libraries not found. Disabling screensaver prevention.")
if platform.system() == "Linux":
env.Append(CPPDEFINES=["JOYDEV_ENABLED"])
if env["udev"]:
if os.system("pkg-config --exists libudev") == 0: # 0 means found
- print("Enabling udev support")
env.Append(CPPDEFINES=["UDEV_ENABLED"])
else:
- print("libudev development libraries not found, disabling udev support")
+ print("Warning: libudev development libraries not found. Disabling controller hotplugging support.")
else:
env["udev"] = False # Linux specific
@@ -375,7 +377,7 @@ def configure(env):
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
- if not env["builtin_vulkan"]:
+ if not env["use_volk"]:
env.ParseConfig("pkg-config vulkan --cflags --libs")
if not env["builtin_glslang"]:
# No pkgconfig file for glslang so far
@@ -403,7 +405,7 @@ def configure(env):
gnu_ld_version = re.search("^GNU ld [^$]*(\d+\.\d+)$", linker_version_str, re.MULTILINE)
if not gnu_ld_version:
print(
- "Warning: Creating template binaries enabled for PCK embedding is currently only supported with GNU ld"
+ "Warning: Creating template binaries enabled for PCK embedding is currently only supported with GNU ld, not gold or LLD."
)
else:
if float(gnu_ld_version.group(1)) >= 2.30:
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 8b6922699c..f2cd336b39 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -121,6 +121,9 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
case FEATURE_ICON:
case FEATURE_NATIVE_ICON:
case FEATURE_SWAP_BUFFERS:
+#ifdef DBUS_ENABLED
+ case FEATURE_KEEP_SCREEN_ON:
+#endif
return true;
default: {
}
@@ -133,70 +136,6 @@ String DisplayServerX11::get_name() const {
return "X11";
}
-void DisplayServerX11::alert(const String &p_alert, const String &p_title) {
- const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" };
-
- String path = OS::get_singleton()->get_environment("PATH");
- Vector<String> path_elems = path.split(":", false);
- String program;
-
- for (int i = 0; i < path_elems.size(); i++) {
- for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
- String tested_path = path_elems[i].plus_file(message_programs[k]);
-
- if (FileAccess::exists(tested_path)) {
- program = tested_path;
- break;
- }
- }
-
- if (program.length()) {
- break;
- }
- }
-
- List<String> args;
-
- if (program.ends_with("zenity")) {
- args.push_back("--error");
- args.push_back("--width");
- args.push_back("500");
- args.push_back("--title");
- args.push_back(p_title);
- args.push_back("--text");
- args.push_back(p_alert);
- }
-
- if (program.ends_with("kdialog")) {
- args.push_back("--error");
- args.push_back(p_alert);
- args.push_back("--title");
- args.push_back(p_title);
- }
-
- if (program.ends_with("Xdialog")) {
- args.push_back("--title");
- args.push_back(p_title);
- args.push_back("--msgbox");
- args.push_back(p_alert);
- args.push_back("0");
- args.push_back("0");
- }
-
- if (program.ends_with("xmessage")) {
- args.push_back("-center");
- args.push_back("-title");
- args.push_back(p_title);
- args.push_back(p_alert);
- }
-
- if (program.length()) {
- OS::get_singleton()->execute(program, args);
- } else {
- print_line(p_alert);
- }
-}
-
void DisplayServerX11::_update_real_mouse_position(const WindowData &wd) {
Window root_return, child_return;
int root_x, root_y, win_x, win_y;
@@ -367,11 +306,11 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
// The only modes that show a cursor are VISIBLE and CONFINED
bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
if (showCursor) {
- XDefineCursor(x11_display, E->get().x11_window, cursors[current_cursor]); // show cursor
+ XDefineCursor(x11_display, E.value.x11_window, cursors[current_cursor]); // show cursor
} else {
- XDefineCursor(x11_display, E->get().x11_window, null_cursor); // hide cursor
+ XDefineCursor(x11_display, E.value.x11_window, null_cursor); // hide cursor
}
}
mouse_mode = p_mode;
@@ -450,7 +389,7 @@ Point2i DisplayServerX11::mouse_get_absolute_position() const {
return Vector2i();
}
-int DisplayServerX11::mouse_get_button_state() const {
+MouseButton DisplayServerX11::mouse_get_button_state() const {
return last_button_state;
}
@@ -822,20 +761,40 @@ bool DisplayServerX11::screen_is_touchscreen(int p_screen) const {
return DisplayServer::screen_is_touchscreen(p_screen);
}
+#ifdef DBUS_ENABLED
+void DisplayServerX11::screen_set_keep_on(bool p_enable) {
+ if (screen_is_kept_on() == p_enable) {
+ return;
+ }
+
+ if (p_enable) {
+ screensaver->inhibit();
+ } else {
+ screensaver->uninhibit();
+ }
+
+ keep_screen_on = p_enable;
+}
+
+bool DisplayServerX11::screen_is_kept_on() const {
+ return keep_screen_on;
+}
+#endif
+
Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
_THREAD_SAFE_METHOD_
Vector<int> ret;
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- ret.push_back(E->key());
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ ret.push_back(E.key);
}
return ret;
}
-DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
_THREAD_SAFE_METHOD_
- WindowID id = _create_window(p_mode, p_flags, p_rect);
+ WindowID id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect);
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
@@ -848,7 +807,9 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, u
void DisplayServerX11::show_window(WindowID p_id) {
_THREAD_SAFE_METHOD_
- WindowData &wd = windows[p_id];
+ const WindowData &wd = windows[p_id];
+
+ DEBUG_LOG_X11("show_window: %lu (%u) \n", wd.x11_window, p_id);
XMapWindow(x11_display, wd.x11_window);
}
@@ -903,8 +864,8 @@ DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const
WindowID found_window = INVALID_WINDOW_ID;
WindowID parent_window = INVALID_WINDOW_ID;
unsigned int focus_order = 0;
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- const WindowData &wd = E->get();
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ const WindowData &wd = E.value;
// Discard windows with no focus.
if (wd.focus_order == 0) {
@@ -912,7 +873,7 @@ DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const
}
// Find topmost window which contains the given position.
- WindowID window_id = E->key();
+ WindowID window_id = E.key;
Rect2i win_rect = Rect2i(window_get_position(window_id), window_get_size(window_id));
if (win_rect.has_point(p_position)) {
// For siblings, pick the window which was focused last.
@@ -1072,6 +1033,8 @@ void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent
WindowID prev_parent = wd_window.transient_parent;
ERR_FAIL_COND(prev_parent == p_parent);
+ DEBUG_LOG_X11("window_set_transient: %lu (%u), prev_parent=%u, parent=%u\n", wd_window.x11_window, p_window, prev_parent, p_parent);
+
ERR_FAIL_COND_MSG(wd_window.on_top, "Windows with the 'on top' can't become transient.");
if (p_parent == INVALID_WINDOW_ID) {
//remove transient
@@ -1086,10 +1049,10 @@ void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent
XSetTransientForHint(x11_display, wd_window.x11_window, None);
- // Set focus to parent sub window to avoid losing all focus with nested menus.
+ // Set focus to parent sub window to avoid losing all focus when closing a nested sub-menu.
// RevertToPointerRoot is used to make sure we don't lose all focus in case
// a subwindow and its parent are both destroyed.
- if (wd_window.menu_type && !wd_window.no_focus) {
+ if (wd_window.menu_type && !wd_window.no_focus && wd_window.focused) {
if (!wd_parent.no_focus) {
XSetInputFocus(x11_display, wd_parent.x11_window, RevertToPointerRoot, CurrentTime);
}
@@ -1805,8 +1768,8 @@ bool DisplayServerX11::window_can_draw(WindowID p_window) const {
bool DisplayServerX11::can_any_window_draw() const {
_THREAD_SAFE_METHOD_
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- if (window_get_mode(E->key()) != WINDOW_MODE_MINIMIZED) {
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ if (window_get_mode(E.key) != WINDOW_MODE_MINIMIZED) {
return true;
}
}
@@ -1878,12 +1841,12 @@ void DisplayServerX11::cursor_set_shape(CursorShape p_shape) {
if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) {
if (cursors[p_shape] != None) {
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- XDefineCursor(x11_display, E->get().x11_window, cursors[p_shape]);
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ XDefineCursor(x11_display, E.value.x11_window, cursors[p_shape]);
}
} else if (cursors[CURSOR_ARROW] != None) {
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- XDefineCursor(x11_display, E->get().x11_window, cursors[CURSOR_ARROW]);
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ XDefineCursor(x11_display, E.value.x11_window, cursors[CURSOR_ARROW]);
}
}
}
@@ -1981,8 +1944,8 @@ void DisplayServerX11::cursor_set_custom_image(const RES &p_cursor, CursorShape
if (p_shape == current_cursor) {
if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) {
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- XDefineCursor(x11_display, E->get().x11_window, cursors[p_shape]);
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ XDefineCursor(x11_display, E.value.x11_window, cursors[p_shape]);
}
}
}
@@ -2105,6 +2068,24 @@ String DisplayServerX11::keyboard_get_layout_name(int p_index) const {
return ret;
}
+Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const {
+ unsigned int modifiers = p_keycode & KEY_MODIFIER_MASK;
+ unsigned int keycode_no_mod = p_keycode & KEY_CODE_MASK;
+ unsigned int xkeycode = KeyMappingX11::get_xlibcode((Key)keycode_no_mod);
+ KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, 0, 0);
+ if (xkeysym >= 'a' && xkeysym <= 'z') {
+ xkeysym -= ('a' - 'A');
+ }
+
+ Key key = KeyMappingX11::get_keycode(xkeysym);
+ // If not found, fallback to QWERTY.
+ // This should match the behavior of the event pump
+ if (key == KEY_NONE) {
+ return p_keycode;
+ }
+ return (Key)(key | modifiers);
+}
+
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {
Atom actual_type = None;
int actual_format = 0;
@@ -2172,13 +2153,13 @@ void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<Inp
state->set_meta_pressed((p_x11_state & Mod4Mask));
}
-unsigned int DisplayServerX11::_get_mouse_button_state(unsigned int p_x11_button, int p_x11_type) {
- unsigned int mask = 1 << (p_x11_button - 1);
+MouseButton DisplayServerX11::_get_mouse_button_state(MouseButton p_x11_button, int p_x11_type) {
+ MouseButton mask = MouseButton(1 << (p_x11_button - 1));
if (p_x11_type == ButtonPress) {
last_button_state |= mask;
} else {
- last_button_state &= ~mask;
+ last_button_state &= MouseButton(~mask);
}
return last_button_state;
@@ -2204,7 +2185,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
// still works in half the cases. (won't handle deadkeys)
// For more complex input methods (deadkeys and more advanced)
// you have to use XmbLookupString (??).
- // So.. then you have to chosse which of both results
+ // So then you have to choose which of both results
// you want to keep.
// This is a real bizarreness and cpu waster.
@@ -2244,7 +2225,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
if (status == XLookupChars) {
bool keypress = xkeyevent->type == KeyPress;
- unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
+ Key keycode = KeyMappingX11::get_keycode(keysym_keycode);
unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
if (keycode >= 'a' && keycode <= 'z') {
@@ -2255,13 +2236,13 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
tmp.parse_utf8(utf8string, utf8bytes);
for (int i = 0; i < tmp.length(); i++) {
Ref<InputEventKey> k;
- k.instance();
+ k.instantiate();
if (physical_keycode == 0 && keycode == 0 && tmp[i] == 0) {
continue;
}
if (keycode == 0) {
- keycode = physical_keycode;
+ keycode = (Key)physical_keycode;
}
_get_key_modifier_state(xkeyevent->state, k);
@@ -2273,7 +2254,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_keycode(keycode);
- k->set_physical_keycode(physical_keycode);
+ k->set_physical_keycode((Key)physical_keycode);
k->set_echo(false);
@@ -2284,7 +2265,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_shift_pressed(true);
}
- Input::get_singleton()->accumulate_input_event(k);
+ Input::get_singleton()->parse_input_event(k);
}
memfree(utf8string);
return;
@@ -2308,7 +2289,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
// KeyMappingX11 just translated the X11 keysym to a PIGUI
// keysym, so it works in all platforms the same.
- unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
+ Key keycode = KeyMappingX11::get_keycode(keysym_keycode);
unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
/* Phase 3, obtain a unicode character from the keysym */
@@ -2329,12 +2310,12 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
bool keypress = xkeyevent->type == KeyPress;
- if (physical_keycode == 0 && keycode == 0 && unicode == 0) {
+ if (physical_keycode == 0 && keycode == KEY_NONE && unicode == 0) {
return;
}
- if (keycode == 0) {
- keycode = physical_keycode;
+ if (keycode == KEY_NONE) {
+ keycode = (Key)physical_keycode;
}
/* Phase 5, determine modifier mask */
@@ -2346,7 +2327,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
//print_verbose("mod1: "+itos(xkeyevent->state&Mod1Mask)+" mod 5: "+itos(xkeyevent->state&Mod5Mask));
Ref<InputEventKey> k;
- k.instance();
+ k.instantiate();
k->set_window_id(p_window);
_get_key_modifier_state(xkeyevent->state, k);
@@ -2397,11 +2378,11 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_pressed(keypress);
if (keycode >= 'a' && keycode <= 'z') {
- keycode -= 'a' - 'A';
+ keycode -= int('a' - 'A');
}
k->set_keycode(keycode);
- k->set_physical_keycode(physical_keycode);
+ k->set_physical_keycode((Key)physical_keycode);
k->set_unicode(unicode);
k->set_echo(p_echo);
@@ -2433,7 +2414,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
}
}
- Input::get_singleton()->accumulate_input_event(k);
+ Input::get_singleton()->parse_input_event(k);
}
Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property) const {
@@ -2554,8 +2535,8 @@ void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data,
DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data);
ds->xim = nullptr;
- for (Map<WindowID, WindowData>::Element *E = ds->windows.front(); E; E = E->next()) {
- E->get().xic = nullptr;
+ for (KeyValue<WindowID, WindowData> &E : ds->windows) {
+ E.value.xic = nullptr;
}
}
@@ -2563,9 +2544,9 @@ void DisplayServerX11::_window_changed(XEvent *event) {
WindowID window_id = MAIN_WINDOW_ID;
// Assign the event to the relevant window
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- if (event->xany.window == E->get().x11_window) {
- window_id = E->key();
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ if (event->xany.window == E.value.x11_window) {
+ window_id = E.key;
break;
}
}
@@ -2639,8 +2620,8 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) {
callable.call((const Variant **)&evp, 1, ret, ce);
} else {
//send to all windows
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- Callable callable = E->get().input_event_callback;
+ for (KeyValue<WindowID, WindowData> &E : windows) {
+ Callable callable = E.value.input_event_callback;
if (callable.is_null()) {
continue;
}
@@ -2740,8 +2721,8 @@ void DisplayServerX11::process_events() {
if (app_focused) {
//verify that one of the windows has focus, else send focus out notification
bool focus_found = false;
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- if (E->get().focused) {
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ if (E.value.focused) {
focus_found = true;
break;
}
@@ -2786,9 +2767,9 @@ void DisplayServerX11::process_events() {
WindowID window_id = MAIN_WINDOW_ID;
// Assign the event to the relevant window
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- if (event.xany.window == E->get().x11_window) {
- window_id = E->key();
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ if (event.xany.window == E.value.x11_window) {
+ window_id = E.key;
break;
}
}
@@ -2904,7 +2885,7 @@ void DisplayServerX11::process_events() {
bool is_begin = event_data->evtype == XI_TouchBegin;
Ref<InputEventScreenTouch> st;
- st.instance();
+ st.instantiate();
st->set_window_id(window_id);
st->set_index(index);
st->set_position(pos);
@@ -2920,13 +2901,13 @@ void DisplayServerX11::process_events() {
// in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
xi.mouse_pos_to_filter = pos;
}
- Input::get_singleton()->accumulate_input_event(st);
+ Input::get_singleton()->parse_input_event(st);
} else {
if (!xi.state.has(index)) { // Defensive
break;
}
xi.state.erase(index);
- Input::get_singleton()->accumulate_input_event(st);
+ Input::get_singleton()->parse_input_event(st);
}
} break;
@@ -2938,12 +2919,12 @@ void DisplayServerX11::process_events() {
if (curr_pos_elem->value() != pos) {
Ref<InputEventScreenDrag> sd;
- sd.instance();
+ sd.instantiate();
sd->set_window_id(window_id);
sd->set_index(index);
sd->set_position(pos);
sd->set_relative(pos - curr_pos_elem->value());
- Input::get_singleton()->accumulate_input_event(sd);
+ Input::get_singleton()->parse_input_event(sd);
curr_pos_elem->value() = pos;
}
@@ -3027,17 +3008,17 @@ void DisplayServerX11::process_events() {
if (mouse_mode_grab) {
// Show and update the cursor if confined and the window regained focus.
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
if (mouse_mode == MOUSE_MODE_CONFINED) {
- XUndefineCursor(x11_display, E->get().x11_window);
+ XUndefineCursor(x11_display, E.value.x11_window);
} else if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { // Or re-hide it.
- XDefineCursor(x11_display, E->get().x11_window, null_cursor);
+ XDefineCursor(x11_display, E.value.x11_window, null_cursor);
}
XGrabPointer(
- x11_display, E->get().x11_window, True,
+ x11_display, E.value.x11_window, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, E->get().x11_window, None, CurrentTime);
+ GrabModeAsync, GrabModeAsync, E.value.x11_window, None, CurrentTime);
}
}
#ifdef TOUCH_ENABLED
@@ -3073,11 +3054,11 @@ void DisplayServerX11::process_events() {
_send_window_event(wd, WINDOW_EVENT_FOCUS_OUT);
if (mouse_mode_grab) {
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
//dear X11, I try, I really try, but you never work, you do whathever you want.
if (mouse_mode == MOUSE_MODE_CAPTURED) {
// Show the cursor if we're in captured mode so it doesn't look weird.
- XUndefineCursor(x11_display, E->get().x11_window);
+ XUndefineCursor(x11_display, E.value.x11_window);
}
}
XUngrabPointer(x11_display, CurrentTime);
@@ -3089,13 +3070,13 @@ void DisplayServerX11::process_events() {
}*/
// Release every pointer to avoid sticky points
- for (Map<int, Vector2>::Element *E = xi.state.front(); E; E = E->next()) {
+ for (const KeyValue<int, Vector2> &E : xi.state) {
Ref<InputEventScreenTouch> st;
- st.instance();
- st->set_index(E->key());
+ st.instantiate();
+ st->set_index(E.key);
st->set_window_id(window_id);
- st->set_position(E->get());
- Input::get_singleton()->accumulate_input_event(st);
+ st->set_position(E.value);
+ Input::get_singleton()->parse_input_event(st);
}
xi.state.clear();
#endif
@@ -3126,15 +3107,15 @@ void DisplayServerX11::process_events() {
}
Ref<InputEventMouseButton> mb;
- mb.instance();
+ mb.instantiate();
mb->set_window_id(window_id);
_get_key_modifier_state(event.xbutton.state, mb);
- mb->set_button_index(event.xbutton.button);
- if (mb->get_button_index() == 2) {
- mb->set_button_index(3);
- } else if (mb->get_button_index() == 3) {
- mb->set_button_index(2);
+ mb->set_button_index((MouseButton)event.xbutton.button);
+ if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
+ mb->set_button_index(MOUSE_BUTTON_MIDDLE);
+ } else if (mb->get_button_index() == MOUSE_BUTTON_MIDDLE) {
+ mb->set_button_index(MOUSE_BUTTON_RIGHT);
}
mb->set_button_mask(_get_mouse_button_state(mb->get_button_index(), event.xbutton.type));
mb->set_position(Vector2(event.xbutton.x, event.xbutton.y));
@@ -3181,9 +3162,9 @@ void DisplayServerX11::process_events() {
// Note: This is needed for drag & drop to work between windows,
// because the engine expects events to keep being processed
// on the same window dragging started.
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- const WindowData &wd_other = E->get();
- WindowID window_id_other = E->key();
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ const WindowData &wd_other = E.value;
+ WindowID window_id_other = E.key;
if (wd_other.focused) {
if (window_id_other != window_id) {
int x, y;
@@ -3193,7 +3174,7 @@ void DisplayServerX11::process_events() {
mb->set_window_id(window_id_other);
mb->set_position(Vector2(x, y));
mb->set_global_position(mb->get_position());
- Input::get_singleton()->accumulate_input_event(mb);
+ Input::get_singleton()->parse_input_event(mb);
}
break;
}
@@ -3201,7 +3182,7 @@ void DisplayServerX11::process_events() {
}
}
- Input::get_singleton()->accumulate_input_event(mb);
+ Input::get_singleton()->parse_input_event(mb);
} break;
case MotionNotify: {
@@ -3291,13 +3272,13 @@ void DisplayServerX11::process_events() {
}
Ref<InputEventMouseMotion> mm;
- mm.instance();
+ mm.instantiate();
mm->set_window_id(window_id);
if (xi.pressure_supported) {
mm->set_pressure(xi.pressure);
} else {
- mm->set_pressure((mouse_get_button_state() & (1 << (MOUSE_BUTTON_LEFT - 1))) ? 1.0f : 0.0f);
+ mm->set_pressure((mouse_get_button_state() & MOUSE_BUTTON_MASK_LEFT) ? 1.0f : 0.0f);
}
mm->set_tilt(xi.tilt);
@@ -3317,15 +3298,15 @@ void DisplayServerX11::process_events() {
// this is so that the relative motion doesn't get messed up
// after we regain focus.
if (focused) {
- Input::get_singleton()->accumulate_input_event(mm);
+ Input::get_singleton()->parse_input_event(mm);
} else {
// Propagate the event to the focused window,
// because it's received only on the topmost window.
// Note: This is needed for drag & drop to work between windows,
// because the engine expects events to keep being processed
// on the same window dragging started.
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- const WindowData &wd_other = E->get();
+ for (const KeyValue<WindowID, WindowData> &E : windows) {
+ const WindowData &wd_other = E.value;
if (wd_other.focused) {
int x, y;
Window child;
@@ -3333,11 +3314,11 @@ void DisplayServerX11::process_events() {
Point2i pos_focused(x, y);
- mm->set_window_id(E->key());
+ mm->set_window_id(E.key);
mm->set_position(pos_focused);
mm->set_global_position(pos_focused);
mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
- Input::get_singleton()->accumulate_input_event(mm);
+ Input::get_singleton()->parse_input_event(mm);
break;
}
@@ -3470,7 +3451,7 @@ void DisplayServerX11::process_events() {
*/
}
- Input::get_singleton()->flush_accumulated_events();
+ Input::get_singleton()->flush_buffered_events();
}
void DisplayServerX11::release_rendering_thread() {
@@ -3524,8 +3505,8 @@ void DisplayServerX11::set_context(Context p_context) {
context = p_context;
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
- _update_context(E->get());
+ for (KeyValue<WindowID, WindowData> &E : windows) {
+ _update_context(E.value);
}
}
@@ -3618,6 +3599,22 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
XSetErrorHandler(oldHandler);
}
+void DisplayServerX11::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+#endif
+}
+
+DisplayServer::VSyncMode DisplayServerX11::window_get_vsync_mode(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+#if defined(VULKAN_ENABLED)
+ return context_vulkan->get_vsync_mode(p_window);
+#else
+ return DisplayServer::VSYNC_ENABLED;
+#endif
+}
+
Vector<String> DisplayServerX11::get_rendering_drivers_func() {
Vector<String> drivers;
@@ -3631,17 +3628,18 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
return drivers;
}
-DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
if (r_error != OK) {
- ds->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
- "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan versions.\n"
+ "Please update your drivers or if you have a very old or integrated GPU, upgrade it.\n"
+ "If you have updated your graphics drivers recently, try rebooting.",
"Unable to initialize Video driver");
}
return ds;
}
-DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) {
//Create window
long visualMask = VisualScreenMask;
@@ -3805,7 +3803,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
#if defined(VULKAN_ENABLED)
if (context_vulkan) {
- Error err = context_vulkan->window_create(id, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height);
+ Error err = context_vulkan->window_create(id, p_vsync_mode, wd.x11_window, x11_display, p_rect.size.width, p_rect.size.height);
ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan window");
}
#endif
@@ -3842,7 +3840,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
return id;
}
-DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3855,8 +3853,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
img[i] = nullptr;
}
- last_button_state = 0;
-
xmbstring = nullptr;
last_click_ms = 0;
@@ -3935,8 +3931,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
if (!_refresh_device_info()) {
- alert("Your system does not support XInput 2.\n"
- "Please upgrade your distribution.",
+ OS::get_singleton()->alert("Your system does not support XInput 2.\n"
+ "Please upgrade your distribution.",
"Unable to initialize XInput");
r_error = ERR_UNAVAILABLE;
return;
@@ -4080,7 +4076,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
Point2i window_position(
(screen_get_size(0).width - p_resolution.width) / 2,
(screen_get_size(0).height - p_resolution.height) / 2);
- WindowID main_window = _create_window(p_mode, p_flags, Rect2i(window_position, p_resolution));
+ WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution));
if (main_window == INVALID_WINDOW_ID) {
r_error = ERR_CANT_CREATE;
return;
@@ -4272,6 +4268,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
_update_real_mouse_position(windows[MAIN_WINDOW_ID]);
+#ifdef DBUS_ENABLED
+ screensaver = memnew(FreeDesktopScreenSaver);
+ screen_set_keep_on(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true));
+#endif
+
r_error = OK;
}
@@ -4285,14 +4286,14 @@ DisplayServerX11::~DisplayServerX11() {
events_thread.wait_to_finish();
//destroy all windows
- for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ for (KeyValue<WindowID, WindowData> &E : windows) {
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
- context_vulkan->window_destroy(E->key());
+ context_vulkan->window_destroy(E.key);
}
#endif
- WindowData &wd = E->get();
+ WindowData &wd = E.value;
if (wd.xic) {
XDestroyIC(wd.xic);
wd.xic = nullptr;
@@ -4336,6 +4337,10 @@ DisplayServerX11::~DisplayServerX11() {
if (xmbstring) {
memfree(xmbstring);
}
+
+#ifdef DBUS_ENABLED
+ memdelete(screensaver);
+#endif
}
void DisplayServerX11::register_x11_driver() {
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 10686d8424..1887c7105b 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -55,6 +55,10 @@
#include "platform/linuxbsd/vulkan_context_x11.h"
#endif
+#if defined(DBUS_ENABLED)
+#include "freedesktop_screensaver.h"
+#endif
+
#include <X11/Xcursor/Xcursor.h>
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
@@ -103,6 +107,11 @@ class DisplayServerX11 : public DisplayServer {
RenderingDeviceVulkan *rendering_device_vulkan;
#endif
+#if defined(DBUS_ENABLED)
+ FreeDesktopScreenSaver *screensaver;
+ bool keep_screen_on = false;
+#endif
+
struct WindowData {
Window x11_window;
::XIC xic;
@@ -143,7 +152,7 @@ class DisplayServerX11 : public DisplayServer {
Map<WindowID, WindowData> windows;
WindowID window_id_counter = MAIN_WINDOW_ID;
- WindowID _create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect);
+ WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
String internal_clipboard;
Window xdnd_source_window;
@@ -162,7 +171,7 @@ class DisplayServerX11 : public DisplayServer {
Point2i last_click_pos;
uint64_t last_click_ms;
int last_click_button_index;
- uint32_t last_button_state;
+ MouseButton last_button_state = MOUSE_BUTTON_NONE;
bool app_focused = false;
uint64_t time_since_no_focus = 0;
@@ -187,7 +196,7 @@ class DisplayServerX11 : public DisplayServer {
bool _refresh_device_info();
- unsigned int _get_mouse_button_state(unsigned int p_x11_button, int p_x11_type);
+ MouseButton _get_mouse_button_state(MouseButton p_x11_button, int p_x11_type);
void _get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
void _flush_mouse_motion();
@@ -268,113 +277,120 @@ protected:
void _window_changed(XEvent *event);
public:
- virtual bool has_feature(Feature p_feature) const;
- virtual String get_name() const;
-
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
-
- virtual void mouse_set_mode(MouseMode p_mode);
- virtual MouseMode mouse_get_mode() const;
-
- virtual void mouse_warp_to_position(const Point2i &p_to);
- virtual Point2i mouse_get_position() const;
- virtual Point2i mouse_get_absolute_position() const;
- virtual int mouse_get_button_state() const;
-
- virtual void clipboard_set(const String &p_text);
- virtual String clipboard_get() const;
+ virtual bool has_feature(Feature p_feature) const override;
+ virtual String get_name() const override;
+
+ virtual void mouse_set_mode(MouseMode p_mode) override;
+ virtual MouseMode mouse_get_mode() const override;
+
+ virtual void mouse_warp_to_position(const Point2i &p_to) override;
+ virtual Point2i mouse_get_position() const override;
+ virtual Point2i mouse_get_absolute_position() const override;
+ virtual MouseButton mouse_get_button_state() const override;
+
+ virtual void clipboard_set(const String &p_text) override;
+ virtual String clipboard_get() const override;
+
+ virtual int get_screen_count() const override;
+ virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+ virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+
+#if defined(DBUS_ENABLED)
+ virtual void screen_set_keep_on(bool p_enable) override;
+ virtual bool screen_is_kept_on() const override;
+#endif
- virtual int get_screen_count() const;
- virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual Vector<DisplayServer::WindowID> get_window_list() const override;
- virtual Vector<DisplayServer::WindowID> get_window_list() const;
+ virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
+ virtual void show_window(WindowID p_id) override;
+ virtual void delete_sub_window(WindowID p_id) override;
- virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
- virtual void show_window(WindowID p_id);
- virtual void delete_sub_window(WindowID p_id);
+ virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
- virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
+ virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID);
- virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
- virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const;
- virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
- virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_transient(WindowID p_window, WindowID p_parent) override;
- virtual void window_set_transient(WindowID p_window, WindowID p_parent);
+ virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
- virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override;
+ virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
- virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const;
- virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID);
- virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
- virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID);
+ virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
- virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual bool can_any_window_draw() const override;
- virtual bool can_any_window_draw() const;
+ virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID) override;
- virtual void window_set_ime_active(const bool p_active, WindowID p_window = MAIN_WINDOW_ID);
- virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
- virtual void cursor_set_shape(CursorShape p_shape);
- virtual CursorShape cursor_get_shape() const;
- virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
+ virtual void cursor_set_shape(CursorShape p_shape) override;
+ virtual CursorShape cursor_get_shape() const override;
+ virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override;
- virtual int keyboard_get_layout_count() const;
- virtual int keyboard_get_current_layout() const;
- virtual void keyboard_set_current_layout(int p_index);
- virtual String keyboard_get_layout_language(int p_index) const;
- virtual String keyboard_get_layout_name(int p_index) const;
+ virtual int keyboard_get_layout_count() const override;
+ virtual int keyboard_get_current_layout() const override;
+ virtual void keyboard_set_current_layout(int p_index) override;
+ virtual String keyboard_get_layout_language(int p_index) const override;
+ virtual String keyboard_get_layout_name(int p_index) const override;
+ virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
- virtual void process_events();
+ virtual void process_events() override;
- virtual void release_rendering_thread();
- virtual void make_rendering_thread();
- virtual void swap_buffers();
+ virtual void release_rendering_thread() override;
+ virtual void make_rendering_thread() override;
+ virtual void swap_buffers() override;
- virtual void set_context(Context p_context);
+ virtual void set_context(Context p_context) override;
- virtual void set_native_icon(const String &p_filename);
- virtual void set_icon(const Ref<Image> &p_icon);
+ virtual void set_native_icon(const String &p_filename) override;
+ virtual void set_icon(const Ref<Image> &p_icon) override;
- static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
static Vector<String> get_rendering_drivers_func();
static void register_x11_driver();
- DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerX11();
};
diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp
index cb95068314..965a38ef4e 100644
--- a/platform/linuxbsd/export/export.cpp
+++ b/platform/linuxbsd/export/export.cpp
@@ -30,7 +30,7 @@
#include "export.h"
-#include "core/os/file_access.h"
+#include "core/io/file_access.h"
#include "editor/editor_export.h"
#include "platform/linuxbsd/logo.gen.h"
#include "scene/resources/texture.h"
@@ -39,11 +39,11 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start,
void register_linuxbsd_exporter() {
Ref<EditorExportPlatformPC> platform;
- platform.instance();
+ platform.instantiate();
Ref<Image> img = memnew(Image(_linuxbsd_logo));
Ref<ImageTexture> logo;
- logo.instance();
+ logo.instantiate();
logo->create_from_image(img);
platform->set_logo(logo);
platform->set_name("Linux/X11");
@@ -53,7 +53,7 @@ void register_linuxbsd_exporter() {
platform->set_debug_32("linux_x11_32_debug");
platform->set_release_64("linux_x11_64_release");
platform->set_debug_64("linux_x11_64_debug");
- platform->set_os_name("X11");
+ platform->set_os_name("LinuxBSD");
platform->set_chmod_flags(0755);
platform->set_fixup_embedded_pck_func(&fixup_embedded_pck);
diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp
new file mode 100644
index 0000000000..a6a3b27d76
--- /dev/null
+++ b/platform/linuxbsd/freedesktop_screensaver.cpp
@@ -0,0 +1,125 @@
+/*************************************************************************/
+/* freedesktop_screensaver.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#include "freedesktop_screensaver.h"
+
+#ifdef DBUS_ENABLED
+
+#include "core/config/project_settings.h"
+
+#include <dbus/dbus.h>
+
+#define BUS_OBJECT_NAME "org.freedesktop.ScreenSaver"
+#define BUS_OBJECT_PATH "/org/freedesktop/ScreenSaver"
+#define BUS_INTERFACE "org.freedesktop.ScreenSaver"
+
+void FreeDesktopScreenSaver::inhibit() {
+ if (unsupported) {
+ return;
+ }
+
+ DBusError error;
+ dbus_error_init(&error);
+
+ DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
+ if (dbus_error_is_set(&error)) {
+ unsupported = true;
+ return;
+ }
+
+ String app_name_string = ProjectSettings::get_singleton()->get("application/config/name");
+ CharString app_name_utf8 = app_name_string.utf8();
+ const char *app_name = app_name_string.is_empty() ? "Godot Engine" : app_name_utf8.get_data();
+
+ const char *reason = "Running Godot Engine project";
+
+ DBusMessage *message = dbus_message_new_method_call(
+ BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE,
+ "Inhibit");
+ dbus_message_append_args(
+ message,
+ DBUS_TYPE_STRING, &app_name,
+ DBUS_TYPE_STRING, &reason,
+ DBUS_TYPE_INVALID);
+
+ DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);
+ dbus_message_unref(message);
+ if (dbus_error_is_set(&error)) {
+ dbus_connection_unref(bus);
+ unsupported = false;
+ return;
+ }
+
+ DBusMessageIter reply_iter;
+ dbus_message_iter_init(reply, &reply_iter);
+ dbus_message_iter_get_basic(&reply_iter, &cookie);
+ print_verbose("FreeDesktopScreenSaver: Acquired screensaver inhibition cookie: " + uitos(cookie));
+
+ dbus_message_unref(reply);
+ dbus_connection_unref(bus);
+}
+
+void FreeDesktopScreenSaver::uninhibit() {
+ if (unsupported) {
+ return;
+ }
+
+ DBusError error;
+ dbus_error_init(&error);
+
+ DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
+ if (dbus_error_is_set(&error)) {
+ unsupported = true;
+ return;
+ }
+
+ DBusMessage *message = dbus_message_new_method_call(
+ BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE,
+ "UnInhibit");
+ dbus_message_append_args(
+ message,
+ DBUS_TYPE_UINT32, &cookie,
+ DBUS_TYPE_INVALID);
+
+ DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);
+ if (dbus_error_is_set(&error)) {
+ dbus_connection_unref(bus);
+ unsupported = true;
+ return;
+ }
+
+ print_verbose("FreeDesktopScreenSaver: Released screensaver inhibition cookie: " + uitos(cookie));
+
+ dbus_message_unref(message);
+ dbus_message_unref(reply);
+ dbus_connection_unref(bus);
+}
+
+#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/freedesktop_screensaver.h b/platform/linuxbsd/freedesktop_screensaver.h
new file mode 100644
index 0000000000..f27e60fce4
--- /dev/null
+++ b/platform/linuxbsd/freedesktop_screensaver.h
@@ -0,0 +1,47 @@
+/*************************************************************************/
+/* freedesktop_screensaver.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifdef DBUS_ENABLED
+
+#include <dbus/dbus.h>
+#include <stdint.h>
+
+class FreeDesktopScreenSaver {
+private:
+ uint32_t cookie = 0;
+ bool unsupported = false;
+
+public:
+ FreeDesktopScreenSaver() {}
+ void inhibit();
+ void uninhibit();
+};
+
+#endif // DBUS_ENABLED
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index e8f4352dff..8b6dbc4c20 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -475,7 +475,7 @@ void JoypadLinux::process_joypads() {
switch (ev.type) {
case EV_KEY:
- input->joy_button(i, joy->key_map[ev.code], ev.value);
+ input->joy_button(i, (JoyButton)joy->key_map[ev.code], ev.value);
break;
case EV_ABS:
@@ -484,29 +484,29 @@ void JoypadLinux::process_joypads() {
case ABS_HAT0X:
if (ev.value != 0) {
if (ev.value < 0) {
- joy->dpad = (joy->dpad | Input::HAT_MASK_LEFT) & ~Input::HAT_MASK_RIGHT;
+ joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_LEFT) & ~HatMask::HAT_MASK_RIGHT);
} else {
- joy->dpad = (joy->dpad | Input::HAT_MASK_RIGHT) & ~Input::HAT_MASK_LEFT;
+ joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_RIGHT) & ~HatMask::HAT_MASK_LEFT);
}
} else {
- joy->dpad &= ~(Input::HAT_MASK_LEFT | Input::HAT_MASK_RIGHT);
+ joy->dpad &= ~(HatMask::HAT_MASK_LEFT | HatMask::HAT_MASK_RIGHT);
}
- input->joy_hat(i, joy->dpad);
+ input->joy_hat(i, (HatMask)joy->dpad);
break;
case ABS_HAT0Y:
if (ev.value != 0) {
if (ev.value < 0) {
- joy->dpad = (joy->dpad | Input::HAT_MASK_UP) & ~Input::HAT_MASK_DOWN;
+ joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_UP) & ~HatMask::HAT_MASK_DOWN);
} else {
- joy->dpad = (joy->dpad | Input::HAT_MASK_DOWN) & ~Input::HAT_MASK_UP;
+ joy->dpad = (HatMask)((joy->dpad | HatMask::HAT_MASK_DOWN) & ~HatMask::HAT_MASK_UP);
}
} else {
- joy->dpad &= ~(Input::HAT_MASK_UP | Input::HAT_MASK_DOWN);
+ joy->dpad &= ~(HatMask::HAT_MASK_UP | HatMask::HAT_MASK_DOWN);
}
- input->joy_hat(i, joy->dpad);
+ input->joy_hat(i, (HatMask)joy->dpad);
break;
default:
@@ -526,7 +526,7 @@ void JoypadLinux::process_joypads() {
for (int j = 0; j < MAX_ABS; j++) {
int index = joy->abs_map[j];
if (index != -1) {
- input->joy_axis(i, index, joy->curr_axis[index]);
+ input->joy_axis(i, (JoyAxis)index, joy->curr_axis[index]);
}
}
if (len == 0 || (len < 0 && errno != EAGAIN)) {
diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp
index 74257a7e61..829feda40a 100644
--- a/platform/linuxbsd/key_mapping_x11.cpp
+++ b/platform/linuxbsd/key_mapping_x11.cpp
@@ -34,7 +34,7 @@
struct _XTranslatePair {
KeySym keysym;
- unsigned int keycode;
+ Key keycode;
};
static _XTranslatePair _xkeysym_to_keycode[] = {
@@ -176,7 +176,7 @@ static _XTranslatePair _xkeysym_to_keycode[] = {
{ XF86XK_LaunchC, KEY_LAUNCHE },
{ XF86XK_LaunchD, KEY_LAUNCHF },
- { 0, 0 }
+ { 0, KEY_NONE }
};
struct _TranslatePair {
@@ -309,11 +309,23 @@ unsigned int KeyMappingX11::get_scancode(unsigned int p_code) {
return keycode;
}
-unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) {
+unsigned int KeyMappingX11::get_xlibcode(unsigned int p_keysym) {
+ unsigned int code = 0;
+ for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
+ if (_scancode_to_keycode[i].keysym == p_keysym) {
+ code = _scancode_to_keycode[i].keycode;
+ break;
+ }
+ }
+
+ return code;
+}
+
+Key KeyMappingX11::get_keycode(KeySym p_keysym) {
// kinda bruteforce.. could optimize.
if (p_keysym < 0x100) { // Latin 1, maps 1-1
- return p_keysym;
+ return (Key)p_keysym;
}
// look for special key
@@ -323,14 +335,14 @@ unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) {
}
}
- return 0;
+ return KEY_NONE;
}
-KeySym KeyMappingX11::get_keysym(unsigned int p_code) {
+KeySym KeyMappingX11::get_keysym(Key p_code) {
// kinda bruteforce.. could optimize.
if (p_code < 0x100) { // Latin 1, maps 1-1
- return p_code;
+ return (KeySym)p_code;
}
// look for special key
@@ -340,7 +352,7 @@ KeySym KeyMappingX11::get_keysym(unsigned int p_code) {
}
}
- return 0;
+ return (KeySym)KEY_NONE;
}
/***** UNICODE CONVERSION ******/
diff --git a/platform/linuxbsd/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h
index 163a8e21db..d4f1554671 100644
--- a/platform/linuxbsd/key_mapping_x11.h
+++ b/platform/linuxbsd/key_mapping_x11.h
@@ -44,9 +44,10 @@ class KeyMappingX11 {
KeyMappingX11() {}
public:
- static unsigned int get_keycode(KeySym p_keysym);
+ static Key get_keycode(KeySym p_keysym);
+ static unsigned int get_xlibcode(unsigned int p_keysym);
static unsigned int get_scancode(unsigned int p_code);
- static KeySym get_keysym(unsigned int p_code);
+ static KeySym get_keysym(Key p_code);
static unsigned int get_unicode_from_keysym(KeySym p_keysym);
static KeySym get_keysym_from_unicode(unsigned int p_unicode);
};
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index 65a9f3b042..69474c6dec 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -30,7 +30,7 @@
#include "os_linuxbsd.h"
-#include "core/os/dir_access.h"
+#include "core/io/dir_access.h"
#include "main/main.h"
#ifdef X11_ENABLED
@@ -51,6 +51,70 @@
#include <sys/types.h>
#include <unistd.h>
+void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) {
+ const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" };
+
+ String path = get_environment("PATH");
+ Vector<String> path_elems = path.split(":", false);
+ String program;
+
+ for (int i = 0; i < path_elems.size(); i++) {
+ for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
+ String tested_path = path_elems[i].plus_file(message_programs[k]);
+
+ if (FileAccess::exists(tested_path)) {
+ program = tested_path;
+ break;
+ }
+ }
+
+ if (program.length()) {
+ break;
+ }
+ }
+
+ List<String> args;
+
+ if (program.ends_with("zenity")) {
+ args.push_back("--error");
+ args.push_back("--width");
+ args.push_back("500");
+ args.push_back("--title");
+ args.push_back(p_title);
+ args.push_back("--text");
+ args.push_back(p_alert);
+ }
+
+ if (program.ends_with("kdialog")) {
+ args.push_back("--error");
+ args.push_back(p_alert);
+ args.push_back("--title");
+ args.push_back(p_title);
+ }
+
+ if (program.ends_with("Xdialog")) {
+ args.push_back("--title");
+ args.push_back(p_title);
+ args.push_back("--msgbox");
+ args.push_back(p_alert);
+ args.push_back("0");
+ args.push_back("0");
+ }
+
+ if (program.ends_with("xmessage")) {
+ args.push_back("-center");
+ args.push_back("-title");
+ args.push_back(p_title);
+ args.push_back(p_alert);
+ }
+
+ if (program.length()) {
+ execute(program, args);
+ } else {
+ print_line(p_alert);
+ }
+}
+
void OS_LinuxBSD::initialize() {
crash_handler.initialize();
@@ -166,7 +230,7 @@ bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) {
String OS_LinuxBSD::get_config_path() const {
if (has_environment("XDG_CONFIG_HOME")) {
- if (get_environment("XDG_CONFIG_HOME").is_abs_path()) {
+ if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) {
return get_environment("XDG_CONFIG_HOME");
} else {
WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.config` or `.` per the XDG Base Directory specification.");
@@ -181,7 +245,7 @@ String OS_LinuxBSD::get_config_path() const {
String OS_LinuxBSD::get_data_path() const {
if (has_environment("XDG_DATA_HOME")) {
- if (get_environment("XDG_DATA_HOME").is_abs_path()) {
+ if (get_environment("XDG_DATA_HOME").is_absolute_path()) {
return get_environment("XDG_DATA_HOME");
} else {
WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.local/share` or `get_config_path()` per the XDG Base Directory specification.");
@@ -196,7 +260,7 @@ String OS_LinuxBSD::get_data_path() const {
String OS_LinuxBSD::get_cache_path() const {
if (has_environment("XDG_CACHE_HOME")) {
- if (get_environment("XDG_CACHE_HOME").is_abs_path()) {
+ if (get_environment("XDG_CACHE_HOME").is_absolute_path()) {
return get_environment("XDG_CACHE_HOME");
} else {
WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `$HOME/.cache` or `get_config_path()` per the XDG Base Directory specification.");
@@ -209,7 +273,7 @@ String OS_LinuxBSD::get_cache_path() const {
}
}
-String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const {
+String OS_LinuxBSD::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
String xdgparam;
switch (p_dir) {
@@ -387,7 +451,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = dir_access->make_dir_recursive(trash_path);
- // Issue an error if trash can is not created proprely.
+ // Issue an error if trash can is not created properly.
ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"");
err = dir_access->make_dir_recursive(trash_path + "/files");
ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/files");
@@ -428,8 +492,8 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
// Generates the .trashinfo file
OS::Date date = OS::get_singleton()->get_date(false);
OS::Time time = OS::get_singleton()->get_time(false);
- String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, date.month, date.day, time.hour, time.min);
- timestamp = vformat("%s%02d", timestamp, time.sec); // vformat only supports up to 6 arguments.
+ String timestamp = vformat("%04d-%02d-%02dT%02d:%02d:", date.year, (int)date.month, date.day, time.hour, time.minute);
+ timestamp = vformat("%s%02d", timestamp, time.second); // vformat only supports up to 6 arguments.
String trash_info = "[Trash Info]\nPath=" + p_path.uri_encode() + "\nDeletionDate=" + timestamp + "\n";
{
Error err;
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index b6cf93c551..35c80e3f9b 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -84,12 +84,14 @@ public:
virtual String get_data_path() const override;
virtual String get_cache_path() const override;
- virtual String get_system_dir(SystemDir p_dir) const override;
+ virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;
virtual Error shell_open(String p_uri) override;
virtual String get_unique_id() const override;
+ virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
+
virtual bool _check_internal_feature_support(const String &p_feature) override;
void run();
diff --git a/platform/linuxbsd/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp
index 021db630e0..4d58e4999b 100644
--- a/platform/linuxbsd/vulkan_context_x11.cpp
+++ b/platform/linuxbsd/vulkan_context_x11.cpp
@@ -29,13 +29,17 @@
/*************************************************************************/
#include "vulkan_context_x11.h"
-#include <vulkan/vulkan_xlib.h>
+#ifdef USE_VOLK
+#include <volk.h>
+#else
+#include <vulkan/vulkan.h>
+#endif
const char *VulkanContextX11::_get_platform_surface_extension() const {
return VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
}
-Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) {
+Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height) {
VkXlibSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
@@ -44,9 +48,9 @@ Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Win
createInfo.window = p_window;
VkSurfaceKHR surface;
- VkResult err = vkCreateXlibSurfaceKHR(_get_instance(), &createInfo, nullptr, &surface);
+ VkResult err = vkCreateXlibSurfaceKHR(get_instance(), &createInfo, nullptr, &surface);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- return _window_create(p_window_id, surface, p_width, p_height);
+ return _window_create(p_window_id, p_vsync_mode, surface, p_width, p_height);
}
VulkanContextX11::VulkanContextX11() {
diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index 26472444ad..de4a9c7b90 100644
--- a/platform/linuxbsd/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
@@ -38,7 +38,7 @@ class VulkanContextX11 : public VulkanContext {
virtual const char *_get_platform_surface_extension() const;
public:
- Error window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height);
+ Error window_create(DisplayServer::WindowID p_window_id, DisplayServer::VSyncMode p_vsync_mode, ::Window p_window, Display *p_display, int p_width, int p_height);
VulkanContextX11();
~VulkanContextX11();