diff options
Diffstat (limited to 'platform/x11')
-rw-r--r-- | platform/x11/context_gl_x11.cpp | 1 | ||||
-rw-r--r-- | platform/x11/crash_handler_x11.cpp | 17 | ||||
-rw-r--r-- | platform/x11/detect.py | 47 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 186 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 3 | ||||
-rw-r--r-- | platform/x11/power_x11.cpp | 2 |
6 files changed, 160 insertions, 96 deletions
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index aadf7ee36d..9718b03164 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -191,6 +191,7 @@ Error ContextGL_X11::initialize() { swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa); + XStoreName(x11_display, x11_window, "Godot Engine"); ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED); set_class_hint(x11_display, x11_window); diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp index 1e7f393bdd..ca7251078f 100644 --- a/platform/x11/crash_handler_x11.cpp +++ b/platform/x11/crash_handler_x11.cpp @@ -53,7 +53,12 @@ static void handle_crash(int sig) { void *bt_buffer[256]; size_t size = backtrace(bt_buffer, 256); String _execpath = OS::get_singleton()->get_executable_path(); - String msg = GLOBAL_GET("debug/settings/crash_handler/message"); + + String msg; + const ProjectSettings *proj_settings = ProjectSettings::get_singleton(); + if (proj_settings) { + msg = proj_settings->get("debug/settings/crash_handler/message"); + } // Dump the backtrace to stderr with a message to the user fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig); @@ -96,12 +101,10 @@ static void handle_crash(int sig) { String output = ""; // Try to get the file/line number using addr2line - if (OS::get_singleton()) { - int ret; - Error err = OS::get_singleton()->execute(String("addr2line"), args, true, NULL, &output, &ret); - if (err == OK) { - output.erase(output.length() - 1, 1); - } + int ret; + Error err = OS::get_singleton()->execute(String("addr2line"), args, true, NULL, &output, &ret); + if (err == OK) { + output.erase(output.length() - 1, 1); } fprintf(stderr, "[%ld] %s (%ls)\n", i, fname, output.c_str()); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 5f7b825f5e..933ee6b72e 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -1,7 +1,7 @@ import os import platform import sys -from methods import get_compiler_version, using_gcc +from methods import get_compiler_version, using_gcc, using_clang def is_active(): @@ -58,11 +58,13 @@ def get_opts(): return [ BoolVariable('use_llvm', 'Use the LLVM compiler', False), + BoolVariable('use_lld', 'Use the LLD linker', False), + BoolVariable('use_thinlto', 'Use ThinLTO', False), BoolVariable('use_static_cpp', 'Link libgcc and libstdc++ statically for better portability', False), BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False), BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False), BoolVariable('use_lsan', 'Use LLVM/GCC compiler leak sanitizer (LSAN))', False), - BoolVariable('pulseaudio', 'Detect & use pulseaudio', True), + BoolVariable('pulseaudio', 'Detect and use PulseAudio', True), BoolVariable('udev', 'Use udev for gamepad connection callbacks', False), EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')), BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False), @@ -97,9 +99,10 @@ def configure(env): elif (env["target"] == "release_debug"): if (env["optimize"] == "speed"): #optimize for speed (default) - env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) + env.Prepend(CCFLAGS=['-O2']) else: #optimize for size - env.Prepend(CCFLAGS=['-Os', '-DDEBUG_ENABLED']) + env.Prepend(CCFLAGS=['-Os']) + env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) @@ -107,7 +110,8 @@ def configure(env): env.Prepend(CCFLAGS=['-g2']) elif (env["target"] == "debug"): - env.Prepend(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CCFLAGS=['-g3']) + env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['-rdynamic']) ## Architecture @@ -130,6 +134,15 @@ def configure(env): env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix + if env['use_lld']: + if env['use_llvm']: + env.Append(LINKFLAGS=['-fuse-ld=lld']) + if env['use_thinlto']: + # A convenience so you don't need to write use_lto too when using SCons + env['use_lto'] = True + else: + print("Using LLD with GCC is not supported yet, try compiling with 'use_llvm=yes'.") + sys.exit(255) if env['use_ubsan'] or env['use_asan'] or env['use_lsan']: env.extra_suffix += "s" @@ -147,11 +160,17 @@ def configure(env): env.Append(LINKFLAGS=['-fsanitize=leak']) if env['use_lto']: - env.Append(CCFLAGS=['-flto']) if not env['use_llvm'] and env.GetOption("num_jobs") > 1: + env.Append(CCFLAGS=['-flto']) env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))]) else: - env.Append(LINKFLAGS=['-flto']) + if env['use_lld'] and env['use_thinlto']: + env.Append(CCFLAGS=['-flto=thin']) + env.Append(LINKFLAGS=['-flto=thin']) + else: + env.Append(CCFLAGS=['-flto']) + env.Append(LINKFLAGS=['-flto']) + if not env['use_llvm']: env['RANLIB'] = 'gcc-ranlib' env['AR'] = 'gcc-ar' @@ -165,6 +184,12 @@ def configure(env): if version != None and version[0] >= '6': env.Append(CCFLAGS=['-fpie']) env.Append(LINKFLAGS=['-no-pie']) + # Do the same for clang should be fine with Clang 4 and higher + if using_clang(env): + version = get_compiler_version(env) + if version != None and version[0] >= '4': + env.Append(CCFLAGS=['-fpie']) + env.Append(LINKFLAGS=['-no-pie']) ## Dependencies @@ -250,7 +275,7 @@ def configure(env): if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. - env.Append(CPPPATH=["/usr/include/miniupnpc"]) + env.Prepend(CPPPATH=["/usr/include/miniupnpc"]) env.Append(LIBS=["miniupnpc"]) # On Linux wchar_t should be 32-bits @@ -291,7 +316,7 @@ def configure(env): if not env['builtin_zlib']: env.ParseConfig('pkg-config zlib --cflags --libs') - env.Append(CPPPATH=['#platform/x11']) + env.Prepend(CPPPATH=['#platform/x11']) env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) env.Append(LIBS=['GL', 'pthread']) @@ -307,10 +332,10 @@ def configure(env): ## Cross-compilation if (is64 and env["bits"] == "32"): - env.Append(CPPFLAGS=['-m32']) + env.Append(CCFLAGS=['-m32']) env.Append(LINKFLAGS=['-m32', '-L/usr/lib/i386-linux-gnu']) elif (not is64 and env["bits"] == "64"): - env.Append(CPPFLAGS=['-m64']) + env.Append(CCFLAGS=['-m64']) env.Append(LINKFLAGS=['-m64', '-L/usr/lib/i686-linux-gnu']) # Link those statically for portability diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index ba74ba2437..f034b2389b 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -503,55 +503,57 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a current_cursor = CURSOR_ARROW; - if (cursor_theme) { - for (int i = 0; i < CURSOR_MAX; i++) { - - static const char *cursor_file[] = { - "left_ptr", - "xterm", - "hand2", - "cross", - "watch", - "left_ptr_watch", - "fleur", - "hand1", - "X_cursor", - "sb_v_double_arrow", - "sb_h_double_arrow", - "size_bdiag", - "size_fdiag", - "hand1", - "sb_v_double_arrow", - "sb_h_double_arrow", - "question_arrow" - }; + for (int i = 0; i < CURSOR_MAX; i++) { - img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size); - if (img[i]) { - cursors[i] = XcursorImageLoadCursor(x11_display, img[i]); - } else { - print_verbose("Failed loading custom cursor: " + String(cursor_file[i])); - } + static const char *cursor_file[] = { + "left_ptr", + "xterm", + "hand2", + "cross", + "watch", + "left_ptr_watch", + "fleur", + "hand1", + "X_cursor", + "sb_v_double_arrow", + "sb_h_double_arrow", + "size_bdiag", + "size_fdiag", + "hand1", + "sb_v_double_arrow", + "sb_h_double_arrow", + "question_arrow" + }; + + img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size); + if (img[i]) { + cursors[i] = XcursorImageLoadCursor(x11_display, img[i]); + } else { + print_verbose("Failed loading custom cursor: " + String(cursor_file[i])); } } { - Pixmap cursormask; - XGCValues xgc; - GC gc; - XColor col; - Cursor cursor; + // Creating an empty/transparent cursor - cursormask = XCreatePixmap(x11_display, RootWindow(x11_display, DefaultScreen(x11_display)), 1, 1, 1); + // Create 1x1 bitmap + Pixmap cursormask = XCreatePixmap(x11_display, + RootWindow(x11_display, DefaultScreen(x11_display)), 1, 1, 1); + + // Fill with zero + XGCValues xgc; xgc.function = GXclear; - gc = XCreateGC(x11_display, cursormask, GCFunction, &xgc); + GC gc = XCreateGC(x11_display, cursormask, GCFunction, &xgc); XFillRectangle(x11_display, cursormask, gc, 0, 0, 1, 1); - col.pixel = 0; - col.red = 0; - col.flags = 4; - cursor = XCreatePixmapCursor(x11_display, - cursormask, cursormask, + + // Color value doesn't matter. Mask zero means no foreground or background will be drawn + XColor col = {}; + + Cursor cursor = XCreatePixmapCursor(x11_display, + cursormask, // source (using cursor mask as placeholder, since it'll all be ignored) + cursormask, // mask &col, &col, 0, 0); + XFreePixmap(x11_display, cursormask); XFreeGC(x11_display, gc); @@ -1165,7 +1167,7 @@ int OS_X11::get_screen_dpi(int p_screen) const { int height_mm = DisplayHeightMM(x11_display, p_screen); double xdpi = (width_mm ? sc.width / (double)width_mm * 25.4 : 0); double ydpi = (height_mm ? sc.height / (double)height_mm * 25.4 : 0); - if (xdpi || xdpi) + if (xdpi || ydpi) return (xdpi + ydpi) / (xdpi && ydpi ? 2 : 1); //could not get dpi @@ -1176,15 +1178,33 @@ Point2 OS_X11::get_window_position() const { int x, y; Window child; XTranslateCoordinates(x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child); - - int screen = get_current_screen(); - Point2i screen_position = get_screen_position(screen); - - return Point2i(x - screen_position.x, y - screen_position.y); + return Point2i(x, y); } void OS_X11::set_window_position(const Point2 &p_position) { - XMoveWindow(x11_display, x11_window, p_position.x, p_position.y); + int x = 0; + int y = 0; + if (get_borderless_window() == false) { + //exclude window decorations + XSync(x11_display, False); + Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", 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, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + if (format == 32 && len == 4) { + long *extents = (long *)data; + x = extents[0]; + y = extents[2]; + } + XFree(data); + } + } + } + XMoveWindow(x11_display, x11_window, p_position.x - x, p_position.y - y); update_real_mouse_position(); } @@ -1201,15 +1221,20 @@ Size2 OS_X11::get_real_window_size() const { int w = xwa.width; int h = xwa.height; Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True); - Atom type; - int format; - unsigned long len; - unsigned long remaining; - unsigned char *data = NULL; - if (XGetWindowProperty(x11_display, x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { - long *extents = (long *)data; - w += extents[0] + extents[1]; // left, right - h += extents[2] + extents[3]; // top, bottom + 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, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + if (format == 32 && len == 4) { + long *extents = (long *)data; + w += extents[0] + extents[1]; // left, right + h += extents[2] + extents[3]; // top, bottom + } + XFree(data); + } } return Size2(w, h); } @@ -2041,15 +2066,11 @@ void OS_X11::process_xevents() { case LeaveNotify: { if (main_loop && !mouse_mode_grab) main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT); - if (input) - input->set_mouse_in_window(false); } break; case EnterNotify: { if (main_loop && !mouse_mode_grab) main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER); - if (input) - input->set_mouse_in_window(true); } break; case FocusIn: minimized = false; @@ -2080,7 +2101,9 @@ void OS_X11::process_xevents() { case FocusOut: window_has_focus = false; + input->release_pressed_events(); main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); + if (mouse_mode_grab) { //dear X11, I try, I really try, but you never work, you do whathever you want. if (mouse_mode == MOUSE_MODE_CAPTURED) { @@ -2573,7 +2596,7 @@ String OS_X11::get_clipboard() const { return ret; } -String OS_X11::get_name() { +String OS_X11::get_name() const { return "X11"; } @@ -2722,6 +2745,11 @@ void OS_X11::set_cursor_shape(CursorShape p_shape) { current_cursor = p_shape; } +OS::CursorShape OS_X11::get_cursor_shape() const { + + return current_cursor; +} + void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (p_cursor.is_valid()) { Ref<Texture> texture = p_cursor; @@ -3035,34 +3063,40 @@ bool OS_X11::is_vsync_enabled() const { */ void OS_X11::set_context(int p_context) { - char *config_name = NULL; XClassHint *classHint = XAllocClassHint(); if (classHint) { - char *wm_class = (char *)"Godot"; - if (p_context == CONTEXT_EDITOR) - classHint->res_name = (char *)"Godot_Editor"; - if (p_context == CONTEXT_PROJECTMAN) - classHint->res_name = (char *)"Godot_ProjectList"; + CharString name_str; + switch (p_context) { + case CONTEXT_EDITOR: + name_str = "Godot_Editor"; + break; + case CONTEXT_PROJECTMAN: + name_str = "Godot_ProjectList"; + break; + case CONTEXT_ENGINE: + name_str = "Godot_Engine"; + break; + } + CharString class_str; if (p_context == CONTEXT_ENGINE) { - classHint->res_name = (char *)"Godot_Engine"; - String config_name_tmp = GLOBAL_GET("application/config/name"); - if (config_name_tmp.length() > 0) { - config_name = strdup(config_name_tmp.utf8().get_data()); + String config_name = GLOBAL_GET("application/config/name"); + if (config_name.length() == 0) { + class_str = "Godot_Engine"; } else { - config_name = strdup("Godot Engine"); + class_str = config_name.utf8(); } - - wm_class = config_name; + } else { + class_str = "Godot"; } - classHint->res_class = wm_class; + classHint->res_class = class_str.ptrw(); + classHint->res_name = name_str.ptrw(); XSetClassHint(x11_display, x11_window, classHint); XFree(classHint); - free(config_name); } } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 6d1a66af84..ad35cdb4f9 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -216,9 +216,10 @@ protected: bool is_window_maximize_allowed(); public: - virtual String get_name(); + virtual String get_name() const; virtual void set_cursor_shape(CursorShape p_shape); + virtual CursorShape get_cursor_shape() const; virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); void set_mouse_mode(MouseMode p_mode); diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp index 943c2b1383..50da6a4967 100644 --- a/platform/x11/power_x11.cpp +++ b/platform/x11/power_x11.cpp @@ -115,7 +115,7 @@ bool PowerX11::make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) { *(ptr++) = '\0'; /* terminate the key. */ - while ((*ptr == ' ') && (*ptr != '\0')) { + while (*ptr == ' ') { ptr++; /* skip whitespace. */ } |