diff options
Diffstat (limited to 'platform/x11')
-rw-r--r-- | platform/x11/context_gl_x11.cpp | 2 | ||||
-rw-r--r-- | platform/x11/detect.py | 39 | ||||
-rw-r--r-- | platform/x11/detect_prime.cpp | 14 | ||||
-rw-r--r-- | platform/x11/export/export.cpp | 112 | ||||
-rw-r--r-- | platform/x11/godot_x11.cpp | 8 | ||||
-rw-r--r-- | platform/x11/joypad_linux.cpp | 11 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 197 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 11 | ||||
-rw-r--r-- | platform/x11/pck_embed.ld | 10 | ||||
-rw-r--r-- | platform/x11/power_x11.cpp | 5 |
10 files changed, 348 insertions, 61 deletions
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 9718b03164..d70b947fcc 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -145,6 +145,7 @@ Error ContextGL_X11::initialize() { break; } } + XFree(fbc); ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED); swa.background_pixmap = None; @@ -159,6 +160,7 @@ Error ContextGL_X11::initialize() { vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); fbconfig = fbc[0]; + XFree(fbc); } int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 933ee6b72e..f3a486df02 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -75,11 +75,7 @@ def get_opts(): def get_flags(): - return [ - ('builtin_freetype', False), - ('builtin_libpng', False), - ('builtin_zlib', False), - ] + return [] def configure(env): @@ -102,7 +98,7 @@ def configure(env): env.Prepend(CCFLAGS=['-O2']) else: #optimize for size env.Prepend(CCFLAGS=['-Os']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) @@ -111,7 +107,7 @@ def configure(env): elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['-rdynamic']) ## Architecture @@ -131,7 +127,7 @@ def configure(env): env["CC"] = "clang" env["CXX"] = "clang++" env["LINK"] = "clang++" - env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix if env['use_lld']: @@ -201,7 +197,7 @@ def configure(env): env.ParseConfig('pkg-config xi --cflags --libs') if (env['touch']): - env.Append(CPPFLAGS=['-DTOUCH_ENABLED']) + env.Append(CPPDEFINES=['TOUCH_ENABLED']) # FIXME: Check for existence of the libs before parsing their flags with pkg-config @@ -216,15 +212,15 @@ def configure(env): env.ParseConfig('pkg-config freetype2 --cflags --libs') if not env['builtin_libpng']: - env.ParseConfig('pkg-config libpng --cflags --libs') + env.ParseConfig('pkg-config libpng16 --cflags --libs') if not env['builtin_bullet']: - # We need at least version 2.88 + # We need at least version 2.89 import subprocess bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip() - if str(bullet_version) < "2.88": + if str(bullet_version) < "2.89": # Abort as system bullet was requested but too old - print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88")) + print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.89")) sys.exit(255) env.ParseConfig('pkg-config bullet --cflags --libs') @@ -270,8 +266,8 @@ def configure(env): # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509']) - if not env['builtin_libwebsockets']: - env.ParseConfig('pkg-config libwebsockets --cflags --libs') + if not env['builtin_wslay']: + env.ParseConfig('pkg-config libwslay --cflags --libs') if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. @@ -287,7 +283,7 @@ def configure(env): if (os.system("pkg-config --exists alsa") == 0): # 0 means found print("Enabling ALSA") - env.Append(CPPFLAGS=["-DALSA_ENABLED", "-DALSAMIDI_ENABLED"]) + env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) # Don't parse --cflags, we don't need to add /usr/include/alsa to include path env.ParseConfig('pkg-config alsa --libs') else: @@ -296,18 +292,18 @@ def configure(env): if env['pulseaudio']: if (os.system("pkg-config --exists libpulse") == 0): # 0 means found print("Enabling PulseAudio") - env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"]) + env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"]) env.ParseConfig('pkg-config --cflags --libs libpulse') else: print("PulseAudio development libraries not found, disabling driver") if (platform.system() == "Linux"): - env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + env.Append(CPPDEFINES=["JOYDEV_ENABLED"]) if env['udev']: if (os.system("pkg-config --exists libudev") == 0): # 0 means found print("Enabling udev support") - env.Append(CPPFLAGS=["-DUDEV_ENABLED"]) + env.Append(CPPDEFINES=["UDEV_ENABLED"]) env.ParseConfig('pkg-config libudev --cflags --libs') else: print("libudev development libraries not found, disabling udev support") @@ -317,7 +313,7 @@ def configure(env): env.ParseConfig('pkg-config zlib --cflags --libs') env.Prepend(CPPPATH=['#platform/x11']) - env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) + env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED', 'OPENGL_ENABLED', 'GLES_ENABLED']) env.Append(LIBS=['GL', 'pthread']) if (platform.system() == "Linux"): @@ -328,6 +324,9 @@ def configure(env): if env["execinfo"]: env.Append(LIBS=['execinfo']) + + if not env['tools']: + env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.ld']) ## Cross-compilation diff --git a/platform/x11/detect_prime.cpp b/platform/x11/detect_prime.cpp index 0fde2a0c04..26008feade 100644 --- a/platform/x11/detect_prime.cpp +++ b/platform/x11/detect_prime.cpp @@ -159,10 +159,11 @@ int detect_prime() { if (!stat_loc) { // No need to do anything complicated here. Anything less than // PIPE_BUF will be delivered in one read() call. - read(fdset[0], string, sizeof(string) - 1); - - vendors[i] = string; - renderers[i] = string + strlen(string) + 1; + // Leave it 'Unknown' otherwise. + if (read(fdset[0], string, sizeof(string) - 1) > 0) { + vendors[i] = string; + renderers[i] = string + strlen(string) + 1; + } } close(fdset[0]); @@ -190,8 +191,9 @@ int detect_prime() { memcpy(&string, vendor, vendor_len); memcpy(&string[vendor_len], renderer, renderer_len); - write(fdset[1], string, vendor_len + renderer_len); - + if (write(fdset[1], string, vendor_len + renderer_len) == -1) { + print_verbose("Couldn't write vendor/renderer string."); + } close(fdset[1]); exit(0); } diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp index f7d98c1d68..8767aac517 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -30,10 +30,13 @@ #include "export.h" +#include "core/os/file_access.h" #include "editor/editor_export.h" #include "platform/x11/logo.gen.h" #include "scene/resources/texture.h" +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); + void register_x11_exporter() { Ref<EditorExportPlatformPC> platform; @@ -53,6 +56,115 @@ void register_x11_exporter() { platform->set_debug_64("linux_x11_64_debug"); platform->set_os_name("X11"); platform->set_chmod_flags(0755); + platform->set_fixup_embedded_pck_func(&fixup_embedded_pck); EditorExport::get_singleton()->add_export_platform(platform); } + +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { + + // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + // Read and check ELF magic number + { + uint32_t magic = f->get_32(); + if (magic != 0x464c457f) { // 0x7F + "ELF" + f->close(); + return ERR_FILE_CORRUPT; + } + } + + // Read program architecture bits from class field + + int bits = f->get_8() * 32; + + if (bits == 32 && p_embedded_size >= 0x100000000) { + f->close(); + ERR_EXPLAIN("32-bit executables cannot have embedded data >= 4 GiB"); + ERR_FAIL_V(ERR_INVALID_DATA); + } + + // Get info about the section header table + + int64_t section_table_pos; + int64_t section_header_size; + if (bits == 32) { + section_header_size = 40; + f->seek(0x20); + section_table_pos = f->get_32(); + f->seek(0x30); + } else { // 64 + section_header_size = 64; + f->seek(0x28); + section_table_pos = f->get_64(); + f->seek(0x3c); + } + int num_sections = f->get_16(); + int string_section_idx = f->get_16(); + + // Load the strings table + uint8_t *strings; + { + // Jump to the strings section header + f->seek(section_table_pos + string_section_idx * section_header_size); + + // Read strings data size and offset + int64_t string_data_pos; + int64_t string_data_size; + if (bits == 32) { + f->seek(f->get_position() + 0x10); + string_data_pos = f->get_32(); + string_data_size = f->get_32(); + } else { // 64 + f->seek(f->get_position() + 0x18); + string_data_pos = f->get_64(); + string_data_size = f->get_64(); + } + + // Read strings data + f->seek(string_data_pos); + strings = (uint8_t *)memalloc(string_data_size); + if (!strings) { + f->close(); + return ERR_OUT_OF_MEMORY; + } + f->get_buffer(strings, string_data_size); + } + + // Search for the "pck" section + + bool found = false; + for (int i = 0; i < num_sections; ++i) { + + int64_t section_header_pos = section_table_pos + i * section_header_size; + f->seek(section_header_pos); + + uint32_t name_offset = f->get_32(); + if (strcmp((char *)strings + name_offset, "pck") == 0) { + // "pck" section found, let's patch! + + if (bits == 32) { + f->seek(section_header_pos + 0x10); + f->store_32(p_embedded_start); + f->store_32(p_embedded_size); + } else { // 64 + f->seek(section_header_pos + 0x18); + f->store_64(p_embedded_start); + f->store_64(p_embedded_size); + } + + found = true; + break; + } + } + + memfree(strings); + f->close(); + + return found ? OK : ERR_FILE_CORRUPT; +} diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp index 79407cd9dc..755ef7a84f 100644 --- a/platform/x11/godot_x11.cpp +++ b/platform/x11/godot_x11.cpp @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) { setlocale(LC_CTYPE, ""); char *cwd = (char *)malloc(PATH_MAX); + ERR_FAIL_COND_V(!cwd, ERR_OUT_OF_MEMORY); char *ret = getcwd(cwd, PATH_MAX); Error err = Main::setup(argv[0], argc - 1, &argv[1]); @@ -55,8 +56,11 @@ int main(int argc, char *argv[]) { os.run(); // it is actually the OS that decides how to run Main::cleanup(); - if (ret) - chdir(cwd); + if (ret) { // Previous getcwd was successful + if (chdir(cwd) != 0) { + ERR_PRINT("Couldn't return to previous working directory."); + } + } free(cwd); return os.get_exit_code(); diff --git a/platform/x11/joypad_linux.cpp b/platform/x11/joypad_linux.cpp index c4dd8fe0e0..e6328ee14d 100644 --- a/platform/x11/joypad_linux.cpp +++ b/platform/x11/joypad_linux.cpp @@ -101,7 +101,6 @@ void JoypadLinux::joy_thread_func(void *p_user) { JoypadLinux *joy = (JoypadLinux *)p_user; joy->run_joypad_thread(); } - return; } void JoypadLinux::run_joypad_thread() { @@ -414,7 +413,9 @@ void JoypadLinux::joypad_vibration_start(int p_id, float p_weak_magnitude, float play.type = EV_FF; play.code = effect.id; play.value = 1; - write(joy.fd, (const void *)&play, sizeof(play)); + if (write(joy.fd, (const void *)&play, sizeof(play)) == -1) { + print_verbose("Couldn't write to Joypad device."); + } joy.ff_effect_id = effect.id; joy.ff_effect_timestamp = p_timestamp; @@ -444,10 +445,10 @@ InputDefault::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int jx.min = -1; if (p_value < 0) { jx.value = (float)-p_value / min; + } else { + jx.value = (float)p_value / max; } - jx.value = (float)p_value / max; - } - if (min == 0) { + } else if (min == 0) { jx.min = 0; jx.value = 0.0f + (float)p_value / max; } diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 311b42be22..9b35648046 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -146,7 +146,7 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a if (is_stdout_verbose()) { WARN_PRINT("IME is disabled"); } - modifiers = XSetLocaleModifiers("@im=none"); + XSetLocaleModifiers("@im=none"); WARN_PRINT("Error setting locale modifiers"); } @@ -583,6 +583,9 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a AudioDriverManager::initialize(p_audio_driver); + ///@TODO implement a subclass for Linux and instantiate that instead + camera_server = memnew(CameraServer); + input = memnew(InputDefault); window_has_focus = true; // Set focus to true at init @@ -593,7 +596,7 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a power_manager = memnew(PowerX11); - if (p_desired.layered_splash) { + if (p_desired.layered) { set_window_per_pixel_transparency_enabled(true); } @@ -783,6 +786,8 @@ void OS_X11::finalize() { memdelete(input); + memdelete(camera_server); + visual_server->finish(); memdelete(visual_server); //memdelete(rasterizer); @@ -1001,28 +1006,38 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { XFlush(x11_display); - if (!p_enabled && !is_window_resizable()) { + if (!p_enabled) { // Reset the non-resizable flags if we un-set these before. Size2 size = get_window_size(); XSizeHints *xsh; - xsh = XAllocSizeHints(); - xsh->flags = PMinSize | PMaxSize; - xsh->min_width = size.x; - xsh->max_width = size.x; - xsh->min_height = size.y; - xsh->max_height = size.y; - + if (!is_window_resizable()) { + xsh->flags = PMinSize | PMaxSize; + xsh->min_width = size.x; + xsh->max_width = size.x; + xsh->min_height = size.y; + xsh->max_height = size.y; + } else { + xsh->flags = 0L; + if (min_size != Size2()) { + xsh->flags |= PMinSize; + xsh->min_width = min_size.x; + xsh->min_height = min_size.y; + } + if (max_size != Size2()) { + xsh->flags |= PMaxSize; + xsh->max_width = max_size.x; + xsh->max_height = max_size.y; + } + } XSetWMNormalHints(x11_display, x11_window, xsh); XFree(xsh); - } - if (!p_enabled && !get_borderless_window()) { - // put decorations back if the window wasn't suppoesed to be borderless + // put back or remove decorations according to the last set borderless state Hints hints; Atom property; hints.flags = 2; - hints.decorations = 1; + hints.decorations = current_videomode.borderless_window ? 0 : 1; property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); } @@ -1184,7 +1199,7 @@ Point2 OS_X11::get_window_position() const { void OS_X11::set_window_position(const Point2 &p_position) { int x = 0; int y = 0; - if (get_borderless_window() == false) { + if (!get_borderless_window()) { //exclude window decorations XSync(x11_display, False); Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True); @@ -1239,6 +1254,72 @@ Size2 OS_X11::get_real_window_size() const { return Size2(w, h); } +Size2 OS_X11::get_max_window_size() const { + return max_size; +} + +Size2 OS_X11::get_min_window_size() const { + return min_size; +} + +void OS_X11::set_min_window_size(const Size2 p_size) { + + if ((p_size != Size2()) && (max_size != Size2()) && ((p_size.x > max_size.x) || (p_size.y > max_size.y))) { + WARN_PRINT("Minimum window size can't be larger than maximum window size!"); + return; + } + min_size = p_size; + + if (is_window_resizable()) { + XSizeHints *xsh; + xsh = XAllocSizeHints(); + xsh->flags = 0L; + if (min_size != Size2()) { + xsh->flags |= PMinSize; + xsh->min_width = min_size.x; + xsh->min_height = min_size.y; + } + if (max_size != Size2()) { + xsh->flags |= PMaxSize; + xsh->max_width = max_size.x; + xsh->max_height = max_size.y; + } + XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); + + XFlush(x11_display); + } +} + +void OS_X11::set_max_window_size(const Size2 p_size) { + + if ((p_size != Size2()) && ((p_size.x < min_size.x) || (p_size.y < min_size.y))) { + WARN_PRINT("Maximum window size can't be smaller than minimum window size!"); + return; + } + max_size = p_size; + + if (is_window_resizable()) { + XSizeHints *xsh; + xsh = XAllocSizeHints(); + xsh->flags = 0L; + if (min_size != Size2()) { + xsh->flags |= PMinSize; + xsh->min_width = min_size.x; + xsh->min_height = min_size.y; + } + if (max_size != Size2()) { + xsh->flags |= PMaxSize; + xsh->max_width = max_size.x; + xsh->max_height = max_size.y; + } + XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); + + XFlush(x11_display); + } +} + void OS_X11::set_window_size(const Size2 p_size) { if (current_videomode.width == p_size.width && current_videomode.height == p_size.height) @@ -1251,17 +1332,29 @@ void OS_X11::set_window_size(const Size2 p_size) { int old_h = xwa.height; // If window resizable is disabled we need to update the attributes first + XSizeHints *xsh; + xsh = XAllocSizeHints(); if (!is_window_resizable()) { - XSizeHints *xsh; - xsh = XAllocSizeHints(); xsh->flags = PMinSize | PMaxSize; xsh->min_width = p_size.x; xsh->max_width = p_size.x; xsh->min_height = p_size.y; xsh->max_height = p_size.y; - XSetWMNormalHints(x11_display, x11_window, xsh); - XFree(xsh); + } else { + xsh->flags = 0L; + if (min_size != Size2()) { + xsh->flags |= PMinSize; + xsh->min_width = min_size.x; + xsh->min_height = min_size.y; + } + if (max_size != Size2()) { + xsh->flags |= PMaxSize; + xsh->max_width = max_size.x; + xsh->max_height = max_size.y; + } } + XSetWMNormalHints(x11_display, x11_window, xsh); + XFree(xsh); // Resize the window XResizeWindow(x11_display, x11_window, p_size.x, p_size.y); @@ -1307,20 +1400,37 @@ bool OS_X11::is_window_fullscreen() const { } void OS_X11::set_window_resizable(bool p_enabled) { - XSizeHints *xsh; - Size2 size = get_window_size(); + XSizeHints *xsh; xsh = XAllocSizeHints(); - xsh->flags = p_enabled ? 0L : PMinSize | PMaxSize; if (!p_enabled) { + Size2 size = get_window_size(); + + xsh->flags = PMinSize | PMaxSize; xsh->min_width = size.x; xsh->max_width = size.x; xsh->min_height = size.y; xsh->max_height = size.y; + } else { + xsh->flags = 0L; + if (min_size != Size2()) { + xsh->flags |= PMinSize; + xsh->min_width = min_size.x; + xsh->min_height = min_size.y; + } + if (max_size != Size2()) { + xsh->flags |= PMaxSize; + xsh->max_width = max_size.x; + xsh->max_height = max_size.y; + } } + XSetWMNormalHints(x11_display, x11_window, xsh); XFree(xsh); + current_videomode.resizable = p_enabled; + + XFlush(x11_display); } bool OS_X11::is_window_resizable() const { @@ -1531,7 +1641,7 @@ bool OS_X11::is_window_always_on_top() const { void OS_X11::set_borderless_window(bool p_borderless) { - if (current_videomode.borderless_window == p_borderless) + if (get_borderless_window() == p_borderless) return; if (!p_borderless && layered_window) @@ -1551,7 +1661,24 @@ void OS_X11::set_borderless_window(bool p_borderless) { } bool OS_X11::get_borderless_window() { - return current_videomode.borderless_window; + + bool borderless = current_videomode.borderless_window; + Atom prop = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); + if (prop != None) { + + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + if (XGetWindowProperty(x11_display, x11_window, prop, 0, sizeof(Hints), False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + if (data && (format == 32) && (len >= 5)) { + borderless = !((Hints *)data)->decorations; + } + XFree(data); + } + } + return borderless; } void OS_X11::request_attention() { @@ -2751,7 +2878,20 @@ OS::CursorShape OS_X11::get_cursor_shape() const { } void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + + Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + + if (cursor_c) { + if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { + set_cursor_shape(p_shape); + return; + } + + cursors_cache.erase(p_shape); + } + Ref<Texture> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; @@ -2820,6 +2960,11 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c // Save it for a further usage cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_image); + Vector<Variant> params; + params.push_back(p_cursor); + params.push_back(p_hotspot); + cursors_cache.insert(p_shape, params); + if (p_shape == current_cursor) { if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { XDefineCursor(x11_display, x11_window, cursors[p_shape]); @@ -2870,7 +3015,7 @@ void OS_X11::alert(const String &p_alert, const String &p_title) { for (int i = 0; i < path_elems.size(); i++) { for (unsigned int k = 0; k < sizeof(message_programs) / sizeof(char *); k++) { - String tested_path = path_elems[i] + "/" + message_programs[k]; + String tested_path = path_elems[i].plus_file(message_programs[k]); if (FileAccess::exists(tested_path)) { program = tested_path; @@ -2922,8 +3067,6 @@ void OS_X11::alert(const String &p_alert, const String &p_title) { } else { print_line(p_alert); } - - return; } bool g_set_icon_error = false; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index ad35cdb4f9..a4c22cf08a 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -42,6 +42,7 @@ #include "main/input_default.h" #include "power_x11.h" #include "servers/audio_server.h" +#include "servers/camera_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" //#include "servers/visual/visual_server_wrap_mt.h" @@ -119,6 +120,9 @@ class OS_X11 : public OS_Unix { bool im_active; Vector2 im_position; + Size2 min_size; + Size2 max_size; + Point2 last_mouse_pos; bool last_mouse_pos_valid; Point2i last_click_pos; @@ -146,6 +150,8 @@ class OS_X11 : public OS_Unix { void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state); void flush_mouse_motion(); + CameraServer *camera_server; + MouseMode mouse_mode; Point2i center; @@ -164,6 +170,7 @@ class OS_X11 : public OS_Unix { Cursor cursors[CURSOR_MAX]; Cursor null_cursor; CursorShape current_cursor; + Map<CursorShape, Vector<Variant> > cursors_cache; InputDefault *input; @@ -265,6 +272,10 @@ public: virtual void set_window_position(const Point2 &p_position); virtual Size2 get_window_size() const; virtual Size2 get_real_window_size() const; + virtual Size2 get_max_window_size() const; + virtual Size2 get_min_window_size() const; + virtual void set_min_window_size(const Size2 p_size); + virtual void set_max_window_size(const Size2 p_size); virtual void set_window_size(const Size2 p_size); virtual void set_window_fullscreen(bool p_enabled); virtual bool is_window_fullscreen() const; diff --git a/platform/x11/pck_embed.ld b/platform/x11/pck_embed.ld new file mode 100644 index 0000000000..fe09144d88 --- /dev/null +++ b/platform/x11/pck_embed.ld @@ -0,0 +1,10 @@ +SECTIONS +{ + /* Add a zero-sized section; the exporter will patch it to enclose the data appended to the executable (embedded PCK) */ + pck 0 (NOLOAD) : + { + /* Just some content to avoid the linker discarding the section */ + . = ALIGN(8); + } +} +INSERT AFTER .rodata; diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp index 50da6a4967..758bd84114 100644 --- a/platform/x11/power_x11.cpp +++ b/platform/x11/power_x11.cpp @@ -202,7 +202,10 @@ void PowerX11::check_proc_acpi_battery(const char *node, bool *have_battery, boo * We pick the battery that claims to have the most minutes left. * (failing a report of minutes, we'll take the highest percent.) */ - if ((secs < 0) && (this->nsecs_left < 0)) { + // -- GODOT start -- + //if ((secs < 0) && (this->nsecs_left < 0)) { + if (this->nsecs_left < 0) { + // -- GODOT end -- if ((pct < 0) && (this->percent_left < 0)) { choose = true; /* at least we know there's a battery. */ } |