summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/osx/SCsub7
-rw-r--r--platform/osx/audio_driver_osx.cpp11
-rw-r--r--platform/osx/crash_handler_osx.h47
-rw-r--r--platform/osx/crash_handler_osx.mm178
-rw-r--r--platform/osx/dir_access_osx.h3
-rw-r--r--platform/osx/dir_access_osx.mm18
-rw-r--r--platform/osx/export/export.cpp15
-rw-r--r--platform/osx/godot_main_osx.mm8
-rw-r--r--platform/osx/os_osx.h7
-rw-r--r--platform/osx/os_osx.mm21
-rw-r--r--platform/windows/SCsub3
-rw-r--r--platform/windows/crash_handler_win.cpp211
-rw-r--r--platform/windows/crash_handler_win.h56
-rw-r--r--platform/windows/detect.py11
-rw-r--r--platform/windows/godot_win.cpp34
-rw-r--r--platform/windows/os_windows.cpp30
-rw-r--r--platform/windows/os_windows.h6
-rw-r--r--platform/x11/SCsub13
-rw-r--r--platform/x11/crash_handler_x11.cpp135
-rw-r--r--platform/x11/crash_handler_x11.h47
-rw-r--r--platform/x11/detect.py1
-rw-r--r--platform/x11/joypad_linux.cpp1
-rw-r--r--platform/x11/os_x11.cpp26
-rw-r--r--platform/x11/os_x11.h7
24 files changed, 861 insertions, 35 deletions
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 27117c2e8d..5b2de54535 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -3,6 +3,7 @@
Import('env')
files = [
+ 'crash_handler_osx.mm',
'os_osx.mm',
'godot_main_osx.mm',
'audio_driver_osx.cpp',
@@ -12,4 +13,8 @@ files = [
'power_osx.cpp',
]
-env.Program('#bin/godot', files)
+prog = env.Program('#bin/godot', files)
+if (env['target'] == "debug" or env['target'] == "release_debug"):
+ # Build the .dSYM file for atos
+ action = "dsymutil " + File(prog)[0].path + " -o " + File(prog)[0].path + ".dSYM"
+ env.AddPostAction(prog, action)
diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp
index 78c52af201..3b3ba60507 100644
--- a/platform/osx/audio_driver_osx.cpp
+++ b/platform/osx/audio_driver_osx.cpp
@@ -58,14 +58,14 @@ Error AudioDriverOSX::initDevice() {
AudioStreamBasicDescription strdesc;
- // TODO: Implement this
- /*zeromem(&strdesc, sizeof(strdesc));
+ zeromem(&strdesc, sizeof(strdesc));
UInt32 size = sizeof(strdesc);
result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &strdesc, &size);
ERR_FAIL_COND_V(result != noErr, FAILED);
switch (strdesc.mChannelsPerFrame) {
case 2: // Stereo
+ case 4: // Surround 3.1
case 6: // Surround 5.1
case 8: // Surround 7.1
channels = strdesc.mChannelsPerFrame;
@@ -75,7 +75,7 @@ Error AudioDriverOSX::initDevice() {
// Unknown number of channels, default to stereo
channels = 2;
break;
- }*/
+ }
mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
@@ -103,7 +103,8 @@ Error AudioDriverOSX::initDevice() {
samples_in.resize(buffer_size);
if (OS::get_singleton()->is_stdout_verbose()) {
- print_line("audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ print_line("CoreAudio: detected " + itos(channels) + " channels");
+ print_line("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
}
AURenderCallbackStruct callback;
@@ -242,7 +243,7 @@ int AudioDriverOSX::get_mix_rate() const {
};
AudioDriver::SpeakerMode AudioDriverOSX::get_speaker_mode() const {
- return SPEAKER_MODE_STEREO;
+ return get_speaker_mode_by_total_channels(channels);
};
void AudioDriverOSX::lock() {
diff --git a/platform/osx/crash_handler_osx.h b/platform/osx/crash_handler_osx.h
new file mode 100644
index 0000000000..ff037e6b7a
--- /dev/null
+++ b/platform/osx/crash_handler_osx.h
@@ -0,0 +1,47 @@
+/*************************************************************************/
+/* crash_handler_osx.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef CRASH_HANDLER_OSX_H
+#define CRASH_HANDLER_OSX_H
+
+class CrashHandler {
+
+ bool disabled;
+
+public:
+ void initialize();
+
+ void disable();
+ bool is_disabled() const { return disabled; };
+
+ CrashHandler();
+ ~CrashHandler();
+};
+
+#endif
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
new file mode 100644
index 0000000000..9239573734
--- /dev/null
+++ b/platform/osx/crash_handler_osx.mm
@@ -0,0 +1,178 @@
+/*************************************************************************/
+/* crash_handler_osx.mm */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "main/main.h"
+#include "os_osx.h"
+
+#include <string.h>
+#include <unistd.h>
+
+// Note: Dump backtrace in 32bit mode is getting a bus error on the fgets by the ->execute, so enable only on 64bit
+#if defined(DEBUG_ENABLED) && defined(__x86_64__)
+#define CRASH_HANDLER_ENABLED 1
+#endif
+
+#ifdef CRASH_HANDLER_ENABLED
+#include <cxxabi.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <signal.h>
+
+#include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
+
+#ifdef __x86_64__
+static uint64_t load_address() {
+ const struct segment_command_64 *cmd = getsegbyname("__TEXT");
+#else
+static uint32_t load_address() {
+ const struct segment_command *cmd = getsegbyname("__TEXT");
+#endif
+ char full_path[1024];
+ uint32_t size = sizeof(full_path);
+
+ if (cmd && !_NSGetExecutablePath(full_path, &size)) {
+ uint32_t dyld_count = _dyld_image_count();
+ for (uint32_t i = 0; i < dyld_count; i++) {
+ const char *image_name = _dyld_get_image_name(i);
+ if (image_name && strncmp(image_name, full_path, 1024) == 0) {
+ return cmd->vmaddr + _dyld_get_image_vmaddr_slide(i);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void handle_crash(int sig) {
+ if (OS::get_singleton() == NULL)
+ return;
+
+ 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/backtrace/message");
+
+ // Dump the backtrace to stderr with a message to the user
+ fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
+ fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
+ char **strings = backtrace_symbols(bt_buffer, size);
+ if (strings) {
+ void *load_addr = (void *)load_address();
+
+ for (int i = 1; i < size; i++) {
+ char fname[1024];
+ Dl_info info;
+
+ snprintf(fname, 1024, "%s", strings[i]);
+
+ // Try to demangle the function name to provide a more readable one
+ if (dladdr(bt_buffer[i], &info) && info.dli_sname) {
+ if (info.dli_sname[0] == '_') {
+ int status;
+ char *demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
+
+ if (status == 0 && demangled) {
+ snprintf(fname, 1024, "%s", demangled);
+ }
+
+ if (demangled)
+ free(demangled);
+ }
+ }
+
+ String output = fname;
+
+ // Try to get the file/line number using atos
+ if (bt_buffer[i] > (void *)0x0 && OS::get_singleton()) {
+ List<String> args;
+ char str[1024];
+
+ args.push_back("-o");
+ args.push_back(_execpath);
+ args.push_back("-arch");
+#ifdef __x86_64__
+ args.push_back("x86_64");
+#else
+ args.push_back("i386");
+#endif
+ args.push_back("-l");
+ snprintf(str, 1024, "%p", load_addr);
+ args.push_back(str);
+ snprintf(str, 1024, "%p", bt_buffer[i]);
+ args.push_back(str);
+
+ int ret;
+ String out = "";
+ Error err = OS::get_singleton()->execute(String("atos"), args, true, NULL, &out, &ret);
+ if (err == OK && out.substr(0, 2) != "0x") {
+ out.erase(out.length() - 1, 1);
+ output = out;
+ }
+ }
+
+ fprintf(stderr, "[%d] %ls\n", i, output.c_str());
+ }
+
+ free(strings);
+ }
+ fprintf(stderr, "-- END OF BACKTRACE --\n");
+
+ // Abort to pass the error to the OS
+ abort();
+}
+#endif
+
+CrashHandler::CrashHandler() {
+ disabled = false;
+}
+
+CrashHandler::~CrashHandler() {
+}
+
+void CrashHandler::disable() {
+ if (disabled)
+ return;
+
+#ifdef CRASH_HANDLER_ENABLED
+ signal(SIGSEGV, NULL);
+ signal(SIGFPE, NULL);
+ signal(SIGILL, NULL);
+#endif
+
+ disabled = true;
+}
+
+void CrashHandler::initialize() {
+#ifdef CRASH_HANDLER_ENABLED
+ signal(SIGSEGV, handle_crash);
+ signal(SIGFPE, handle_crash);
+ signal(SIGILL, handle_crash);
+#endif
+}
diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h
index c988dfe425..9a7773f5ee 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/osx/dir_access_osx.h
@@ -46,6 +46,9 @@
class DirAccessOSX : public DirAccessUnix {
protected:
virtual String fix_unicode_name(const char *p_name) const;
+
+ virtual int get_drive_count();
+ virtual String get_drive(int p_drive);
};
#endif //UNIX ENABLED
diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm
index 6e8ceb5e19..6121e6ccfb 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/osx/dir_access_osx.mm
@@ -33,7 +33,8 @@
#include <errno.h>
-#include <Foundation/NSString.h>
+#include <AppKit/NSWorkspace.h>
+#include <Foundation/Foundation.h>
String DirAccessOSX::fix_unicode_name(const char *p_name) const {
@@ -45,4 +46,19 @@ String DirAccessOSX::fix_unicode_name(const char *p_name) const {
return fname;
}
+int DirAccessOSX::get_drive_count() {
+ NSArray *vols = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths];
+ return [vols count];
+}
+
+String DirAccessOSX::get_drive(int p_drive) {
+ NSArray *vols = [[NSWorkspace sharedWorkspace] mountedLocalVolumePaths];
+ int count = [vols count];
+
+ ERR_FAIL_INDEX_V(p_drive, count, "");
+
+ NSString *path = vols[p_drive];
+ return String([path UTF8String]);
+}
+
#endif //posix_enabled
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 7f749030ec..2ec76fe0dd 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -88,8 +88,15 @@ public:
};
void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
-
- // what does this need to do?
+ if (p_preset->get("texture_format/s3tc")) {
+ r_features->push_back("s3tc");
+ }
+ if (p_preset->get("texture_format/etc")) {
+ r_features->push_back("etc");
+ }
+ if (p_preset->get("texture_format/etc2")) {
+ r_features->push_back("etc2");
+ }
}
void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
@@ -112,6 +119,10 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements"), ""));
#endif
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false));
}
void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm
index 83d782cc2f..e2740fc666 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/osx/godot_main_osx.mm
@@ -35,7 +35,6 @@
#include <unistd.h>
int main(int argc, char **argv) {
-
int first_arg = 1;
const char *dbg_arg = "-NSDocumentRevisionsDebugMode";
printf("arguments\n");
@@ -74,6 +73,13 @@ int main(int argc, char **argv) {
}
}
+#ifdef DEBUG_ENABLED
+ // lets report the path we made current after all that
+ char cwd[4096];
+ getcwd(cwd, 4096);
+ printf("Current path: %s\n", cwd);
+#endif
+
OS_OSX os;
Error err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index b5163609c2..059dd5afd0 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -30,6 +30,7 @@
#ifndef OS_OSX_H
#define OS_OSX_H
+#include "crash_handler_osx.h"
#include "drivers/alsa/audio_driver_alsa.h"
#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "drivers/unix/os_unix.h"
@@ -110,6 +111,8 @@ public:
power_osx *power_manager;
+ CrashHandler crash_handler;
+
float _mouse_scale(float p_scale) {
if (display_scale > 1.0)
return p_scale;
@@ -181,6 +184,7 @@ public:
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
virtual String get_executable_path() const;
+ virtual String get_resource_dir() const;
virtual LatinKeyboardVariant get_latin_keyboard_variant() const;
@@ -223,6 +227,9 @@ public:
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;
+ void disable_crash_handler();
+ bool is_disable_crash_handler() const;
+
OS_OSX();
};
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index c18e3ff7c3..5a23d76755 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -910,6 +910,8 @@ OS::VideoMode OS_OSX::get_default_video_mode() const {
void OS_OSX::initialize_core() {
+ crash_handler.initialize();
+
OS_Unix::initialize_core();
DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_RESOURCES);
@@ -1736,6 +1738,17 @@ String OS_OSX::get_executable_path() const {
}
}
+String OS_OSX::get_resource_dir() const {
+ // start with our executable path
+ String path = get_executable_path();
+
+ int pos = path.find_last("/Contents/MacOS/");
+ if (pos < 0)
+ return OS::get_resource_dir();
+
+ return path.substr(0, pos) + "/Contents/Resources/";
+}
+
// Returns string representation of keys, if they are printable.
//
static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) {
@@ -2011,3 +2024,11 @@ OS_OSX::OS_OSX() {
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
return p_feature == "pc" || p_feature == "s3tc";
}
+
+void OS_OSX::disable_crash_handler() {
+ crash_handler.disable();
+}
+
+bool OS_OSX::is_disable_crash_handler() const {
+ return crash_handler.is_disabled();
+}
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index befbe00183..b56a5c6a80 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -5,6 +5,7 @@ Import('env')
common_win = [
"context_gl_win.cpp",
+ "crash_handler_win.cpp",
"os_windows.cpp",
"ctxgl_procaddr.cpp",
"key_mapping_win.cpp",
@@ -12,7 +13,7 @@ common_win = [
"packet_peer_udp_winsock.cpp",
"stream_peer_winsock.cpp",
"joypad.cpp",
- "power_windows.cpp",
+ "power_windows.cpp",
]
restarget = "godot_res" + env["OBJSUFFIX"]
diff --git a/platform/windows/crash_handler_win.cpp b/platform/windows/crash_handler_win.cpp
new file mode 100644
index 0000000000..c9385f36d6
--- /dev/null
+++ b/platform/windows/crash_handler_win.cpp
@@ -0,0 +1,211 @@
+/*************************************************************************/
+/* crash_handler_win.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "main/main.h"
+#include "os_windows.h"
+
+#ifdef CRASH_HANDLER_EXCEPTION
+
+// Backtrace code code based on: https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app
+
+#include <psapi.h>
+#include <algorithm>
+#include <iterator>
+
+#pragma comment(lib, "psapi.lib")
+#pragma comment(lib, "dbghelp.lib")
+
+// Some versions of imagehlp.dll lack the proper packing directives themselves
+// so we need to do it.
+#pragma pack(push, before_imagehlp, 8)
+#include <imagehlp.h>
+#pragma pack(pop, before_imagehlp)
+
+struct module_data {
+ std::string image_name;
+ std::string module_name;
+ void *base_address;
+ DWORD load_size;
+};
+
+class symbol {
+ typedef IMAGEHLP_SYMBOL64 sym_type;
+ sym_type *sym;
+ static const int max_name_len = 1024;
+
+public:
+ symbol(HANDLE process, DWORD64 address)
+ : sym((sym_type *)::operator new(sizeof(*sym) + max_name_len)) {
+ memset(sym, '\0', sizeof(*sym) + max_name_len);
+ sym->SizeOfStruct = sizeof(*sym);
+ sym->MaxNameLength = max_name_len;
+ DWORD64 displacement;
+
+ SymGetSymFromAddr64(process, address, &displacement, sym);
+ }
+
+ std::string name() { return std::string(sym->Name); }
+ std::string undecorated_name() {
+ if (*sym->Name == '\0')
+ return "<couldn't map PC to fn name>";
+ std::vector<char> und_name(max_name_len);
+ UnDecorateSymbolName(sym->Name, &und_name[0], max_name_len, UNDNAME_COMPLETE);
+ return std::string(&und_name[0], strlen(&und_name[0]));
+ }
+};
+
+class get_mod_info {
+ HANDLE process;
+
+public:
+ get_mod_info(HANDLE h)
+ : process(h) {}
+
+ module_data operator()(HMODULE module) {
+ module_data ret;
+ char temp[4096];
+ MODULEINFO mi;
+
+ GetModuleInformation(process, module, &mi, sizeof(mi));
+ ret.base_address = mi.lpBaseOfDll;
+ ret.load_size = mi.SizeOfImage;
+
+ GetModuleFileNameEx(process, module, temp, sizeof(temp));
+ ret.image_name = temp;
+ GetModuleBaseName(process, module, temp, sizeof(temp));
+ ret.module_name = temp;
+ std::vector<char> img(ret.image_name.begin(), ret.image_name.end());
+ std::vector<char> mod(ret.module_name.begin(), ret.module_name.end());
+ SymLoadModule64(process, 0, &img[0], &mod[0], (DWORD64)ret.base_address, ret.load_size);
+ return ret;
+ }
+};
+
+DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
+ HANDLE process = GetCurrentProcess();
+ HANDLE hThread = GetCurrentThread();
+ DWORD offset_from_symbol = 0;
+ IMAGEHLP_LINE64 line = { 0 };
+ std::vector<module_data> modules;
+ DWORD cbNeeded;
+ std::vector<HMODULE> module_handles(1);
+
+ if (OS::get_singleton() == NULL || OS::get_singleton()->is_disable_crash_handler()) {
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ fprintf(stderr, "%s: Program crashed\n", __FUNCTION__);
+
+ // Load the symbols:
+ if (!SymInitialize(process, NULL, false))
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
+ EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
+ module_handles.resize(cbNeeded / sizeof(HMODULE));
+ EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
+ std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), get_mod_info(process));
+ void *base = modules[0].base_address;
+
+ // Setup stuff:
+ CONTEXT *context = ep->ContextRecord;
+ STACKFRAME64 frame;
+ bool skip_first = false;
+
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrStack.Mode = AddrModeFlat;
+ frame.AddrFrame.Mode = AddrModeFlat;
+
+#ifdef _M_X64
+ frame.AddrPC.Offset = context->Rip;
+ frame.AddrStack.Offset = context->Rsp;
+ frame.AddrFrame.Offset = context->Rbp;
+#else
+ frame.AddrPC.Offset = context->Eip;
+ frame.AddrStack.Offset = context->Esp;
+ frame.AddrFrame.Offset = context->Ebp;
+
+ // Skip the first one to avoid a duplicate on 32-bit mode
+ skip_first = true;
+#endif
+
+ line.SizeOfStruct = sizeof(line);
+ IMAGE_NT_HEADERS *h = ImageNtHeader(base);
+ DWORD image_type = h->FileHeader.Machine;
+ int n = 0;
+ String msg = GLOBAL_GET("debug/settings/backtrace/message");
+
+ fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
+
+ do {
+ if (skip_first) {
+ skip_first = false;
+ } else {
+ if (frame.AddrPC.Offset != 0) {
+ std::string fnName = symbol(process, frame.AddrPC.Offset).undecorated_name();
+
+ if (SymGetLineFromAddr64(process, frame.AddrPC.Offset, &offset_from_symbol, &line))
+ fprintf(stderr, "[%d] %s (%s:%d)\n", n, fnName.c_str(), line.FileName, line.LineNumber);
+ else
+ fprintf(stderr, "[%d] %s\n", n, fnName.c_str());
+ } else
+ fprintf(stderr, "[%d] ???\n", n);
+
+ n++;
+ }
+
+ if (!StackWalk64(image_type, process, hThread, &frame, context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
+ break;
+ } while (frame.AddrReturn.Offset != 0 && n < 256);
+
+ fprintf(stderr, "-- END OF BACKTRACE --\n");
+
+ SymCleanup(process);
+
+ // Pass the exception to the OS
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+CrashHandler::CrashHandler() {
+ disabled = false;
+}
+
+CrashHandler::~CrashHandler() {
+}
+
+void CrashHandler::disable() {
+ if (disabled)
+ return;
+
+ disabled = true;
+}
+
+void CrashHandler::initialize() {
+}
diff --git a/platform/windows/crash_handler_win.h b/platform/windows/crash_handler_win.h
new file mode 100644
index 0000000000..0b1889e4fe
--- /dev/null
+++ b/platform/windows/crash_handler_win.h
@@ -0,0 +1,56 @@
+/*************************************************************************/
+/* crash_handler_win.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef CRASH_HANDLER_WIN_H
+#define CRASH_HANDLER_WIN_H
+
+#include <windows.h>
+
+// Crash handler exception only enabled with MSVC
+#if defined(DEBUG_ENABLED) && defined(MSVC)
+#define CRASH_HANDLER_EXCEPTION 1
+
+extern DWORD CrashHandlerException(EXCEPTION_POINTERS *ep);
+#endif
+
+class CrashHandler {
+
+ bool disabled;
+
+public:
+ void initialize();
+
+ void disable();
+ bool is_disabled() const { return disabled; };
+
+ CrashHandler();
+ ~CrashHandler();
+};
+
+#endif
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index d239ccf7d2..5bd9a78f49 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -123,7 +123,7 @@ def configure(env):
env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup'])
elif (env["target"] == "debug"):
- env.Append(CCFLAGS=['/Z7', '/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED', '/DD3D_DEBUG_INFO', '/Od'])
+ env.Append(CCFLAGS=['/Z7', '/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED', '/DD3D_DEBUG_INFO', '/Od', '/EHsc'])
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
env.Append(LINKFLAGS=['/DEBUG'])
@@ -226,10 +226,13 @@ def configure(env):
else:
env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe" # for linux cross-compilation
- mingw_prefix = ""
-
if (env["bits"] == "default"):
- env["bits"] = "64" if "PROGRAMFILES(X86)" in os.environ else "32"
+ if (os.name == "nt"):
+ env["bits"] = "64" if "PROGRAMFILES(X86)" in os.environ else "32"
+ else: # default to 64-bit on Linux
+ env["bits"] = "64"
+
+ mingw_prefix = ""
if (env["bits"] == "32"):
env.Append(LINKFLAGS=['-static'])
diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp
index d2ac6ecb50..4450cb3670 100644
--- a/platform/windows/godot_win.cpp
+++ b/platform/windows/godot_win.cpp
@@ -157,24 +157,32 @@ int widechar_main(int argc, wchar_t **argv) {
};
int main(int _argc, char **_argv) {
- // _argc and _argv are ignored
- // we are going to use the WideChar version of them instead
+// _argc and _argv are ignored
+// we are going to use the WideChar version of them instead
- LPWSTR *wc_argv;
- int argc;
- int result;
+#ifdef CRASH_HANDLER_EXCEPTION
+ __try {
+#endif
+ LPWSTR *wc_argv;
+ int argc;
+ int result;
- wc_argv = CommandLineToArgvW(GetCommandLineW(), &argc);
+ wc_argv = CommandLineToArgvW(GetCommandLineW(), &argc);
- if (NULL == wc_argv) {
- wprintf(L"CommandLineToArgvW failed\n");
- return 0;
- }
+ if (NULL == wc_argv) {
+ wprintf(L"CommandLineToArgvW failed\n");
+ return 0;
+ }
- result = widechar_main(argc, wc_argv);
+ result = widechar_main(argc, wc_argv);
- LocalFree(wc_argv);
- return result;
+ LocalFree(wc_argv);
+ return result;
+#ifdef CRASH_HANDLER_EXCEPTION
+ } __except (CrashHandlerException(GetExceptionInformation())) {
+ return 1;
+ }
+#endif
}
HINSTANCE godot_hinstance = NULL;
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index a061536e7a..62954e1a56 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -164,6 +164,8 @@ const char *OS_Windows::get_audio_driver_name(int p_driver) const {
void OS_Windows::initialize_core() {
+ crash_handler.initialize();
+
last_button_state = 0;
//RedirectIOToConsole();
@@ -887,6 +889,12 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau
return (dpiX + dpiY) / 2;
}
+typedef enum _SHC_PROCESS_DPI_AWARENESS {
+ SHC_PROCESS_DPI_UNAWARE = 0,
+ SHC_PROCESS_SYSTEM_DPI_AWARE = 1,
+ SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2
+} SHC_PROCESS_DPI_AWARENESS;
+
void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
main_loop = NULL;
@@ -894,6 +902,20 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
window_has_focus = true;
WNDCLASSEXW wc;
+ if (is_hidpi_allowed()) {
+ HMODULE Shcore = LoadLibraryW(L"Shcore.dll");
+
+ if (Shcore != NULL) {
+ typedef HRESULT(WINAPI * SetProcessDpiAwareness_t)(SHC_PROCESS_DPI_AWARENESS);
+
+ SetProcessDpiAwareness_t SetProcessDpiAwareness = (SetProcessDpiAwareness_t)GetProcAddress(Shcore, "SetProcessDpiAwareness");
+
+ if (SetProcessDpiAwareness) {
+ SetProcessDpiAwareness(SHC_PROCESS_SYSTEM_DPI_AWARE);
+ }
+ }
+ }
+
video_mode = p_desired;
//printf("**************** desired %s, mode %s\n", p_desired.fullscreen?"true":"false", video_mode.fullscreen?"true":"false");
RECT WindowRect;
@@ -2348,6 +2370,14 @@ bool OS_Windows::_check_internal_feature_support(const String &p_feature) {
return p_feature == "pc" || p_feature == "s3tc";
}
+void OS_Windows::disable_crash_handler() {
+ crash_handler.disable();
+}
+
+bool OS_Windows::is_disable_crash_handler() const {
+ return crash_handler.is_disabled();
+}
+
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
key_event_pos = 0;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 5d2b84746e..1a01ac950d 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -31,6 +31,7 @@
#define OS_WINDOWS_H
#include "context_gl_win.h"
+#include "crash_handler_win.h"
#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "drivers/wasapi/audio_driver_wasapi.h"
#include "os/input.h"
@@ -134,6 +135,8 @@ class OS_Windows : public OS {
AudioDriverXAudio2 driver_xaudio2;
#endif
+ CrashHandler crash_handler;
+
void _drag_event(int p_x, int p_y, int idx);
void _touch_event(bool p_pressed, int p_x, int p_y, int idx);
@@ -284,6 +287,9 @@ public:
virtual bool _check_internal_feature_support(const String &p_feature);
+ void disable_crash_handler();
+ bool is_disable_crash_handler() const;
+
OS_Windows(HINSTANCE _hInstance);
~OS_Windows();
};
diff --git a/platform/x11/SCsub b/platform/x11/SCsub
index fc9208c563..62717f3221 100644
--- a/platform/x11/SCsub
+++ b/platform/x11/SCsub
@@ -3,12 +3,13 @@
Import('env')
-common_x11 = [\
- "context_gl_x11.cpp",\
- "os_x11.cpp",\
- "key_mapping_x11.cpp",\
- "joypad_linux.cpp",\
- "power_x11.cpp",\
+common_x11 = [
+ "context_gl_x11.cpp",
+ "crash_handler_x11.cpp",
+ "os_x11.cpp",
+ "key_mapping_x11.cpp",
+ "joypad_linux.cpp",
+ "power_x11.cpp",
]
env.Program('#bin/godot', ['godot_x11.cpp'] + common_x11)
diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp
new file mode 100644
index 0000000000..c926b7799d
--- /dev/null
+++ b/platform/x11/crash_handler_x11.cpp
@@ -0,0 +1,135 @@
+/*************************************************************************/
+/* crash_handler_x11.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifdef DEBUG_ENABLED
+#define CRASH_HANDLER_ENABLED 1
+#endif
+
+#include "main/main.h"
+#include "os_x11.h"
+
+#ifdef CRASH_HANDLER_ENABLED
+#include <cxxabi.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#include <signal.h>
+
+static void handle_crash(int sig) {
+ if (OS::get_singleton() == NULL)
+ return;
+
+ 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/backtrace/message");
+
+ // Dump the backtrace to stderr with a message to the user
+ fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
+ fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
+ char **strings = backtrace_symbols(bt_buffer, size);
+ if (strings) {
+ for (size_t i = 1; i < size; i++) {
+ char fname[1024];
+ Dl_info info;
+
+ snprintf(fname, 1024, "%s", strings[i]);
+
+ // Try to demangle the function name to provide a more readable one
+ if (dladdr(bt_buffer[i], &info) && info.dli_sname) {
+ if (info.dli_sname[0] == '_') {
+ int status;
+ char *demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
+
+ if (status == 0 && demangled) {
+ snprintf(fname, 1024, "%s", demangled);
+ }
+
+ if (demangled)
+ free(demangled);
+ }
+ }
+
+ List<String> args;
+
+ char str[1024];
+ snprintf(str, 1024, "%p", bt_buffer[i]);
+ args.push_back(str);
+ args.push_back("-e");
+ args.push_back(_execpath);
+
+ 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);
+ }
+ }
+
+ fprintf(stderr, "[%ld] %s (%ls)\n", i, fname, output.c_str());
+ }
+
+ free(strings);
+ }
+ fprintf(stderr, "-- END OF BACKTRACE --\n");
+
+ // Abort to pass the error to the OS
+ abort();
+}
+#endif
+
+CrashHandler::CrashHandler() {
+ disabled = false;
+}
+
+CrashHandler::~CrashHandler() {
+}
+
+void CrashHandler::disable() {
+ if (disabled)
+ return;
+
+#ifdef CRASH_HANDLER_ENABLED
+ signal(SIGSEGV, NULL);
+ signal(SIGFPE, NULL);
+ signal(SIGILL, NULL);
+#endif
+
+ disabled = true;
+}
+
+void CrashHandler::initialize() {
+#ifdef CRASH_HANDLER_ENABLED
+ signal(SIGSEGV, handle_crash);
+ signal(SIGFPE, handle_crash);
+ signal(SIGILL, handle_crash);
+#endif
+}
diff --git a/platform/x11/crash_handler_x11.h b/platform/x11/crash_handler_x11.h
new file mode 100644
index 0000000000..e01334cbf2
--- /dev/null
+++ b/platform/x11/crash_handler_x11.h
@@ -0,0 +1,47 @@
+/*************************************************************************/
+/* crash_handler_x11.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef CRASH_HANDLER_X11_H
+#define CRASH_HANDLER_X11_H
+
+class CrashHandler {
+
+ bool disabled;
+
+public:
+ void initialize();
+
+ void disable();
+ bool is_disabled() const { return disabled; };
+
+ CrashHandler();
+ ~CrashHandler();
+};
+
+#endif
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 086681d4a4..d61175da60 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -87,6 +87,7 @@ def configure(env):
elif (env["target"] == "debug"):
env.Prepend(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+ env.Append(LINKFLAGS=['-rdynamic'])
## Architecture
diff --git a/platform/x11/joypad_linux.cpp b/platform/x11/joypad_linux.cpp
index 3453297716..428385f7cb 100644
--- a/platform/x11/joypad_linux.cpp
+++ b/platform/x11/joypad_linux.cpp
@@ -125,7 +125,6 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) {
enumerate = udev_enumerate_new(p_udev);
udev_enumerate_add_match_subsystem(enumerate, "input");
- udev_enumerate_add_match_property(enumerate, "ID_INPUT_JOYPAD", "1");
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index ea91fe20da..4e78e0318c 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -93,6 +93,13 @@ const char *OS_X11::get_audio_driver_name(int p_driver) const {
return AudioDriverManager::get_driver(p_driver)->get_name();
}
+void OS_X11::initialize_core() {
+
+ crash_handler.initialize();
+
+ OS_Unix::initialize_core();
+}
+
void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
long im_event_mask = 0;
@@ -246,6 +253,11 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
// borderless fullscreen window mode
if (current_videomode.fullscreen) {
+ // set bypass compositor hint
+ Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False);
+ unsigned long compositing_disable_on = 1;
+ XChangeProperty(x11_display, x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1);
+
// needed for lxde/openbox, possibly others
Hints hints;
Atom property;
@@ -695,6 +707,12 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
xev.xclient.data.l[2] = 0;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+
+ // set bypass compositor hint
+ Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False);
+ unsigned long compositing_disable_on = p_enabled ? 1 : 0;
+ XChangeProperty(x11_display, x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1);
+
XFlush(x11_display);
if (!p_enabled && !is_window_resizable()) {
@@ -2161,6 +2179,14 @@ int OS_X11::get_power_percent_left() {
return power_manager->get_power_percent_left();
}
+void OS_X11::disable_crash_handler() {
+ crash_handler.disable();
+}
+
+bool OS_X11::is_disable_crash_handler() const {
+ return crash_handler.is_disabled();
+}
+
OS_X11::OS_X11() {
#ifdef RTAUDIO_ENABLED
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index c1f9505063..2ba7f07cef 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -31,6 +31,7 @@
#define OS_X11_H
#include "context_gl_x11.h"
+#include "crash_handler_x11.h"
#include "drivers/unix/os_unix.h"
#include "os/input.h"
#include "servers/visual_server.h"
@@ -170,6 +171,8 @@ class OS_X11 : public OS_Unix {
PowerX11 *power_manager;
+ CrashHandler crash_handler;
+
int audio_driver_index;
unsigned int capture_idle;
bool maximized;
@@ -191,6 +194,7 @@ protected:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
virtual void finalize();
@@ -273,6 +277,9 @@ public:
void run();
+ void disable_crash_handler();
+ bool is_disable_crash_handler() const;
+
OS_X11();
};