summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/file_access_android.cpp5
-rw-r--r--platform/android/file_access_android.h1
-rw-r--r--platform/android/file_access_jandroid.cpp3
-rw-r--r--platform/android/file_access_jandroid.h1
-rw-r--r--platform/android/os_android.cpp32
-rw-r--r--platform/android/os_android.h3
-rw-r--r--platform/iphone/SCsub1
-rw-r--r--platform/iphone/app_delegate.mm6
-rw-r--r--platform/iphone/audio_driver_iphone.cpp187
-rw-r--r--platform/iphone/detect.py2
-rw-r--r--platform/iphone/os_iphone.cpp16
-rw-r--r--platform/iphone/os_iphone.h6
-rw-r--r--platform/javascript/engine.js6
-rw-r--r--platform/javascript/os_javascript.cpp4
-rw-r--r--platform/javascript/os_javascript.h6
-rw-r--r--platform/osx/SCsub1
-rw-r--r--platform/osx/audio_driver_osx.cpp301
-rw-r--r--platform/osx/audio_driver_osx.h85
-rw-r--r--platform/osx/detect.py2
-rw-r--r--platform/osx/os_osx.h11
-rw-r--r--platform/osx/os_osx.mm105
-rw-r--r--platform/uwp/os_uwp.cpp60
-rw-r--r--platform/uwp/os_uwp.h4
-rw-r--r--platform/windows/SCsub1
-rw-r--r--platform/windows/detect.py5
-rw-r--r--platform/windows/os_windows.cpp170
-rw-r--r--platform/windows/os_windows.h6
-rw-r--r--platform/windows/windows_terminal_logger.cpp157
-rw-r--r--platform/windows/windows_terminal_logger.h (renamed from platform/iphone/audio_driver_iphone.h)43
-rw-r--r--platform/x11/detect.py5
-rw-r--r--platform/x11/os_x11.cpp72
-rw-r--r--platform/x11/os_x11.h2
32 files changed, 437 insertions, 872 deletions
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index c7b0d9afcd..0fdf9002d7 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -146,6 +146,11 @@ Error FileAccessAndroid::get_error() const {
return eof ? ERR_FILE_EOF : OK; //not sure what else it may happen
}
+void FileAccessAndroid::flush() {
+
+ ERR_FAIL();
+}
+
void FileAccessAndroid::store_8(uint8_t p_dest) {
ERR_FAIL();
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index beccf494dd..c8fedbe684 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -63,6 +63,7 @@ public:
virtual Error get_error() const; ///< get last error
+ virtual void flush();
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String &p_path); ///< return true if a file exists
diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp
index fe934c89fb..980afd8f46 100644
--- a/platform/android/file_access_jandroid.cpp
+++ b/platform/android/file_access_jandroid.cpp
@@ -157,6 +157,9 @@ Error FileAccessJAndroid::get_error() const {
return OK;
}
+void FileAccessJAndroid::flush() {
+}
+
void FileAccessJAndroid::store_8(uint8_t p_dest) {
}
diff --git a/platform/android/file_access_jandroid.h b/platform/android/file_access_jandroid.h
index 75a6a21335..368d2c98fa 100644
--- a/platform/android/file_access_jandroid.h
+++ b/platform/android/file_access_jandroid.h
@@ -67,6 +67,7 @@ public:
virtual Error get_error() const; ///< get last error
+ virtual void flush();
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String &p_path); ///< return true if a file exists
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index dbea2d7531..0eb14f6af3 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -47,6 +47,15 @@
#include "file_access_jandroid.h"
#endif
+class AndroidLogger : public Logger {
+public:
+ virtual void logv(const char *p_format, va_list p_list, bool p_err) {
+ __android_log_vprint(p_err ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "godot", p_format, p_list);
+ }
+
+ virtual ~AndroidLogger() {}
+};
+
int OS_Android::get_video_driver_count() const {
return 1;
@@ -111,6 +120,13 @@ void OS_Android::initialize_core() {
#endif
}
+void OS_Android::initialize_logger() {
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(AndroidLogger));
+ loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
+ _set_logger(memnew(CompositeLogger(loggers)));
+}
+
void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
ERR_FAIL_COND(!p_gl_extensions);
@@ -162,23 +178,9 @@ void OS_Android::delete_main_loop() {
}
void OS_Android::finalize() {
-
memdelete(input);
}
-void OS_Android::vprint(const char *p_format, va_list p_list, bool p_stderr) {
-
- __android_log_vprint(p_stderr ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "godot", p_format, p_list);
-}
-
-void OS_Android::print(const char *p_format, ...) {
-
- va_list argp;
- va_start(argp, p_format);
- __android_log_vprint(ANDROID_LOG_INFO, "godot", p_format, argp);
- va_end(argp);
-}
-
void OS_Android::alert(const String &p_alert, const String &p_title) {
//print("ALERT: %s\n", p_alert.utf8().get_data());
@@ -737,6 +739,8 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
set_keep_screen_on_func = p_set_keep_screen_on_func;
alert_func = p_alert_func;
use_reload_hooks = false;
+
+ _set_logger(memnew(AndroidLogger));
}
OS_Android::~OS_Android() {
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 119c14bff3..a614bb8067 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -149,6 +149,7 @@ public:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -161,8 +162,6 @@ public:
static OS *get_singleton();
- virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
- virtual void print(const char *p_format, ...);
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual void set_mouse_show(bool p_show);
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 998d0a3f0d..61798c5f87 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -5,7 +5,6 @@ Import('env')
iphone_lib = [
'os_iphone.cpp',
- 'audio_driver_iphone.cpp',
'sem_iphone.cpp',
'gl_view.mm',
'main.m',
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index c7b65b476b..da6ceacdac 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -29,8 +29,8 @@
/*************************************************************************/
#import "app_delegate.h"
-#include "audio_driver_iphone.h"
#include "core/project_settings.h"
+#include "drivers/coreaudio/audio_driver_coreaudio.h"
#import "gl_view.h"
#include "main/main.h"
#include "os_iphone.h"
@@ -736,8 +736,8 @@ static int frame_count = 0;
};
// Fixed audio can not resume if it is interrupted cause by an incoming phone call
- if (AudioDriverIphone::get_singleton() != NULL)
- AudioDriverIphone::get_singleton()->start();
+ if (AudioDriverCoreAudio::get_singleton() != NULL)
+ AudioDriverCoreAudio::get_singleton()->start();
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
diff --git a/platform/iphone/audio_driver_iphone.cpp b/platform/iphone/audio_driver_iphone.cpp
deleted file mode 100644
index dbc5bdb654..0000000000
--- a/platform/iphone/audio_driver_iphone.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*************************************************************************/
-/* audio_driver_iphone.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 "audio_driver_iphone.h"
-
-Error AudioDriverIphone::init() {
-
- active = false;
- channels = 2;
-
- AudioStreamBasicDescription strdesc;
- strdesc.mFormatID = kAudioFormatLinearPCM;
- strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
- strdesc.mChannelsPerFrame = channels;
- strdesc.mSampleRate = 44100;
- strdesc.mFramesPerPacket = 1;
- strdesc.mBitsPerChannel = 16;
- strdesc.mBytesPerFrame =
- strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
- strdesc.mBytesPerPacket =
- strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
-
- AURenderCallbackStruct callback;
- AudioComponentDescription desc;
- const AudioUnitElement output_bus = 0;
- const AudioUnitElement bus = output_bus;
- const AudioUnitScope scope = kAudioUnitScope_Input;
-
- zeromem(&desc, sizeof(desc));
- desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = kAudioUnitSubType_RemoteIO; /* !!! FIXME: ? */
- AudioComponent comp = AudioComponentFindNext(NULL, &desc);
- desc.componentManufacturer = kAudioUnitManufacturer_Apple;
-
- OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
- ERR_FAIL_COND_V(comp == NULL, FAILED);
-
- result = AudioUnitSetProperty(audio_unit,
- kAudioUnitProperty_StreamFormat,
- scope, bus, &strdesc, sizeof(strdesc));
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- zeromem(&callback, sizeof(AURenderCallbackStruct));
- callback.inputProc = &AudioDriverIphone::output_callback;
- callback.inputProcRefCon = this;
- result = AudioUnitSetProperty(audio_unit,
- kAudioUnitProperty_SetRenderCallback,
- scope, bus, &callback, sizeof(callback));
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- result = AudioUnitInitialize(audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- result = AudioOutputUnitStart(audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- const int samples = 1024;
- samples_in = memnew_arr(int32_t, samples); // whatever
- buffer_frames = samples / channels;
-
- return FAILED;
-};
-
-OSStatus AudioDriverIphone::output_callback(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList *ioData) {
-
- AudioBuffer *abuf;
- AudioDriverIphone *ad = (AudioDriverIphone *)inRefCon;
-
- bool mix = true;
-
- if (!ad->active)
- mix = false;
- else if (ad->mutex) {
- mix = ad->mutex->try_lock() == OK;
- };
-
- if (!mix) {
- for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
- abuf = &ioData->mBuffers[i];
- zeromem(abuf->mData, abuf->mDataByteSize);
- };
- return 0;
- };
-
- int frames_left;
-
- for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
-
- abuf = &ioData->mBuffers[i];
- frames_left = inNumberFrames;
- int16_t *out = (int16_t *)abuf->mData;
-
- while (frames_left) {
-
- int frames = MIN(frames_left, ad->buffer_frames);
- //ad->lock();
- ad->audio_server_process(frames, ad->samples_in);
- //ad->unlock();
-
- for (int i = 0; i < frames * ad->channels; i++) {
-
- out[i] = ad->samples_in[i] >> 16;
- }
-
- frames_left -= frames;
- out += frames * ad->channels;
- };
- };
-
- if (ad->mutex)
- ad->mutex->unlock();
-
- return 0;
-};
-
-void AudioDriverIphone::start() {
- active = true;
- // Resume audio
- // iOS audio-thread stoped if it is interrupted cause by an incoming phone call
- // Use AudioOutputUnitStart to re-create audio-thread
- OSStatus result = AudioOutputUnitStart(audio_unit);
- ERR_FAIL_COND(result != noErr);
-};
-
-int AudioDriverIphone::get_mix_rate() const {
- return 44100;
-};
-
-AudioDriver::SpeakerMode AudioDriverIphone::get_speaker_mode() const {
- return SPEAKER_MODE_STEREO;
-};
-
-void AudioDriverIphone::lock() {
-
- if (active && mutex)
- mutex->lock();
-};
-
-void AudioDriverIphone::unlock() {
- if (active && mutex)
- mutex->unlock();
-};
-
-void AudioDriverIphone::finish() {
-
- memdelete_arr(samples_in);
-};
-
-AudioDriverIphone::AudioDriverIphone() {
-
- mutex = Mutex::create(); //NULL;
-};
-
-AudioDriverIphone::~AudioDriverIphone(){
-
-};
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index dd4db0b1cd..00d8a59f74 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -148,7 +148,7 @@ def configure(env):
env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate'
env.Append(CPPPATH=['#platform/iphone'])
- env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DMPC_FIXED_POINT'])
+ env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DMPC_FIXED_POINT', '-DCOREAUDIO_ENABLED'])
# TODO: Move that to opus module's config
if 'module_opus_enabled' in env and env['module_opus_enabled']:
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 0e3eeed114..5009f7d8ae 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -35,13 +35,13 @@
#include "servers/visual/visual_server_raster.h"
//#include "servers/visual/visual_server_wrap_mt.h"
-#include "audio_driver_iphone.h"
#include "main/main.h"
#include "core/io/file_access_pack.h"
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
+#include "drivers/unix/syslog_logger.h"
#include "sem_iphone.h"
@@ -99,6 +99,13 @@ void OSIPhone::initialize_core() {
SemaphoreIphone::make_default();
};
+void OSIPhone::initialize_logger() {
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(SyslogLogger));
+ loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
+ _set_logger(memnew(CompositeLogger(loggers)));
+}
+
void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
supported_orientations = 0;
@@ -124,9 +131,8 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_
// reset this to what it should be, it will have been set to 0 after visual_server->init() is called
RasterizerStorageGLES3::system_fbo = gl_view_base_fb;
- audio_driver = memnew(AudioDriverIphone);
- audio_driver->set_singleton();
- audio_driver->init();
+ AudioDriverManager::add_driver(&audio_driver);
+ AudioDriverManager::initialize(p_audio_driver);
// init physics servers
physics_server = memnew(PhysicsServerSW);
@@ -570,6 +576,8 @@ OSIPhone::OSIPhone(int width, int height) {
vm.resizable = false;
set_video_mode(vm);
event_count = 0;
+
+ _set_logger(memnew(SyslogLogger));
};
OSIPhone::~OSIPhone() {
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 475dceebf2..11f4eed5e7 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -32,6 +32,7 @@
#ifndef OS_IPHONE_H
#define OS_IPHONE_H
+#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/unix/os_unix.h"
#include "os/input.h"
@@ -46,8 +47,6 @@
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
-class AudioDriverIphone;
-
class OSIPhone : public OS_Unix {
public:
@@ -70,7 +69,7 @@ private:
PhysicsServer *physics_server;
Physics2DServer *physics_2d_server;
- AudioDriverIphone *audio_driver;
+ AudioDriverCoreAudio audio_driver;
#ifdef GAME_CENTER_ENABLED
GameCenter *game_center;
@@ -91,6 +90,7 @@ private:
virtual VideoMode get_default_video_mode() const;
+ virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js
index 552f5a7e02..99d1c20bbd 100644
--- a/platform/javascript/engine.js
+++ b/platform/javascript/engine.js
@@ -84,10 +84,10 @@
rtenvOpts.print = stdout;
if (typeof stderr === 'function')
rtenvOpts.printErr = stderr;
- if (typeof WebAssembly === 'object' && initializer instanceof WebAssembly.Module) {
+ if (typeof WebAssembly === 'object' && initializer instanceof ArrayBuffer) {
rtenvOpts.instantiateWasm = function(imports, onSuccess) {
WebAssembly.instantiate(initializer, imports).then(function(result) {
- onSuccess(result);
+ onSuccess(result.instance);
});
return {};
};
@@ -241,7 +241,7 @@
return Promise.reject(new Error("Browser doesn't support WebAssembly"));
// TODO cache/retrieve module to/from idb
engineLoadPromise = loadPromise(basePath + '.wasm').then(function(xhr) {
- return WebAssembly.compile(xhr.response);
+ return xhr.response;
});
} else {
var asmjsPromise = loadPromise(basePath + '.asm.js').then(function(xhr) {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index f103035b27..82a8409615 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -85,6 +85,10 @@ void OS_JavaScript::initialize_core() {
FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES);
}
+void OS_JavaScript::initialize_logger() {
+ _set_logger(memnew(StdLogger));
+}
+
void OS_JavaScript::set_opengl_extensions(const char *p_gl_extensions) {
ERR_FAIL_COND(!p_gl_extensions);
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 4c6469cb58..1c7bcfef45 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -92,6 +92,7 @@ public:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -104,11 +105,6 @@ public:
//static OS* get_singleton();
- virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
-
- OS::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
- }
-
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual void set_mouse_mode(MouseMode p_mode);
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 27bffbe80e..be3950bc6d 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -10,7 +10,6 @@ files = [
'crash_handler_osx.mm',
'os_osx.mm',
'godot_main_osx.mm',
- 'audio_driver_osx.cpp',
'sem_osx.cpp',
'dir_access_osx.mm',
'joypad_osx.cpp',
diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp
deleted file mode 100644
index 3b3ba60507..0000000000
--- a/platform/osx/audio_driver_osx.cpp
+++ /dev/null
@@ -1,301 +0,0 @@
-/*************************************************************************/
-/* audio_driver_osx.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 OSX_ENABLED
-
-#include "audio_driver_osx.h"
-#include "core/project_settings.h"
-#include "os/os.h"
-
-#define kOutputBus 0
-
-static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *__nullable inClientData) {
- AudioDriverOSX *driver = (AudioDriverOSX *)inClientData;
-
- driver->reopen();
-
- return noErr;
-}
-
-Error AudioDriverOSX::initDevice() {
- AudioComponentDescription desc;
- zeromem(&desc, sizeof(desc));
- desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = kAudioUnitSubType_HALOutput;
- desc.componentManufacturer = kAudioUnitManufacturer_Apple;
-
- AudioComponent comp = AudioComponentFindNext(NULL, &desc);
- ERR_FAIL_COND_V(comp == NULL, FAILED);
-
- OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- AudioStreamBasicDescription 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;
- break;
-
- default:
- // Unknown number of channels, default to stereo
- channels = 2;
- break;
- }
-
- mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
-
- zeromem(&strdesc, sizeof(strdesc));
- strdesc.mFormatID = kAudioFormatLinearPCM;
- strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
- strdesc.mChannelsPerFrame = channels;
- strdesc.mSampleRate = mix_rate;
- strdesc.mFramesPerPacket = 1;
- strdesc.mBitsPerChannel = 16;
- strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
- strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
-
- result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
- // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
- buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
-
- result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- buffer_size = buffer_frames * channels;
- samples_in.resize(buffer_size);
-
- if (OS::get_singleton()->is_stdout_verbose()) {
- 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;
- zeromem(&callback, sizeof(AURenderCallbackStruct));
- callback.inputProc = &AudioDriverOSX::output_callback;
- callback.inputProcRefCon = this;
- result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- result = AudioUnitInitialize(audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- return OK;
-}
-
-Error AudioDriverOSX::finishDevice() {
- OSStatus result;
-
- if (active) {
- result = AudioOutputUnitStop(audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- active = false;
- }
-
- result = AudioUnitUninitialize(audio_unit);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- return OK;
-}
-
-Error AudioDriverOSX::init() {
- OSStatus result;
-
- mutex = Mutex::create();
- active = false;
- channels = 2;
-
- outputDeviceAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
- outputDeviceAddress.mScope = kAudioObjectPropertyScopeGlobal;
- outputDeviceAddress.mElement = kAudioObjectPropertyElementMaster;
-
- result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- return initDevice();
-};
-
-Error AudioDriverOSX::reopen() {
- bool restart = false;
-
- lock();
-
- if (active) {
- restart = true;
- }
-
- Error err = finishDevice();
- if (err != OK) {
- ERR_PRINT("finishDevice failed");
- unlock();
- return err;
- }
-
- err = initDevice();
- if (err != OK) {
- ERR_PRINT("initDevice failed");
- unlock();
- return err;
- }
-
- if (restart) {
- start();
- }
-
- unlock();
-
- return OK;
-}
-
-OSStatus AudioDriverOSX::output_callback(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList *ioData) {
-
- AudioDriverOSX *ad = (AudioDriverOSX *)inRefCon;
-
- if (!ad->active || !ad->try_lock()) {
- for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
- AudioBuffer *abuf = &ioData->mBuffers[i];
- zeromem(abuf->mData, abuf->mDataByteSize);
- };
- return 0;
- };
-
- for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
-
- AudioBuffer *abuf = &ioData->mBuffers[i];
- int frames_left = inNumberFrames;
- int16_t *out = (int16_t *)abuf->mData;
-
- while (frames_left) {
-
- int frames = MIN(frames_left, ad->buffer_frames);
- ad->audio_server_process(frames, ad->samples_in.ptr());
-
- for (int j = 0; j < frames * ad->channels; j++) {
-
- out[j] = ad->samples_in[j] >> 16;
- }
-
- frames_left -= frames;
- out += frames * ad->channels;
- };
- };
-
- ad->unlock();
-
- return 0;
-};
-
-void AudioDriverOSX::start() {
- if (!active) {
- OSStatus result = AudioOutputUnitStart(audio_unit);
- if (result != noErr) {
- ERR_PRINT("AudioOutputUnitStart failed");
- } else {
- active = true;
- }
- }
-};
-
-int AudioDriverOSX::get_mix_rate() const {
- return mix_rate;
-};
-
-AudioDriver::SpeakerMode AudioDriverOSX::get_speaker_mode() const {
- return get_speaker_mode_by_total_channels(channels);
-};
-
-void AudioDriverOSX::lock() {
- if (mutex)
- mutex->lock();
-};
-
-void AudioDriverOSX::unlock() {
- if (mutex)
- mutex->unlock();
-};
-
-bool AudioDriverOSX::try_lock() {
- if (mutex)
- return mutex->try_lock() == OK;
- return true;
-}
-
-void AudioDriverOSX::finish() {
- finishDevice();
-
- OSStatus result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
- if (result != noErr) {
- ERR_PRINT("AudioObjectRemovePropertyListener failed");
- }
-
- AURenderCallbackStruct callback;
- zeromem(&callback, sizeof(AURenderCallbackStruct));
- result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
- if (result != noErr) {
- ERR_PRINT("AudioUnitSetProperty failed");
- }
-
- if (mutex) {
- memdelete(mutex);
- mutex = NULL;
- }
-};
-
-AudioDriverOSX::AudioDriverOSX() {
- active = false;
- mutex = NULL;
-
- mix_rate = 0;
- channels = 2;
-
- buffer_size = 0;
- buffer_frames = 0;
-
- samples_in.clear();
-};
-
-AudioDriverOSX::~AudioDriverOSX(){};
-
-#endif
diff --git a/platform/osx/audio_driver_osx.h b/platform/osx/audio_driver_osx.h
deleted file mode 100644
index a7e68c8141..0000000000
--- a/platform/osx/audio_driver_osx.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*************************************************************************/
-/* audio_driver_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. */
-/*************************************************************************/
-#ifdef OSX_ENABLED
-
-#ifndef AUDIO_DRIVER_OSX_H
-#define AUDIO_DRIVER_OSX_H
-
-#include "servers/audio_server.h"
-
-#include <AudioUnit/AudioUnit.h>
-#include <CoreAudio/AudioHardware.h>
-
-class AudioDriverOSX : public AudioDriver {
-
- AudioComponentInstance audio_unit;
- AudioObjectPropertyAddress outputDeviceAddress;
- bool active;
- Mutex *mutex;
-
- int mix_rate;
- unsigned int channels;
- unsigned int buffer_frames;
- unsigned int buffer_size;
-
- Vector<int32_t> samples_in;
-
- static OSStatus output_callback(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList *ioData);
-
- Error initDevice();
- Error finishDevice();
-
-public:
- const char *get_name() const {
- return "AudioUnit";
- };
-
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual void lock();
- virtual void unlock();
- virtual void finish();
-
- bool try_lock();
- Error reopen();
-
- AudioDriverOSX();
- ~AudioDriverOSX();
-};
-
-#endif
-
-#endif
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 51da000712..f66c3f00da 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -103,7 +103,7 @@ def configure(env):
## Flags
env.Append(CPPPATH=['#platform/osx'])
- env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DAPPLE_STYLE_KEYS'])
+ env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED'])
env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
env.Append(LIBS=['pthread'])
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 6c81da04f5..eb8c0566b4 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -31,13 +31,11 @@
#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/coreaudio/audio_driver_coreaudio.h"
#include "drivers/unix/os_unix.h"
#include "joypad_osx.h"
#include "main/input_default.h"
#include "os/input.h"
-#include "platform/osx/audio_driver_osx.h"
#include "power_osx.h"
#include "servers/audio_server.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
@@ -69,7 +67,7 @@ public:
IP_Unix *ip_unix;
- AudioDriverOSX audio_driver_osx;
+ AudioDriverCoreAudio audio_driver;
InputDefault *input;
JoypadOSX *joypad_osx;
@@ -129,6 +127,7 @@ protected:
virtual const char *get_video_driver_name(int p_driver) const;
virtual VideoMode get_default_video_mode() const;
+ virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
virtual void finalize();
@@ -143,8 +142,6 @@ public:
virtual String get_name();
- virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
-
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual void set_cursor_shape(CursorShape p_shape);
@@ -229,6 +226,8 @@ public:
void disable_crash_handler();
bool is_disable_crash_handler() const;
+ virtual Error move_to_trash(const String &p_path);
+
OS_OSX();
};
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 9a26adc155..8323aa84a8 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1071,7 +1071,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
bool use_gl2 = p_video_driver != 1;
- AudioDriverManager::add_driver(&audio_driver_osx);
+ AudioDriverManager::add_driver(&audio_driver);
// only opengl support here...
RasterizerGLES3::register_config();
@@ -1145,43 +1145,67 @@ String OS_OSX::get_name() {
return "OSX";
}
-void OS_OSX::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
-
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
- if (!_print_error_enabled)
- return;
-
- const char *err_details;
- if (p_rationale && p_rationale[0])
- err_details = p_rationale;
- else
- err_details = p_code;
+class OSXTerminalLogger : public StdLogger {
+public:
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR) {
+ if (!should_log(true)) {
+ return;
+ }
- switch (p_type) {
- case ERR_ERROR:
- os_log_error(OS_LOG_DEFAULT, "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
- print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
- case ERR_WARNING:
- os_log_info(OS_LOG_DEFAULT, "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
- print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
- case ERR_SCRIPT:
- os_log_error(OS_LOG_DEFAULT, "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
- print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
- case ERR_SHADER:
- os_log_error(OS_LOG_DEFAULT, "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
- print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
+ const char *err_details;
+ if (p_rationale && p_rationale[0])
+ err_details = p_rationale;
+ else
+ err_details = p_code;
+
+ switch (p_type) {
+ case ERR_WARNING:
+ os_log_info(OS_LOG_DEFAULT,
+ "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.",
+ p_function, err_details, p_file, p_line);
+ logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function,
+ err_details);
+ logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_SCRIPT:
+ os_log_error(OS_LOG_DEFAULT,
+ "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
+ p_function, err_details, p_file, p_line);
+ logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function,
+ err_details);
+ logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_SHADER:
+ os_log_error(OS_LOG_DEFAULT,
+ "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
+ p_function, err_details, p_file, p_line);
+ logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function,
+ err_details);
+ logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_ERROR:
+ default:
+ os_log_error(OS_LOG_DEFAULT,
+ "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
+ p_function, err_details, p_file, p_line);
+ logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ }
}
+};
+
#else
- OS_Unix::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
+
+typedef UnixTerminalLogger OSXTerminalLogger;
#endif
+
+void OS_OSX::initialize_logger() {
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(OSXTerminalLogger));
+ loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
+ _set_logger(memnew(CompositeLogger(loggers)));
}
void OS_OSX::alert(const String &p_alert, const String &p_title) {
@@ -1910,6 +1934,19 @@ int OS_OSX::get_power_percent_left() {
return power_manager->get_power_percent_left();
}
+Error OS_OSX::move_to_trash(const String &p_path) {
+ NSFileManager *fm = [NSFileManager defaultManager];
+ NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
+ NSError *err;
+
+ if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) {
+ ERR_PRINTS("trashItemAtURL error: " + String(err.localizedDescription.UTF8String));
+ return FAILED;
+ }
+
+ return OK;
+}
+
OS_OSX *OS_OSX::singleton = NULL;
OS_OSX::OS_OSX() {
@@ -2003,6 +2040,8 @@ OS_OSX::OS_OSX() {
window_size = Vector2(1024, 600);
zoomed = false;
display_scale = 1.0;
+
+ _set_logger(memnew(OSXTerminalLogger));
}
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index b909ccccd6..031c714514 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -40,6 +40,7 @@
#include "platform/windows/packet_peer_udp_winsock.h"
#include "platform/windows/stream_peer_winsock.h"
#include "platform/windows/tcp_server_winsock.h"
+#include "platform/windows/windows_terminal_logger.h"
#include "project_settings.h"
#include "servers/audio_server.h"
#include "servers/visual/visual_server_raster.h"
@@ -182,6 +183,13 @@ void OSUWP::initialize_core() {
cursor_shape = CURSOR_ARROW;
}
+void OSUWP::initialize_logger() {
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(WindowsTerminalLogger));
+ loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
+ _set_logger(memnew(CompositeLogger(loggers)));
+}
+
bool OSUWP::can_draw() const {
return !minimized;
@@ -371,32 +379,6 @@ void OSUWP::finalize() {
void OSUWP::finalize_core() {
}
-void OSUWP::vprint(const char *p_format, va_list p_list, bool p_stderr) {
-
- char buf[16384 + 1];
- int len = vsnprintf(buf, 16384, p_format, p_list);
- if (len <= 0)
- return;
- buf[len] = 0;
-
- int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
- if (wlen < 0)
- return;
-
- wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
- wbuf[wlen] = 0;
-
- if (p_stderr)
- fwprintf(stderr, L"%s", wbuf);
- else
- wprintf(L"%s", wbuf);
-
- free(wbuf);
-
- fflush(stdout);
-};
-
void OSUWP::alert(const String &p_alert, const String &p_title) {
Platform::String ^ alert = ref new Platform::String(p_alert.c_str());
@@ -520,30 +502,6 @@ OS::VideoMode OSUWP::get_video_mode(int p_screen) const {
void OSUWP::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
}
-void OSUWP::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
-
- const char *err_details;
- if (p_rationale && p_rationale[0])
- err_details = p_rationale;
- else
- err_details = p_code;
-
- switch (p_type) {
- case ERR_ERROR:
- print("ERROR: %s: %s\n", p_function, err_details);
- print(" At: %s:%i\n", p_file, p_line);
- break;
- case ERR_WARNING:
- print("WARNING: %s: %s\n", p_function, err_details);
- print(" At: %s:%i\n", p_file, p_line);
- break;
- case ERR_SCRIPT:
- print("SCRIPT ERROR: %s: %s\n", p_function, err_details);
- print(" At: %s:%i\n", p_file, p_line);
- break;
- }
-}
-
String OSUWP::get_name() {
return "UWP";
@@ -890,6 +848,8 @@ OSUWP::OSUWP() {
mouse_mode_changed = CreateEvent(NULL, TRUE, FALSE, L"os_mouse_mode_changed");
AudioDriverManager::add_driver(&audio_driver);
+
+ _set_logger(memnew(WindowsTerminalLogger));
}
OSUWP::~OSUWP() {
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index a7a5d32cb9..df38faa8e1 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -163,6 +163,7 @@ protected:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -180,9 +181,6 @@ public:
// Event to send to the app wrapper
HANDLE mouse_mode_changed;
- void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type);
-
- virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
String get_stdin_string(bool p_block);
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index d3c160f052..aa9eb3e69b 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -19,6 +19,7 @@ common_win = [
"stream_peer_winsock.cpp",
"joypad.cpp",
"power_windows.cpp",
+ "windows_terminal_logger.cpp"
]
restarget = "godot_res" + env["OBJSUFFIX"]
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 92f2e078c8..031b397988 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -265,7 +265,10 @@ def configure(env):
if env['use_lto']:
env.Append(CCFLAGS=['-flto'])
- env.Append(LINKFLAGS=['-flto'])
+ if not env['use_llvm'] and env.GetOption("num_jobs") > 1:
+ env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))])
+ else:
+ env.Append(LINKFLAGS=['-flto'])
## Compile flags
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index db7cd0b938..bee8c90ad3 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -48,6 +48,7 @@
#include "servers/visual/visual_server_wrap_mt.h"
#include "stream_peer_winsock.h"
#include "tcp_server_winsock.h"
+#include "windows_terminal_logger.h"
#include <process.h>
#include <regstr.h>
@@ -205,6 +206,13 @@ void OS_Windows::initialize_core() {
cursor_shape = CURSOR_ARROW;
}
+void OS_Windows::initialize_logger() {
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(WindowsTerminalLogger));
+ loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
+ _set_logger(memnew(CompositeLogger(loggers)));
+}
+
bool OS_Windows::can_draw() const {
return !minimized;
@@ -1231,38 +1239,6 @@ void OS_Windows::finalize_core() {
StreamPeerWinsock::cleanup();
}
-void OS_Windows::vprint(const char *p_format, va_list p_list, bool p_stderr) {
-
- const unsigned int BUFFER_SIZE = 16384;
- char buf[BUFFER_SIZE + 1]; // +1 for the terminating character
- int len = vsnprintf(buf, BUFFER_SIZE, p_format, p_list);
- if (len <= 0)
- return;
- if (len >= BUFFER_SIZE)
- len = BUFFER_SIZE; // Output is too big, will be truncated
- buf[len] = 0;
-
- int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
- if (wlen < 0)
- return;
-
- wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
- wbuf[wlen] = 0;
-
- if (p_stderr)
- fwprintf(stderr, L"%ls", wbuf);
- else
- wprintf(L"%ls", wbuf);
-
-#ifdef STDOUT_FILE
-//vwfprintf(stdo,p_format,p_list);
-#endif
- free(wbuf);
-
- fflush(stdout);
-};
-
void OS_Windows::alert(const String &p_alert, const String &p_title) {
if (!is_no_window_mode_enabled())
@@ -1676,107 +1652,6 @@ void OS_Windows::request_attention() {
FlashWindowEx(&info);
}
-void OS_Windows::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
-
- HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
- if (!hCon || hCon == INVALID_HANDLE_VALUE) {
-
- const char *err_details;
- if (p_rationale && p_rationale[0])
- err_details = p_rationale;
- else
- err_details = p_code;
-
- switch (p_type) {
- case ERR_ERROR:
- print("ERROR: %s: %s\n", p_function, err_details);
- print(" At: %s:%i\n", p_file, p_line);
- break;
- case ERR_WARNING:
- print("WARNING: %s: %s\n", p_function, err_details);
- print(" At: %s:%i\n", p_file, p_line);
- break;
- case ERR_SCRIPT:
- print("SCRIPT ERROR: %s: %s\n", p_function, err_details);
- print(" At: %s:%i\n", p_file, p_line);
- break;
- case ERR_SHADER:
- print("SHADER ERROR: %s: %s\n", p_function, err_details);
- print(" At: %s:%i\n", p_file, p_line);
- break;
- }
-
- } else {
-
- CONSOLE_SCREEN_BUFFER_INFO sbi; //original
- GetConsoleScreenBufferInfo(hCon, &sbi);
-
- WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
- WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
-
- uint32_t basecol = 0;
- switch (p_type) {
- case ERR_ERROR: basecol = FOREGROUND_RED; break;
- case ERR_WARNING: basecol = FOREGROUND_RED | FOREGROUND_GREEN; break;
- case ERR_SCRIPT: basecol = FOREGROUND_RED | FOREGROUND_BLUE; break;
- case ERR_SHADER: basecol = FOREGROUND_GREEN | FOREGROUND_BLUE; break;
- }
-
- basecol |= current_bg;
-
- if (p_rationale && p_rationale[0]) {
-
- SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
- switch (p_type) {
- case ERR_ERROR: print("ERROR: "); break;
- case ERR_WARNING: print("WARNING: "); break;
- case ERR_SCRIPT: print("SCRIPT ERROR: "); break;
- case ERR_SHADER: print("SHADER ERROR: "); break;
- }
-
- SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
- print("%s\n", p_rationale);
-
- SetConsoleTextAttribute(hCon, basecol);
- switch (p_type) {
- case ERR_ERROR: print(" At: "); break;
- case ERR_WARNING: print(" At: "); break;
- case ERR_SCRIPT: print(" At: "); break;
- case ERR_SHADER: print(" At: "); break;
- }
-
- SetConsoleTextAttribute(hCon, current_fg | current_bg);
- print("%s:%i\n", p_file, p_line);
-
- } else {
-
- SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
- switch (p_type) {
- case ERR_ERROR: print("ERROR: %s: ", p_function); break;
- case ERR_WARNING: print("WARNING: %s: ", p_function); break;
- case ERR_SCRIPT: print("SCRIPT ERROR: %s: ", p_function); break;
- case ERR_SHADER: print("SCRIPT ERROR: %s: ", p_function); break;
- }
-
- SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
- print("%s\n", p_code);
-
- SetConsoleTextAttribute(hCon, basecol);
- switch (p_type) {
- case ERR_ERROR: print(" At: "); break;
- case ERR_WARNING: print(" At: "); break;
- case ERR_SCRIPT: print(" At: "); break;
- case ERR_SHADER: print(" At: "); break;
- }
-
- SetConsoleTextAttribute(hCon, current_fg | current_bg);
- print("%s:%i\n", p_file, p_line);
- }
-
- SetConsoleTextAttribute(hCon, sbi.wAttributes);
- }
-}
-
String OS_Windows::get_name() {
return "Windows";
@@ -2373,6 +2248,33 @@ bool OS_Windows::is_disable_crash_handler() const {
return crash_handler.is_disabled();
}
+Error OS_Windows::move_to_trash(const String &p_path) {
+ SHFILEOPSTRUCTA sf;
+ TCHAR *from = new TCHAR[p_path.length() + 2];
+ strcpy(from, p_path.utf8().get_data());
+ from[p_path.length()] = 0;
+ from[p_path.length() + 1] = 0;
+
+ sf.hwnd = hWnd;
+ sf.wFunc = FO_DELETE;
+ sf.pFrom = from;
+ sf.pTo = NULL;
+ sf.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
+ sf.fAnyOperationsAborted = FALSE;
+ sf.hNameMappings = NULL;
+ sf.lpszProgressTitle = NULL;
+
+ int ret = SHFileOperation(&sf);
+ delete[] from;
+
+ if (ret) {
+ ERR_PRINTS("SHFileOperation error: " + itos(ret));
+ return FAILED;
+ }
+
+ return OK;
+}
+
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
key_event_pos = 0;
@@ -2402,6 +2304,8 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
#ifdef XAUDIO2_ENABLED
AudioDriverManager::add_driver(&driver_xaudio2);
#endif
+
+ _set_logger(memnew(WindowsTerminalLogger));
}
OS_Windows::~OS_Windows() {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 8a955aa224..9560bc61ca 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -152,6 +152,7 @@ protected:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual void initialize_logger();
virtual void initialize_core();
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -180,9 +181,6 @@ protected:
public:
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type);
-
- virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
String get_stdin_string(bool p_block);
@@ -290,6 +288,8 @@ public:
void disable_crash_handler();
bool is_disable_crash_handler() const;
+ virtual Error move_to_trash(const String &p_path);
+
OS_Windows(HINSTANCE _hInstance);
~OS_Windows();
};
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
new file mode 100644
index 0000000000..ef8140ffa7
--- /dev/null
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -0,0 +1,157 @@
+/*************************************************************************/
+/* windows_terminal_logger.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 "windows_terminal_logger.h"
+
+#ifdef WINDOWS_ENABLED
+
+#include <stdio.h>
+#include <windows.h>
+
+void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_err) {
+ if (!should_log(p_err)) {
+ return;
+ }
+
+ const unsigned int BUFFER_SIZE = 16384;
+ char buf[BUFFER_SIZE + 1]; // +1 for the terminating character
+ int len = vsnprintf(buf, BUFFER_SIZE, p_format, p_list);
+ if (len <= 0)
+ return;
+ if (len >= BUFFER_SIZE)
+ len = BUFFER_SIZE; // Output is too big, will be truncated
+ buf[len] = 0;
+
+ int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
+ if (wlen < 0)
+ return;
+
+ wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
+ wbuf[wlen] = 0;
+
+ if (p_err)
+ fwprintf(stderr, L"%ls", wbuf);
+ else
+ wprintf(L"%ls", wbuf);
+
+ free(wbuf);
+
+#ifdef DEBUG_ENABLED
+ fflush(stdout);
+#endif
+}
+
+void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+ if (!should_log(true)) {
+ return;
+ }
+
+#ifndef UWP_ENABLED
+ HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (!hCon || hCon == INVALID_HANDLE_VALUE) {
+#endif
+ StdLogger::log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
+#ifndef UWP_ENABLED
+ } else {
+
+ CONSOLE_SCREEN_BUFFER_INFO sbi; //original
+ GetConsoleScreenBufferInfo(hCon, &sbi);
+
+ WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
+ WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
+
+ uint32_t basecol = 0;
+ switch (p_type) {
+ case ERR_ERROR: basecol = FOREGROUND_RED; break;
+ case ERR_WARNING: basecol = FOREGROUND_RED | FOREGROUND_GREEN; break;
+ case ERR_SCRIPT: basecol = FOREGROUND_RED | FOREGROUND_BLUE; break;
+ case ERR_SHADER: basecol = FOREGROUND_GREEN | FOREGROUND_BLUE; break;
+ }
+
+ basecol |= current_bg;
+
+ if (p_rationale && p_rationale[0]) {
+
+ SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
+ switch (p_type) {
+ case ERR_ERROR: logf("ERROR: "); break;
+ case ERR_WARNING: logf("WARNING: "); break;
+ case ERR_SCRIPT: logf("SCRIPT ERROR: "); break;
+ case ERR_SHADER: logf("SHADER ERROR: "); break;
+ }
+
+ SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
+ logf("%s\n", p_rationale);
+
+ SetConsoleTextAttribute(hCon, basecol);
+ switch (p_type) {
+ case ERR_ERROR: logf(" At: "); break;
+ case ERR_WARNING: logf(" At: "); break;
+ case ERR_SCRIPT: logf(" At: "); break;
+ case ERR_SHADER: logf(" At: "); break;
+ }
+
+ SetConsoleTextAttribute(hCon, current_fg | current_bg);
+ logf("%s:%i\n", p_file, p_line);
+
+ } else {
+
+ SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
+ switch (p_type) {
+ case ERR_ERROR: logf("ERROR: %s: ", p_function); break;
+ case ERR_WARNING: logf("WARNING: %s: ", p_function); break;
+ case ERR_SCRIPT: logf("SCRIPT ERROR: %s: ", p_function); break;
+ case ERR_SHADER: logf("SCRIPT ERROR: %s: ", p_function); break;
+ }
+
+ SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
+ logf("%s\n", p_code);
+
+ SetConsoleTextAttribute(hCon, basecol);
+ switch (p_type) {
+ case ERR_ERROR: logf(" At: "); break;
+ case ERR_WARNING: logf(" At: "); break;
+ case ERR_SCRIPT: logf(" At: "); break;
+ case ERR_SHADER: logf(" At: "); break;
+ }
+
+ SetConsoleTextAttribute(hCon, current_fg | current_bg);
+ logf("%s:%i\n", p_file, p_line);
+ }
+
+ SetConsoleTextAttribute(hCon, sbi.wAttributes);
+ }
+#endif
+}
+
+WindowsTerminalLogger::~WindowsTerminalLogger() {}
+
+#endif \ No newline at end of file
diff --git a/platform/iphone/audio_driver_iphone.h b/platform/windows/windows_terminal_logger.h
index 930ed168f7..f6b1a68d18 100644
--- a/platform/iphone/audio_driver_iphone.h
+++ b/platform/windows/windows_terminal_logger.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* audio_driver_iphone.h */
+/* windows_terminal_logger.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,39 +28,20 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "servers/audio_server.h"
+#ifndef WINDOWS_TERMINAL_LOGGER_H
+#define WINDOWS_TERMINAL_LOGGER_H
-#include <AudioUnit/AudioUnit.h>
+#ifdef WINDOWS_ENABLED
-class AudioDriverIphone : public AudioDriver {
-
- AudioComponentInstance audio_unit;
- bool active;
- Mutex *mutex;
-
- int channels;
- int32_t *samples_in;
- int buffer_frames;
-
- static OSStatus output_callback(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber, UInt32 inNumberFrames,
- AudioBufferList *ioData);
+#include "io/logger.h"
+class WindowsTerminalLogger : public StdLogger {
public:
- const char *get_name() const {
- return "IPhone";
- };
+ virtual void logv(const char *p_format, va_list p_list, bool p_err);
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
+ virtual ~WindowsTerminalLogger();
+};
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual void lock();
- virtual void unlock();
- virtual void finish();
+#endif
- AudioDriverIphone();
- ~AudioDriverIphone();
-};
+#endif \ No newline at end of file
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index c8d9930af1..1f7f67fe10 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -120,7 +120,10 @@ def configure(env):
if env['use_lto']:
env.Append(CCFLAGS=['-flto'])
- env.Append(LINKFLAGS=['-flto'])
+ if not env['use_llvm'] and env.GetOption("num_jobs") > 1:
+ env.Append(LINKFLAGS=['-flto=' + str(env.GetOption("num_jobs"))])
+ else:
+ env.Append(LINKFLAGS=['-flto'])
if not env['use_llvm']:
env['RANLIB'] = 'gcc-ranlib'
env['AR'] = 'gcc-ar'
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 599c0d2278..041666a594 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -35,6 +35,7 @@
#include "servers/physics/physics_server_sw.h"
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
+#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -2175,6 +2176,77 @@ bool OS_X11::is_disable_crash_handler() const {
return crash_handler.is_disabled();
}
+static String get_mountpoint(const String &p_path) {
+ struct stat s;
+ if (stat(p_path.utf8().get_data(), &s)) {
+ return "";
+ }
+
+ dev_t dev = s.st_dev;
+ FILE *fd = setmntent("/proc/mounts", "r");
+ if (!fd) {
+ return "";
+ }
+
+ struct mntent mnt;
+ char buf[1024];
+ size_t buflen = 1024;
+ while (getmntent_r(fd, &mnt, buf, buflen)) {
+ if (!stat(mnt.mnt_dir, &s) && s.st_dev == dev) {
+ endmntent(fd);
+ return String(mnt.mnt_dir);
+ }
+ }
+
+ endmntent(fd);
+ return "";
+}
+
+Error OS_X11::move_to_trash(const String &p_path) {
+ String trashcan = "";
+ String mnt = get_mountpoint(p_path);
+
+ if (mnt != "") {
+ String path(mnt + "/.Trash-" + itos(getuid()) + "/files");
+ struct stat s;
+ if (!stat(path.utf8().get_data(), &s)) {
+ trashcan = path;
+ }
+ }
+
+ if (trashcan == "") {
+ char *dhome = getenv("XDG_DATA_HOME");
+ if (dhome) {
+ trashcan = String(dhome) + "/Trash/files";
+ }
+ }
+
+ if (trashcan == "") {
+ char *home = getenv("HOME");
+ if (home) {
+ trashcan = String(home) + "/.local/share/Trash/files";
+ }
+ }
+
+ if (trashcan == "") {
+ ERR_PRINTS("move_to_trash: Could not determine trashcan location");
+ return FAILED;
+ }
+
+ List<String> args;
+ args.push_back("-p");
+ args.push_back(trashcan);
+ Error err = execute("/bin/mkdir", args, true);
+ if (err == OK) {
+ List<String> args2;
+ args2.push_back(p_path);
+ args2.push_back(trashcan);
+ err = execute("/bin/mv", args2, true);
+ }
+
+ return err;
+}
+
OS_X11::OS_X11() {
#ifdef PULSEAUDIO_ENABLED
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index a0338dacf1..0d5c272ed4 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -273,6 +273,8 @@ public:
void disable_crash_handler();
bool is_disable_crash_handler() const;
+ virtual Error move_to_trash(const String &p_path);
+
OS_X11();
};