feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -14,7 +14,7 @@ used by this platform.
|
|||
|
||||
## Artwork license
|
||||
|
||||
[`logo.png`](logo.png) is derived from the [Linux logo](https://isc.tamu.edu/~lewing/linux/):
|
||||
[`logo.svg`](export/logo.svg) 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/)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ common_linuxbsd = [
|
|||
"joypad_linux.cpp",
|
||||
"freedesktop_portal_desktop.cpp",
|
||||
"freedesktop_screensaver.cpp",
|
||||
"freedesktop_at_spi_monitor.cpp",
|
||||
]
|
||||
|
||||
if env["use_sowrap"]:
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ static void handle_crash(int sig) {
|
|||
print_error(vformat("%s: Program crashed with signal %d", __FUNCTION__, sig));
|
||||
|
||||
// Print the engine version just before, so that people are reminded to include the version in backtrace reports.
|
||||
if (String(VERSION_HASH).is_empty()) {
|
||||
print_error(vformat("Engine version: %s", VERSION_FULL_NAME));
|
||||
if (String(GODOT_VERSION_HASH).is_empty()) {
|
||||
print_error(vformat("Engine version: %s", GODOT_VERSION_FULL_NAME));
|
||||
} else {
|
||||
print_error(vformat("Engine version: %s (%s)", VERSION_FULL_NAME, VERSION_HASH));
|
||||
print_error(vformat("Engine version: %s (%s)", GODOT_VERSION_FULL_NAME, GODOT_VERSION_HASH));
|
||||
}
|
||||
print_error(vformat("Dumping the backtrace. %s", msg));
|
||||
char **strings = backtrace_symbols(bt_buffer, size);
|
||||
|
|
@ -137,7 +137,8 @@ static void handle_crash(int sig) {
|
|||
}
|
||||
}
|
||||
|
||||
print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, err == OK ? addr2line_results[i] : ""));
|
||||
// Simplify printed file paths to remove redundant `/./` sections (e.g. `/opt/godot/./core` -> `/opt/godot/core`).
|
||||
print_error(vformat("[%d] %s (%s)", (int64_t)i, fname, err == OK ? addr2line_results[i].replace("/./", "/") : ""));
|
||||
}
|
||||
|
||||
free(strings);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef CRASH_HANDLER_LINUXBSD_H
|
||||
#define CRASH_HANDLER_LINUXBSD_H
|
||||
#pragma once
|
||||
|
||||
class CrashHandler {
|
||||
bool disabled;
|
||||
|
|
@ -43,5 +42,3 @@ public:
|
|||
CrashHandler();
|
||||
~CrashHandler();
|
||||
};
|
||||
|
||||
#endif // CRASH_HANDLER_LINUXBSD_H
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ def configure(env: "SConsEnvironment"):
|
|||
|
||||
if not env["builtin_recastnavigation"]:
|
||||
# No pkgconfig file so far, hardcode default paths.
|
||||
env.Prepend(CPPPATH=["/usr/include/recastnavigation"])
|
||||
env.Prepend(CPPEXTPATH=["/usr/include/recastnavigation"])
|
||||
env.Append(LIBS=["Recast"])
|
||||
|
||||
if not env["builtin_embree"] and env["arch"] in ["x86_64", "arm64"]:
|
||||
|
|
@ -394,7 +394,7 @@ def configure(env: "SConsEnvironment"):
|
|||
|
||||
env.Prepend(CPPPATH=["#platform/linuxbsd"])
|
||||
if env["use_sowrap"]:
|
||||
env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers"])
|
||||
env.Prepend(CPPEXTPATH=["#thirdparty/linuxbsd_headers"])
|
||||
|
||||
env.Append(
|
||||
CPPDEFINES=[
|
||||
|
|
@ -456,9 +456,9 @@ def configure(env: "SConsEnvironment"):
|
|||
sys.exit(255)
|
||||
env.ParseConfig("pkg-config wayland-egl --cflags --libs")
|
||||
else:
|
||||
env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers/wayland/"])
|
||||
env.Prepend(CPPEXTPATH=["#thirdparty/linuxbsd_headers/wayland/"])
|
||||
if env["libdecor"]:
|
||||
env.Prepend(CPPPATH=["#thirdparty/linuxbsd_headers/libdecor-0/"])
|
||||
env.Prepend(CPPEXTPATH=["#thirdparty/linuxbsd_headers/libdecor-0/"])
|
||||
|
||||
if env["libdecor"]:
|
||||
env.Append(CPPDEFINES=["LIBDECOR_ENABLED"])
|
||||
|
|
@ -466,6 +466,24 @@ def configure(env: "SConsEnvironment"):
|
|||
env.Append(CPPDEFINES=["WAYLAND_ENABLED"])
|
||||
env.Append(LIBS=["rt"]) # Needed by glibc, used by _allocate_shm_file
|
||||
|
||||
if env["accesskit"]:
|
||||
if env["accesskit_sdk_path"] != "":
|
||||
env.Prepend(CPPPATH=[env["accesskit_sdk_path"] + "/include"])
|
||||
if env["arch"] == "arm64":
|
||||
env.Append(LIBPATH=[env["accesskit_sdk_path"] + "/lib/linux/arm64/static/"])
|
||||
elif env["arch"] == "arm32":
|
||||
env.Append(LIBPATH=[env["accesskit_sdk_path"] + "/lib/linux/arm32/static/"])
|
||||
elif env["arch"] == "rv64":
|
||||
env.Append(LIBPATH=[env["accesskit_sdk_path"] + "/lib/linux/riscv64gc/static/"])
|
||||
elif env["arch"] == "x86_64":
|
||||
env.Append(LIBPATH=[env["accesskit_sdk_path"] + "/lib/linux/x86_64/static/"])
|
||||
elif env["arch"] == "x86_32":
|
||||
env.Append(LIBPATH=[env["accesskit_sdk_path"] + "/lib/linux/x86/static/"])
|
||||
env.Append(LIBS=["accesskit"])
|
||||
else:
|
||||
env.Append(CPPDEFINES=["ACCESSKIT_DYNAMIC"])
|
||||
env.Append(CPPDEFINES=["ACCESSKIT_ENABLED"])
|
||||
|
||||
if env["vulkan"]:
|
||||
env.Append(CPPDEFINES=["VULKAN_ENABLED", "RD_ENABLED"])
|
||||
if not env["use_volk"]:
|
||||
|
|
|
|||
|
|
@ -28,10 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef LINUXBSD_EXPORT_H
|
||||
#define LINUXBSD_EXPORT_H
|
||||
#pragma once
|
||||
|
||||
void register_linuxbsd_exporter_types();
|
||||
void register_linuxbsd_exporter();
|
||||
|
||||
#endif // LINUXBSD_EXPORT_H
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ Error EditorExportPlatformLinuxBSD::_export_debug_script(const Ref<EditorExportP
|
|||
}
|
||||
|
||||
f->store_line("#!/bin/sh");
|
||||
f->store_line("echo -ne '\\033c\\033]0;" + p_app_name + "\\a'");
|
||||
f->store_line("printf '\\033c\\033]0;%s\\a' " + p_app_name);
|
||||
f->store_line("base_path=\"$(dirname \"$(realpath \"$0\")\")\"");
|
||||
f->store_line("\"$base_path/" + p_pkg_name + "\" \"$@\"");
|
||||
|
||||
|
|
@ -67,16 +67,21 @@ Error EditorExportPlatformLinuxBSD::export_project(const Ref<EditorExportPreset>
|
|||
if (!template_path.is_empty()) {
|
||||
String exe_arch = _get_exe_arch(template_path);
|
||||
if (arch != exe_arch) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Mismatching custom export template executable architecture, found \"%s\", expected \"%s\"."), exe_arch, arch));
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Mismatching custom export template executable architecture: found \"%s\", expected \"%s\"."), exe_arch, arch));
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
}
|
||||
|
||||
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||
if (da->file_exists(template_path.get_base_dir().path_join("libaccesskit." + arch + ".so"))) {
|
||||
da->copy(template_path.get_base_dir().path_join("libaccesskit." + arch + ".so"), p_path.get_base_dir().path_join("libaccesskit." + arch + ".so"), get_chmod_flags());
|
||||
}
|
||||
|
||||
bool export_as_zip = p_path.ends_with("zip");
|
||||
|
||||
String pkg_name;
|
||||
if (String(GLOBAL_GET("application/config/name")) != "") {
|
||||
pkg_name = String(GLOBAL_GET("application/config/name"));
|
||||
if (String(get_project_setting(p_preset, "application/config/name")) != "") {
|
||||
pkg_name = String(get_project_setting(p_preset, "application/config/name"));
|
||||
} else {
|
||||
pkg_name = "Unnamed";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef LINUXBSD_EXPORT_PLUGIN_H
|
||||
#define LINUXBSD_EXPORT_PLUGIN_H
|
||||
#pragma once
|
||||
|
||||
#include "core/io/file_access.h"
|
||||
#include "editor/editor_settings.h"
|
||||
|
|
@ -92,5 +91,3 @@ public:
|
|||
|
||||
EditorExportPlatformLinuxBSD();
|
||||
};
|
||||
|
||||
#endif // LINUXBSD_EXPORT_PLUGIN_H
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
<svg width="32" height="32"><path fill="#fff" d="M13 31h6s3 0 6-6c2.864-5.727-6-17-6-17h-6S3.775 18.55 7 25c3 6 6 6 6 6z"/><path fill="#333" d="M15.876 28.636c-.05.322-.116.637-.204.941-.142.496-.35.993-.659 1.416.32.02.649.023.985.007a9.1 9.1 0 0 0 .985-.007c-.309-.423-.516-.92-.659-1.416a7.666 7.666 0 0 1-.203-.94l-.123.003c-.04 0-.081-.003-.122-.004z"/><path fill="#f4bb37" d="M21.693 21.916c-.629.01-.934.633-1.497.7-.694.08-1.128-.722-2.11-.123-.98.6-1.826 7.473.45 8.409 2.274.935 6.506-4.545 6.23-5.662-.275-1.116-1.146-.853-1.582-1.399-.436-.545.003-1.41-.995-1.82a1.246 1.246 0 0 0-.496-.105zm-11.461 0a1.315 1.315 0 0 0-.421.105c-.998.41-.56 1.275-.995 1.82-.436.546-1.31.283-1.586 1.4-.275 1.116 3.956 6.596 6.232 5.66 2.275-.935 1.429-7.808.448-8.408-.981-.6-1.415.204-2.11.122-.584-.068-.888-.739-1.568-.7z"/><path fill="#333" d="M15.998.99c-2.934 0-4.657 1.79-4.982 4.204-.324 2.414.198 2.856-.614 5.328-.813 2.472-4.456 6.71-4.37 10.62.026 1.217.166 2.27.41 3.192.3-.496.743-.846 1.066-.995.253-.117.375-.173.432-.194.008-.062.04-.205.098-.485.08-.386.387-.99.91-1.386-.005-.12-.01-.239-.013-.363-.06-3.033 3.073-6.318 3.65-8.236.577-1.917.326-2.114.421-2.59.096-.477.463-1.032.992-1.475a.23.23 0 0 1 .15-.06c.482-.005.965 1.75 1.898 1.752.933 0 1.419-2.141 1.956-1.692.529.443.896.998.992 1.474.095.477-.156.674.42 2.591.578 1.918 3.708 5.203 3.648 8.236-.003.123-.008.24-.014.36.526.396.834 1.002.914 1.389.058.28.09.423.098.485.057.021.18.08.432.197.323.15.764.499 1.063.995.244-.922.387-1.976.414-3.195.085-3.91-3.562-8.148-4.374-10.62-.813-2.472-.287-2.914-.611-5.328C20.659 2.78 18.933.99 15.998.99z"/></svg>
|
||||
<svg width="32" height="32"><path fill="#fff" d="M13 31h6s3 0 6-6c2.864-5.727-6-17-6-17h-6S3.775 18.55 7 25c3 6 6 6 6 6z"/><path fill="#333" d="M15.876 28.636c-.05.322-.116.637-.204.941-.142.496-.35.993-.659 1.416.32.02.649.023.985.007a9.1 9.1 0 0 0 .985-.007c-.309-.423-.516-.92-.659-1.416a7.666 7.666 0 0 1-.203-.94l-.123.003c-.04 0-.081-.003-.122-.004z"/><path fill="#f4bb37" d="M21.693 21.916c-.629.01-.934.633-1.497.7-.694.08-1.128-.722-2.11-.123-.98.6-1.826 7.473.45 8.409 2.274.935 6.506-4.545 6.23-5.662-.275-1.116-1.146-.853-1.582-1.399-.436-.545.003-1.41-.995-1.82a1.246 1.246 0 0 0-.496-.105zm-11.461 0a1.315 1.315 0 0 0-.421.105c-.998.41-.56 1.275-.995 1.82-.436.546-1.31.283-1.586 1.4-.275 1.116 3.956 6.596 6.232 5.66 2.275-.935 1.429-7.808.448-8.408-.981-.6-1.415.204-2.11.122-.584-.068-.888-.739-1.568-.7z"/><path fill="#333" d="M15.998.99c-2.934 0-4.657 1.79-4.982 4.204-.324 2.414.198 2.856-.614 5.328-.813 2.472-4.456 6.71-4.37 10.62.026 1.217.166 2.27.41 3.192.3-.496.743-.846 1.066-.995.253-.117.375-.173.432-.194.008-.062.04-.205.098-.485.08-.386.387-.99.91-1.386-.005-.12-.01-.239-.013-.363-.06-3.033 3.073-6.318 3.65-8.236.577-1.917.326-2.114.421-2.59.096-.477.463-1.032.992-1.475a.23.23 0 0 1 .15-.06c.482-.005.965 1.75 1.898 1.752.933 0 1.419-2.141 1.956-1.692.529.443.896.998.992 1.474.095.477-.156.674.42 2.591.578 1.918 3.708 5.203 3.648 8.236-.003.123-.008.24-.014.36.526.396.834 1.002.914 1.389.058.28.09.423.098.485.057.021.18.08.432.197.323.15.764.499 1.063.995.244-.922.387-1.976.414-3.195.085-3.91-3.562-8.148-4.374-10.62-.813-2.472-.287-2.914-.611-5.328C20.659 2.78 18.933.99 15.998.99z"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16"><path fill="#e0e0e0" d="M7.941 13.966a3.62 3.62 0 0 1-.096.444 2.129 2.129 0 0 1-.31.668c.15.01.305.01.464.003.16.008.314.007.465-.003a2.129 2.129 0 0 1-.31-.668 3.62 3.62 0 0 1-.097-.444zM8 .914c-1.386 0-2.2.845-2.353 1.985-.153 1.14.094 1.348-.29 2.515s-2.103 3.168-2.063 5.013c.012.575.078 1.072.194 1.507a1.25 1.25 0 0 1 .503-.47 4.37 4.37 0 0 1 .204-.09c.004-.03.019-.098.046-.23.038-.182.183-.467.43-.654a4.773 4.773 0 0 1-.006-.172c-.029-1.431 1.45-2.982 1.723-3.888.272-.905.154-.998.199-1.223.045-.225.218-.487.468-.696.253-.211.483.798.945.799.462 0 .692-1.01.945-.799.25.21.423.471.468.696.045.225-.073.318.199 1.223.272.906 1.75 2.457 1.722 3.888a4.773 4.773 0 0 0-.007.17 1.2 1.2 0 0 1 .432.656c.027.132.042.2.046.23.027.01.085.037.204.092.153.07.36.236.502.47.115-.435.183-.933.195-1.509.04-1.845-1.681-3.846-2.065-5.013-.383-1.167-.135-1.376-.288-2.515C10.2 1.759 9.385.914 7.999.914z"/><path fill="#e0e0e0" d="M10.688 10.793c-.297.005-.441.299-.707.33-.328.038-.533-.34-.996-.058-.463.283-.862 3.528.212 3.97 1.074.442 3.072-2.146 2.942-2.673-.13-.527-.542-.403-.747-.66-.206-.258 0-.666-.47-.86a.588.588 0 0 0-.234-.05zm-5.411 0a.62.62 0 0 0-.199.05c-.47.193-.264.601-.47.859-.205.257-.618.133-.748.66s1.867 3.115 2.942 2.673c1.074-.442.674-3.687.211-3.97-.463-.283-.668.096-.995.058-.277-.032-.42-.349-.741-.33z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16"><path fill="#e0e0e0" d="M7.941 13.966a3.62 3.62 0 0 1-.096.444 2.129 2.129 0 0 1-.31.668c.15.01.305.01.464.003.16.008.314.007.465-.003a2.129 2.129 0 0 1-.31-.668 3.62 3.62 0 0 1-.097-.444zM8 .914c-1.386 0-2.2.845-2.353 1.985-.153 1.14.094 1.348-.29 2.515s-2.103 3.168-2.063 5.013c.012.575.078 1.072.194 1.507a1.25 1.25 0 0 1 .503-.47 4.37 4.37 0 0 1 .204-.09c.004-.03.019-.098.046-.23.038-.182.183-.467.43-.654a4.773 4.773 0 0 1-.006-.172c-.029-1.431 1.45-2.982 1.723-3.888.272-.905.154-.998.199-1.223.045-.225.218-.487.468-.696.253-.211.483.798.945.799.462 0 .692-1.01.945-.799.25.21.423.471.468.696.045.225-.073.318.199 1.223.272.906 1.75 2.457 1.722 3.888a4.773 4.773 0 0 0-.007.17 1.2 1.2 0 0 1 .432.656c.027.132.042.2.046.23.027.01.085.037.204.092.153.07.36.236.502.47.115-.435.183-.933.195-1.509.04-1.845-1.681-3.846-2.065-5.013-.383-1.167-.135-1.376-.288-2.515C10.2 1.759 9.385.914 7.999.914z"/><path fill="#e0e0e0" d="M10.688 10.793c-.297.005-.441.299-.707.33-.328.038-.533-.34-.996-.058-.463.283-.862 3.528.212 3.97 1.074.442 3.072-2.146 2.942-2.673-.13-.527-.542-.403-.747-.66-.206-.258 0-.666-.47-.86a.588.588 0 0 0-.234-.05zm-5.411 0a.62.62 0 0 0-.199.05c-.47.193-.264.601-.47.859-.205.257-.618.133-.748.66s1.867 3.115 2.942 2.673c1.074-.442.674-3.687.211-3.97-.463-.283-.668.096-.995.058-.277-.032-.42-.349-.741-.33z"/></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
157
engine/platform/linuxbsd/freedesktop_at_spi_monitor.cpp
Normal file
157
engine/platform/linuxbsd/freedesktop_at_spi_monitor.cpp
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/**************************************************************************/
|
||||
/* freedesktop_at_spi_monitor.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "freedesktop_at_spi_monitor.h"
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
|
||||
#include "core/os/os.h"
|
||||
|
||||
#ifdef SOWRAP_ENABLED
|
||||
#include "dbus-so_wrap.h"
|
||||
#else
|
||||
#include <dbus/dbus.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define BUS_OBJECT_NAME "org.a11y.Bus"
|
||||
#define BUS_OBJECT_PATH "/org/a11y/bus"
|
||||
|
||||
#define BUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
|
||||
|
||||
void FreeDesktopAtSPIMonitor::monitor_thread_func(void *p_userdata) {
|
||||
FreeDesktopAtSPIMonitor *mon = (FreeDesktopAtSPIMonitor *)p_userdata;
|
||||
|
||||
DBusError error;
|
||||
dbus_error_init(&error);
|
||||
|
||||
DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
dbus_error_free(&error);
|
||||
mon->supported.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
static const char *iface = "org.a11y.Status";
|
||||
static const char *member = "IsEnabled";
|
||||
|
||||
while (!mon->exit_thread.is_set()) {
|
||||
DBusMessage *message = dbus_message_new_method_call(BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_PROPERTIES, "Get");
|
||||
|
||||
dbus_message_append_args(
|
||||
message,
|
||||
DBUS_TYPE_STRING, &iface,
|
||||
DBUS_TYPE_STRING, &member,
|
||||
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)) {
|
||||
DBusMessageIter iter, iter_variant, iter_struct;
|
||||
dbus_bool_t result;
|
||||
dbus_message_iter_init(reply, &iter);
|
||||
dbus_message_iter_recurse(&iter, &iter_variant);
|
||||
switch (dbus_message_iter_get_arg_type(&iter_variant)) {
|
||||
case DBUS_TYPE_STRUCT: {
|
||||
dbus_message_iter_recurse(&iter_variant, &iter_struct);
|
||||
if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) {
|
||||
dbus_message_iter_get_basic(&iter_struct, &result);
|
||||
if (result) {
|
||||
mon->sr_enabled.set();
|
||||
} else {
|
||||
mon->sr_enabled.clear();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case DBUS_TYPE_BOOLEAN: {
|
||||
dbus_message_iter_get_basic(&iter_variant, &result);
|
||||
if (result) {
|
||||
mon->sr_enabled.set();
|
||||
} else {
|
||||
mon->sr_enabled.clear();
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dbus_message_unref(reply);
|
||||
} else {
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
}
|
||||
|
||||
dbus_connection_unref(bus);
|
||||
}
|
||||
|
||||
FreeDesktopAtSPIMonitor::FreeDesktopAtSPIMonitor() {
|
||||
#ifdef SOWRAP_ENABLED
|
||||
#ifdef DEBUG_ENABLED
|
||||
int dylibloader_verbose = 1;
|
||||
#else
|
||||
int dylibloader_verbose = 0;
|
||||
#endif
|
||||
if (initialize_dbus(dylibloader_verbose) != 0) {
|
||||
print_verbose("AT-SPI2: Failed to load DBus library!");
|
||||
supported.clear();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
bool ver_ok = false;
|
||||
int version_major = 0;
|
||||
int version_minor = 0;
|
||||
int version_rev = 0;
|
||||
dbus_get_version(&version_major, &version_minor, &version_rev);
|
||||
ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0
|
||||
print_verbose(vformat("AT-SPI2: DBus %d.%d.%d detected.", version_major, version_minor, version_rev));
|
||||
if (!ver_ok) {
|
||||
print_verbose("AT-SPI2: Unsupported DBus library version!");
|
||||
supported.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
supported.set();
|
||||
sr_enabled.clear();
|
||||
exit_thread.clear();
|
||||
|
||||
thread.start(FreeDesktopAtSPIMonitor::monitor_thread_func, this);
|
||||
}
|
||||
|
||||
FreeDesktopAtSPIMonitor::~FreeDesktopAtSPIMonitor() {
|
||||
exit_thread.set();
|
||||
if (thread.is_started()) {
|
||||
thread.wait_to_finish();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DBUS_ENABLED
|
||||
56
engine/platform/linuxbsd/freedesktop_at_spi_monitor.h
Normal file
56
engine/platform/linuxbsd/freedesktop_at_spi_monitor.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/**************************************************************************/
|
||||
/* freedesktop_at_spi_monitor.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 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. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
|
||||
#include "core/os/thread.h"
|
||||
#include "core/os/thread_safe.h"
|
||||
|
||||
class FreeDesktopAtSPIMonitor {
|
||||
private:
|
||||
Thread thread;
|
||||
|
||||
SafeFlag exit_thread;
|
||||
SafeFlag sr_enabled;
|
||||
SafeFlag supported;
|
||||
|
||||
static void monitor_thread_func(void *p_userdata);
|
||||
|
||||
public:
|
||||
FreeDesktopAtSPIMonitor();
|
||||
~FreeDesktopAtSPIMonitor();
|
||||
|
||||
bool is_supported() { return supported.is_set(); }
|
||||
bool is_active() { return sr_enabled.is_set(); }
|
||||
};
|
||||
|
||||
#endif // DBUS_ENABLED
|
||||
|
|
@ -52,8 +52,9 @@
|
|||
#define BUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
|
||||
#define BUS_INTERFACE_SETTINGS "org.freedesktop.portal.Settings"
|
||||
#define BUS_INTERFACE_FILE_CHOOSER "org.freedesktop.portal.FileChooser"
|
||||
#define BUS_INTERFACE_SCREENSHOT "org.freedesktop.portal.Screenshot"
|
||||
|
||||
bool FreeDesktopPortalDesktop::try_parse_variant(DBusMessage *p_reply_message, int p_type, void *r_value) {
|
||||
bool FreeDesktopPortalDesktop::try_parse_variant(DBusMessage *p_reply_message, ReadVariantType p_type, void *r_value) {
|
||||
DBusMessageIter iter[3];
|
||||
|
||||
dbus_message_iter_init(p_reply_message, &iter[0]);
|
||||
|
|
@ -67,15 +68,49 @@ bool FreeDesktopPortalDesktop::try_parse_variant(DBusMessage *p_reply_message, i
|
|||
}
|
||||
|
||||
dbus_message_iter_recurse(&iter[1], &iter[2]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[2]) != p_type) {
|
||||
return false;
|
||||
if (p_type == VAR_TYPE_COLOR) {
|
||||
if (dbus_message_iter_get_arg_type(&iter[2]) != DBUS_TYPE_STRUCT) {
|
||||
return false;
|
||||
}
|
||||
DBusMessageIter struct_iter;
|
||||
dbus_message_iter_recurse(&iter[2], &struct_iter);
|
||||
int idx = 0;
|
||||
while (dbus_message_iter_get_arg_type(&struct_iter) == DBUS_TYPE_DOUBLE) {
|
||||
double value = 0.0;
|
||||
dbus_message_iter_get_basic(&struct_iter, &value);
|
||||
if (value < 0.0 || value > 1.0) {
|
||||
return false;
|
||||
}
|
||||
if (idx == 0) {
|
||||
static_cast<Color *>(r_value)->r = value;
|
||||
} else if (idx == 1) {
|
||||
static_cast<Color *>(r_value)->g = value;
|
||||
} else if (idx == 2) {
|
||||
static_cast<Color *>(r_value)->b = value;
|
||||
}
|
||||
idx++;
|
||||
if (!dbus_message_iter_next(&struct_iter)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx != 3) {
|
||||
return false;
|
||||
}
|
||||
} else if (p_type == VAR_TYPE_UINT32) {
|
||||
if (dbus_message_iter_get_arg_type(&iter[2]) != DBUS_TYPE_UINT32) {
|
||||
return false;
|
||||
}
|
||||
dbus_message_iter_get_basic(&iter[2], r_value);
|
||||
} else if (p_type == VAR_TYPE_BOOL) {
|
||||
if (dbus_message_iter_get_arg_type(&iter[2]) != DBUS_TYPE_BOOLEAN) {
|
||||
return false;
|
||||
}
|
||||
dbus_message_iter_get_basic(&iter[2], r_value);
|
||||
}
|
||||
|
||||
dbus_message_iter_get_basic(&iter[2], r_value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreeDesktopPortalDesktop::read_setting(const char *p_namespace, const char *p_key, int p_type, void *r_value) {
|
||||
bool FreeDesktopPortalDesktop::read_setting(const char *p_namespace, const char *p_key, ReadVariantType p_type, void *r_value) {
|
||||
if (unsupported) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -127,8 +162,36 @@ uint32_t FreeDesktopPortalDesktop::get_appearance_color_scheme() {
|
|||
}
|
||||
|
||||
uint32_t value = 0;
|
||||
read_setting("org.freedesktop.appearance", "color-scheme", DBUS_TYPE_UINT32, &value);
|
||||
return value;
|
||||
if (read_setting("org.freedesktop.appearance", "color-scheme", VAR_TYPE_UINT32, &value)) {
|
||||
return value;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Color FreeDesktopPortalDesktop::get_appearance_accent_color() {
|
||||
if (unsupported) {
|
||||
return Color(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Color value;
|
||||
if (read_setting("org.freedesktop.appearance", "accent-color", VAR_TYPE_COLOR, &value)) {
|
||||
return value;
|
||||
} else {
|
||||
return Color(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t FreeDesktopPortalDesktop::get_high_contrast() {
|
||||
if (unsupported) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbus_bool_t value = false;
|
||||
if (read_setting("org.gnome.desktop.a11y.interface", "high-contrast", VAR_TYPE_BOOL, &value)) {
|
||||
return value;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *cs_empty = "";
|
||||
|
|
@ -226,7 +289,7 @@ void FreeDesktopPortalDesktop::append_dbus_dict_filters(DBusMessageIter *p_iter,
|
|||
int filter_slice_count = flt.get_slice_count(",");
|
||||
for (int j = 0; j < filter_slice_count; j++) {
|
||||
dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, nullptr, &array_struct_iter);
|
||||
String str = (flt.get_slice(",", j).strip_edges());
|
||||
String str = (flt.get_slicec(',', j).strip_edges());
|
||||
{
|
||||
const unsigned flt_type = 0;
|
||||
dbus_message_iter_append_basic(&array_struct_iter, DBUS_TYPE_UINT32, &flt_type);
|
||||
|
|
@ -295,6 +358,61 @@ void FreeDesktopPortalDesktop::append_dbus_dict_bool(DBusMessageIter *p_iter, co
|
|||
dbus_message_iter_close_container(p_iter, &dict_iter);
|
||||
}
|
||||
|
||||
bool FreeDesktopPortalDesktop::color_picker_parse_response(DBusMessageIter *p_iter, bool &r_cancel, Color &r_color) {
|
||||
ERR_FAIL_COND_V(dbus_message_iter_get_arg_type(p_iter) != DBUS_TYPE_UINT32, false);
|
||||
|
||||
dbus_uint32_t resp_code;
|
||||
dbus_message_iter_get_basic(p_iter, &resp_code);
|
||||
if (resp_code != 0) {
|
||||
r_cancel = true;
|
||||
} else {
|
||||
r_cancel = false;
|
||||
ERR_FAIL_COND_V(!dbus_message_iter_next(p_iter), false);
|
||||
ERR_FAIL_COND_V(dbus_message_iter_get_arg_type(p_iter) != DBUS_TYPE_ARRAY, false);
|
||||
|
||||
DBusMessageIter dict_iter;
|
||||
dbus_message_iter_recurse(p_iter, &dict_iter);
|
||||
while (dbus_message_iter_get_arg_type(&dict_iter) == DBUS_TYPE_DICT_ENTRY) {
|
||||
DBusMessageIter iter;
|
||||
dbus_message_iter_recurse(&dict_iter, &iter);
|
||||
if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
|
||||
const char *key;
|
||||
dbus_message_iter_get_basic(&iter, &key);
|
||||
dbus_message_iter_next(&iter);
|
||||
|
||||
DBusMessageIter var_iter;
|
||||
dbus_message_iter_recurse(&iter, &var_iter);
|
||||
if (strcmp(key, "color") == 0) { // (ddd)
|
||||
if (dbus_message_iter_get_arg_type(&var_iter) == DBUS_TYPE_STRUCT) {
|
||||
DBusMessageIter struct_iter;
|
||||
dbus_message_iter_recurse(&var_iter, &struct_iter);
|
||||
int idx = 0;
|
||||
while (dbus_message_iter_get_arg_type(&struct_iter) == DBUS_TYPE_DOUBLE) {
|
||||
double value = 0.0;
|
||||
dbus_message_iter_get_basic(&struct_iter, &value);
|
||||
if (idx == 0) {
|
||||
r_color.r = value;
|
||||
} else if (idx == 1) {
|
||||
r_color.g = value;
|
||||
} else if (idx == 2) {
|
||||
r_color.b = value;
|
||||
}
|
||||
idx++;
|
||||
if (!dbus_message_iter_next(&struct_iter)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dbus_message_iter_next(&dict_iter)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_iter, const Vector<String> &p_names, const HashMap<String, String> &p_ids, bool &r_cancel, Vector<String> &r_urls, int &r_index, Dictionary &r_options) {
|
||||
ERR_FAIL_COND_V(dbus_message_iter_get_arg_type(p_iter) != DBUS_TYPE_UINT32, false);
|
||||
|
||||
|
|
@ -372,7 +490,7 @@ bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_it
|
|||
while (dbus_message_iter_get_arg_type(&uri_iter) == DBUS_TYPE_STRING) {
|
||||
const char *value;
|
||||
dbus_message_iter_get_basic(&uri_iter, &value);
|
||||
r_urls.push_back(String::utf8(value).trim_prefix("file://").uri_decode());
|
||||
r_urls.push_back(String::utf8(value).trim_prefix("file://").uri_file_decode());
|
||||
if (!dbus_message_iter_next(&uri_iter)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -388,6 +506,92 @@ bool FreeDesktopPortalDesktop::file_chooser_parse_response(DBusMessageIter *p_it
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FreeDesktopPortalDesktop::color_picker(const String &p_xid, const Callable &p_callback) {
|
||||
if (unsupported) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
|
||||
// Open connection and add signal handler.
|
||||
ColorPickerData cd;
|
||||
cd.callback = p_callback;
|
||||
|
||||
CryptoCore::RandomGenerator rng;
|
||||
ERR_FAIL_COND_V_MSG(rng.init(), false, "Failed to initialize random number generator.");
|
||||
uint8_t uuid[64];
|
||||
Error rng_err = rng.get_random_bytes(uuid, 64);
|
||||
ERR_FAIL_COND_V_MSG(rng_err, false, "Failed to generate unique token.");
|
||||
|
||||
String dbus_unique_name = String::utf8(dbus_bus_get_unique_name(monitor_connection));
|
||||
String token = String::hex_encode_buffer(uuid, 64);
|
||||
String path = vformat("/org/freedesktop/portal/desktop/request/%s/%s", dbus_unique_name.replace_char('.', '_').remove_char(':'), token);
|
||||
|
||||
cd.path = path;
|
||||
cd.filter = vformat("type='signal',sender='org.freedesktop.portal.Desktop',path='%s',interface='org.freedesktop.portal.Request',member='Response',destination='%s'", path, dbus_unique_name);
|
||||
dbus_bus_add_match(monitor_connection, cd.filter.utf8().get_data(), &err);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
ERR_PRINT(vformat("Failed to add DBus match: %s", err.message));
|
||||
dbus_error_free(&err);
|
||||
return false;
|
||||
}
|
||||
|
||||
DBusMessage *message = dbus_message_new_method_call(BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_SCREENSHOT, "PickColor");
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
dbus_message_iter_init_append(message, &iter);
|
||||
|
||||
append_dbus_string(&iter, p_xid);
|
||||
|
||||
DBusMessageIter arr_iter;
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &arr_iter);
|
||||
append_dbus_dict_string(&arr_iter, "handle_token", token);
|
||||
dbus_message_iter_close_container(&iter, &arr_iter);
|
||||
}
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(monitor_connection, message, DBUS_TIMEOUT_INFINITE, &err);
|
||||
dbus_message_unref(message);
|
||||
|
||||
if (!reply || dbus_error_is_set(&err)) {
|
||||
ERR_PRINT(vformat("Failed to send DBus message: %s", err.message));
|
||||
dbus_error_free(&err);
|
||||
dbus_bus_remove_match(monitor_connection, cd.filter.utf8().get_data(), &err);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update signal path.
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
if (dbus_message_iter_init(reply, &iter)) {
|
||||
if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_OBJECT_PATH) {
|
||||
const char *new_path = nullptr;
|
||||
dbus_message_iter_get_basic(&iter, &new_path);
|
||||
if (String::utf8(new_path) != path) {
|
||||
dbus_bus_remove_match(monitor_connection, cd.filter.utf8().get_data(), &err);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
ERR_PRINT(vformat("Failed to remove DBus match: %s", err.message));
|
||||
dbus_error_free(&err);
|
||||
return false;
|
||||
}
|
||||
cd.filter = String::utf8(new_path);
|
||||
dbus_bus_add_match(monitor_connection, cd.filter.utf8().get_data(), &err);
|
||||
if (dbus_error_is_set(&err)) {
|
||||
ERR_PRINT(vformat("Failed to add DBus match: %s", err.message));
|
||||
dbus_error_free(&err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dbus_message_unref(reply);
|
||||
|
||||
MutexLock lock(color_picker_mutex);
|
||||
color_pickers.push_back(cd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FreeDesktopPortalDesktop::_is_interface_supported(const char *p_iface) {
|
||||
bool supported = false;
|
||||
DBusError err;
|
||||
|
|
@ -443,6 +647,14 @@ bool FreeDesktopPortalDesktop::is_settings_supported() {
|
|||
return supported;
|
||||
}
|
||||
|
||||
bool FreeDesktopPortalDesktop::is_screenshot_supported() {
|
||||
static int supported = -1;
|
||||
if (supported == -1) {
|
||||
supported = _is_interface_supported(BUS_INTERFACE_SCREENSHOT);
|
||||
}
|
||||
return supported;
|
||||
}
|
||||
|
||||
Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_window_id, const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, bool p_options_in_cb) {
|
||||
if (unsupported) {
|
||||
return FAILED;
|
||||
|
|
@ -505,7 +717,7 @@ Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_windo
|
|||
|
||||
String dbus_unique_name = String::utf8(dbus_bus_get_unique_name(monitor_connection));
|
||||
String token = String::hex_encode_buffer(uuid, 64);
|
||||
String path = vformat("/org/freedesktop/portal/desktop/request/%s/%s", dbus_unique_name.replace(".", "_").replace(":", ""), token);
|
||||
String path = vformat("/org/freedesktop/portal/desktop/request/%s/%s", dbus_unique_name.replace_char('.', '_').remove_char(':'), token);
|
||||
|
||||
fd.path = path;
|
||||
fd.filter = vformat("type='signal',sender='org.freedesktop.portal.Desktop',path='%s',interface='org.freedesktop.portal.Request',member='Response',destination='%s'", path, dbus_unique_name);
|
||||
|
|
@ -592,29 +804,47 @@ Error FreeDesktopPortalDesktop::file_dialog_show(DisplayServer::WindowID p_windo
|
|||
return OK;
|
||||
}
|
||||
|
||||
void FreeDesktopPortalDesktop::process_file_dialog_callbacks() {
|
||||
MutexLock lock(file_dialog_mutex);
|
||||
while (!pending_cbs.is_empty()) {
|
||||
FileDialogCallback cb = pending_cbs.front()->get();
|
||||
pending_cbs.pop_front();
|
||||
void FreeDesktopPortalDesktop::process_callbacks() {
|
||||
{
|
||||
MutexLock lock(file_dialog_mutex);
|
||||
while (!pending_file_cbs.is_empty()) {
|
||||
FileDialogCallback cb = pending_file_cbs.front()->get();
|
||||
pending_file_cbs.pop_front();
|
||||
|
||||
if (cb.opt_in_cb) {
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
const Variant *args[4] = { &cb.status, &cb.files, &cb.index, &cb.options };
|
||||
if (cb.opt_in_cb) {
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
const Variant *args[4] = { &cb.status, &cb.files, &cb.index, &cb.options };
|
||||
|
||||
cb.callback.callp(args, 4, ret, ce);
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 4, ce)));
|
||||
cb.callback.callp(args, 4, ret, ce);
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 4, ce)));
|
||||
}
|
||||
} else {
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
const Variant *args[3] = { &cb.status, &cb.files, &cb.index };
|
||||
|
||||
cb.callback.callp(args, 3, ret, ce);
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 3, ce)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
{
|
||||
MutexLock lock(color_picker_mutex);
|
||||
while (!pending_color_cbs.is_empty()) {
|
||||
ColorPickerCallback cb = pending_color_cbs.front()->get();
|
||||
pending_color_cbs.pop_front();
|
||||
|
||||
Variant ret;
|
||||
Callable::CallError ce;
|
||||
const Variant *args[3] = { &cb.status, &cb.files, &cb.index };
|
||||
const Variant *args[2] = { &cb.status, &cb.color };
|
||||
|
||||
cb.callback.callp(args, 3, ret, ce);
|
||||
cb.callback.callp(args, 2, ret, ce);
|
||||
if (ce.error != Callable::CallError::CALL_OK) {
|
||||
ERR_PRINT(vformat("Failed to execute file dialog callback: %s.", Variant::get_callable_error_text(cb.callback, args, 3, ce)));
|
||||
ERR_PRINT(vformat("Failed to execute color picker callback: %s.", Variant::get_callable_error_text(cb.callback, args, 2, ce)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -639,46 +869,78 @@ void FreeDesktopPortalDesktop::_thread_monitor(void *p_ud) {
|
|||
dbus_message_iter_get_basic(&iter, &value);
|
||||
String key = String::utf8(value);
|
||||
|
||||
if (name_space == "org.freedesktop.appearance" && key == "color-scheme") {
|
||||
if (name_space == "org.freedesktop.appearance" && (key == "color-scheme" || key == "accent-color")) {
|
||||
callable_mp(portal, &FreeDesktopPortalDesktop::_system_theme_changed_callback).call_deferred();
|
||||
}
|
||||
}
|
||||
} else if (dbus_message_is_signal(msg, "org.freedesktop.portal.Request", "Response")) {
|
||||
String path = String::utf8(dbus_message_get_path(msg));
|
||||
MutexLock lock(portal->file_dialog_mutex);
|
||||
for (int i = 0; i < portal->file_dialogs.size(); i++) {
|
||||
FreeDesktopPortalDesktop::FileDialogData &fd = portal->file_dialogs.write[i];
|
||||
if (fd.path == path) {
|
||||
DBusMessageIter iter;
|
||||
if (dbus_message_iter_init(msg, &iter)) {
|
||||
bool cancel = false;
|
||||
Vector<String> uris;
|
||||
Dictionary options;
|
||||
int index = 0;
|
||||
file_chooser_parse_response(&iter, fd.filter_names, fd.option_ids, cancel, uris, index, options);
|
||||
{
|
||||
MutexLock lock(portal->file_dialog_mutex);
|
||||
for (int i = 0; i < portal->file_dialogs.size(); i++) {
|
||||
FreeDesktopPortalDesktop::FileDialogData &fd = portal->file_dialogs.write[i];
|
||||
if (fd.path == path) {
|
||||
DBusMessageIter iter;
|
||||
if (dbus_message_iter_init(msg, &iter)) {
|
||||
bool cancel = false;
|
||||
Vector<String> uris;
|
||||
Dictionary options;
|
||||
int index = 0;
|
||||
file_chooser_parse_response(&iter, fd.filter_names, fd.option_ids, cancel, uris, index, options);
|
||||
|
||||
if (fd.callback.is_valid()) {
|
||||
FileDialogCallback cb;
|
||||
cb.callback = fd.callback;
|
||||
cb.status = !cancel;
|
||||
cb.files = uris;
|
||||
cb.index = index;
|
||||
cb.options = options;
|
||||
cb.opt_in_cb = fd.opt_in_cb;
|
||||
portal->pending_cbs.push_back(cb);
|
||||
}
|
||||
if (fd.prev_focus != DisplayServer::INVALID_WINDOW_ID) {
|
||||
callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus);
|
||||
if (fd.callback.is_valid()) {
|
||||
FileDialogCallback cb;
|
||||
cb.callback = fd.callback;
|
||||
cb.status = !cancel;
|
||||
cb.files = uris;
|
||||
cb.index = index;
|
||||
cb.options = options;
|
||||
cb.opt_in_cb = fd.opt_in_cb;
|
||||
portal->pending_file_cbs.push_back(cb);
|
||||
}
|
||||
if (fd.prev_focus != DisplayServer::INVALID_WINDOW_ID) {
|
||||
callable_mp(DisplayServer::get_singleton(), &DisplayServer::window_move_to_foreground).call_deferred(fd.prev_focus);
|
||||
}
|
||||
}
|
||||
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_remove_match(portal->monitor_connection, fd.filter.utf8().get_data(), &err);
|
||||
dbus_error_free(&err);
|
||||
|
||||
portal->file_dialogs.remove_at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
MutexLock lock(portal->color_picker_mutex);
|
||||
for (int i = 0; i < portal->color_pickers.size(); i++) {
|
||||
FreeDesktopPortalDesktop::ColorPickerData &cd = portal->color_pickers.write[i];
|
||||
if (cd.path == path) {
|
||||
DBusMessageIter iter;
|
||||
if (dbus_message_iter_init(msg, &iter)) {
|
||||
bool cancel = false;
|
||||
Color c;
|
||||
color_picker_parse_response(&iter, cancel, c);
|
||||
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_remove_match(portal->monitor_connection, fd.filter.utf8().get_data(), &err);
|
||||
dbus_error_free(&err);
|
||||
if (cd.callback.is_valid()) {
|
||||
ColorPickerCallback cb;
|
||||
cb.callback = cd.callback;
|
||||
cb.color = c;
|
||||
cb.status = !cancel;
|
||||
portal->pending_color_cbs.push_back(cb);
|
||||
}
|
||||
}
|
||||
|
||||
portal->file_dialogs.remove_at(i);
|
||||
break;
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
dbus_bus_remove_match(portal->monitor_connection, cd.filter.utf8().get_data(), &err);
|
||||
dbus_error_free(&err);
|
||||
|
||||
portal->color_pickers.remove_at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FREEDESKTOP_PORTAL_DESKTOP_H
|
||||
#define FREEDESKTOP_PORTAL_DESKTOP_H
|
||||
#pragma once
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
|
||||
|
|
@ -45,9 +44,15 @@ class FreeDesktopPortalDesktop : public Object {
|
|||
private:
|
||||
bool unsupported = false;
|
||||
|
||||
static bool try_parse_variant(DBusMessage *p_reply_message, int p_type, void *r_value);
|
||||
enum ReadVariantType {
|
||||
VAR_TYPE_UINT32, // u
|
||||
VAR_TYPE_BOOL, // b
|
||||
VAR_TYPE_COLOR, // (ddd)
|
||||
};
|
||||
|
||||
static bool try_parse_variant(DBusMessage *p_reply_message, ReadVariantType p_type, void *r_value);
|
||||
// Read a setting from org.freekdesktop.portal.Settings
|
||||
bool read_setting(const char *p_namespace, const char *p_key, int p_type, void *r_value);
|
||||
bool read_setting(const char *p_namespace, const char *p_key, ReadVariantType p_type, void *r_value);
|
||||
|
||||
static void append_dbus_string(DBusMessageIter *p_iter, const String &p_string);
|
||||
static void append_dbus_dict_options(DBusMessageIter *p_iter, const TypedArray<Dictionary> &p_options, HashMap<String, String> &r_ids);
|
||||
|
|
@ -55,6 +60,23 @@ private:
|
|||
static void append_dbus_dict_string(DBusMessageIter *p_iter, const String &p_key, const String &p_value, bool p_as_byte_array = false);
|
||||
static void append_dbus_dict_bool(DBusMessageIter *p_iter, const String &p_key, bool p_value);
|
||||
static bool file_chooser_parse_response(DBusMessageIter *p_iter, const Vector<String> &p_names, const HashMap<String, String> &p_ids, bool &r_cancel, Vector<String> &r_urls, int &r_index, Dictionary &r_options);
|
||||
static bool color_picker_parse_response(DBusMessageIter *p_iter, bool &r_cancel, Color &r_color);
|
||||
|
||||
struct ColorPickerData {
|
||||
Callable callback;
|
||||
String filter;
|
||||
String path;
|
||||
};
|
||||
|
||||
struct ColorPickerCallback {
|
||||
Callable callback;
|
||||
Variant status;
|
||||
Variant color;
|
||||
};
|
||||
List<ColorPickerCallback> pending_color_cbs;
|
||||
|
||||
Mutex color_picker_mutex;
|
||||
Vector<ColorPickerData> color_pickers;
|
||||
|
||||
struct FileDialogData {
|
||||
Vector<String> filter_names;
|
||||
|
|
@ -74,7 +96,7 @@ private:
|
|||
Variant options;
|
||||
bool opt_in_cb = false;
|
||||
};
|
||||
List<FileDialogCallback> pending_cbs;
|
||||
List<FileDialogCallback> pending_file_cbs;
|
||||
|
||||
Mutex file_dialog_mutex;
|
||||
Vector<FileDialogData> file_dialogs;
|
||||
|
|
@ -96,11 +118,11 @@ public:
|
|||
bool is_supported() { return !unsupported; }
|
||||
bool is_file_chooser_supported();
|
||||
bool is_settings_supported();
|
||||
bool is_screenshot_supported();
|
||||
|
||||
// org.freedesktop.portal.FileChooser methods.
|
||||
|
||||
Error file_dialog_show(DisplayServer::WindowID p_window_id, const String &p_xid, const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, DisplayServer::FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, bool p_options_in_cb);
|
||||
void process_file_dialog_callbacks();
|
||||
void process_callbacks();
|
||||
|
||||
// org.freedesktop.portal.Settings methods.
|
||||
|
||||
|
|
@ -109,11 +131,19 @@ public:
|
|||
// 1: Prefer dark appearance.
|
||||
// 2: Prefer light appearance.
|
||||
uint32_t get_appearance_color_scheme();
|
||||
Color get_appearance_accent_color();
|
||||
void set_system_theme_change_callback(const Callable &p_system_theme_changed) {
|
||||
system_theme_changed = p_system_theme_changed;
|
||||
}
|
||||
|
||||
// Retrieve high-contrast setting.
|
||||
// -1: Unknown.
|
||||
// 0: Disabled.
|
||||
// 1: Enabled.
|
||||
uint32_t get_high_contrast();
|
||||
|
||||
// org.freedesktop.portal.Screenshot methods.
|
||||
bool color_picker(const String &p_xid, const Callable &p_callback);
|
||||
};
|
||||
|
||||
#endif // DBUS_ENABLED
|
||||
|
||||
#endif // FREEDESKTOP_PORTAL_DESKTOP_H
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ void FreeDesktopScreenSaver::inhibit() {
|
|||
if (dbus_error_is_set(&error)) {
|
||||
dbus_error_free(&error);
|
||||
dbus_connection_unref(bus);
|
||||
unsupported = false;
|
||||
unsupported = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -116,6 +116,7 @@ void FreeDesktopScreenSaver::uninhibit() {
|
|||
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_error_free(&error);
|
||||
dbus_connection_unref(bus);
|
||||
|
|
@ -125,7 +126,6 @@ void FreeDesktopScreenSaver::uninhibit() {
|
|||
|
||||
print_verbose("FreeDesktopScreenSaver: Released screensaver inhibition cookie: " + uitos(cookie));
|
||||
|
||||
dbus_message_unref(message);
|
||||
dbus_message_unref(reply);
|
||||
dbus_connection_unref(bus);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FREEDESKTOP_SCREENSAVER_H
|
||||
#define FREEDESKTOP_SCREENSAVER_H
|
||||
#pragma once
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
|
||||
|
|
@ -47,5 +46,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // DBUS_ENABLED
|
||||
|
||||
#endif // FREEDESKTOP_SCREENSAVER_H
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ JoypadLinux::Joypad::~Joypad() {
|
|||
}
|
||||
|
||||
void JoypadLinux::Joypad::reset() {
|
||||
dpad = 0;
|
||||
dpad.clear();
|
||||
fd = -1;
|
||||
for (int i = 0; i < MAX_ABS; i++) {
|
||||
abs_map[i] = -1;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef JOYPAD_LINUX_H
|
||||
#define JOYPAD_LINUX_H
|
||||
#pragma once
|
||||
|
||||
#ifdef JOYDEV_ENABLED
|
||||
|
||||
|
|
@ -63,7 +62,7 @@ private:
|
|||
float curr_axis[MAX_ABS];
|
||||
int key_map[MAX_KEY];
|
||||
int abs_map[MAX_ABS];
|
||||
BitField<HatMask> dpad;
|
||||
BitField<HatMask> dpad = HatMask::CENTER;
|
||||
int fd = -1;
|
||||
|
||||
String devpath;
|
||||
|
|
@ -135,5 +134,3 @@ private:
|
|||
};
|
||||
|
||||
#endif // JOYDEV_ENABLED
|
||||
|
||||
#endif // JOYPAD_LINUX_H
|
||||
|
|
|
|||
11
engine/platform/linuxbsd/msvs.py
Normal file
11
engine/platform/linuxbsd/msvs.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Tuples with the name of the arch
|
||||
def get_platforms():
|
||||
return [("x64", "x86_64")]
|
||||
|
||||
|
||||
def get_configurations():
|
||||
return ["editor", "template_debug", "template_release"]
|
||||
|
||||
|
||||
def get_build_prefix(env):
|
||||
return []
|
||||
|
|
@ -37,10 +37,12 @@
|
|||
#include "servers/rendering_server.h"
|
||||
|
||||
#ifdef X11_ENABLED
|
||||
#include "x11/detect_prime_x11.h"
|
||||
#include "x11/display_server_x11.h"
|
||||
#endif
|
||||
|
||||
#ifdef WAYLAND_ENABLED
|
||||
#include "wayland/detect_prime_egl.h"
|
||||
#include "wayland/display_server_wayland.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -49,6 +51,22 @@
|
|||
#include "modules/regex/regex.h"
|
||||
#endif
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#endif
|
||||
|
||||
#if defined(VULKAN_ENABLED)
|
||||
#ifdef X11_ENABLED
|
||||
#include "x11/rendering_context_driver_vulkan_x11.h"
|
||||
#endif
|
||||
#ifdef WAYLAND_ENABLED
|
||||
#include "wayland/rendering_context_driver_vulkan_wayland.h"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(GLES3_ENABLED)
|
||||
#include "drivers/gles3/rasterizer_gles3.h"
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -74,7 +92,7 @@ void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) {
|
|||
String program;
|
||||
|
||||
for (int i = 0; i < path_elems.size(); i++) {
|
||||
for (uint64_t k = 0; k < sizeof(message_programs) / sizeof(char *); k++) {
|
||||
for (uint64_t k = 0; k < std::size(message_programs); k++) {
|
||||
String tested_path = path_elems[i].path_join(message_programs[k]);
|
||||
|
||||
if (FileAccess::exists(tested_path)) {
|
||||
|
|
@ -155,7 +173,7 @@ String OS_LinuxBSD::get_unique_id() const {
|
|||
memset(buf, 0, sizeof(buf));
|
||||
size_t len = sizeof(buf) - 1;
|
||||
if (sysctl(mib, 2, buf, &len, 0x0, 0) != -1) {
|
||||
machine_id = String::utf8(buf).replace("-", "");
|
||||
machine_id = String::utf8(buf).remove_char('-');
|
||||
}
|
||||
#else
|
||||
Ref<FileAccess> f = FileAccess::open("/etc/machine-id", FileAccess::READ);
|
||||
|
|
@ -751,7 +769,7 @@ Vector<String> OS_LinuxBSD::get_system_font_path_for_text(const String &p_font_n
|
|||
|
||||
Vector<String> ret;
|
||||
static const char *allowed_formats[] = { "TrueType", "CFF" };
|
||||
for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) {
|
||||
for (size_t i = 0; i < std::size(allowed_formats); i++) {
|
||||
FcPattern *pattern = FcPatternCreate();
|
||||
if (pattern) {
|
||||
FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
|
||||
|
|
@ -1180,6 +1198,73 @@ String OS_LinuxBSD::get_system_ca_certificates() {
|
|||
return f->get_as_text();
|
||||
}
|
||||
|
||||
bool OS_LinuxBSD::_test_create_rendering_device(const String &p_display_driver) const {
|
||||
// Tests Rendering Device creation.
|
||||
|
||||
bool ok = false;
|
||||
#if defined(RD_ENABLED)
|
||||
Error err;
|
||||
RenderingContextDriver *rcd = nullptr;
|
||||
|
||||
#if defined(VULKAN_ENABLED)
|
||||
#ifdef X11_ENABLED
|
||||
if (p_display_driver == "x11" || p_display_driver.is_empty()) {
|
||||
rcd = memnew(RenderingContextDriverVulkanX11);
|
||||
}
|
||||
#endif
|
||||
#ifdef WAYLAND_ENABLED
|
||||
if (p_display_driver == "wayland") {
|
||||
rcd = memnew(RenderingContextDriverVulkanWayland);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (rcd != nullptr) {
|
||||
err = rcd->initialize();
|
||||
if (err == OK) {
|
||||
RenderingDevice *rd = memnew(RenderingDevice);
|
||||
err = rd->initialize(rcd);
|
||||
memdelete(rd);
|
||||
rd = nullptr;
|
||||
if (err == OK) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
memdelete(rcd);
|
||||
rcd = nullptr;
|
||||
}
|
||||
#endif
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool OS_LinuxBSD::_test_create_rendering_device_and_gl(const String &p_display_driver) const {
|
||||
// Tests OpenGL context and Rendering Device simultaneous creation. This function is expected to crash on some drivers.
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
#ifdef X11_ENABLED
|
||||
if (p_display_driver == "x11" || p_display_driver.is_empty()) {
|
||||
#ifdef SOWRAP_ENABLED
|
||||
if (initialize_xlib(0) != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
DetectPrimeX11::create_context();
|
||||
}
|
||||
#endif
|
||||
#ifdef WAYLAND_ENABLED
|
||||
if (p_display_driver == "wayland") {
|
||||
#ifdef SOWRAP_ENABLED
|
||||
if (initialize_wayland_egl(0) != 0) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
DetectPrimeEGL::create_context(EGL_PLATFORM_WAYLAND_KHR);
|
||||
}
|
||||
#endif
|
||||
RasterizerGLES3::make_current(true);
|
||||
#endif
|
||||
return _test_create_rendering_device(p_display_driver);
|
||||
}
|
||||
|
||||
OS_LinuxBSD::OS_LinuxBSD() {
|
||||
main_loop = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef OS_LINUXBSD_H
|
||||
#define OS_LINUXBSD_H
|
||||
#pragma once
|
||||
|
||||
#include "crash_handler_linuxbsd.h"
|
||||
#include "joypad_linux.h"
|
||||
|
|
@ -138,8 +137,9 @@ public:
|
|||
|
||||
virtual String get_system_ca_certificates() override;
|
||||
|
||||
virtual bool _test_create_rendering_device_and_gl(const String &p_display_driver) const override;
|
||||
virtual bool _test_create_rendering_device(const String &p_display_driver) const override;
|
||||
|
||||
OS_LinuxBSD();
|
||||
~OS_LinuxBSD();
|
||||
};
|
||||
|
||||
#endif // OS_LINUXBSD_H
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __linux__
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef PLATFORM_GL_H
|
||||
#define PLATFORM_GL_H
|
||||
#pragma once
|
||||
|
||||
#ifndef GL_API_ENABLED
|
||||
#define GL_API_ENABLED // Allow using desktop GL.
|
||||
|
|
@ -41,5 +40,3 @@
|
|||
|
||||
#include "thirdparty/glad/glad/egl.h"
|
||||
#include "thirdparty/glad/glad/gl.h"
|
||||
|
||||
#endif // PLATFORM_GL_H
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void TTS_Linux::speech_init_thread_func(void *p_userdata) {
|
|||
} else {
|
||||
class_str = config_name.utf8();
|
||||
}
|
||||
tts->synth = spd_open(class_str, "Godot_Engine_Speech_API", "Godot_Engine", SPD_MODE_THREADED);
|
||||
tts->synth = spd_open(class_str.get_data(), "Godot_Engine_Speech_API", "Godot_Engine", SPD_MODE_THREADED);
|
||||
if (tts->synth) {
|
||||
tts->synth->callback_end = &speech_event_callback;
|
||||
tts->synth->callback_cancel = &speech_event_callback;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TTS_LINUX_H
|
||||
#define TTS_LINUX_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/thread.h"
|
||||
#include "core/os/thread_safe.h"
|
||||
|
|
@ -90,5 +89,3 @@ public:
|
|||
TTS_Linux();
|
||||
~TTS_Linux();
|
||||
};
|
||||
|
||||
#endif // TTS_LINUX_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DETECT_PRIME_EGL_H
|
||||
#define DETECT_PRIME_EGL_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
#ifdef EGL_ENABLED
|
||||
|
|
@ -77,13 +76,11 @@ private:
|
|||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
public:
|
||||
static void create_context(EGLenum p_platform_enum);
|
||||
|
||||
public:
|
||||
static int detect_prime(EGLenum p_platform_enum);
|
||||
};
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
#endif // EGL_ENABLED
|
||||
|
||||
#endif // DETECT_PRIME_EGL_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DISPLAY_SERVER_WAYLAND_H
|
||||
#define DISPLAY_SERVER_WAYLAND_H
|
||||
#pragma once
|
||||
|
||||
#ifdef WAYLAND_ENABLED
|
||||
|
||||
|
|
@ -53,6 +52,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
#include "freedesktop_at_spi_monitor.h"
|
||||
#include "freedesktop_portal_desktop.h"
|
||||
#include "freedesktop_screensaver.h"
|
||||
#endif
|
||||
|
|
@ -67,9 +67,18 @@
|
|||
#undef CursorShape
|
||||
|
||||
class DisplayServerWayland : public DisplayServer {
|
||||
// No need to register with GDCLASS, it's platform-specific and nothing is added.
|
||||
GDSOFTCLASS(DisplayServerWayland, DisplayServer);
|
||||
|
||||
struct WindowData {
|
||||
WindowID id;
|
||||
WindowID id = INVALID_WINDOW_ID;
|
||||
|
||||
WindowID parent_id = INVALID_WINDOW_ID;
|
||||
|
||||
// For popups.
|
||||
WindowID root_id = INVALID_WINDOW_ID;
|
||||
|
||||
// For toplevels.
|
||||
List<WindowID> popup_stack;
|
||||
|
||||
Rect2i rect;
|
||||
Size2i max_size;
|
||||
|
|
@ -77,6 +86,8 @@ class DisplayServerWayland : public DisplayServer {
|
|||
|
||||
Rect2i safe_rect;
|
||||
|
||||
bool emulate_vsync = false;
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
struct wl_egl_window *wl_egl_window = nullptr;
|
||||
#endif
|
||||
|
|
@ -120,16 +131,25 @@ class DisplayServerWayland : public DisplayServer {
|
|||
|
||||
HashMap<CursorShape, CustomCursor> custom_cursors;
|
||||
|
||||
WindowData main_window;
|
||||
HashMap<WindowID, WindowData> windows;
|
||||
WindowID window_id_counter = MAIN_WINDOW_ID;
|
||||
|
||||
WaylandThread wayland_thread;
|
||||
|
||||
Context context;
|
||||
bool swap_cancel_ok = false;
|
||||
|
||||
// NOTE: These are the based on WINDOW_FLAG_POPUP, which does NOT imply what it
|
||||
// seems. It's particularly confusing for our usecase, but just know that these
|
||||
// are the "take all input thx" windows while the `popup_stack` variable keeps
|
||||
// track of all the generic floating window concept.
|
||||
List<WindowID> popup_menu_list;
|
||||
BitField<MouseButtonMask> last_mouse_monitor_mask = MouseButtonMask::NONE;
|
||||
|
||||
String ime_text;
|
||||
Vector2i ime_selection;
|
||||
|
||||
SuspendState suspend_state = SuspendState::NONE;
|
||||
bool emulate_vsync = false;
|
||||
|
||||
String rendering_driver;
|
||||
|
||||
|
|
@ -149,23 +169,24 @@ class DisplayServerWayland : public DisplayServer {
|
|||
|
||||
#if DBUS_ENABLED
|
||||
FreeDesktopPortalDesktop *portal_desktop = nullptr;
|
||||
FreeDesktopAtSPIMonitor *atspi_monitor = nullptr;
|
||||
|
||||
FreeDesktopScreenSaver *screensaver = nullptr;
|
||||
bool screensaver_inhibited = false;
|
||||
#endif
|
||||
static String _get_app_id_from_context(Context p_context);
|
||||
|
||||
void _send_window_event(WindowEvent p_event);
|
||||
void _send_window_event(WindowEvent p_event, WindowID p_window_id = MAIN_WINDOW_ID);
|
||||
|
||||
static void dispatch_input_events(const Ref<InputEvent> &p_event);
|
||||
void _dispatch_input_event(const Ref<InputEvent> &p_event);
|
||||
|
||||
void _resize_window(const Size2i &p_size);
|
||||
|
||||
virtual void _show_window();
|
||||
void _update_window_rect(const Rect2i &p_rect, WindowID p_window_id = MAIN_WINDOW_ID);
|
||||
|
||||
void try_suspend();
|
||||
|
||||
void initialize_tts() const;
|
||||
|
||||
public:
|
||||
virtual bool has_feature(Feature p_feature) const override;
|
||||
|
||||
|
|
@ -185,10 +206,11 @@ public:
|
|||
#ifdef DBUS_ENABLED
|
||||
virtual bool is_dark_mode_supported() const override;
|
||||
virtual bool is_dark_mode() const override;
|
||||
virtual Color get_accent_color() const override;
|
||||
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
|
||||
|
||||
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) override;
|
||||
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) override;
|
||||
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) override;
|
||||
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, WindowID p_window_id) override;
|
||||
#endif
|
||||
|
||||
virtual void beep() const override;
|
||||
|
|
@ -224,6 +246,14 @@ public:
|
|||
|
||||
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
|
||||
|
||||
virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID) override;
|
||||
virtual void show_window(WindowID p_id) override;
|
||||
virtual void delete_sub_window(WindowID p_id) override;
|
||||
|
||||
virtual WindowID window_get_active_popup() const override;
|
||||
virtual void window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) override;
|
||||
virtual Rect2i window_get_popup_safe_rect(WindowID p_window) const override;
|
||||
|
||||
virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
|
||||
|
|
@ -280,6 +310,9 @@ public:
|
|||
virtual void window_set_ime_active(const bool p_active, WindowID p_window_id = MAIN_WINDOW_ID) override;
|
||||
virtual void window_set_ime_position(const Point2i &p_pos, WindowID p_window_id = MAIN_WINDOW_ID) override;
|
||||
|
||||
virtual int accessibility_should_increase_contrast() const override;
|
||||
virtual int accessibility_screen_reader_active() const override;
|
||||
|
||||
virtual Point2i ime_get_selection() const override;
|
||||
virtual String ime_get_text() const override;
|
||||
|
||||
|
|
@ -293,6 +326,8 @@ public:
|
|||
virtual CursorShape cursor_get_shape() const override;
|
||||
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override;
|
||||
|
||||
virtual bool get_swap_cancel_ok() override;
|
||||
|
||||
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;
|
||||
|
|
@ -300,6 +335,8 @@ public:
|
|||
virtual String keyboard_get_layout_name(int p_index) const override;
|
||||
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
|
||||
|
||||
virtual bool color_picker(const Callable &p_callback) override;
|
||||
|
||||
virtual void process_events() override;
|
||||
|
||||
virtual void release_rendering_thread() override;
|
||||
|
|
@ -319,5 +356,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // WAYLAND_ENABLED
|
||||
|
||||
#endif // DISPLAY_SERVER_WAYLAND_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EGL_MANAGER_WAYLAND_H
|
||||
#define EGL_MANAGER_WAYLAND_H
|
||||
#pragma once
|
||||
|
||||
#ifdef WAYLAND_ENABLED
|
||||
#ifdef EGL_ENABLED
|
||||
|
|
@ -49,5 +48,3 @@ public:
|
|||
#endif // GLES3_ENABLED
|
||||
#endif // EGL_ENABLED
|
||||
#endif // WAYLAND_ENABLED
|
||||
|
||||
#endif // EGL_MANAGER_WAYLAND_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef EGL_MANAGER_WAYLAND_GLES_H
|
||||
#define EGL_MANAGER_WAYLAND_GLES_H
|
||||
#pragma once
|
||||
|
||||
#ifdef WAYLAND_ENABLED
|
||||
#ifdef EGL_ENABLED
|
||||
|
|
@ -49,5 +48,3 @@ public:
|
|||
#endif // GLES3_ENABLED
|
||||
#endif // EGL_ENABLED
|
||||
#endif // WAYLAND_ENABLED
|
||||
|
||||
#endif // EGL_MANAGER_WAYLAND_GLES_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef KEY_MAPPING_XKB_H
|
||||
#define KEY_MAPPING_XKB_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/keyboard.h"
|
||||
#include "core/templates/hash_map.h"
|
||||
|
|
@ -61,5 +60,3 @@ public:
|
|||
static Key get_scancode(unsigned int p_code);
|
||||
static KeyLocation get_location(unsigned int p_code);
|
||||
};
|
||||
|
||||
#endif // KEY_MAPPING_XKB_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDERING_CONTEXT_DRIVER_VULKAN_WAYLAND_H
|
||||
#define RENDERING_CONTEXT_DRIVER_VULKAN_WAYLAND_H
|
||||
#pragma once
|
||||
|
||||
#ifdef VULKAN_ENABLED
|
||||
|
||||
|
|
@ -53,5 +52,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // VULKAN_ENABLED
|
||||
|
||||
#endif // RENDERING_CONTEXT_DRIVER_VULKAN_WAYLAND_H
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef WAYLAND_THREAD_H
|
||||
#define WAYLAND_THREAD_H
|
||||
#pragma once
|
||||
|
||||
#ifdef WAYLAND_ENABLED
|
||||
|
||||
|
|
@ -89,41 +88,62 @@ class WaylandThread {
|
|||
public:
|
||||
// Messages used for exchanging information between Godot's and Wayland's thread.
|
||||
class Message : public RefCounted {
|
||||
GDSOFTCLASS(Message, RefCounted);
|
||||
|
||||
public:
|
||||
Message() {}
|
||||
virtual ~Message() = default;
|
||||
};
|
||||
|
||||
class WindowMessage : public Message {
|
||||
GDSOFTCLASS(WindowMessage, Message);
|
||||
|
||||
public:
|
||||
DisplayServer::WindowID id = DisplayServer::INVALID_WINDOW_ID;
|
||||
};
|
||||
|
||||
// Message data for window rect changes.
|
||||
class WindowRectMessage : public Message {
|
||||
class WindowRectMessage : public WindowMessage {
|
||||
GDSOFTCLASS(WindowRectMessage, WindowMessage);
|
||||
|
||||
public:
|
||||
// NOTE: This is in "scaled" terms. For example, if there's a 1920x1080 rect
|
||||
// with a scale factor of 2, the actual value of `rect` will be 3840x2160.
|
||||
Rect2i rect;
|
||||
};
|
||||
|
||||
class WindowEventMessage : public Message {
|
||||
class WindowEventMessage : public WindowMessage {
|
||||
GDSOFTCLASS(WindowEventMessage, WindowMessage);
|
||||
|
||||
public:
|
||||
DisplayServer::WindowEvent event;
|
||||
};
|
||||
|
||||
class InputEventMessage : public Message {
|
||||
GDSOFTCLASS(InputEventMessage, Message);
|
||||
|
||||
public:
|
||||
Ref<InputEvent> event;
|
||||
};
|
||||
|
||||
class DropFilesEventMessage : public Message {
|
||||
class DropFilesEventMessage : public WindowMessage {
|
||||
GDSOFTCLASS(DropFilesEventMessage, WindowMessage);
|
||||
|
||||
public:
|
||||
Vector<String> files;
|
||||
};
|
||||
|
||||
class IMEUpdateEventMessage : public Message {
|
||||
class IMEUpdateEventMessage : public WindowMessage {
|
||||
GDSOFTCLASS(IMEUpdateEventMessage, WindowMessage);
|
||||
|
||||
public:
|
||||
String text;
|
||||
Vector2i selection;
|
||||
};
|
||||
|
||||
class IMECommitEventMessage : public Message {
|
||||
class IMECommitEventMessage : public WindowMessage {
|
||||
GDSOFTCLASS(IMECommitEventMessage, WindowMessage);
|
||||
|
||||
public:
|
||||
String text;
|
||||
};
|
||||
|
|
@ -202,7 +222,8 @@ public:
|
|||
// TODO: Make private?
|
||||
|
||||
struct WindowState {
|
||||
DisplayServer::WindowID id;
|
||||
DisplayServer::WindowID id = DisplayServer::INVALID_WINDOW_ID;
|
||||
DisplayServer::WindowID parent_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
|
||||
Rect2i rect;
|
||||
DisplayServer::WindowMode mode = DisplayServer::WINDOW_MODE_WINDOWED;
|
||||
|
|
@ -224,6 +245,7 @@ public:
|
|||
// be called even after being destroyed, pointing to probably invalid window
|
||||
// data by then and segfaulting hard.
|
||||
struct wl_callback *frame_callback = nullptr;
|
||||
uint64_t last_frame_time = 0;
|
||||
|
||||
struct wl_surface *wl_surface = nullptr;
|
||||
struct xdg_surface *xdg_surface = nullptr;
|
||||
|
|
@ -237,6 +259,8 @@ public:
|
|||
|
||||
struct zxdg_exported_v2 *xdg_exported_v2 = nullptr;
|
||||
|
||||
struct xdg_popup *xdg_popup = nullptr;
|
||||
|
||||
String exported_handle;
|
||||
|
||||
// Currently applied buffer scale.
|
||||
|
|
@ -317,11 +341,14 @@ public:
|
|||
Vector2 relative_motion;
|
||||
uint32_t relative_motion_time = 0;
|
||||
|
||||
BitField<MouseButtonMask> pressed_button_mask;
|
||||
BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;
|
||||
|
||||
MouseButton last_button_pressed = MouseButton::NONE;
|
||||
Point2 last_pressed_position;
|
||||
|
||||
DisplayServer::WindowID pointed_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
DisplayServer::WindowID last_pointed_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
|
||||
// This is needed to check for a new double click every time.
|
||||
bool double_click_begun = false;
|
||||
|
||||
|
|
@ -344,27 +371,24 @@ public:
|
|||
Vector2 tilt;
|
||||
uint32_t pressure = 0;
|
||||
|
||||
BitField<MouseButtonMask> pressed_button_mask;
|
||||
BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;
|
||||
|
||||
MouseButton last_button_pressed = MouseButton::NONE;
|
||||
Point2 last_pressed_position;
|
||||
|
||||
bool double_click_begun = false;
|
||||
|
||||
// Note: the protocol doesn't have it (I guess that this isn't really meant to
|
||||
// be used as a mouse...), but we'll hack one in with the current ticks.
|
||||
uint64_t button_time = 0;
|
||||
|
||||
uint64_t motion_time = 0;
|
||||
|
||||
DisplayServer::WindowID proximal_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
DisplayServer::WindowID last_proximal_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
uint32_t proximity_serial = 0;
|
||||
struct wl_surface *proximal_surface = nullptr;
|
||||
};
|
||||
|
||||
struct TabletToolState {
|
||||
struct wl_seat *wl_seat = nullptr;
|
||||
|
||||
struct wl_surface *last_surface = nullptr;
|
||||
bool is_eraser = false;
|
||||
|
||||
TabletToolData data_pending;
|
||||
|
|
@ -388,9 +412,6 @@ public:
|
|||
|
||||
uint32_t pointer_enter_serial = 0;
|
||||
|
||||
struct wl_surface *pointed_surface = nullptr;
|
||||
struct wl_surface *last_pointed_surface = nullptr;
|
||||
|
||||
struct zwp_relative_pointer_v1 *wp_relative_pointer = nullptr;
|
||||
struct zwp_locked_pointer_v1 *wp_locked_pointer = nullptr;
|
||||
struct zwp_confined_pointer_v1 *wp_confined_pointer = nullptr;
|
||||
|
|
@ -421,6 +442,9 @@ public:
|
|||
// Keyboard.
|
||||
struct wl_keyboard *wl_keyboard = nullptr;
|
||||
|
||||
// For key events.
|
||||
DisplayServer::WindowID focused_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
|
||||
struct xkb_context *xkb_context = nullptr;
|
||||
struct xkb_keymap *xkb_keymap = nullptr;
|
||||
struct xkb_state *xkb_state = nullptr;
|
||||
|
|
@ -449,6 +473,7 @@ public:
|
|||
struct wl_data_device *wl_data_device = nullptr;
|
||||
|
||||
// Drag and drop.
|
||||
DisplayServer::WindowID dnd_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
struct wl_data_offer *wl_data_offer_dnd = nullptr;
|
||||
uint32_t dnd_enter_serial = 0;
|
||||
|
||||
|
|
@ -473,6 +498,7 @@ public:
|
|||
|
||||
// IME.
|
||||
struct zwp_text_input_v3 *wp_text_input = nullptr;
|
||||
DisplayServer::WindowID ime_window_id = DisplayServer::INVALID_WINDOW_ID;
|
||||
bool ime_enabled = false;
|
||||
bool ime_active = false;
|
||||
String ime_text;
|
||||
|
|
@ -503,7 +529,7 @@ private:
|
|||
Thread events_thread;
|
||||
ThreadData thread_data;
|
||||
|
||||
WindowState main_window;
|
||||
HashMap<DisplayServer::WindowID, WindowState> windows;
|
||||
|
||||
List<Ref<Message>> messages;
|
||||
|
||||
|
|
@ -615,6 +641,10 @@ private:
|
|||
static void _xdg_toplevel_on_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height);
|
||||
static void _xdg_toplevel_on_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel, struct wl_array *capabilities);
|
||||
|
||||
static void _xdg_popup_on_configure(void *data, struct xdg_popup *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
static void _xdg_popup_on_popup_done(void *data, struct xdg_popup *xdg_popup);
|
||||
static void _xdg_popup_on_repositioned(void *data, struct xdg_popup *xdg_popup, uint32_t token);
|
||||
|
||||
// wayland-protocols event handlers.
|
||||
static void _wp_fractional_scale_on_preferred_scale(void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1, uint32_t scale);
|
||||
|
||||
|
|
@ -770,6 +800,12 @@ private:
|
|||
.wm_capabilities = _xdg_toplevel_on_wm_capabilities,
|
||||
};
|
||||
|
||||
static constexpr struct xdg_popup_listener xdg_popup_listener = {
|
||||
.configure = _xdg_popup_on_configure,
|
||||
.popup_done = _xdg_popup_on_popup_done,
|
||||
.repositioned = _xdg_popup_on_repositioned,
|
||||
};
|
||||
|
||||
// wayland-protocols event listeners.
|
||||
static constexpr struct wp_fractional_scale_v1_listener wp_fractional_scale_listener = {
|
||||
.preferred_scale = _wp_fractional_scale_on_preferred_scale,
|
||||
|
|
@ -955,8 +991,13 @@ public:
|
|||
void beep() const;
|
||||
|
||||
void window_create(DisplayServer::WindowID p_window_id, int p_width, int p_height);
|
||||
void window_create_popup(DisplayServer::WindowID p_window_id, DisplayServer::WindowID p_parent_id, Rect2i p_rect);
|
||||
void window_destroy(DisplayServer::WindowID p_window_Id);
|
||||
|
||||
void window_set_parent(DisplayServer::WindowID p_window_id, DisplayServer::WindowID p_parent_id);
|
||||
|
||||
struct wl_surface *window_get_wl_surface(DisplayServer::WindowID p_window_id) const;
|
||||
WindowState *window_get_state(DisplayServer::WindowID p_window_id);
|
||||
|
||||
void window_start_resize(DisplayServer::WindowResizeEdge p_edge, DisplayServer::WindowID p_window);
|
||||
|
||||
|
|
@ -989,6 +1030,7 @@ public:
|
|||
void pointer_set_hint(const Point2i &p_hint);
|
||||
PointerConstraint pointer_get_constraint() const;
|
||||
DisplayServer::WindowID pointer_get_pointed_window_id() const;
|
||||
DisplayServer::WindowID pointer_get_last_pointed_window_id() const;
|
||||
BitField<MouseButtonMask> pointer_get_button_mask() const;
|
||||
|
||||
void cursor_set_visible(bool p_visible);
|
||||
|
|
@ -1027,6 +1069,8 @@ public:
|
|||
bool get_reset_frame();
|
||||
bool wait_frame_suspend_ms(int p_timeout);
|
||||
|
||||
uint64_t window_get_last_frame_time(DisplayServer::WindowID p_window_id) const;
|
||||
bool window_is_suspended(DisplayServer::WindowID p_window_id) const;
|
||||
bool is_suspended() const;
|
||||
|
||||
Error init();
|
||||
|
|
@ -1034,5 +1078,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // WAYLAND_ENABLED
|
||||
|
||||
#endif // WAYLAND_THREAD_H
|
||||
|
|
|
|||
|
|
@ -60,25 +60,23 @@ typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLX
|
|||
// To prevent shadowing warnings
|
||||
#undef glGetString
|
||||
|
||||
struct vendor {
|
||||
const char *glxvendor = nullptr;
|
||||
int priority = 0;
|
||||
};
|
||||
int silent_error_handler(Display *display, XErrorEvent *error) {
|
||||
static char message[1024];
|
||||
XGetErrorText(display, error->error_code, message, sizeof(message));
|
||||
print_verbose(vformat("XServer error: %s"
|
||||
"\n Major opcode of failed request: %d"
|
||||
"\n Serial number of failed request: %d"
|
||||
"\n Current serial number in output stream: %d",
|
||||
String::utf8(message), (uint64_t)error->request_code, (uint64_t)error->minor_code, (uint64_t)error->serial));
|
||||
|
||||
vendor vendormap[] = {
|
||||
{ "Advanced Micro Devices, Inc.", 30 },
|
||||
{ "AMD", 30 },
|
||||
{ "NVIDIA Corporation", 30 },
|
||||
{ "X.Org", 30 },
|
||||
{ "Intel Open Source Technology Center", 20 },
|
||||
{ "Intel", 20 },
|
||||
{ "nouveau", 10 },
|
||||
{ "Mesa Project", 0 },
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
quick_exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Runs inside a child. Exiting will not quit the engine.
|
||||
void create_context() {
|
||||
void DetectPrimeX11::create_context() {
|
||||
XSetErrorHandler(&silent_error_handler);
|
||||
|
||||
Display *x11_display = XOpenDisplay(nullptr);
|
||||
Window x11_window;
|
||||
GLXContext glx_context;
|
||||
|
|
@ -137,20 +135,7 @@ void create_context() {
|
|||
XFree(vi);
|
||||
}
|
||||
|
||||
int silent_error_handler(Display *display, XErrorEvent *error) {
|
||||
static char message[1024];
|
||||
XGetErrorText(display, error->error_code, message, sizeof(message));
|
||||
print_verbose(vformat("XServer error: %s"
|
||||
"\n Major opcode of failed request: %d"
|
||||
"\n Serial number of failed request: %d"
|
||||
"\n Current serial number in output stream: %d",
|
||||
String::utf8(message), (uint64_t)error->request_code, (uint64_t)error->minor_code, (uint64_t)error->serial));
|
||||
|
||||
quick_exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int detect_prime() {
|
||||
int DetectPrimeX11::detect_prime() {
|
||||
pid_t p;
|
||||
int priorities[2] = {};
|
||||
String vendors[2];
|
||||
|
|
@ -202,7 +187,6 @@ int detect_prime() {
|
|||
// cleaning up these processes, and fork() makes a copy
|
||||
// of all globals.
|
||||
CoreGlobals::leak_reporting_enabled = false;
|
||||
XSetErrorHandler(&silent_error_handler);
|
||||
|
||||
char string[201];
|
||||
|
||||
|
|
@ -253,7 +237,7 @@ int detect_prime() {
|
|||
}
|
||||
|
||||
for (int i = 1; i >= 0; --i) {
|
||||
vendor *v = vendormap;
|
||||
const Vendor *v = vendor_map;
|
||||
while (v->glxvendor) {
|
||||
if (v->glxvendor == vendors[i]) {
|
||||
priorities[i] = v->priority;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,33 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DETECT_PRIME_X11_H
|
||||
#define DETECT_PRIME_X11_H
|
||||
#pragma once
|
||||
|
||||
#if defined(X11_ENABLED) && defined(GLES3_ENABLED)
|
||||
|
||||
int detect_prime();
|
||||
class DetectPrimeX11 {
|
||||
private:
|
||||
struct Vendor {
|
||||
const char *glxvendor = nullptr;
|
||||
int priority = 0;
|
||||
};
|
||||
|
||||
static constexpr Vendor vendor_map[] = {
|
||||
{ "Advanced Micro Devices, Inc.", 30 },
|
||||
{ "AMD", 30 },
|
||||
{ "NVIDIA Corporation", 30 },
|
||||
{ "X.Org", 30 },
|
||||
{ "Intel Open Source Technology Center", 20 },
|
||||
{ "Intel", 20 },
|
||||
{ "nouveau", 10 },
|
||||
{ "Mesa Project", 0 },
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
public:
|
||||
static void create_context();
|
||||
|
||||
static int detect_prime();
|
||||
};
|
||||
|
||||
#endif // X11_ENABLED && GLES3_ENABLED
|
||||
|
||||
#endif // DETECT_PRIME_X11_H
|
||||
|
|
|
|||
|
|
@ -39,9 +39,12 @@
|
|||
#include "core/math/math_funcs.h"
|
||||
#include "core/string/print_string.h"
|
||||
#include "core/string/ustring.h"
|
||||
#include "core/version.h"
|
||||
#include "drivers/png/png_driver_common.h"
|
||||
#include "main/main.h"
|
||||
|
||||
#include "servers/rendering/dummy/rasterizer_dummy.h"
|
||||
|
||||
#if defined(VULKAN_ENABLED)
|
||||
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
||||
#endif
|
||||
|
|
@ -50,6 +53,10 @@
|
|||
#include "drivers/gles3/rasterizer_gles3.h"
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
#include "drivers/accesskit/accessibility_driver_accesskit.h"
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -111,8 +118,7 @@ struct Hints {
|
|||
static String get_atom_name(Display *p_disp, Atom p_atom) {
|
||||
char *name = XGetAtomName(p_disp, p_atom);
|
||||
ERR_FAIL_NULL_V_MSG(name, String(), "Atom is invalid.");
|
||||
String ret;
|
||||
ret.parse_utf8(name);
|
||||
String ret = String::utf8(name);
|
||||
XFree(name);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -156,6 +162,9 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
|
|||
case FEATURE_NATIVE_DIALOG_FILE_MIME: {
|
||||
return (portal_desktop && portal_desktop->is_supported() && portal_desktop->is_file_chooser_supported());
|
||||
} break;
|
||||
case FEATURE_NATIVE_COLOR_PICKER: {
|
||||
return (portal_desktop && portal_desktop->is_supported() && portal_desktop->is_screenshot_supported());
|
||||
} break;
|
||||
#endif
|
||||
case FEATURE_SCREEN_CAPTURE: {
|
||||
return !xwayland;
|
||||
|
|
@ -167,6 +176,12 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
|
|||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
case FEATURE_ACCESSIBILITY_SCREEN_READER: {
|
||||
return (accessibility_driver != nullptr);
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -338,38 +353,63 @@ void DisplayServerX11::_flush_mouse_motion() {
|
|||
|
||||
#ifdef SPEECHD_ENABLED
|
||||
|
||||
void DisplayServerX11::initialize_tts() const {
|
||||
const_cast<DisplayServerX11 *>(this)->tts = memnew(TTS_Linux);
|
||||
}
|
||||
|
||||
bool DisplayServerX11::tts_is_speaking() const {
|
||||
ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL_V(tts, false);
|
||||
return tts->is_speaking();
|
||||
}
|
||||
|
||||
bool DisplayServerX11::tts_is_paused() const {
|
||||
ERR_FAIL_NULL_V_MSG(tts, false, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL_V(tts, false);
|
||||
return tts->is_paused();
|
||||
}
|
||||
|
||||
TypedArray<Dictionary> DisplayServerX11::tts_get_voices() const {
|
||||
ERR_FAIL_NULL_V_MSG(tts, TypedArray<Dictionary>(), "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL_V(tts, TypedArray<Dictionary>());
|
||||
return tts->get_voices();
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->speak(p_text, p_voice, p_volume, p_pitch, p_rate, p_utterance_id, p_interrupt);
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_pause() {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->pause();
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_resume() {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->resume();
|
||||
}
|
||||
|
||||
void DisplayServerX11::tts_stop() {
|
||||
ERR_FAIL_NULL_MSG(tts, "Enable the \"audio/general/text_to_speech\" project setting to use text-to-speech.");
|
||||
if (unlikely(!tts)) {
|
||||
initialize_tts();
|
||||
}
|
||||
ERR_FAIL_NULL(tts);
|
||||
tts->stop();
|
||||
}
|
||||
|
||||
|
|
@ -398,30 +438,34 @@ bool DisplayServerX11::is_dark_mode() const {
|
|||
}
|
||||
}
|
||||
|
||||
Color DisplayServerX11::get_accent_color() const {
|
||||
return portal_desktop->get_appearance_accent_color();
|
||||
}
|
||||
|
||||
void DisplayServerX11::set_system_theme_change_callback(const Callable &p_callable) {
|
||||
portal_desktop->set_system_theme_change_callback(p_callable);
|
||||
}
|
||||
|
||||
Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) {
|
||||
WindowID window_id = last_focused_window;
|
||||
Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) {
|
||||
WindowID window_id = p_window_id;
|
||||
|
||||
if (!windows.has(window_id)) {
|
||||
if (!windows.has(window_id) || windows[window_id].is_popup) {
|
||||
window_id = MAIN_WINDOW_ID;
|
||||
}
|
||||
|
||||
String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window);
|
||||
return portal_desktop->file_dialog_show(last_focused_window, xid, p_title, p_current_directory, String(), p_filename, p_mode, p_filters, TypedArray<Dictionary>(), p_callback, false);
|
||||
return portal_desktop->file_dialog_show(p_window_id, xid, p_title, p_current_directory, String(), p_filename, p_mode, p_filters, TypedArray<Dictionary>(), p_callback, false);
|
||||
}
|
||||
|
||||
Error DisplayServerX11::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) {
|
||||
WindowID window_id = last_focused_window;
|
||||
Error DisplayServerX11::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, WindowID p_window_id) {
|
||||
WindowID window_id = p_window_id;
|
||||
|
||||
if (!windows.has(window_id)) {
|
||||
if (!windows.has(window_id) || windows[window_id].is_popup) {
|
||||
window_id = MAIN_WINDOW_ID;
|
||||
}
|
||||
|
||||
String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window);
|
||||
return portal_desktop->file_dialog_show(last_focused_window, xid, p_title, p_current_directory, p_root, p_filename, p_mode, p_filters, p_options, p_callback, true);
|
||||
return portal_desktop->file_dialog_show(p_window_id, xid, p_title, p_current_directory, p_root, p_filename, p_mode, p_filters, p_options, p_callback, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -578,7 +622,7 @@ BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
|
|||
int root_x, root_y, win_x, win_y;
|
||||
unsigned int mask;
|
||||
if (XQueryPointer(x11_display, XRootWindow(x11_display, i), &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) {
|
||||
BitField<MouseButtonMask> last_button_state = 0;
|
||||
BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
|
||||
|
||||
if (mask & Button1Mask) {
|
||||
last_button_state.set_flag(MouseButtonMask::LEFT);
|
||||
|
|
@ -599,7 +643,7 @@ BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
|
|||
return last_button_state;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return MouseButtonMask::NONE;
|
||||
}
|
||||
|
||||
void DisplayServerX11::clipboard_set(const String &p_text) {
|
||||
|
|
@ -759,7 +803,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
|
|||
}
|
||||
|
||||
if (success && (data_size > 0)) {
|
||||
ret.parse_utf8((const char *)incr_data.ptr(), data_size);
|
||||
ret.append_utf8((const char *)incr_data.ptr(), data_size);
|
||||
}
|
||||
} else if (bytes_left > 0) {
|
||||
// Data is ready and can be processed all at once.
|
||||
|
|
@ -769,7 +813,7 @@ String DisplayServerX11::_clipboard_get_impl(Atom p_source, Window x11_window, A
|
|||
&len, &dummy, &data);
|
||||
|
||||
if (result == Success) {
|
||||
ret.parse_utf8((const char *)data);
|
||||
ret.append_utf8((const char *)data);
|
||||
} else {
|
||||
print_verbose("Failed to get selection data.");
|
||||
}
|
||||
|
|
@ -1912,6 +1956,12 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->window_destroy(p_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wd.xic) {
|
||||
XDestroyIC(wd.xic);
|
||||
wd.xic = nullptr;
|
||||
|
|
@ -2061,7 +2111,7 @@ void DisplayServerX11::_update_window_mouse_passthrough(WindowID p_window) {
|
|||
Region region = XCreateRegion();
|
||||
XShapeCombineRegion(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, region, ShapeSet);
|
||||
XDestroyRegion(region);
|
||||
} else if (region_path.size() == 0) {
|
||||
} else if (region_path.is_empty()) {
|
||||
XShapeCombineMask(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, None, ShapeSet);
|
||||
} else {
|
||||
XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * region_path.size());
|
||||
|
|
@ -2284,6 +2334,40 @@ void DisplayServerX11::_update_size_hints(WindowID p_window) {
|
|||
XFree(xsh);
|
||||
}
|
||||
|
||||
void DisplayServerX11::_update_actions_hints(WindowID p_window) {
|
||||
WindowData &wd = windows[p_window];
|
||||
|
||||
Atom prop = XInternAtom(x11_display, "_NET_WM_ALLOWED_ACTIONS", False);
|
||||
if (prop != None) {
|
||||
Atom wm_act_max_horz = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_HORZ", False);
|
||||
Atom wm_act_max_vert = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_VERT", False);
|
||||
Atom wm_act_min = XInternAtom(x11_display, "_NET_WM_ACTION_MINIMIZE", False);
|
||||
Atom type;
|
||||
int format;
|
||||
unsigned long len;
|
||||
unsigned long remaining;
|
||||
unsigned char *data = nullptr;
|
||||
if (XGetWindowProperty(x11_display, wd.x11_window, prop, 0, 1024, False, XA_ATOM, &type, &format, &len, &remaining, &data) == Success) {
|
||||
Atom *atoms = (Atom *)data;
|
||||
Vector<Atom> new_atoms;
|
||||
for (uint64_t i = 0; i < len; i++) {
|
||||
if (atoms[i] != wm_act_max_horz && atoms[i] != wm_act_max_vert && atoms[i] != wm_act_min) {
|
||||
new_atoms.push_back(atoms[i]);
|
||||
}
|
||||
}
|
||||
if (!wd.no_max_btn) {
|
||||
new_atoms.push_back(wm_act_max_horz);
|
||||
new_atoms.push_back(wm_act_max_vert);
|
||||
}
|
||||
if (!wd.no_min_btn) {
|
||||
new_atoms.push_back(wm_act_min);
|
||||
}
|
||||
XChangeProperty(x11_display, wd.x11_window, prop, XA_ATOM, 32, PropModeReplace, (unsigned char *)new_atoms.ptrw(), new_atoms.size());
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Point2i DisplayServerX11::window_get_position(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -2338,6 +2422,7 @@ void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p
|
|||
return;
|
||||
}
|
||||
|
||||
wd.position = p_position;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (!window_get_flag(WINDOW_FLAG_BORDERLESS, p_window)) {
|
||||
|
|
@ -2563,7 +2648,8 @@ bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_a
|
|||
Atom *atoms = (Atom *)data;
|
||||
Atom wm_act_max_horz;
|
||||
Atom wm_act_max_vert;
|
||||
if (strcmp(p_atom_name, "_NET_WM_STATE") == 0) {
|
||||
bool checking_state = strcmp(p_atom_name, "_NET_WM_STATE") == 0;
|
||||
if (checking_state) {
|
||||
wm_act_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||
wm_act_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||
} else {
|
||||
|
|
@ -2581,9 +2667,16 @@ bool DisplayServerX11::_window_maximize_check(WindowID p_window, const char *p_a
|
|||
found_wm_act_max_vert = true;
|
||||
}
|
||||
|
||||
if (found_wm_act_max_horz || found_wm_act_max_vert) {
|
||||
retval = true;
|
||||
break;
|
||||
if (checking_state) {
|
||||
if (found_wm_act_max_horz && found_wm_act_max_vert) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (found_wm_act_max_horz || found_wm_act_max_vert) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2961,6 +3054,18 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
|
|||
WindowData &wd = windows[p_window];
|
||||
|
||||
switch (p_flag) {
|
||||
case WINDOW_FLAG_MAXIMIZE_DISABLED: {
|
||||
wd.no_max_btn = p_enabled;
|
||||
_update_actions_hints(p_window);
|
||||
|
||||
XFlush(x11_display);
|
||||
} break;
|
||||
case WINDOW_FLAG_MINIMIZE_DISABLED: {
|
||||
wd.no_min_btn = p_enabled;
|
||||
_update_actions_hints(p_window);
|
||||
|
||||
XFlush(x11_display);
|
||||
} break;
|
||||
case WINDOW_FLAG_RESIZE_DISABLED: {
|
||||
if (p_enabled && wd.embed_parent) {
|
||||
print_line("Embedded window resize can't be disabled.");
|
||||
|
|
@ -2969,6 +3074,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
|
|||
|
||||
wd.resize_disabled = p_enabled;
|
||||
_update_size_hints(p_window);
|
||||
_update_actions_hints(p_window);
|
||||
|
||||
XFlush(x11_display);
|
||||
} break;
|
||||
|
|
@ -3055,6 +3161,12 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
|
|||
const WindowData &wd = windows[p_window];
|
||||
|
||||
switch (p_flag) {
|
||||
case WINDOW_FLAG_MAXIMIZE_DISABLED: {
|
||||
return wd.no_max_btn;
|
||||
} break;
|
||||
case WINDOW_FLAG_MINIMIZE_DISABLED: {
|
||||
return wd.no_min_btn;
|
||||
} break;
|
||||
case WINDOW_FLAG_RESIZE_DISABLED: {
|
||||
return wd.resize_disabled;
|
||||
} break;
|
||||
|
|
@ -3244,6 +3356,22 @@ void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_
|
|||
}
|
||||
}
|
||||
|
||||
int DisplayServerX11::accessibility_should_increase_contrast() const {
|
||||
#ifdef DBUS_ENABLED
|
||||
return portal_desktop->get_high_contrast();
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DisplayServerX11::accessibility_screen_reader_active() const {
|
||||
#ifdef DBUS_ENABLED
|
||||
if (atspi_monitor->is_supported()) {
|
||||
return atspi_monitor->is_active();
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
Point2i DisplayServerX11::ime_get_selection() const {
|
||||
return im_selection;
|
||||
}
|
||||
|
|
@ -3355,6 +3483,10 @@ void DisplayServerX11::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
|
|||
}
|
||||
}
|
||||
|
||||
bool DisplayServerX11::get_swap_cancel_ok() {
|
||||
return swap_cancel_ok;
|
||||
}
|
||||
|
||||
int DisplayServerX11::keyboard_get_layout_count() const {
|
||||
int _group_count = 0;
|
||||
XkbDescRec *kbd = XkbAllocKeyboard();
|
||||
|
|
@ -3496,6 +3628,17 @@ Key DisplayServerX11::keyboard_get_label_from_physical(Key p_keycode) const {
|
|||
return (Key)(key | modifiers);
|
||||
}
|
||||
|
||||
bool DisplayServerX11::color_picker(const Callable &p_callback) {
|
||||
WindowID window_id = last_focused_window;
|
||||
|
||||
if (!windows.has(window_id)) {
|
||||
window_id = MAIN_WINDOW_ID;
|
||||
}
|
||||
|
||||
String xid = vformat("x11:%x", (uint64_t)windows[window_id].x11_window);
|
||||
return portal_desktop->color_picker(xid, p_callback);
|
||||
}
|
||||
|
||||
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {
|
||||
Atom actual_type = None;
|
||||
int actual_format = 0;
|
||||
|
|
@ -3657,8 +3800,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
|
|||
keycode -= 'a' - 'A';
|
||||
}
|
||||
|
||||
String tmp;
|
||||
tmp.parse_utf8(utf8string, utf8bytes);
|
||||
String tmp = String::utf8(utf8string, utf8bytes);
|
||||
for (int i = 0; i < tmp.length(); i++) {
|
||||
Ref<InputEventKey> k;
|
||||
k.instantiate();
|
||||
|
|
@ -3738,8 +3880,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
|
|||
char str_xkb[256] = {};
|
||||
int str_xkb_size = xkb_compose_state_get_utf8(wd.xkb_state, str_xkb, 255);
|
||||
|
||||
String tmp;
|
||||
tmp.parse_utf8(str_xkb, str_xkb_size);
|
||||
String tmp = String::utf8(str_xkb, str_xkb_size);
|
||||
for (int i = 0; i < tmp.length(); i++) {
|
||||
Ref<InputEventKey> k;
|
||||
k.instantiate();
|
||||
|
|
@ -3961,7 +4102,7 @@ Atom DisplayServerX11::_process_selection_request_target(Atom p_target, Window p
|
|||
32,
|
||||
PropModeReplace,
|
||||
(unsigned char *)&data,
|
||||
sizeof(data) / sizeof(data[0]));
|
||||
std::size(data));
|
||||
return p_property;
|
||||
} else if (p_target == XInternAtom(x11_display, "SAVE_TARGETS", 0)) {
|
||||
// Request to check if SAVE_TARGETS is supported, nothing special to do.
|
||||
|
|
@ -4094,7 +4235,7 @@ void DisplayServerX11::_xim_preedit_draw_callback(::XIM xim, ::XPointer client_d
|
|||
if (xim_text->encoding_is_wchar) {
|
||||
changed_text = String(xim_text->string.wide_char);
|
||||
} else {
|
||||
changed_text.parse_utf8(xim_text->string.multi_byte);
|
||||
changed_text.append_utf8(xim_text->string.multi_byte);
|
||||
}
|
||||
|
||||
if (call_data->chg_length < 0) {
|
||||
|
|
@ -4789,6 +4930,9 @@ void DisplayServerX11::process_events() {
|
|||
XSync(x11_display, False);
|
||||
XGetWindowAttributes(x11_display, wd.x11_window, &xwa);
|
||||
|
||||
_update_actions_hints(window_id);
|
||||
XFlush(x11_display);
|
||||
|
||||
// Set focus when menu window is started.
|
||||
// RevertToPointerRoot is used to make sure we don't lose all focus in case
|
||||
// a subwindow and its parent are both destroyed.
|
||||
|
|
@ -4878,6 +5022,11 @@ void DisplayServerX11::process_events() {
|
|||
static unsigned int focus_order = 0;
|
||||
wd.focus_order = ++focus_order;
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_set_window_focused(window_id, true);
|
||||
}
|
||||
#endif
|
||||
_send_window_event(wd, WINDOW_EVENT_FOCUS_IN);
|
||||
|
||||
if (mouse_mode_grab) {
|
||||
|
|
@ -4929,6 +5078,11 @@ void DisplayServerX11::process_events() {
|
|||
wd.focused = false;
|
||||
|
||||
Input::get_singleton()->release_pressed_events();
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->accessibility_set_window_focused(window_id, false);
|
||||
}
|
||||
#endif
|
||||
_send_window_event(wd, WINDOW_EVENT_FOCUS_OUT);
|
||||
|
||||
if (mouse_mode_grab) {
|
||||
|
|
@ -5164,7 +5318,7 @@ void DisplayServerX11::process_events() {
|
|||
pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
|
||||
}
|
||||
|
||||
BitField<MouseButtonMask> last_button_state = 0;
|
||||
BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
|
||||
if (event.xmotion.state & Button1Mask) {
|
||||
last_button_state.set_flag(MouseButtonMask::LEFT);
|
||||
}
|
||||
|
|
@ -5268,7 +5422,7 @@ void DisplayServerX11::process_events() {
|
|||
Vector<String> files = String((char *)p.data).split("\r\n", false);
|
||||
XFree(p.data);
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
files.write[i] = files[i].replace("file://", "").uri_decode();
|
||||
files.write[i] = files[i].replace("file://", "").uri_file_decode();
|
||||
}
|
||||
|
||||
if (windows[window_id].drop_files_callback.is_valid()) {
|
||||
|
|
@ -5385,7 +5539,7 @@ void DisplayServerX11::process_events() {
|
|||
|
||||
#ifdef DBUS_ENABLED
|
||||
if (portal_desktop) {
|
||||
portal_desktop->process_file_dialog_callbacks();
|
||||
portal_desktop->process_callbacks();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -6030,6 +6184,7 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
|
|||
drivers.push_back("opengl3");
|
||||
drivers.push_back("opengl3_es");
|
||||
#endif
|
||||
drivers.push_back("dummy");
|
||||
|
||||
return drivers;
|
||||
}
|
||||
|
|
@ -6178,6 +6333,15 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
|
|||
if (dead_tbl && xkb_loaded_v05p) {
|
||||
wd.xkb_state = xkb_compose_state_new(dead_tbl, XKB_COMPOSE_STATE_NO_FLAGS);
|
||||
}
|
||||
#endif
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver && !accessibility_driver->window_create(id, nullptr)) {
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
ERR_PRINT("Can't create an accessibility adapter for window, accessibility support disabled!");
|
||||
}
|
||||
memdelete(accessibility_driver);
|
||||
accessibility_driver = nullptr;
|
||||
}
|
||||
#endif
|
||||
// Enable receiving notification when the window is initialized (MapNotify)
|
||||
// so the focus can be set at the right time.
|
||||
|
|
@ -6466,8 +6630,12 @@ static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMSt
|
|||
DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
|
||||
KeyMappingX11::initialize();
|
||||
|
||||
String current_desk = OS::get_singleton()->get_environment("XDG_CURRENT_DESKTOP").to_lower();
|
||||
String session_desk = OS::get_singleton()->get_environment("XDG_SESSION_DESKTOP").to_lower();
|
||||
swap_cancel_ok = (current_desk.contains("kde") || session_desk.contains("kde") || current_desk.contains("lxqt") || session_desk.contains("lxqt"));
|
||||
|
||||
xwayland = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").to_lower() == "wayland";
|
||||
kde5_embed_workaround = OS::get_singleton()->get_environment("XDG_CURRENT_DESKTOP").to_lower() == "kde" && OS::get_singleton()->get_environment("KDE_SESSION_VERSION") == "5";
|
||||
kde5_embed_workaround = current_desk == "kde" && OS::get_singleton()->get_environment("KDE_SESSION_VERSION") == "5";
|
||||
|
||||
native_menu = memnew(NativeMenu);
|
||||
context = p_context;
|
||||
|
|
@ -6757,7 +6925,17 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
// Init TTS
|
||||
bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech");
|
||||
if (tts_enabled) {
|
||||
tts = memnew(TTS_Linux);
|
||||
initialize_tts();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_get_mode() != DisplayServer::AccessibilityMode::ACCESSIBILITY_DISABLED) {
|
||||
accessibility_driver = memnew(AccessibilityDriverAccessKit);
|
||||
if (accessibility_driver->init() != OK) {
|
||||
memdelete(accessibility_driver);
|
||||
accessibility_driver = nullptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -6770,6 +6948,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
|
||||
// Initialize context and rendering device.
|
||||
|
||||
if (rendering_driver == "dummy") {
|
||||
RasterizerDummy::make_current();
|
||||
driver_found = true;
|
||||
}
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
#if defined(VULKAN_ENABLED)
|
||||
if (rendering_driver == "vulkan") {
|
||||
|
|
@ -6844,7 +7027,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
|
||||
if (use_prime == -1) {
|
||||
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
|
||||
use_prime = detect_prime();
|
||||
use_prime = DetectPrimeX11::detect_prime();
|
||||
}
|
||||
|
||||
if (use_prime) {
|
||||
|
|
@ -6931,7 +7114,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
window_set_flag(WindowFlags(i), true, main_window);
|
||||
}
|
||||
}
|
||||
show_window(main_window);
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
|
|
@ -7101,8 +7283,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
|
||||
|
||||
portal_desktop = memnew(FreeDesktopPortalDesktop);
|
||||
atspi_monitor = memnew(FreeDesktopAtSPIMonitor);
|
||||
#endif // DBUS_ENABLED
|
||||
|
||||
XSetErrorHandler(&default_window_error_handler);
|
||||
|
||||
r_error = OK;
|
||||
|
|
@ -7142,6 +7324,12 @@ DisplayServerX11::~DisplayServerX11() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
accessibility_driver->window_destroy(E.key);
|
||||
}
|
||||
#endif
|
||||
|
||||
WindowData &wd = E.value;
|
||||
if (wd.xic) {
|
||||
XDestroyIC(wd.xic);
|
||||
|
|
@ -7216,7 +7404,11 @@ DisplayServerX11::~DisplayServerX11() {
|
|||
if (xmbstring) {
|
||||
memfree(xmbstring);
|
||||
}
|
||||
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
if (accessibility_driver) {
|
||||
memdelete(accessibility_driver);
|
||||
}
|
||||
#endif
|
||||
#ifdef SPEECHD_ENABLED
|
||||
if (tts) {
|
||||
memdelete(tts);
|
||||
|
|
@ -7226,6 +7418,7 @@ DisplayServerX11::~DisplayServerX11() {
|
|||
#ifdef DBUS_ENABLED
|
||||
memdelete(screensaver);
|
||||
memdelete(portal_desktop);
|
||||
memdelete(atspi_monitor);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DISPLAY_SERVER_X11_H
|
||||
#define DISPLAY_SERVER_X11_H
|
||||
#pragma once
|
||||
|
||||
#ifdef X11_ENABLED
|
||||
|
||||
|
|
@ -66,6 +65,7 @@
|
|||
#endif
|
||||
|
||||
#if defined(DBUS_ENABLED)
|
||||
#include "freedesktop_at_spi_monitor.h"
|
||||
#include "freedesktop_portal_desktop.h"
|
||||
#include "freedesktop_screensaver.h"
|
||||
#endif
|
||||
|
|
@ -123,7 +123,7 @@ typedef struct _xrr_monitor_info {
|
|||
#undef CursorShape
|
||||
|
||||
class DisplayServerX11 : public DisplayServer {
|
||||
// No need to register with GDCLASS, it's platform-specific and nothing is added.
|
||||
GDSOFTCLASS(DisplayServerX11, DisplayServer);
|
||||
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
|
|
@ -160,6 +160,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||
|
||||
#if defined(DBUS_ENABLED)
|
||||
FreeDesktopPortalDesktop *portal_desktop = nullptr;
|
||||
FreeDesktopAtSPIMonitor *atspi_monitor = nullptr;
|
||||
#endif
|
||||
|
||||
struct WindowData {
|
||||
|
|
@ -200,6 +201,8 @@ class DisplayServerX11 : public DisplayServer {
|
|||
bool on_top = false;
|
||||
bool borderless = false;
|
||||
bool resize_disabled = false;
|
||||
bool no_min_btn = false;
|
||||
bool no_max_btn = false;
|
||||
Vector2i last_position_before_fs;
|
||||
bool focused = true;
|
||||
bool minimized = false;
|
||||
|
|
@ -353,6 +356,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||
bool _window_minimize_check(WindowID p_window) const;
|
||||
void _validate_mode_on_map(WindowID p_window);
|
||||
void _update_size_hints(WindowID p_window);
|
||||
void _update_actions_hints(WindowID p_window);
|
||||
void _set_wm_fullscreen(WindowID p_window, bool p_enabled, bool p_exclusive);
|
||||
void _set_wm_maximized(WindowID p_window, bool p_enabled);
|
||||
void _set_wm_minimized(WindowID p_window, bool p_enabled);
|
||||
|
|
@ -360,6 +364,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||
void _update_context(WindowData &wd);
|
||||
|
||||
Context context = CONTEXT_ENGINE;
|
||||
bool swap_cancel_ok = false;
|
||||
|
||||
WindowID _get_focused_window_or_popup() const;
|
||||
bool _window_focus_check();
|
||||
|
|
@ -395,6 +400,8 @@ class DisplayServerX11 : public DisplayServer {
|
|||
void _set_window_taskbar_pager_enabled(Window p_window, bool p_enabled);
|
||||
Rect2i _screens_get_full_rect() const;
|
||||
|
||||
void initialize_tts() const;
|
||||
|
||||
protected:
|
||||
void _window_changed(XEvent *event);
|
||||
|
||||
|
|
@ -420,10 +427,11 @@ public:
|
|||
#if defined(DBUS_ENABLED)
|
||||
virtual bool is_dark_mode_supported() const override;
|
||||
virtual bool is_dark_mode() const override;
|
||||
virtual Color get_accent_color() const override;
|
||||
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
|
||||
|
||||
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback) override;
|
||||
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback) override;
|
||||
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) override;
|
||||
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, WindowID p_window_id) override;
|
||||
#endif
|
||||
|
||||
virtual void beep() const override;
|
||||
|
|
@ -530,6 +538,9 @@ public:
|
|||
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 int accessibility_should_increase_contrast() const override;
|
||||
virtual int accessibility_screen_reader_active() const override;
|
||||
|
||||
virtual Point2i ime_get_selection() const override;
|
||||
virtual String ime_get_text() const override;
|
||||
|
||||
|
|
@ -548,6 +559,8 @@ public:
|
|||
virtual CursorShape cursor_get_shape() const override;
|
||||
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) override;
|
||||
|
||||
virtual bool get_swap_cancel_ok() override;
|
||||
|
||||
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;
|
||||
|
|
@ -556,6 +569,8 @@ public:
|
|||
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
|
||||
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
|
||||
|
||||
virtual bool color_picker(const Callable &p_callback) override;
|
||||
|
||||
virtual void process_events() override;
|
||||
|
||||
virtual void release_rendering_thread() override;
|
||||
|
|
@ -578,5 +593,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // X11_ENABLED
|
||||
|
||||
#endif // DISPLAY_SERVER_X11_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GL_MANAGER_X11_H
|
||||
#define GL_MANAGER_X11_H
|
||||
#pragma once
|
||||
|
||||
#if defined(X11_ENABLED) && defined(GLES3_ENABLED)
|
||||
|
||||
|
|
@ -134,5 +133,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // X11_ENABLED && GLES3_ENABLED
|
||||
|
||||
#endif // GL_MANAGER_X11_H
|
||||
|
|
|
|||
|
|
@ -28,12 +28,10 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef GL_MANAGER_X11_EGL_H
|
||||
#define GL_MANAGER_X11_EGL_H
|
||||
#pragma once
|
||||
|
||||
#if defined(X11_ENABLED) && defined(GLES3_ENABLED)
|
||||
|
||||
#include "core/error/error_list.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/templates/local_vector.h"
|
||||
#include "drivers/egl/egl_manager.h"
|
||||
|
|
@ -57,5 +55,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // X11_ENABLED && GLES3_ENABLED
|
||||
|
||||
#endif // GL_MANAGER_X11_EGL_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef KEY_MAPPING_X11_H
|
||||
#define KEY_MAPPING_X11_H
|
||||
#pragma once
|
||||
|
||||
#include "core/os/keyboard.h"
|
||||
#include "core/templates/hash_map.h"
|
||||
|
|
@ -68,5 +67,3 @@ public:
|
|||
static char32_t get_unicode_from_keysym(KeySym p_keysym);
|
||||
static KeyLocation get_location(unsigned int p_code);
|
||||
};
|
||||
|
||||
#endif // KEY_MAPPING_X11_H
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef RENDERING_CONTEXT_DRIVER_VULKAN_X11_H
|
||||
#define RENDERING_CONTEXT_DRIVER_VULKAN_X11_H
|
||||
#pragma once
|
||||
|
||||
#ifdef VULKAN_ENABLED
|
||||
|
||||
|
|
@ -55,5 +54,3 @@ public:
|
|||
};
|
||||
|
||||
#endif // VULKAN_ENABLED
|
||||
|
||||
#endif // RENDERING_CONTEXT_DRIVER_VULKAN_X11_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue