diff options
Diffstat (limited to 'platform')
177 files changed, 1349 insertions, 333 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub index 0cd91276ef..d2285a82dd 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -104,7 +104,7 @@ gradle_asset_dirs_text = "" gradle_default_config_text = "" minSdk = 18 -targetSdk = 23 +targetSdk = 27 for x in env.android_default_config: if x.startswith("minSdkVersion") and int(x.split(" ")[-1]) < minSdk: diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index 1f05d6cd9b..7545ee88d0 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -27,6 +27,7 @@ /* 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_jandroid.h" #include "os/os.h" diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h index 5cd8eb8e0c..763f0e9b5a 100644 --- a/platform/android/audio_driver_jandroid.h +++ b/platform/android/audio_driver_jandroid.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef AUDIO_DRIVER_ANDROID_H #define AUDIO_DRIVER_ANDROID_H diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index f0218e13bd..87a7d04e01 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -27,6 +27,7 @@ /* 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_opensl.h" #include <string.h> diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h index 9dc74c6c8a..2022bad02a 100644 --- a/platform/android/audio_driver_opensl.h +++ b/platform/android/audio_driver_opensl.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef AUDIO_DRIVER_OPENSL_H #define AUDIO_DRIVER_OPENSL_H diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template index 4a44d1c5f9..7269e658b4 100644 --- a/platform/android/build.gradle.template +++ b/platform/android/build.gradle.template @@ -15,12 +15,13 @@ allprojects { repositories { jcenter() mavenCentral() + google() $$GRADLE_REPOSITORY_URLS$$ } } dependencies { - compile 'com.android.support:support-v4:23.+' // can be removed if minSdkVersion 16 and modify DownloadNotification.java & V14CustomNotification.java + compile 'com.android.support:support-v4:27.+' // can be removed if minSdkVersion 16 and modify DownloadNotification.java & V14CustomNotification.java $$GRADLE_DEPENDENCIES$$ } @@ -31,8 +32,8 @@ android { disable 'MissingTranslation' } - compileSdkVersion 26 - buildToolsVersion "26.0.1" + compileSdkVersion 27 + buildToolsVersion "27.0.3" useLibrary 'org.apache.http.legacy' packagingOptions { diff --git a/platform/android/detect.py b/platform/android/detect.py index 892b1b6a85..971368db17 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -14,10 +14,13 @@ def get_name(): def can_build(): - return ("ANDROID_NDK_ROOT" in os.environ) +def get_platform(platform): + return int(platform.split("-")[1]) + + def get_opts(): from SCons.Variables import BoolVariable, EnumVariable @@ -124,6 +127,9 @@ def configure(env): else: env.extra_suffix = ".armv7" + env.extra_suffix elif env["android_arch"] == "arm64v8": + if get_platform(env["ndk_platform"]) < 21: + print("WARNING: android_arch=arm64v8 is not supported by ndk_platform lower than andorid-21; setting ndk_platform=android-21") + env["ndk_platform"] = "android-21" env['ARCH'] = 'arch-arm64' target_subpath = "aarch64-linux-android-4.9" abi_subpath = "aarch64-linux-android" @@ -160,12 +166,13 @@ def configure(env): elif (sys.platform.startswith('win')): if (platform.machine().endswith('64')): host_subpath = "windows-x86_64" - if env["android_arch"] == "arm64v8": - mt_link = False else: mt_link = False host_subpath = "windows" + if env["android_arch"] == "arm64v8": + mt_link = False + compiler_path = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/" + host_subpath + "/bin" gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath tools_path = gcc_toolchain_path + "/" + abi_subpath + "/bin" @@ -199,7 +206,7 @@ def configure(env): env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include"]) env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath]) # For unified headers this define has to be set manually - env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(int(env['ndk_platform'].split("-")[1]))]) + env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(get_platform(env['ndk_platform']))]) else: print("Using NDK deprecated headers") env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"]) @@ -254,10 +261,10 @@ def configure(env): env.Append(LINKFLAGS=target_opts) env.Append(LINKFLAGS=common_opts) - env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/' + + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/lib/gcc/' + abi_subpath + '/4.9.x']) env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + - '/toolchains/arm-linux-androideabi-4.9/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) + '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) env.Append(CPPPATH=['#platform/android']) env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT']) diff --git a/platform/android/dir_access_android.cpp b/platform/android/dir_access_android.cpp index c6e11ec505..402da4527e 100644 --- a/platform/android/dir_access_android.cpp +++ b/platform/android/dir_access_android.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef ANDROID_NATIVE_ACTIVITY #include "dir_access_android.h" #include "file_access_android.h" diff --git a/platform/android/dir_access_android.h b/platform/android/dir_access_android.h index 970202b5cc..085d7160cd 100644 --- a/platform/android/dir_access_android.h +++ b/platform/android/dir_access_android.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef DIR_ACCESS_ANDROID_H #define DIR_ACCESS_ANDROID_H diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 6abab3edf6..5601dcc763 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef ANDROID_NATIVE_ACTIVITY #include "dir_access_jandroid.h" diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index 4a9112fb27..8dc52ab9c8 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef DIR_ACCESS_JANDROID_H #define DIR_ACCESS_JANDROID_H diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 922a53621f..2a61f8d873 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "export.h" #include "editor/editor_export.h" @@ -551,6 +552,10 @@ class EditorExportAndroid : public EditorExportPlatform { return OK; } + static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { + return OK; + } + void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet) { // Leaving the unused types commented because looking these constants up @@ -1503,6 +1508,10 @@ public: cl.push_back(passwd); }*/ + APKExportData ed; + ed.ep = &ep; + ed.apk = unaligned_apk; + err = export_project_files(p_preset, ignore_apk_file, &ed, save_apk_so); } else { //all files @@ -1530,17 +1539,17 @@ public: err = export_project_files(p_preset, save_apk_file, &ed, save_apk_so); } + } - if (!err) { - APKExportData ed; - ed.ep = &ep; - ed.apk = unaligned_apk; - for (int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { - String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges(); - if (icon_path != "" && icon_path.ends_with(".png") && FileAccess::exists(icon_path)) { - Vector<uint8_t> data = FileAccess::get_file_as_array(icon_path); - store_in_apk(&ed, launcher_icons[i].export_path, data); - } + if (!err) { + APKExportData ed; + ed.ep = &ep; + ed.apk = unaligned_apk; + for (int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { + String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges(); + if (icon_path != "" && icon_path.ends_with(".png") && FileAccess::exists(icon_path)) { + Vector<uint8_t> data = FileAccess::get_file_as_array(icon_path); + store_in_apk(&ed, launcher_icons[i].export_path, data); } } } diff --git a/platform/android/export/export.h b/platform/android/export/export.h index eb18e04863..9d66626866 100644 --- a/platform/android/export/export.h +++ b/platform/android/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_android_exporter(); diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp index d958ef8294..c2eed50e4c 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "file_access_android.h" #include "print_string.h" diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index f44c19f963..03f4c59521 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef FILE_ACCESS_ANDROID_H #define FILE_ACCESS_ANDROID_H diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp index 4285a136a2..1a9d3af4ea 100644 --- a/platform/android/file_access_jandroid.cpp +++ b/platform/android/file_access_jandroid.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef ANDROID_NATIVE_ACTIVITY #include "file_access_jandroid.h" diff --git a/platform/android/file_access_jandroid.h b/platform/android/file_access_jandroid.h index c537f2f01a..72f81ee02e 100644 --- a/platform/android/file_access_jandroid.h +++ b/platform/android/file_access_jandroid.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef FILE_ACCESS_JANDROID_H #define FILE_ACCESS_JANDROID_H diff --git a/platform/android/globals/global_defaults.cpp b/platform/android/globals/global_defaults.cpp index 4a7dd07090..a315f80452 100644 --- a/platform/android/globals/global_defaults.cpp +++ b/platform/android/globals/global_defaults.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "global_defaults.h" #include "project_settings.h" diff --git a/platform/android/globals/global_defaults.h b/platform/android/globals/global_defaults.h index 412942eb88..99da2dd527 100644 --- a/platform/android/globals/global_defaults.h +++ b/platform/android/globals/global_defaults.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_android_global_defaults(); diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp index 1643be7763..64715b3683 100644 --- a/platform/android/godot_android.cpp +++ b/platform/android/godot_android.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef ANDROID_NATIVE_ACTIVITY #include "engine.h" diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties index ee6901c9d7..fe37fa74a9 100644 --- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/platform/android/java/src/org/godotengine/godot/Dictionary.java b/platform/android/java/src/org/godotengine/godot/Dictionary.java index b7ced69d0e..de6b4af568 100644 --- a/platform/android/java/src/org/godotengine/godot/Dictionary.java +++ b/platform/android/java/src/org/godotengine/godot/Dictionary.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; import java.util.HashMap; diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index d6e060f8d5..0d14211bd0 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; import android.R; @@ -403,7 +404,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC new_cmdline = new String[2]; } - new_cmdline[cll] = "--main_pack"; + new_cmdline[cll] = "--main-pack"; new_cmdline[cll + 1] = expansion_pack_path; command_line = new_cmdline; } @@ -827,7 +828,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC //@Override public boolean dispatchTouchEvent (MotionEvent event) { public boolean gotTouchEvent(final MotionEvent event) { - super.onTouchEvent(event); final int evcount = event.getPointerCount(); if (evcount == 0) return true; @@ -841,6 +841,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC arr[i * 3 + 1] = (int)event.getX(i); arr[i * 3 + 2] = (int)event.getY(i); } + final int pointer_idx = event.getPointerId(event.getActionIndex()); //System.out.printf("gaction: %d\n",event.getAction()); final int action = event.getAction() & MotionEvent.ACTION_MASK; @@ -861,13 +862,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC */ } break; case MotionEvent.ACTION_POINTER_UP: { - final int indexPointUp = event.getActionIndex(); - final int pointer_idx = event.getPointerId(indexPointUp); GodotLib.touch(4, pointer_idx, evcount, arr); //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); } break; case MotionEvent.ACTION_POINTER_DOWN: { - int pointer_idx = event.getActionIndex(); GodotLib.touch(3, pointer_idx, evcount, arr); //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx)); } break; diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java index a3fed28c6f..4701bac9df 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java +++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java index 9da705409b..3a94354843 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java +++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; import android.content.Context; diff --git a/platform/android/java/src/org/godotengine/godot/GodotIO.java b/platform/android/java/src/org/godotengine/godot/GodotIO.java index 2382288ca8..a95c508d21 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/src/org/godotengine/godot/GodotIO.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; import java.util.HashMap; import java.util.Locale; diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java index 9deb9dcb35..45eb188327 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; // Wrapper for native library diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index 7db0ef1b18..d72c590378 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; import android.app.Activity; @@ -66,7 +67,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase { public GodotPaymentV3(Activity p_activity) { - registerClass("GodotPayments", new String[] { "purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails" }); + registerClass("GodotPayments", new String[] { "purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails", "isConnected" }); activity = (Godot)p_activity; mPaymentManager = activity.getPaymentsManager(); mPaymentManager.setBaseSingleton(this); @@ -163,6 +164,19 @@ public class GodotPaymentV3 extends Godot.SingletonBase { GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[] { receipt, signature, sku }); } + public void callbackDisconnected() { + GodotLib.calldeferred(purchaseCallbackId, "iap_disconnected", new Object[]{}); + } + + public void callbackConnected() { + GodotLib.calldeferred(purchaseCallbackId, "iap_connected", new Object[]{}); + } + + // true if connected, false otherwise + public boolean isConnected() { + return mPaymentManager.isConnected(); + } + // consume item automatically after purchase. default is true. public void setAutoConsume(boolean autoConsume) { mPaymentManager.setAutoConsume(autoConsume); diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index db7daa1307..0222758c2b 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot; import android.content.Context; import android.graphics.PixelFormat; @@ -109,7 +110,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { @Override public boolean onTouchEvent(MotionEvent event) { - + super.onTouchEvent(event); return activity.gotTouchEvent(event); }; diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java index df62ac5a01..53fcf5ef70 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.input; import android.content.Context; import android.util.AttributeSet; diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java index eb3075fdfc..5d13f17ffb 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.input; import android.content.Context; import android.text.Editable; @@ -102,13 +103,16 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void onTextChanged(final CharSequence pCharSequence, final int start, final int before, final int count) { //Log.d(TAG, "onTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",before: " + before); + final int[] newChars = new int[count]; + for (int i = start; i < start + count; ++i) { + newChars[i - start] = pCharSequence.charAt(i); + } mView.queueEvent(new Runnable() { @Override public void run() { - for (int i = start; i < start + count; ++i) { - final int ch = pCharSequence.charAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + for (int i = 0; i < count; ++i) { + GodotLib.key(0, newChars[i], true); + GodotLib.key(0, newChars[i], false); } } }); diff --git a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java index f78e454d93..afe5f81b6d 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import com.android.vending.billing.IInAppBillingService; diff --git a/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java b/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java index 747eea5e5c..8b48193ae2 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import com.android.vending.billing.IInAppBillingService; diff --git a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java index b49244cf09..766989f953 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import org.json.JSONException; diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java index 05e634c13c..40cdeea72e 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import android.content.Context; diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java index 8086489897..441a311358 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import android.app.Activity; @@ -92,11 +93,21 @@ public class PaymentsManager { @Override public void onServiceDisconnected(ComponentName name) { mService = null; + + // At this stage, godotPaymentV3 might not have been initialized yet. + if (godotPaymentV3 != null) { + godotPaymentV3.callbackDisconnected(); + } } @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = IInAppBillingService.Stub.asInterface(service); + + // At this stage, godotPaymentV3 might not have been initialized yet. + if (godotPaymentV3 != null) { + godotPaymentV3.callbackConnected(); + } } }; @@ -122,6 +133,10 @@ public class PaymentsManager { .purchase(sku, transactionId); } + public boolean isConnected() { + return mService != null; + } + public void consumeUnconsumedPurchases() { new ReleaseAllConsumablesTask(mService, activity) { diff --git a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java b/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java index a31b6ed9f2..e1d9bcee65 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import org.json.JSONException; diff --git a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java index 6ab6673183..e00e37f9d1 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import java.util.ArrayList; diff --git a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java index c10008c4e1..1eb9d001e0 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.payments; import org.json.JSONException; diff --git a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/src/org/godotengine/godot/utils/Crypt.java index cdaf60bded..f34511137e 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java +++ b/platform/android/java/src/org/godotengine/godot/utils/Crypt.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.utils; import java.security.MessageDigest; diff --git a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java index 7bd8fb63b2..7216d8b5a4 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java +++ b/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.utils; import java.io.IOException; import java.net.Socket; diff --git a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java index ae1233674e..b84f5cce2e 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java +++ b/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.utils; import java.io.BufferedReader; diff --git a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java index 7df98fab85..2368766afa 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java +++ b/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + package org.godotengine.godot.utils; import java.util.ArrayList; diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 1d03c3671a..80a32452a5 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "java_class_wrapper.h" #include "thread_jandroid.h" diff --git a/platform/android/java_class_wrapper.h b/platform/android/java_class_wrapper.h index 4b374bc216..648c147ca8 100644 --- a/platform/android/java_class_wrapper.h +++ b/platform/android/java_class_wrapper.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef JAVA_CLASS_WRAPPER_H #define JAVA_CLASS_WRAPPER_H diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 25aee74c46..2d81d79bf1 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef ANDROID_NATIVE_ACTIVITY #include "java_glue.h" @@ -925,7 +926,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo } else { //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString); - if (strcmp(rawString, "-main_pack") == 0) + if (strcmp(rawString, "--main-pack") == 0) use_apk_expansion = true; } diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h index fb997e950b..d433b5f0d8 100644 --- a/platform/android/java_glue.h +++ b/platform/android/java_glue.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef ANDROID_NATIVE_ACTIVITY #ifndef JAVA_GLUE_H diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index dd23a81977..67ce796279 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "os_android.h" #include "core/io/file_access_buffered_fa.h" @@ -47,6 +48,8 @@ #include "file_access_jandroid.h" #endif +#include <dlfcn.h> + class AndroidLogger : public Logger { public: virtual void logv(const char *p_format, va_list p_list, bool p_err) { @@ -120,7 +123,7 @@ void OS_Android::set_opengl_extensions(const char *p_gl_extensions) { gl_extensions = p_gl_extensions; } -void OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { use_gl2 = p_video_driver != 1; @@ -146,6 +149,8 @@ void OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int input->set_fallback_mapping("Default Android Gamepad"); //power_manager = memnew(power_android); + + return OK; } void OS_Android::set_main_loop(MainLoop *p_main_loop) { @@ -170,6 +175,15 @@ void OS_Android::alert(const String &p_alert, const String &p_title) { alert_func(p_alert, p_title); } +Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { + p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW); + if (!p_library_handle) { + ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror()); + ERR_FAIL_V(ERR_CANT_OPEN); + } + return OK; +} + void OS_Android::set_mouse_show(bool p_show) { //android has no mouse... @@ -248,6 +262,9 @@ void OS_Android::set_cursor_shape(CursorShape p_shape) { //android really really really has no mouse.. how amazing.. } +void OS_Android::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +} + void OS_Android::main_loop_begin() { if (main_loop) @@ -438,25 +455,27 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> } touch.clear(); } - } break; - case 3: { // add tuchi - - ERR_FAIL_INDEX(p_pointer, p_points.size()); + case 3: { // add touch - TouchPos tp = p_points[p_pointer]; - touch.push_back(tp); + for (int i = 0; i < p_points.size(); i++) { + if (p_points[i].id == p_pointer) { + TouchPos tp = p_points[i]; + touch.push_back(tp); - Ref<InputEventScreenTouch> ev; - ev.instance(); + Ref<InputEventScreenTouch> ev; + ev.instance(); - ev->set_index(tp.id); - ev->set_pressed(true); - ev->set_position(tp.pos); - input->parse_input_event(ev); + ev->set_index(tp.id); + ev->set_pressed(true); + ev->set_position(tp.pos); + input->parse_input_event(ev); + break; + } + } } break; - case 4: { + case 4: { // remove touch for (int i = 0; i < touch.size(); i++) { if (touch[i].id == p_pointer) { @@ -468,10 +487,10 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> ev->set_position(touch[i].pos); input->parse_input_event(ev); touch.remove(i); - i--; + + break; } } - } break; } } diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 744dce7ff1..12181b3688 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_ANDROID_H #define OS_ANDROID_H @@ -145,7 +146,7 @@ public: 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 Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void set_main_loop(MainLoop *p_main_loop); virtual void delete_main_loop(); @@ -158,6 +159,8 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); + virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); virtual bool is_mouse_grab_enabled() const; @@ -182,6 +185,7 @@ public: virtual bool can_draw() const; virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); void main_loop_begin(); bool main_loop_iterate(); diff --git a/platform/android/platform_config.h b/platform/android/platform_config.h index 3b3ea3930c..299d8563dd 100644 --- a/platform/android/platform_config.h +++ b/platform/android/platform_config.h @@ -27,5 +27,6 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <alloca.h> #include <malloc.h> diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp index 29c4e7301c..e85813605f 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "thread_jandroid.h" #include "core/safe_refcount.h" diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h index 37b3b38408..2bb64f3db2 100644 --- a/platform/android/thread_jandroid.h +++ b/platform/android/thread_jandroid.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef THREAD_POSIX_H #define THREAD_POSIX_H diff --git a/platform/haiku/audio_driver_media_kit.cpp b/platform/haiku/audio_driver_media_kit.cpp index f687339fec..278a994c54 100644 --- a/platform/haiku/audio_driver_media_kit.cpp +++ b/platform/haiku/audio_driver_media_kit.cpp @@ -27,6 +27,7 @@ /* 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_media_kit.h" #ifdef MEDIA_KIT_ENABLED diff --git a/platform/haiku/audio_driver_media_kit.h b/platform/haiku/audio_driver_media_kit.h index 844ab4c60e..a09403e7d6 100644 --- a/platform/haiku/audio_driver_media_kit.h +++ b/platform/haiku/audio_driver_media_kit.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "servers/audio_server.h" #ifdef MEDIA_KIT_ENABLED diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp index 9332e93389..41df17d2d1 100644 --- a/platform/haiku/context_gl_haiku.cpp +++ b/platform/haiku/context_gl_haiku.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "context_gl_haiku.h" #if defined(OPENGL_ENABLED) diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h index 193c1e77f9..74f09984f2 100644 --- a/platform/haiku/context_gl_haiku.h +++ b/platform/haiku/context_gl_haiku.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef CONTEXT_GL_HAIKU_H #define CONTEXT_GL_HAIKU_H diff --git a/platform/haiku/godot_haiku.cpp b/platform/haiku/godot_haiku.cpp index d207d36606..b042d81650 100644 --- a/platform/haiku/godot_haiku.cpp +++ b/platform/haiku/godot_haiku.cpp @@ -27,6 +27,7 @@ /* 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_haiku.h" diff --git a/platform/haiku/haiku_application.cpp b/platform/haiku/haiku_application.cpp index d7fa505b79..4f5e3e42a2 100644 --- a/platform/haiku/haiku_application.cpp +++ b/platform/haiku/haiku_application.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "haiku_application.h" HaikuApplication::HaikuApplication() : diff --git a/platform/haiku/haiku_application.h b/platform/haiku/haiku_application.h index 4408f466fb..f92969bbb1 100644 --- a/platform/haiku/haiku_application.h +++ b/platform/haiku/haiku_application.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef HAIKU_APPLICATION_H #define HAIKU_APPLICATION_H diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index cf33e42220..b234a2ff91 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <UnicodeChar.h> #include "haiku_direct_window.h" diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index 0bdcb51ca1..55c2f5fccc 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef HAIKU_DIRECT_WINDOW_H #define HAIKU_DIRECT_WINDOW_H diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp index e47dc2f726..a40cbe5765 100644 --- a/platform/haiku/haiku_gl_view.cpp +++ b/platform/haiku/haiku_gl_view.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "haiku_gl_view.h" #include "main/main.h" diff --git a/platform/haiku/haiku_gl_view.h b/platform/haiku/haiku_gl_view.h index e67f3e6b0a..1a694dc13b 100644 --- a/platform/haiku/haiku_gl_view.h +++ b/platform/haiku/haiku_gl_view.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef HAIKU_GL_VIEW_H #define HAIKU_GL_VIEW_H diff --git a/platform/haiku/key_mapping_haiku.cpp b/platform/haiku/key_mapping_haiku.cpp index 62671b0cc3..28a282e25c 100644 --- a/platform/haiku/key_mapping_haiku.cpp +++ b/platform/haiku/key_mapping_haiku.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <InterfaceDefs.h> #include "key_mapping_haiku.h" diff --git a/platform/haiku/key_mapping_haiku.h b/platform/haiku/key_mapping_haiku.h index 5a1b9f9134..917151bc4a 100644 --- a/platform/haiku/key_mapping_haiku.h +++ b/platform/haiku/key_mapping_haiku.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef KEY_MAPPING_HAIKU_H #define KEY_MAPPING_HAIKU_H diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 3324b33e95..97fab5ca0d 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "os_haiku.h" #include "drivers/gles3/rasterizer_gles3.h" @@ -79,7 +80,7 @@ const char *OS_Haiku::get_video_driver_name(int p_driver) const { return "GLES3"; } -void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; current_video_mode = p_desired; @@ -114,7 +115,7 @@ void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_ visual_server = memnew(VisualServerRaster(rasterizer)); - ERR_FAIL_COND(!visual_server); + ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE); // TODO: enable multithreaded VS /* @@ -132,6 +133,8 @@ void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_ AudioDriverManager::initialize(p_audio_driver); power_manager = memnew(PowerHaiku); + + return OK; } void OS_Haiku::finalize() { @@ -200,6 +203,10 @@ void OS_Haiku::set_cursor_shape(CursorShape p_shape) { //ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED"); } +void OS_Haiku::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + // TODO +} + int OS_Haiku::get_screen_count() const { // TODO: implement get_screen_count() return 1; diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index b4d0add04b..615ae682ef 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_HAIKU_H #define OS_HAIKU_H @@ -66,7 +67,7 @@ protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); + virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); virtual void set_main_loop(MainLoop *p_main_loop); @@ -87,6 +88,7 @@ public: virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); virtual int get_screen_count() const; virtual int get_current_screen() const; diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h index 5a7bc3db23..bbd72dfeb6 100644 --- a/platform/haiku/platform_config.h +++ b/platform/haiku/platform_config.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <alloca.h> // for ifaddrs.h needed in drivers/unix/ip_unix.cpp diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h index 11656ca1f3..f14864b5b7 100644 --- a/platform/iphone/app_delegate.h +++ b/platform/iphone/app_delegate.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #import "gl_view.h" #import "view_controller.h" #import <UIKit/UIKit.h> diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 96f542c170..5c3799ab09 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #import "app_delegate.h" #include "core/project_settings.h" diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 99d44f3b5e..e3119814f4 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -407,7 +407,7 @@ Error EditorExportPlatformIOS::_export_loading_screens(const Ref<EditorExportPre Error err = da->copy(loading_screen_file, p_dest_dir + info.export_name); if (err) { memdelete(da); - String err_str = String("Failed to export loading screen: ") + loading_screen_file; + String err_str = String("Failed to export loading screen (") + info.preset_key + ") from path: " + loading_screen_file; ERR_PRINT(err_str.utf8().get_data()); return err; } diff --git a/platform/iphone/export/export.h b/platform/iphone/export/export.h index f67c34a626..ea79973290 100644 --- a/platform/iphone/export/export.h +++ b/platform/iphone/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_iphone_exporter(); diff --git a/platform/iphone/game_center.h b/platform/iphone/game_center.h index bf7ec1f93e..9a62cccb1a 100644 --- a/platform/iphone/game_center.h +++ b/platform/iphone/game_center.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef GAME_CENTER_ENABLED #ifndef GAME_CENTER_H diff --git a/platform/iphone/game_center.mm b/platform/iphone/game_center.mm index 958158c254..57ff79f7bc 100644 --- a/platform/iphone/game_center.mm +++ b/platform/iphone/game_center.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef GAME_CENTER_ENABLED #include "game_center.h" diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index f0dafacd03..69116c64c6 100644 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #import "gl_view.h" #include "core/os/keyboard.h" diff --git a/platform/iphone/globals/global_defaults.cpp b/platform/iphone/globals/global_defaults.cpp index 97a7ec1678..ccc90665c5 100644 --- a/platform/iphone/globals/global_defaults.cpp +++ b/platform/iphone/globals/global_defaults.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "global_defaults.h" #include "project_settings.h" diff --git a/platform/iphone/globals/global_defaults.h b/platform/iphone/globals/global_defaults.h index f58659ebff..3e3c220f4a 100644 --- a/platform/iphone/globals/global_defaults.h +++ b/platform/iphone/globals/global_defaults.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_iphone_global_defaults(); diff --git a/platform/iphone/godot_iphone.cpp b/platform/iphone/godot_iphone.cpp index 440dae5da5..dacbf42087 100644 --- a/platform/iphone/godot_iphone.cpp +++ b/platform/iphone/godot_iphone.cpp @@ -27,6 +27,7 @@ /* 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_iphone.h" #include "ustring.h" diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h index d2514919ba..52bb1131a0 100644 --- a/platform/iphone/icloud.h +++ b/platform/iphone/icloud.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef ICLOUD_ENABLED #ifndef ICLOUD_H diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm index db4d86b812..7508a480ce 100644 --- a/platform/iphone/icloud.mm +++ b/platform/iphone/icloud.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef ICLOUD_ENABLED #include "icloud.h" diff --git a/platform/iphone/in_app_store.h b/platform/iphone/in_app_store.h index 28f23d77e1..7d53eaae20 100644 --- a/platform/iphone/in_app_store.h +++ b/platform/iphone/in_app_store.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef STOREKIT_ENABLED #ifndef IN_APP_STORE_H diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm index 3399a64732..9bb3d7d3fa 100644 --- a/platform/iphone/in_app_store.mm +++ b/platform/iphone/in_app_store.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef STOREKIT_ENABLED #include "in_app_store.h" diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h index aca0ac54a9..5e77683949 100644 --- a/platform/iphone/ios.h +++ b/platform/iphone/ios.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef IOS_H #define IOS_H diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm index 48104b9c4f..7eb4f495f7 100644 --- a/platform/iphone/ios.mm +++ b/platform/iphone/ios.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "ios.h" #import <UIKit/UIKit.h> diff --git a/platform/iphone/main.m b/platform/iphone/main.m index dfe468dc13..0f0810f28f 100644 --- a/platform/iphone/main.m +++ b/platform/iphone/main.m @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #import "app_delegate.h" #import <UIKit/UIKit.h> diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index dcb7b8b1f4..c284ab6905 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef IPHONE_ENABLED #include "os_iphone.h" @@ -97,7 +98,7 @@ void OSIPhone::initialize_core() { set_data_dir(data_dir); }; -void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { supported_orientations = 0; supported_orientations |= ((GLOBAL_DEF("video_mode/allow_horizontal", true) ? 1 : 0) << LandscapeLeft); @@ -144,6 +145,8 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_ //icloud->connect(); #endif Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", memnew(iOS))); + + return OK; }; MainLoop *OSIPhone::get_main_loop() const { @@ -490,6 +493,8 @@ String OSIPhone::get_user_data_dir() const { return data_dir; }; +void OSIPhone::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot){}; + String OSIPhone::get_name() { return "iOS"; diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 7e310e3a03..2e4458aeed 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef IPHONE_ENABLED #ifndef OS_IPHONE_H @@ -87,7 +88,7 @@ private: virtual const char *get_video_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 Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void set_main_loop(MainLoop *p_main_loop); virtual MainLoop *get_main_loop() const; @@ -173,6 +174,7 @@ public: virtual int get_virtual_keyboard_height() const; virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); virtual Size2 get_window_size() const; diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h index 373c70d822..d205c7da83 100644 --- a/platform/iphone/platform_config.h +++ b/platform/iphone/platform_config.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <alloca.h> #define GLES3_INCLUDE_H <ES3/gl.h> diff --git a/platform/iphone/platform_refcount.h b/platform/iphone/platform_refcount.h index 90e716e4e4..94e4e5fa3b 100644 --- a/platform/iphone/platform_refcount.h +++ b/platform/iphone/platform_refcount.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "safe_refcount.h" #ifdef IPHONE_ENABLED diff --git a/platform/iphone/sem_iphone.cpp b/platform/iphone/sem_iphone.cpp index 04eb6e9332..ec1337d63f 100644 --- a/platform/iphone/sem_iphone.cpp +++ b/platform/iphone/sem_iphone.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "sem_iphone.h" #include <fcntl.h> diff --git a/platform/iphone/sem_iphone.h b/platform/iphone/sem_iphone.h index 8311538419..ebd4e4ee43 100644 --- a/platform/iphone/sem_iphone.h +++ b/platform/iphone/sem_iphone.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef SEM_IPHONE_H #define SEM_IPHONE_H diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h index cd08be3aa7..31c4f0daf3 100644 --- a/platform/iphone/view_controller.h +++ b/platform/iphone/view_controller.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #import <GameKit/GameKit.h> #import <UIKit/UIKit.h> diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index f6487ea6c8..cdaae0cb81 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #import "view_controller.h" #include "os_iphone.h" diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index 05992ebac8..66a8a8d93c 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -23,6 +23,7 @@ env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_main_after_fs_sync' target_dir = env.Dir("#bin") build = env.add_program(['#bin/godot', target_dir.File('godot' + env['PROGSUFFIX'] + '.wasm')], javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js'); +js, wasm = build js_libraries = [] js_libraries.append(env.File('http_request.js')) @@ -30,12 +31,10 @@ for lib in js_libraries: env.Append(LINKFLAGS=['--js-library', lib.path]) env.Depends(build, js_libraries) -prejs = env.File('pre.js') -postjs = env.File('engine.js') -env.Append(LINKFLAGS=['--pre-js', prejs.path]) -env.Append(LINKFLAGS=['--post-js', postjs.path]) -env.Depends(build, [prejs, postjs]) +wrapper_start = env.File('pre.js') +wrapper_end = env.File('engine.js') +js_final = env.Textfile('#bin/godot', [wrapper_start, js, wrapper_end], TEXTFILESUFFIX=env['PROGSUFFIX'] + '.wrapped.js') zip_dir = target_dir.Dir('.javascript_zip') -zip_files = env.InstallAs([zip_dir.File('godot.js'), zip_dir.File('godot.wasm'), zip_dir.File('godot.html')], build + ['#misc/dist/html/default.html']) +zip_files = env.InstallAs([zip_dir.File('godot.js'), zip_dir.File('godot.wasm'), zip_dir.File('godot.html')], [js_final, wasm, '#misc/dist/html/default.html']) Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX'] + env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET") diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp index fe3b20b7a0..b377ca4e52 100644 --- a/platform/javascript/api/api.cpp +++ b/platform/javascript/api/api.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "api.h" #include "engine.h" #include "javascript_eval.h" diff --git a/platform/javascript/api/api.h b/platform/javascript/api/api.h index ab3e47ec31..5f22f082e9 100644 --- a/platform/javascript/api/api.h +++ b/platform/javascript/api/api.h @@ -27,5 +27,6 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_javascript_api(); void unregister_javascript_api(); diff --git a/platform/javascript/api/javascript_eval.h b/platform/javascript/api/javascript_eval.h index d39d97f7c5..05f7c9f38a 100644 --- a/platform/javascript/api/javascript_eval.h +++ b/platform/javascript/api/javascript_eval.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef JAVASCRIPT_EVAL_H #define JAVASCRIPT_EVAL_H diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp index acf6ef87ba..5bf345e6cd 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -27,6 +27,7 @@ /* 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_javascript.h" #include <emscripten.h> diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index d44e2c51e6..d78ab8eea4 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef AUDIO_DRIVER_JAVASCRIPT_H #define AUDIO_DRIVER_JAVASCRIPT_H diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 8472c3ccab..7e6a1518ed 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -28,6 +28,11 @@ def get_flags(): return [ ('tools', False), ('module_theora_enabled', False), + # Disabling the mbedtls module reduces file size. + # The module has little use due to the limited networking functionality + # in this platform. For the available networking methods, the browser + # manages TLS. + ('module_mbedtls_enabled', False), ] @@ -49,8 +54,14 @@ def configure(env): ## Build type if (env["target"] == "release"): - env.Append(CCFLAGS=['-O3']) - env.Append(LINKFLAGS=['-O3']) + # Use -Os to prioritize optimizing for reduced file size. This is + # particularly valuable for the web platform because it directly + # decreases download time. + # -Os reduces file size by around 5 MiB over -O3. -Oz only saves about + # 100 KiB over -Os, which does not justify the negative impact on + # run-time performance. + env.Append(CCFLAGS=['-Os']) + env.Append(LINKFLAGS=['-Os']) elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) diff --git a/platform/javascript/dom_keys.h b/platform/javascript/dom_keys.h index cfd55dfc90..4edca63c6d 100644 --- a/platform/javascript/dom_keys.h +++ b/platform/javascript/dom_keys.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef DOM_KEYS_H #define DOM_KEYS_H diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index dc4bdc7efb..bca1851f40 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -138,13 +138,17 @@ } var actualCanvas = this.rtenv.canvas; - var context = false; + var testContext = false; + var testCanvas; try { - context = actualCanvas.getContext('webgl2') || actualCanvas.getContext('experimental-webgl2'); + testCanvas = document.createElement('canvas'); + testContext = testCanvas.getContext('webgl2') || testCanvas.getContext('experimental-webgl2'); } catch (e) {} - if (!context) { + if (!testContext) { throw new Error("WebGL 2 not available"); } + testCanvas = null; + testContext = null; // canvas can grab focus on click if (actualCanvas.tabIndex < 0) { diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 6c2b6799a6..d81aa25c32 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "editor/editor_node.h" #include "editor_export.h" #include "io/zip_io.h" @@ -70,7 +71,7 @@ public: virtual void get_platform_features(List<String> *r_features) { r_features->push_back("web"); - r_features->push_back("JavaScript"); + r_features->push_back(get_os_name()); } EditorExportPlatformJavaScript(); @@ -113,9 +114,9 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) { - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); + 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"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_GLOBAL_FILE, "html"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); @@ -129,7 +130,7 @@ String EditorExportPlatformJavaScript::get_name() const { String EditorExportPlatformJavaScript::get_os_name() const { - return "JavaScript"; + return "HTML5"; } Ref<Texture> EditorExportPlatformJavaScript::get_logo() const { @@ -174,14 +175,14 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese } if (template_path != String() && !FileAccess::exists(template_path)) { - EditorNode::get_singleton()->show_warning(TTR("Template file not found:\n") + template_path); + EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path); return ERR_FILE_NOT_FOUND; } String pck_path = p_path.get_basename() + ".pck"; Error error = save_pack(p_preset, pck_path); if (error != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + pck_path); + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path); return error; } @@ -191,12 +192,12 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese if (!pkg) { - EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:\n") + template_path); + EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:") + "\n" + template_path); return ERR_FILE_NOT_FOUND; } if (unzGoToFirstFile(pkg) != UNZ_OK) { - EditorNode::get_singleton()->show_warning(TTR("Invalid export template:\n") + template_path); + EditorNode::get_singleton()->show_warning(TTR("Invalid export template:") + "\n" + template_path); unzClose(pkg); return ERR_FILE_CORRUPT; } @@ -238,7 +239,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese String dst = p_path.get_base_dir().plus_file(file); FileAccess *f = FileAccess::open(dst, FileAccess::WRITE); if (!f) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + dst); + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + dst); unzClose(pkg); return ERR_FILE_CANT_WRITE; } @@ -252,7 +253,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese FileAccess *f = FileAccess::open(custom_html, FileAccess::READ); if (!f) { - EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:\n") + custom_html); + EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:") + "\n" + custom_html); return ERR_FILE_CANT_READ; } Vector<uint8_t> buf; @@ -263,7 +264,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese f = FileAccess::open(p_path, FileAccess::WRITE); if (!f) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + p_path); + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + p_path); return ERR_FILE_CANT_WRITE; } f->store_buffer(buf.ptr(), buf.size()); @@ -277,7 +278,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese splash.instance(); Error err = splash->load(splash_path); if (err) { - EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:\n") + splash_path + "\nUsing default boot splash image"); + EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:") + "\n" + splash_path + "\n" + TTR("Using default boot splash image.")); splash.unref(); } } @@ -286,7 +287,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese } String png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png"); if (splash->save_png(png_path) != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + png_path); + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + png_path); return ERR_FILE_CANT_WRITE; } return OK; diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h index 756c3ef9fa..2835d0723f 100644 --- a/platform/javascript/export/export.h +++ b/platform/javascript/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_javascript_exporter(); diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index f23867cc60..1cd2719723 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -3,7 +3,7 @@ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ -/* http://www.godotengine.org */ +/* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "http_request.h" #include "io/http_client.h" diff --git a/platform/javascript/http_request.h b/platform/javascript/http_request.h index 2ca48bfd00..b5ff46d7fe 100644 --- a/platform/javascript/http_request.h +++ b/platform/javascript/http_request.h @@ -3,7 +3,7 @@ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ -/* http://www.godotengine.org */ +/* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef HTTP_REQUEST_H #define HTTP_REQUEST_H diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp index 9abea29a93..2ef88345f6 100644 --- a/platform/javascript/javascript_eval.cpp +++ b/platform/javascript/javascript_eval.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef JAVASCRIPT_EVAL_ENABLED #include "api/javascript_eval.h" diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index 973f8f500c..e85fe0800f 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "emscripten.h" #include "io/resource_loader.h" #include "main/main.h" @@ -64,7 +65,7 @@ int main(int argc, char *argv[]) { FS.mkdir('/userfs'); FS.mount(IDBFS, {}, '/userfs'); FS.syncfs(true, function(err) { - Module['ccall']('main_after_fs_sync', null, ['string'], [err ? err.message : ""]) + ccall('main_after_fs_sync', null, ['string'], [err ? err.message : ""]) }); ); /* clang-format on */ diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 0bdd090ba9..e226ab6332 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "os_javascript.h" #include "core/engine.h" @@ -80,12 +81,6 @@ void OS_JavaScript::initialize_core() { FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES); } -void OS_JavaScript::set_opengl_extensions(const char *p_gl_extensions) { - - ERR_FAIL_COND(!p_gl_extensions); - gl_extensions = p_gl_extensions; -} - static EM_BOOL _browser_resize_callback(int event_type, const EmscriptenUiEvent *ui_event, void *user_data) { ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_RESIZE, false); @@ -419,7 +414,7 @@ void send_notification(int notif) { } } -void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { print_line("Init OS"); @@ -429,22 +424,17 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i attributes.antialias = false; attributes.majorVersion = 2; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes); - ERR_FAIL_COND(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS); + ERR_FAIL_COND_V(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE); video_mode = p_desired; // can't fulfil fullscreen request due to browser security video_mode.fullscreen = false; /* clang-format off */ - bool resize_canvas_on_start = EM_ASM_INT_V( - return Module.resizeCanvasOnStart; - ); - /* clang-format on */ - if (resize_canvas_on_start) { + if (EM_ASM_INT_V({ return Module.resizeCanvasOnStart })) { + /* clang-format on */ set_window_size(Size2(video_mode.width, video_mode.height)); } else { - Size2 canvas_size = get_window_size(); - video_mode.width = canvas_size.width; - video_mode.height = canvas_size.height; + set_window_size(get_window_size()); } char locale_ptr[16]; @@ -507,6 +497,8 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i #undef EM_CHECK visual_server->init(); + + return OK; } void OS_JavaScript::set_main_loop(MainLoop *p_main_loop) { @@ -563,7 +555,7 @@ void OS_JavaScript::set_css_cursor(const char *p_cursor) { /* clang-format off */ EM_ASM_({ - Module.canvas.style.cursor = Module.UTF8ToString($0); + Module.canvas.style.cursor = UTF8ToString($0); }, p_cursor); /* clang-format on */ } @@ -573,7 +565,7 @@ const char *OS_JavaScript::get_css_cursor() const { char cursor[16]; /* clang-format off */ EM_ASM_INT({ - Module.stringToUTF8(Module.canvas.style.cursor ? Module.canvas.style.cursor : 'auto', $0, 16); + stringToUTF8(Module.canvas.style.cursor ? Module.canvas.style.cursor : 'auto', $0, 16); }, cursor); /* clang-format on */ return cursor; @@ -779,6 +771,9 @@ void OS_JavaScript::set_cursor_shape(CursorShape p_shape) { set_css_cursor(godot2dom_cursor(cursor_shape)); } +void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +} + void OS_JavaScript::main_loop_begin() { if (main_loop) @@ -786,7 +781,7 @@ void OS_JavaScript::main_loop_begin() { /* clang-format off */ EM_ASM_ARGS({ - const send_notification = Module.cwrap('send_notification', null, ['number']); + const send_notification = cwrap('send_notification', null, ['number']); const notifs = arguments; (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) { Module.canvas.addEventListener(event, send_notification.bind(null, notifs[i])); @@ -969,7 +964,25 @@ int OS_JavaScript::get_power_percent_left() { bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) { - return p_feature == "web" || p_feature == "s3tc"; // TODO check for these features really being available + if (p_feature == "HTML5" || p_feature == "web") + return true; + +#ifdef JAVASCRIPT_EVAL_ENABLED + if (p_feature == "JavaScript") + return true; +#endif + + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_get_current_context(); + // all extensions are already automatically enabled, this function allows + // checking WebGL extension support without inline JavaScript + if (p_feature == "s3tc" && emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_s3tc_srgb")) + return true; + if (p_feature == "etc" && emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc1")) + return true; + if (p_feature == "etc2" && emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc")) + return true; + + return false; } void OS_JavaScript::set_idbfs_available(bool p_idbfs_available) { @@ -983,9 +996,9 @@ bool OS_JavaScript::is_userfs_persistent() const { } OS_JavaScript::OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_user_data_dir_func) { + set_cmdline(p_execpath, get_cmdline_args()); main_loop = NULL; - gl_extensions = NULL; window_maximized = false; soft_fs_enabled = false; canvas_size_adjustment_requested = false; @@ -995,6 +1008,10 @@ OS_JavaScript::OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_us idbfs_available = false; time_to_save_sync = -1; + + Vector<Logger *> loggers; + loggers.push_back(memnew(StdLogger)); + _set_logger(memnew(CompositeLogger(loggers))); } OS_JavaScript::~OS_JavaScript() { diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 8acaac9ef3..f0ba9422e8 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_JAVASCRIPT_H #define OS_JAVASCRIPT_H @@ -51,7 +52,6 @@ class OS_JavaScript : public OS_Unix { VisualServer *visual_server; AudioDriverJavaScript audio_driver_javascript; - const char *gl_extensions; InputDefault *input; Vector2 windowed_size; @@ -82,7 +82,7 @@ public: 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 Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void set_main_loop(MainLoop *p_main_loop); virtual void delete_main_loop(); @@ -127,6 +127,7 @@ public: virtual bool is_userfs_persistent() const; virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); void main_loop_begin(); bool main_loop_iterate(); @@ -137,8 +138,6 @@ public: virtual bool has_touchscreen_ui_hint() const; - void set_opengl_extensions(const char *p_gl_extensions); - virtual Error shell_open(String p_uri); virtual String get_user_data_dir() const; String get_executable_path() const; diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h index 413fea20d8..af4cf07393 100644 --- a/platform/javascript/platform_config.h +++ b/platform/javascript/platform_config.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <alloca.h> diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 029e3d808c..5efe2d0b22 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -10,6 +10,7 @@ def make_debug(target, source, env): os.system(mpprefix + '/libexec/llvm-' + mpclangver + '/bin/llvm-dsymutil %s -o %s.dSYM' % (target[0], target[0])) else: os.system('dsymutil %s -o %s.dSYM' % (target[0], target[0])) + os.system('strip -u -r %s' % (target[0])) files = [ 'crash_handler_osx.mm', @@ -23,6 +24,6 @@ files = [ prog = env.add_program('#bin/godot', files) -if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": +if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: env.AddPostAction(prog, make_debug) diff --git a/platform/osx/crash_handler_osx.h b/platform/osx/crash_handler_osx.h index 51e0a3ffcb..5d93afb22d 100644 --- a/platform/osx/crash_handler_osx.h +++ b/platform/osx/crash_handler_osx.h @@ -27,6 +27,7 @@ /* 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 diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index c4b5204e1a..d757674a9b 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -27,6 +27,7 @@ /* 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 "project_settings.h" diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 2e686fbee4..5f33100e42 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -19,11 +19,12 @@ def can_build(): def get_opts(): - from SCons.Variables import EnumVariable + from SCons.Variables import BoolVariable, EnumVariable return [ ('osxcross_sdk', 'OSXCross SDK version', 'darwin14'), EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')), + BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False), ] @@ -76,7 +77,7 @@ def configure(env): mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local") mpclangver = env["macports_clang"] env["CC"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang" - env["LD"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" + env["LINK"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" env["CXX"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++" env['AR'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar" env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib" @@ -110,7 +111,7 @@ def configure(env): if (env["CXX"] == "clang++"): env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) env["CC"] = "clang" - env["LD"] = "clang++" + env["LINK"] = "clang++" ## Dependencies diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h index eec3016eaa..e01ff2fe4d 100644 --- a/platform/osx/dir_access_osx.h +++ b/platform/osx/dir_access_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef DIR_ACCESS_OSX_H #define DIR_ACCESS_OSX_H diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm index a187083dd1..cf66cab060 100644 --- a/platform/osx/dir_access_osx.mm +++ b/platform/osx/dir_access_osx.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "dir_access_osx.h" #if defined(UNIX_ENABLED) || defined(LIBC_FILEIO_ENABLED) diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 657a899367..c4efa1f0ff 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -359,6 +359,11 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } if (err == OK) { + print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks"); + err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks"); + } + + if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/Resources"); err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources"); } @@ -502,10 +507,23 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (use_dmg()) { String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck"; - err = save_pack(p_preset, pack_path); + Vector<SharedObject> shared_objects; + Error err = save_pack(p_preset, pack_path, &shared_objects); // see if we can code sign our new package String identity = p_preset->get("codesign/identity"); + + if (err == OK) { + DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + for (int i = 0; i < shared_objects.size(); i++) { + da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); + if (err == OK && identity != "") { + err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file()); + } + } + memdelete(da); + } + if (err == OK && identity != "") { ep.step("Code signing bundle", 2); @@ -541,7 +559,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } else { String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck"); - Error err = save_pack(p_preset, pack_path); + + Vector<SharedObject> shared_objects; + Error err = save_pack(p_preset, pack_path, &shared_objects); if (err == OK) { zipOpenNewFileInZip(dst_pkg_zip, @@ -567,11 +587,32 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p break; zipWriteInFileInZip(dst_pkg_zip, buf, r); } + zipCloseFileInZip(dst_pkg_zip); memdelete(pf); } else { err = ERR_CANT_OPEN; } + + //add shared objects + for (int i = 0; i < shared_objects.size(); i++) { + Vector<uint8_t> file = FileAccess::get_file_as_array(shared_objects[i].path); + ERR_CONTINUE(file.empty()); + + zipOpenNewFileInZip(dst_pkg_zip, + (pkg_name + ".app/Contents/Frameworks/").plus_file(shared_objects[i].path.get_file()).utf8().get_data(), + NULL, + NULL, + 0, + NULL, + 0, + NULL, + Z_DEFLATED, + Z_DEFAULT_COMPRESSION); + + zipWriteInFileInZip(dst_pkg_zip, file.ptr(), file.size()); + zipCloseFileInZip(dst_pkg_zip); + } } } } diff --git a/platform/osx/export/export.h b/platform/osx/export/export.h index ccb96022f9..08294fc33c 100644 --- a/platform/osx/export/export.h +++ b/platform/osx/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_osx_exporter(); diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 156b4c02f2..6ccbaf896b 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -27,6 +27,7 @@ /* 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" @@ -81,8 +82,17 @@ int main(int argc, char **argv) { #endif OS_OSX os; + Error err; + + if (os.open_with_filename != "") { + char *argv_c = (char *)malloc(os.open_with_filename.utf8().size()); + memcpy(argv_c, os.open_with_filename.utf8().get_data(), os.open_with_filename.utf8().size()); + err = Main::setup(argv[0], 1, &argv_c); + free(argv_c); + } else { + err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]); + } - Error err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]); if (err != OK) return 255; diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index bc65aa8149..20ceadca9d 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "joypad_osx.h" #include <machine/endian.h> diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index 78ee4581d5..addbefc5ad 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef JOYPADOSX_H #define JOYPADOSX_H diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index a24bf6c0bc..aa8db8f300 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_OSX_H #define OS_OSX_H @@ -41,6 +42,7 @@ #include "servers/visual/rasterizer.h" #include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual_server.h" +#include <AppKit/NSCursor.h> #include <ApplicationServices/ApplicationServices.h> #undef CursorShape @@ -50,6 +52,17 @@ class OS_OSX : public OS_Unix { public: + struct KeyEvent { + unsigned int osx_state; + bool pressed; + bool echo; + uint32_t scancode; + uint32_t unicode; + }; + + Vector<KeyEvent> key_event_buffer; + int key_event_pos; + bool force_quit; // rasterizer seems to no longer be given to visual server, its using GLES3 directly? //Rasterizer *rasterizer; @@ -70,6 +83,7 @@ public: CGEventSourceRef eventSource; void process_events(); + void process_key_events(); void *framework; // pthread_key_t current; @@ -86,6 +100,7 @@ public: id context; CursorShape cursor_shape; + NSCursor *cursors[CURSOR_MAX] = { NULL }; MouseMode mouse_mode; String title; @@ -96,6 +111,8 @@ public: Size2 window_size; Rect2 restore_rect; + String open_with_filename; + Point2 im_position; ImeCallback im_callback; void *im_target; @@ -121,7 +138,7 @@ protected: virtual const char *get_video_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 Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); virtual void set_main_loop(MainLoop *p_main_loop); @@ -136,7 +153,10 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); + virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); @@ -147,6 +167,7 @@ public: virtual void set_window_title(const String &p_title); virtual Size2 get_window_size() const; + virtual Size2 get_real_window_size() const; virtual void set_icon(const Ref<Image> &p_icon); @@ -201,6 +222,8 @@ public: virtual bool is_window_minimized() const; virtual void set_window_maximized(bool p_enabled); virtual bool is_window_maximized() const; + virtual void set_window_always_on_top(bool p_enabled); + virtual bool is_window_always_on_top() const; virtual void request_attention(); virtual String get_joy_guid(int p_device) const; @@ -209,6 +232,8 @@ public: virtual void set_ime_position(const Point2 &p_pos); virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp); + virtual String get_unique_id() const; + virtual OS::PowerState get_power_state(); virtual int get_power_seconds_left(); virtual int get_power_percent_left(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 0cd02663da..4c459772aa 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "os_osx.h" #include "dir_access_osx.h" @@ -38,6 +39,8 @@ #include "servers/visual/visual_server_raster.h" #include "version_generated.gen.h" +#include <mach-o/dyld.h> + #include <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> #include <IOKit/IOCFPlugIn.h> @@ -48,6 +51,7 @@ #include <os/log.h> #endif +#include <dlfcn.h> #include <fcntl.h> #include <libproc.h> #include <stdio.h> @@ -57,25 +61,40 @@ #include <unistd.h> #if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 +#define NSEventMaskAny NSAnyEventMask +#define NSEventTypeKeyDown NSKeyDown +#define NSEventTypeKeyUp NSKeyUp +#define NSEventModifierFlagShift NSShiftKeyMask +#define NSEventModifierFlagCommand NSCommandKeyMask +#define NSEventModifierFlagControl NSControlKeyMask +#define NSEventModifierFlagOption NSAlternateKeyMask +#define NSWindowStyleMaskTitled NSTitledWindowMask +#define NSWindowStyleMaskResizable NSResizableWindowMask +#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask +#define NSWindowStyleMaskClosable NSClosableWindowMask #define NSWindowStyleMaskBorderless NSBorderlessWindowMask #endif static NSRect convertRectToBacking(NSRect contentRect) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - return [OS_OSX::singleton->window_view convertRectToBacking:contentRect]; - else -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - return contentRect; + return [OS_OSX::singleton->window_view convertRectToBacking:contentRect]; } static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> state) { - state->set_shift((p_osx_state & NSShiftKeyMask)); - state->set_control((p_osx_state & NSControlKeyMask)); - state->set_alt((p_osx_state & NSAlternateKeyMask)); - state->set_metakey((p_osx_state & NSCommandKeyMask)); + state->set_shift((p_osx_state & NSEventModifierFlagShift)); + state->set_control((p_osx_state & NSEventModifierFlagControl)); + state->set_alt((p_osx_state & NSEventModifierFlagOption)); + state->set_metakey((p_osx_state & NSEventModifierFlagCommand)); +} + +static void push_to_key_event_buffer(const OS_OSX::KeyEvent &p_event) { + + Vector<OS_OSX::KeyEvent> &buffer = OS_OSX::singleton->key_event_buffer; + if (OS_OSX::singleton->key_event_pos >= buffer.size()) { + buffer.resize(1 + OS_OSX::singleton->key_event_pos); + } + buffer[OS_OSX::singleton->key_event_pos++] = p_event; } static int mouse_x = 0; @@ -99,11 +118,29 @@ static Vector2 get_mouse_pos(NSEvent *event) { @implementation GodotApplication -// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost -// This works around an AppKit bug, where key up events while holding -// down the command key don't get sent to the key window. - (void)sendEvent:(NSEvent *)event { - if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) + + // special case handling of command-period, which is traditionally a special + // shortcut in macOS and doesn't arrive at our regular keyDown handler. + if ([event type] == NSEventTypeKeyDown) { + if (([event modifierFlags] & NSEventModifierFlagCommand) && [event keyCode] == 0x2f) { + + Ref<InputEventKey> k; + k.instance(); + + get_key_modifier_state([event modifierFlags], k); + k->set_pressed(true); + k->set_scancode(KEY_PERIOD); + k->set_echo([event isARepeat]); + + OS_OSX::singleton->push_input(k); + } + } + + // From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost + // This works around an AppKit bug, where key up events while holding + // down the command key don't get sent to the key window. + if ([event type] == NSEventTypeKeyUp && ([event modifierFlags] & NSEventModifierFlagCommand)) [[self keyWindow] sendEvent:event]; else [super sendEvent:event]; @@ -116,6 +153,13 @@ static Vector2 get_mouse_pos(NSEvent *event) { @implementation GodotApplicationDelegate +- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename { + // Note: called before main loop init! + char *utfs = strdup([filename UTF8String]); + OS_OSX::singleton->open_with_filename.parse_utf8(utfs); + return YES; +} + - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); @@ -169,7 +213,6 @@ static Vector2 get_mouse_pos(NSEvent *event) { return NO; } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - (void)windowDidEnterFullScreen:(NSNotification *)notification { OS_OSX::singleton->zoomed = true; } @@ -177,7 +220,6 @@ static Vector2 get_mouse_pos(NSEvent *event) { - (void)windowDidExitFullScreen:(NSNotification *)notification { OS_OSX::singleton->zoomed = false; } -#endif // MAC_OS_X_VERSION_MAX_ALLOWED - (void)windowDidChangeBackingProperties:(NSNotification *)notification { if (!OS_OSX::singleton) @@ -371,8 +413,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)cancelComposition { [self unmarkText]; - NSInputManager *currentInputManager = [NSInputManager currentInputManager]; - [currentInputManager markedTextAbandoned:self]; + NSTextInputContext *currentInputContext = [NSTextInputContext currentInputContext]; + [currentInputContext discardMarkedText]; } - (void)insertText:(id)aString { @@ -381,13 +423,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (void)insertText:(id)aString replacementRange:(NSRange)replacementRange { NSEvent *event = [NSApp currentEvent]; - Ref<InputEventKey> k; - k.instance(); - - get_key_modifier_state([event modifierFlags], k); - k->set_pressed(true); - k->set_echo(false); - k->set_scancode(0); NSString *characters; if ([aString isKindOfClass:[NSAttributedString class]]) { @@ -401,8 +436,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet]; NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet]; if ([characters rangeOfCharacterFromSet:ctrlChars].length && [characters rangeOfCharacterFromSet:wsnlChars].length == 0) { - NSInputManager *currentInputManager = [NSInputManager currentInputManager]; - [currentInputManager markedTextAbandoned:self]; + NSTextInputContext *currentInputContext = [NSTextInputContext currentInputContext]; + [currentInputContext discardMarkedText]; [self cancelComposition]; return; } @@ -412,8 +447,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; if ((codepoint & 0xFF00) == 0xF700) continue; - k->set_unicode(codepoint); - OS_OSX::singleton->push_input(k); + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = false; + ke.scancode = 0; + ke.unicode = codepoint; + + push_to_key_event_buffer(ke); } [self cancelComposition]; } @@ -488,7 +530,7 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { } - (void)mouseDown:(NSEvent *)event { - if (([event modifierFlags] & NSControlKeyMask)) { + if (([event modifierFlags] & NSEventModifierFlagControl)) { mouse_down_control = true; _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, true); } else { @@ -577,8 +619,11 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { return; if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED) OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER); - if (OS_OSX::singleton->input) + if (OS_OSX::singleton->input) { OS_OSX::singleton->input->set_mouse_in_window(true); + OS_OSX::singleton->cursor_shape = OS::CURSOR_MAX; + OS_OSX::singleton->set_cursor_shape(OS::CURSOR_ARROW); + } } - (void)magnifyWithEvent:(NSEvent *)event { @@ -759,80 +804,87 @@ static int translateKey(unsigned int key) { - (void)keyDown:(NSEvent *)event { - Ref<InputEventKey> k; - k.instance(); - - get_key_modifier_state([event modifierFlags], k); - k->set_pressed(true); - k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode]))); - k->set_echo([event isARepeat]); + //disable raw input in IME mode + if (!imeMode) { + OS_OSX::KeyEvent ke; - NSString *characters = [event characters]; - NSUInteger i, length = [characters length]; + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.unicode = 0; - //disable raw input in IME mode - if (!imeMode) - OS_OSX::singleton->push_input(k); + push_to_key_event_buffer(ke); + } if ((OS_OSX::singleton->im_position.x != 0) && (OS_OSX::singleton->im_position.y != 0)) [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } - (void)flagsChanged:(NSEvent *)event { - Ref<InputEventKey> k; - k.instance(); - int key = [event keyCode]; - int mod = [event modifierFlags]; + if (!imeMode) { + OS_OSX::KeyEvent ke; - if (key == 0x36 || key == 0x37) { - if (mod & NSCommandKeyMask) { - mod &= ~NSCommandKeyMask; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x38 || key == 0x3c) { - if (mod & NSShiftKeyMask) { - mod &= ~NSShiftKeyMask; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x3a || key == 0x3d) { - if (mod & NSAlternateKeyMask) { - mod &= ~NSAlternateKeyMask; - k->set_pressed(true); - } else { - k->set_pressed(false); - } - } else if (key == 0x3b || key == 0x3e) { - if (mod & NSControlKeyMask) { - mod &= ~NSControlKeyMask; - k->set_pressed(true); + ke.echo = false; + + int key = [event keyCode]; + int mod = [event modifierFlags]; + + if (key == 0x36 || key == 0x37) { + if (mod & NSEventModifierFlagCommand) { + mod &= ~NSEventModifierFlagCommand; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x38 || key == 0x3c) { + if (mod & NSEventModifierFlagShift) { + mod &= ~NSEventModifierFlagShift; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x3a || key == 0x3d) { + if (mod & NSEventModifierFlagOption) { + mod &= ~NSEventModifierFlagOption; + ke.pressed = true; + } else { + ke.pressed = false; + } + } else if (key == 0x3b || key == 0x3e) { + if (mod & NSEventModifierFlagControl) { + mod &= ~NSEventModifierFlagControl; + ke.pressed = true; + } else { + ke.pressed = false; + } } else { - k->set_pressed(false); + return; } - } else { - return; - } - get_key_modifier_state(mod, k); - k->set_scancode(latin_keyboard_keycode_convert(translateKey(key))); + ke.osx_state = mod; + ke.scancode = latin_keyboard_keycode_convert(translateKey(key)); + ke.unicode = 0; - OS_OSX::singleton->push_input(k); + push_to_key_event_buffer(ke); + } } - (void)keyUp:(NSEvent *)event { - Ref<InputEventKey> k; - k.instance(); + if (!imeMode) { + + OS_OSX::KeyEvent ke; - get_key_modifier_state([event modifierFlags], k); - k->set_pressed(false); - k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode]))); + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = false; + ke.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); + ke.unicode = 0; - OS_OSX::singleton->push_input(k); + push_to_key_event_buffer(ke); + } } inline void sendScrollEvent(int button, double factor, int modifierFlags) { @@ -868,20 +920,12 @@ inline void sendPanEvent(double dx, double dy, int modifierFlags) { - (void)scrollWheel:(NSEvent *)event { double deltaX, deltaY; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { - deltaX = [event scrollingDeltaX]; - deltaY = [event scrollingDeltaY]; + deltaX = [event scrollingDeltaX]; + deltaY = [event scrollingDeltaY]; - if ([event hasPreciseScrollingDeltas]) { - deltaX *= 0.03; - deltaY *= 0.03; - } - } else -#endif // MAC_OS_X_VERSION_MAX_ALLOWED - { - deltaX = [event deltaX]; - deltaY = [event deltaY]; + if ([event hasPreciseScrollingDeltas]) { + deltaX *= 0.03; + deltaY *= 0.03; } if ([event phase] != NSEventPhaseNone || [event momentumPhase] != NSEventPhaseNone) { @@ -919,6 +963,30 @@ void OS_OSX::set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_ } } +String OS_OSX::get_unique_id() const { + + static String serial_number; + + if (serial_number.empty()) { + io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); + CFStringRef serialNumberAsCFString = NULL; + if (platformExpert) { + serialNumberAsCFString = (CFStringRef)IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0); + IOObjectRelease(platformExpert); + } + + NSString *serialNumberAsNSString = nil; + if (serialNumberAsCFString) { + serialNumberAsNSString = [NSString stringWithString:(NSString *)serialNumberAsCFString]; + CFRelease(serialNumberAsCFString); + } + + serial_number = [serialNumberAsNSString UTF8String]; + } + + return serial_number; +} + void OS_OSX::set_ime_position(const Point2 &p_pos) { im_position = p_pos; } @@ -955,7 +1023,7 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay displays_arrangement_dirty = true; } -void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { /*** OSX INITIALIZATION ***/ /*** OSX INITIALIZATION ***/ @@ -983,7 +1051,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au if (p_desired.borderless_window) { styleMask = NSWindowStyleMaskBorderless; } else { - styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable ? NSResizableWindowMask : 0); + styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (p_desired.resizable ? NSWindowStyleMaskResizable : 0); } window_object = [[GodotWindow alloc] @@ -992,7 +1060,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au backing:NSBackingStoreBuffered defer:NO]; - ERR_FAIL_COND(window_object == nil); + ERR_FAIL_COND_V(window_object == nil, ERR_UNAVAILABLE); window_view = [[GodotContentView alloc] init]; @@ -1008,7 +1076,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au window_size.width = p_desired.width * displayScale; window_size.height = p_desired.height * displayScale; - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && displayScale > 1.0) { + if (displayScale > 1.0) { [window_view setWantsBestResolutionOpenGLSurface:YES]; //if (current_videomode.resizable) [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; @@ -1020,8 +1088,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au [window_object setAcceptsMouseMovedEvents:YES]; [window_object center]; - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - [window_object setRestorable:NO]; + [window_object setRestorable:NO]; unsigned int attributeCount = 0; @@ -1079,11 +1146,11 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au #undef ADD_ATTR2 pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - ERR_FAIL_COND(pixelFormat == nil); + ERR_FAIL_COND_V(pixelFormat == nil, ERR_UNAVAILABLE); context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - ERR_FAIL_COND(context == nil); + ERR_FAIL_COND_V(context == nil, ERR_UNAVAILABLE); [context setView:window_view]; @@ -1127,6 +1194,8 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au _ensure_user_data_dir(); restore_rect = Rect2(get_window_position(), get_window_size()); + + return OK; } void OS_OSX::finalize() { @@ -1179,34 +1248,42 @@ public: 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); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + 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); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + 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); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + 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); + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_12) { + 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; @@ -1235,35 +1312,111 @@ void OS_OSX::alert(const String &p_alert, const String &p_title) { [window release]; } +Error OS_OSX::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { + + String path = p_path; + + if (!FileAccess::exists(path)) { + //this code exists so gdnative can load .dylib files from within the executable path + path = get_executable_path().get_base_dir().plus_file(p_path.get_file()); + } + + if (!FileAccess::exists(path)) { + //this code exists so gdnative can load .dylib files from a standard macOS location + path = get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(p_path.get_file()); + } + + p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW); + if (!p_library_handle) { + ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror()); + ERR_FAIL_V(ERR_CANT_OPEN); + } + return OK; +} + void OS_OSX::set_cursor_shape(CursorShape p_shape) { if (cursor_shape == p_shape) return; - switch (p_shape) { - case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break; - case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break; - case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break; - case CURSOR_CROSS: [[NSCursor crosshairCursor] set]; break; - case CURSOR_WAIT: [[NSCursor arrowCursor] set]; break; - case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break; - case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break; - case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break; - case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break; - case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break; - case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break; - case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break; - case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break; - case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break; - case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break; - case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break; - case CURSOR_HELP: [[NSCursor arrowCursor] set]; break; - default: {}; + if (cursors[p_shape] != NULL) { + [cursors[p_shape] set]; + } else { + switch (p_shape) { + case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break; + case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break; + case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break; + case CURSOR_CROSS: [[NSCursor crosshairCursor] set]; break; + case CURSOR_WAIT: [[NSCursor arrowCursor] set]; break; + case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break; + case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break; + case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break; + case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break; + case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break; + case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break; + case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break; + case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break; + case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break; + case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break; + case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break; + case CURSOR_HELP: [[NSCursor arrowCursor] set]; break; + default: {}; + } } cursor_shape = p_shape; } +void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + Ref<Texture> texture = p_cursor; + Ref<Image> image = texture->get_data(); + + int image_size = 32 * 32; + + ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32); + + NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:image->get_width() + pixelsHigh:image->get_height() + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:image->get_width() * 4 + bitsPerPixel:32] autorelease]; + + ERR_FAIL_COND(imgrep == nil); + uint8_t *pixels = [imgrep bitmapData]; + + int len = image->get_width() * image->get_height(); + PoolVector<uint8_t> data = image->get_data(); + PoolVector<uint8_t>::Read r = data.read(); + + /* Premultiply the alpha channel */ + for (int i = 0; i < len; i++) { + uint8_t alpha = r[i * 4 + 3]; + pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255); + pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255); + pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255); + pixels[i * 4 + 3] = alpha; + } + + NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(image->get_width(), image->get_height())] autorelease]; + [nsimage addRepresentation:imgrep]; + + NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)]; + + cursors[p_shape] = cursor; + + if (p_shape == CURSOR_ARROW) { + [cursor set]; + } + } +} + void OS_OSX::set_mouse_show(bool p_show) { } @@ -1665,9 +1818,8 @@ float OS_OSX::_display_scale(id screen) const { if ([screen respondsToSelector:@selector(backingScaleFactor)]) { return fmax(1.0, [screen backingScaleFactor]); } - } else { - return 1.0; } + return 1.0; } Point2 OS_OSX::get_native_window_position() const { @@ -1717,6 +1869,12 @@ Size2 OS_OSX::get_window_size() const { return window_size; }; +Size2 OS_OSX::get_real_window_size() const { + + NSRect frame = [window_object frame]; + return Size2(frame.size.width, frame.size.height); +} + void OS_OSX::set_window_size(const Size2 p_size) { Size2 size = p_size; @@ -1726,10 +1884,14 @@ void OS_OSX::set_window_size(const Size2 p_size) { CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; if (menuBarHeight != 0.f) { size.y += menuBarHeight; -#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101104 } else { - size.y += [[NSStatusBar systemStatusBar] thickness]; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 + if (floor(NSAppKitVersionNumber) < NSAppKitVersionNumber10_12) { +#else + { #endif + size.y += [[NSStatusBar systemStatusBar] thickness]; + } } } @@ -1742,36 +1904,27 @@ void OS_OSX::set_window_size(const Size2 p_size) { void OS_OSX::set_window_fullscreen(bool p_enabled) { if (zoomed != p_enabled) { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 [window_object toggleFullScreen:nil]; -#else - [window_object performZoom:nil]; -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ } zoomed = p_enabled; }; bool OS_OSX::is_window_fullscreen() const { -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 - if ([window_object respondsToSelector:@selector(isZoomed)]) - return [window_object isZoomed]; -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - return zoomed; }; void OS_OSX::set_window_resizable(bool p_enabled) { if (p_enabled) - [window_object setStyleMask:[window_object styleMask] | NSResizableWindowMask]; + [window_object setStyleMask:[window_object styleMask] | NSWindowStyleMaskResizable]; else - [window_object setStyleMask:[window_object styleMask] & ~NSResizableWindowMask]; + [window_object setStyleMask:[window_object styleMask] & ~NSWindowStyleMaskResizable]; }; bool OS_OSX::is_window_resizable() const { - return [window_object styleMask] & NSResizableWindowMask; + return [window_object styleMask] & NSWindowStyleMaskResizable; }; void OS_OSX::set_window_minimized(bool p_enabled) { @@ -1813,6 +1966,20 @@ void OS_OSX::move_window_to_foreground() { [window_object orderFrontRegardless]; } +void OS_OSX::set_window_always_on_top(bool p_enabled) { + if (is_window_always_on_top() == p_enabled) + return; + + if (p_enabled) + [window_object setLevel:NSFloatingWindowLevel]; + else + [window_object setLevel:NSNormalWindowLevel]; +} + +bool OS_OSX::is_window_always_on_top() const { + return [window_object level] == NSFloatingWindowLevel; +} + void OS_OSX::request_attention() { [NSApp requestUserAttention:NSCriticalRequest]; @@ -1826,7 +1993,7 @@ void OS_OSX::set_borderless_window(bool p_borderless) { if (p_borderless) { [window_object setStyleMask:NSWindowStyleMaskBorderless]; } else { - [window_object setStyleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask]; + [window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable]; // Force update of the window styles NSRect frameRect = [window_object frame]; @@ -1950,7 +2117,7 @@ void OS_OSX::process_events() { while (true) { NSEvent *event = [NSApp - nextEventMatchingMask:NSAnyEventMask + nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES]; @@ -1960,11 +2127,49 @@ void OS_OSX::process_events() { [NSApp sendEvent:event]; } + process_key_events(); [autoreleasePool drain]; autoreleasePool = [[NSAutoreleasePool alloc] init]; } +void OS_OSX::process_key_events() { + + Ref<InputEventKey> k; + for (int i = 0; i < key_event_pos; i++) { + + KeyEvent &ke = key_event_buffer[i]; + + if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + k.instance(); + + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(0); + k->set_unicode(ke.unicode); + + push_input(k); + } + if (ke.scancode != 0) { + k.instance(); + + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(ke.scancode); + + if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) { + k->set_unicode(key_event_buffer[i + 1].unicode); + } + + push_input(k); + } + } + + key_event_pos = 0; +} + void OS_OSX::push_input(const Ref<InputEvent> &p_event) { Ref<InputEvent> ev = p_event; @@ -2084,6 +2289,7 @@ OS_OSX *OS_OSX::singleton = NULL; OS_OSX::OS_OSX() { + key_event_pos = 0; mouse_mode = OS::MOUSE_MODE_VISIBLE; main_loop = NULL; singleton = this; @@ -2142,7 +2348,7 @@ OS_OSX::OS_OSX() { [apple_menu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; menu_item = [apple_menu addItemWithTitle:NSLocalizedString(@"Hide Others", nil) action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menu_item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; + [menu_item setKeyEquivalentModifierMask:(NSEventModifierFlagOption | NSEventModifierFlagCommand)]; [apple_menu addItemWithTitle:NSLocalizedString(@"Show all", nil) action:@selector(unhideAllApplications:) keyEquivalent:@""]; @@ -2176,6 +2382,20 @@ OS_OSX::OS_OSX() { Vector<Logger *> loggers; loggers.push_back(memnew(OSXTerminalLogger)); _set_logger(memnew(CompositeLogger(loggers))); + + //process application:openFile: event + while (true) { + NSEvent *event = [NSApp + nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + + if (event == nil) + break; + + [NSApp sendEvent:event]; + } } bool OS_OSX::_check_internal_feature_support(const String &p_feature) { diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h index a3715e7e4e..1b497cebef 100644 --- a/platform/osx/platform_config.h +++ b/platform/osx/platform_config.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <alloca.h> #define GLES3_INCLUDE_H "glad/glad.h" diff --git a/platform/osx/sem_osx.cpp b/platform/osx/sem_osx.cpp index 2e7da62e5b..92f749322e 100644 --- a/platform/osx/sem_osx.cpp +++ b/platform/osx/sem_osx.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "sem_osx.h" #include <fcntl.h> diff --git a/platform/osx/sem_osx.h b/platform/osx/sem_osx.h index 0b9bbdfa76..ce31e966b7 100644 --- a/platform/osx/sem_osx.h +++ b/platform/osx/sem_osx.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef SEM_OSX_H #define SEM_OSX_H diff --git a/platform/register_platform_apis.h b/platform/register_platform_apis.h index 3ac3b319da..1c50eb95e3 100644 --- a/platform/register_platform_apis.h +++ b/platform/register_platform_apis.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef REGISTER_APIS_H #define REGISTER_APIS_H diff --git a/platform/server/detect.py b/platform/server/detect.py index ffec2af933..bc615d3d04 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -59,7 +59,7 @@ def configure(env): if ('clang++' not in env['CXX']): env["CC"] = "clang" env["CXX"] = "clang++" - env["LD"] = "clang++" + env["LINK"] = "clang++" env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix @@ -67,9 +67,6 @@ def configure(env): # FIXME: Check for existence of the libs before parsing their flags with pkg-config - if not env['builtin_openssl']: - env.ParseConfig('pkg-config openssl --cflags --libs') - if not env['builtin_libwebp']: env.ParseConfig('pkg-config libwebp --cflags --libs') @@ -86,6 +83,16 @@ def configure(env): if not env['builtin_libpng']: env.ParseConfig('pkg-config libpng --cflags --libs') + if not env['builtin_bullet']: + # We need at least version 2.88 + import subprocess + bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip() + if bullet_version < "2.88": + # Abort as system bullet was requested but too old + print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88")) + sys.exit(255) + env.ParseConfig('pkg-config bullet --cflags --libs') + if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp index 8e4742a1b0..3e48f0bf7f 100644 --- a/platform/server/godot_server.cpp +++ b/platform/server/godot_server.cpp @@ -27,6 +27,7 @@ /* 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_server.h" diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index c34567aaab..370a347399 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + //#include "servers/visual/visual_server_raster.h" //#include "servers/visual/rasterizer_dummy.h" #include "os_server.h" @@ -47,7 +48,7 @@ const char *OS_Server::get_video_driver_name(int p_driver) const { return "Dummy"; } -void OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { args = OS::get_singleton()->get_cmdline_args(); current_videomode = p_desired; @@ -67,14 +68,17 @@ void OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p spatial_sound_2d_server = memnew(SpatialSound2DServerSW); spatial_sound_2d_server->init(); - ERR_FAIL_COND(!visual_server); + ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE); visual_server->init(); input = memnew(InputDefault); _ensure_user_data_dir(); + + return OK; } + void OS_Server::finalize() { if (main_loop) @@ -179,6 +183,9 @@ void OS_Server::move_window_to_foreground() { void OS_Server::set_cursor_shape(CursorShape p_shape) { } +void OS_Server::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { +} + OS::PowerState OS_Server::get_power_state() { return power_manager->get_power_state(); } diff --git a/platform/server/os_server.h b/platform/server/os_server.h index c58c48500e..7abb4565d5 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_SERVER_H #define OS_SERVER_H @@ -66,7 +67,7 @@ protected: virtual int get_video_driver_count() const; virtual const char *get_video_driver_name(int p_driver) const; - virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); + virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); virtual void set_main_loop(MainLoop *p_main_loop); @@ -75,6 +76,7 @@ public: virtual String get_name(); virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h index 413fea20d8..af4cf07393 100644 --- a/platform/server/platform_config.h +++ b/platform/server/platform_config.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <alloca.h> diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index 4468c18eba..5ff62b38f9 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + // // This file demonstrates how to initialize EGL in a Windows Store app, using ICoreWindow. // diff --git a/platform/uwp/app.h b/platform/uwp/app.h index 0641ea1b8c..c23270b8ba 100644 --- a/platform/uwp/app.h +++ b/platform/uwp/app.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #pragma once #include <string> diff --git a/platform/uwp/export/export.h b/platform/uwp/export/export.h index 8e248b1969..bd759c8647 100644 --- a/platform/uwp/export/export.h +++ b/platform/uwp/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_uwp_exporter(); diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp index 2dde05a01f..88c9c8d687 100644 --- a/platform/uwp/gl_context_egl.cpp +++ b/platform/uwp/gl_context_egl.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "gl_context_egl.h" #include "EGL/eglext.h" diff --git a/platform/uwp/gl_context_egl.h b/platform/uwp/gl_context_egl.h index 55fd7ce705..527baf1054 100644 --- a/platform/uwp/gl_context_egl.h +++ b/platform/uwp/gl_context_egl.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef CONTEXT_EGL_H #define CONTEXT_EGL_H diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h index 442f805b1f..98202cce9e 100644 --- a/platform/uwp/joypad_uwp.h +++ b/platform/uwp/joypad_uwp.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef JOYPAD_UWP_H #define JOYPAD_UWP_H diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index ceccfb281c..d00da3dbcd 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "os_uwp.h" #include "drivers/gles3/rasterizer_gles3.h" @@ -194,7 +195,7 @@ void OSUWP::screen_size_changed() { gl_context->reset(); }; -void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; outside = true; @@ -297,6 +298,8 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud display_request->RequestActive(); set_keep_screen_on(GLOBAL_DEF("display/window/keep_screen_on", true)); + + return OK; } void OSUWP::set_clipboard(const String &p_text) { @@ -651,6 +654,10 @@ void OSUWP::set_cursor_shape(CursorShape p_shape) { cursor_shape = p_shape; } +void OSUWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + // TODO +} + Error OSUWP::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) { return FAILED; diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 7c2371b097..95afdab469 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OSUWP_H #define OSUWP_H @@ -158,7 +159,7 @@ protected: 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 Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void set_main_loop(MainLoop *p_main_loop); virtual void delete_main_loop(); @@ -218,6 +219,7 @@ public: virtual String get_clipboard() const; void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); void set_icon(const Ref<Image> &p_icon); virtual String get_executable_path() const; diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h index 0a21339237..606795479b 100644 --- a/platform/uwp/platform_config.h +++ b/platform/uwp/platform_config.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <malloc.h> diff --git a/platform/uwp/thread_uwp.cpp b/platform/uwp/thread_uwp.cpp index 79d244dd61..25cd29190f 100644 --- a/platform/uwp/thread_uwp.cpp +++ b/platform/uwp/thread_uwp.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "thread_uwp.h" #include "os/memory.h" diff --git a/platform/uwp/thread_uwp.h b/platform/uwp/thread_uwp.h index 24ae5ec22a..89081f3b2b 100644 --- a/platform/uwp/thread_uwp.h +++ b/platform/uwp/thread_uwp.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef THREAD_UWP_H #define THREAD_UWP_H diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 604896b0db..8965b80fb7 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -39,5 +39,5 @@ if env['vsproj']: env.vs_srcs = env.vs_srcs + ["platform/windows/" + str(x)] if not os.getenv("VCINSTALLDIR"): - if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": + if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: env.AddPostAction(prog, make_debug_mingw) diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index 6875d23dfa..8b57fdd9ce 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) // Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008 diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h index d30f842f4b..e7578a1aeb 100644 --- a/platform/windows/context_gl_win.h +++ b/platform/windows/context_gl_win.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) // Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008 diff --git a/platform/windows/crash_handler_win.cpp b/platform/windows/crash_handler_win.cpp index 50b4f2d811..804c2d44eb 100644 --- a/platform/windows/crash_handler_win.cpp +++ b/platform/windows/crash_handler_win.cpp @@ -27,6 +27,7 @@ /* 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" #include "project_settings.h" diff --git a/platform/windows/crash_handler_win.h b/platform/windows/crash_handler_win.h index 6f170fb958..95b1468197 100644 --- a/platform/windows/crash_handler_win.h +++ b/platform/windows/crash_handler_win.h @@ -27,6 +27,7 @@ /* 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 diff --git a/platform/windows/ctxgl_procaddr.cpp b/platform/windows/ctxgl_procaddr.cpp index dfb15cc358..434eeea16e 100644 --- a/platform/windows/ctxgl_procaddr.cpp +++ b/platform/windows/ctxgl_procaddr.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef OPENGL_ENABLED #include "ctxgl_procaddr.h" #include <GL/gl.h> diff --git a/platform/windows/ctxgl_procaddr.h b/platform/windows/ctxgl_procaddr.h index 168f808285..cd229fb8db 100644 --- a/platform/windows/ctxgl_procaddr.h +++ b/platform/windows/ctxgl_procaddr.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef CTXGL_PROCADDR_H #define CTXGL_PROCADDR_H diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 489bac50f5..2b3743b066 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -69,6 +69,7 @@ def get_opts(): # Vista support dropped after EOL due to GH-10243 ('target_win_version', 'Targeted Windows version, >= 0x0601 (Windows 7)', '0x0601'), EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')), + BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False), ] @@ -178,7 +179,7 @@ def configure(env): if env["bits"] == "64": env.Append(CCFLAGS=['/D_WIN64']) - LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', 'shell32', 'advapi32', 'dinput8', 'dxguid'] + LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', 'shell32', 'advapi32', 'dinput8', 'dxguid', 'Imm32'] env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) env.Append(LIBPATH=[os.getenv("WindowsSdkDir") + "/Lib"]) @@ -265,7 +266,7 @@ def configure(env): env['CXX'] = mingw_prefix + "g++" env['AR'] = mingw_prefix + "gcc-ar" env['RANLIB'] = mingw_prefix + "gcc-ranlib" - env['LD'] = mingw_prefix + "g++" + env['LINK'] = mingw_prefix + "g++" env["x86_libtheora_opt_gcc"] = True if env['use_lto']: @@ -280,7 +281,7 @@ def configure(env): env.Append(CCFLAGS=['-DRTAUDIO_ENABLED']) env.Append(CCFLAGS=['-DWASAPI_ENABLED']) env.Append(CCFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']]) - env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser']) + env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'Imm32']) env.Append(CPPFLAGS=['-DMINGW_ENABLED']) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index d5c2cf7992..97544c18f5 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "editor/editor_export.h" #include "editor/editor_settings.h" #include "os/file_access.h" diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h index 78421928ff..7f62e8955c 100644 --- a/platform/windows/export/export.h +++ b/platform/windows/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_windows_exporter(); diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp index 20e351c47c..80f53dd1a1 100644 --- a/platform/windows/godot_win.cpp +++ b/platform/windows/godot_win.cpp @@ -27,6 +27,7 @@ /* 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" #include <locale.h> diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp index 4a3936b175..796531fe24 100644 --- a/platform/windows/joypad.cpp +++ b/platform/windows/joypad.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "joypad.h" #include <oleauto.h> #include <wbemidl.h> diff --git a/platform/windows/joypad.h b/platform/windows/joypad.h index f3d24bce85..0d14480733 100644 --- a/platform/windows/joypad.h +++ b/platform/windows/joypad.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef JOYPAD_H #define JOYPAD_H diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp index bb90cb661a..69dd385354 100644 --- a/platform/windows/key_mapping_win.cpp +++ b/platform/windows/key_mapping_win.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "key_mapping_win.h" #include <stdio.h> diff --git a/platform/windows/key_mapping_win.h b/platform/windows/key_mapping_win.h index 2daf3f4f01..8d6461f27d 100644 --- a/platform/windows/key_mapping_win.h +++ b/platform/windows/key_mapping_win.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef KEY_MAPPING_WINDOWS_H #define KEY_MAPPING_WINDOWS_H diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h index 614fbd8ae9..1a966b502a 100644 --- a/platform/windows/lang_table.h +++ b/platform/windows/lang_table.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef LANG_TABLE_H #define LANG_TABLE_H diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 8edc2c5cff..20129299a1 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -416,6 +416,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /*mm->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0; mm->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ mm->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); + mm->set_global_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); if (mouse_mode == MOUSE_MODE_CAPTURED) { @@ -461,6 +462,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: case WM_RBUTTONDBLCLK: /*case WM_XBUTTONDOWN: case WM_XBUTTONUP: */ { @@ -519,6 +521,12 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) mb->set_button_index(2); mb->set_doubleclick(true); } break; + case WM_MBUTTONDBLCLK: { + + mb->set_pressed(true); + mb->set_button_index(3); + mb->set_doubleclick(true); + } break; case WM_MOUSEWHEEL: { mb->set_pressed(true); @@ -580,7 +588,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) mb->set_position(Vector2(old_x, old_y)); } - if (uMsg != WM_MOUSEWHEEL) { + if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) { if (mb->is_pressed()) { if (++pressrc > 0) @@ -929,7 +937,7 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS { 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) { +Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; outside = true; @@ -975,7 +983,7 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int if (!RegisterClassExW(&wc)) { MessageBox(NULL, "Failed To Register The Window Class.", "ERROR", MB_OK | MB_ICONEXCLAMATION); - return; // Return + return ERR_UNAVAILABLE; } pre_fs_valid = true; @@ -1045,7 +1053,7 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int RECT rect; if (!GetClientRect(hWnd, &rect)) { MessageBoxW(NULL, L"Window Creation Error.", L"ERROR", MB_OK | MB_ICONEXCLAMATION); - return; // Return FALSE + return ERR_UNAVAILABLE; }; video_mode.width = rect.right; video_mode.height = rect.bottom; @@ -1063,10 +1071,14 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int NULL, NULL, hInstance, NULL); if (!hWnd) { MessageBoxW(NULL, L"Window Creation Error.", L"ERROR", MB_OK | MB_ICONEXCLAMATION); - return; // Return FALSE + return ERR_UNAVAILABLE; } }; + if (video_mode.always_on_top) { + SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } + #if defined(OPENGL_ENABLED) gl_context = memnew(ContextGL_Win(hWnd, true)); gl_context->initialize(); @@ -1127,6 +1139,8 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int SetForegroundWindow(hWnd); // Slightly Higher Priority SetFocus(hWnd); // Sets Keyboard Focus To } + + return OK; } void OS_Windows::set_clipboard(const String &p_text) { @@ -1477,6 +1491,12 @@ Size2 OS_Windows::get_window_size() const { GetClientRect(hWnd, &r); return Vector2(r.right - r.left, r.bottom - r.top); } +Size2 OS_Windows::get_real_window_size() const { + + RECT r; + GetWindowRect(hWnd, &r); + return Vector2(r.right - r.left, r.bottom - r.top); +} void OS_Windows::set_window_size(const Size2 p_size) { video_mode.width = p_size.width; @@ -1598,6 +1618,19 @@ bool OS_Windows::is_window_maximized() const { return maximized; } +void OS_Windows::set_window_always_on_top(bool p_enabled) { + if (video_mode.always_on_top == p_enabled) + return; + + video_mode.always_on_top = p_enabled; + + _update_window_style(); +} + +bool OS_Windows::is_window_always_on_top() const { + return video_mode.always_on_top; +} + void OS_Windows::set_borderless_window(bool p_borderless) { if (video_mode.borderless_window == p_borderless) return; @@ -1622,6 +1655,8 @@ void OS_Windows::_update_window_style(bool repaint) { } } + SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + if (repaint) { RECT rect; GetWindowRect(hWnd, &rect); @@ -1631,6 +1666,13 @@ void OS_Windows::_update_window_style(bool repaint) { Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { + String path = p_path; + + if (!FileAccess::exists(path)) { + //this code exists so gdnative can load .dll files from within the executable path + path = get_executable_path().get_base_dir().plus_file(p_path.get_file()); + } + typedef DLL_DIRECTORY_COOKIE(WINAPI * PAddDllDirectory)(PCWSTR); typedef BOOL(WINAPI * PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE); @@ -1638,15 +1680,15 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han PRemoveDllDirectory remove_dll_directory = (PRemoveDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "RemoveDllDirectory"); bool has_dll_directory_api = ((add_dll_directory != NULL) && (remove_dll_directory != NULL)); - DLL_DIRECTORY_COOKIE cookie; + DLL_DIRECTORY_COOKIE cookie = NULL; if (p_also_set_library_path && has_dll_directory_api) { - cookie = add_dll_directory(p_path.get_base_dir().c_str()); + cookie = add_dll_directory(path.get_base_dir().c_str()); } - p_library_handle = (void *)LoadLibraryExW(p_path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0); + p_library_handle = (void *)LoadLibraryExW(path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0); - if (p_also_set_library_path && has_dll_directory_api) { + if (cookie) { remove_dll_directory(cookie); } @@ -1844,10 +1886,125 @@ void OS_Windows::set_cursor_shape(CursorShape p_shape) { IDC_HELP }; - SetCursor(LoadCursor(hInstance, win_cursors[p_shape])); + if (cursors[p_shape] != NULL) { + SetCursor(cursors[p_shape]); + } else { + SetCursor(LoadCursor(hInstance, win_cursors[p_shape])); + } cursor_shape = p_shape; } +void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + Ref<Texture> texture = p_cursor; + Ref<Image> image = texture->get_data(); + + UINT image_size = 32 * 32; + UINT size = sizeof(UINT) * image_size; + + ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32); + + // Create the BITMAP with alpha channel + COLORREF *buffer = (COLORREF *)malloc(sizeof(COLORREF) * image_size); + + image->lock(); + for (UINT index = 0; index < image_size; index++) { + int column_index = floor(index / 32); + int row_index = index % 32; + + Color pcColor = image->get_pixel(row_index, column_index); + *(buffer + index) = image->get_pixel(row_index, column_index).to_argb32(); + } + image->unlock(); + + // Using 4 channels, so 4 * 8 bits + HBITMAP bitmap = CreateBitmap(32, 32, 1, 4 * 8, buffer); + COLORREF clrTransparent = -1; + + // Create the AND and XOR masks for the bitmap + HBITMAP hAndMask = NULL; + HBITMAP hXorMask = NULL; + + GetMaskBitmaps(bitmap, clrTransparent, hAndMask, hXorMask); + + if (NULL == hAndMask || NULL == hXorMask) { + return; + } + + // Finally, create the icon + ICONINFO iconinfo = { 0 }; + iconinfo.fIcon = FALSE; + iconinfo.xHotspot = p_hotspot.x; + iconinfo.yHotspot = p_hotspot.y; + iconinfo.hbmMask = hAndMask; + iconinfo.hbmColor = hXorMask; + + cursors[p_shape] = CreateIconIndirect(&iconinfo); + + if (p_shape == CURSOR_ARROW) { + SetCursor(cursors[p_shape]); + } + + if (hAndMask != NULL) { + DeleteObject(hAndMask); + } + + if (hXorMask != NULL) { + DeleteObject(hXorMask); + } + } +} + +void OS_Windows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap) { + + // Get the system display DC + HDC hDC = GetDC(NULL); + + // Create helper DC + HDC hMainDC = CreateCompatibleDC(hDC); + HDC hAndMaskDC = CreateCompatibleDC(hDC); + HDC hXorMaskDC = CreateCompatibleDC(hDC); + + // Get the dimensions of the source bitmap + BITMAP bm; + GetObject(hSourceBitmap, sizeof(BITMAP), &bm); + + // Create the mask bitmaps + hAndMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // color + hXorMaskBitmap = CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); // color + + // Release the system display DC + ReleaseDC(NULL, hDC); + + // Select the bitmaps to helper DC + HBITMAP hOldMainBitmap = (HBITMAP)SelectObject(hMainDC, hSourceBitmap); + HBITMAP hOldAndMaskBitmap = (HBITMAP)SelectObject(hAndMaskDC, hAndMaskBitmap); + HBITMAP hOldXorMaskBitmap = (HBITMAP)SelectObject(hXorMaskDC, hXorMaskBitmap); + + // Assign the monochrome AND mask bitmap pixels so that a pixels of the source bitmap + // with 'clrTransparent' will be white pixels of the monochrome bitmap + SetBkColor(hMainDC, clrTransparent); + BitBlt(hAndMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hMainDC, 0, 0, SRCCOPY); + + // Assign the color XOR mask bitmap pixels so that a pixels of the source bitmap + // with 'clrTransparent' will be black and rest the pixels same as corresponding + // pixels of the source bitmap + SetBkColor(hXorMaskDC, RGB(0, 0, 0)); + SetTextColor(hXorMaskDC, RGB(255, 255, 255)); + BitBlt(hXorMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hAndMaskDC, 0, 0, SRCCOPY); + BitBlt(hXorMaskDC, 0, 0, bm.bmWidth, bm.bmHeight, hMainDC, 0, 0, SRCAND); + + // Deselect bitmaps from the helper DC + SelectObject(hMainDC, hOldMainBitmap); + SelectObject(hAndMaskDC, hOldAndMaskBitmap); + SelectObject(hXorMaskDC, hOldXorMaskBitmap); + + // Delete the helper DC + DeleteDC(hXorMaskDC); + DeleteDC(hAndMaskDC); + DeleteDC(hMainDC); +} + Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) { if (p_blocking && r_pipe) { @@ -2079,6 +2236,36 @@ String OS_Windows::get_locale() const { return "en"; } +// We need this because GetSystemInfo() is unreliable on WOW64 +// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724381(v=vs.85).aspx +// Taken from MSDN +typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); +LPFN_ISWOW64PROCESS fnIsWow64Process; + +BOOL is_wow64() { + BOOL wow64 = FALSE; + + fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); + + if (fnIsWow64Process) { + if (!fnIsWow64Process(GetCurrentProcess(), &wow64)) { + wow64 = FALSE; + } + } + + return wow64; +} + +int OS_Windows::get_processor_count() const { + SYSTEM_INFO sysinfo; + if (is_wow64()) + GetNativeSystemInfo(&sysinfo); + else + GetSystemInfo(&sysinfo); + + return sysinfo.dwNumberOfProcessors; +} + OS::LatinKeyboardVariant OS_Windows::get_latin_keyboard_variant() const { unsigned long azerty[] = { @@ -2280,6 +2467,24 @@ String OS_Windows::get_user_data_dir() const { return ProjectSettings::get_singleton()->get_resource_path(); } +String OS_Windows::get_unique_id() const { + + HW_PROFILE_INFO HwProfInfo; + ERR_FAIL_COND_V(!GetCurrentHwProfile(&HwProfInfo), ""); + return String(HwProfInfo.szHwProfileGuid); +} + +void OS_Windows::set_ime_position(const Point2 &p_pos) { + + HIMC himc = ImmGetContext(hWnd); + COMPOSITIONFORM cps; + cps.dwStyle = CFS_FORCE_POSITION; + cps.ptCurrentPos.x = p_pos.x; + cps.ptCurrentPos.y = p_pos.y; + ImmSetCompositionWindow(himc, &cps); + ImmReleaseContext(hWnd, himc); +} + bool OS_Windows::is_joy_known(int p_device) { return input->is_joy_mapped(p_device); } diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index d709fb3fe5..4c4fbcf8f0 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_WINDOWS_H #define OS_WINDOWS_H #include "context_gl_win.h" @@ -113,6 +114,7 @@ class OS_Windows : public OS { bool window_has_focus; uint32_t last_button_state; + HCURSOR cursors[CURSOR_MAX] = { NULL }; CursorShape cursor_shape; InputDefault *input; @@ -147,7 +149,7 @@ protected: 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 Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void set_main_loop(MainLoop *p_main_loop); virtual void delete_main_loop(); @@ -199,6 +201,7 @@ public: virtual Point2 get_window_position() const; virtual void set_window_position(const Point2 &p_position); virtual Size2 get_window_size() const; + virtual Size2 get_real_window_size() const; virtual void set_window_size(const Size2 p_size); virtual void set_window_fullscreen(bool p_enabled); virtual bool is_window_fullscreen() const; @@ -208,6 +211,8 @@ public: virtual bool is_window_minimized() const; virtual void set_window_maximized(bool p_enabled); virtual bool is_window_maximized() const; + virtual void set_window_always_on_top(bool p_enabled); + virtual bool is_window_always_on_top() const; virtual void request_attention(); virtual void set_borderless_window(bool p_borderless); @@ -244,11 +249,16 @@ public: virtual String get_clipboard() const; void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); + void GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap); void set_icon(const Ref<Image> &p_icon); virtual String get_executable_path() const; virtual String get_locale() const; + + virtual int get_processor_count() const; + virtual LatinKeyboardVariant get_latin_keyboard_variant() const; virtual void enable_for_stealing_focus(ProcessID pid); @@ -262,6 +272,10 @@ public: virtual String get_system_dir(SystemDir p_dir) const; virtual String get_user_data_dir() const; + virtual String get_unique_id() const; + + virtual void set_ime_position(const Point2 &p_pos); + virtual void release_rendering_thread(); virtual void make_rendering_thread(); virtual void swap_buffers(); diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 6c26a8228d..10ec9110d1 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <malloc.h> //#else //#include <alloca.h> diff --git a/platform/x11/SCsub b/platform/x11/SCsub index 38dd2ddd88..b18757337a 100644 --- a/platform/x11/SCsub +++ b/platform/x11/SCsub @@ -19,5 +19,5 @@ common_x11 = [ prog = env.add_program('#bin/godot', ['godot_x11.cpp'] + common_x11) -if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes": +if (env["debug_symbols"] == "full" or env["debug_symbols"] == "yes") and env["separate_debug_symbols"]: env.AddPostAction(prog, make_debug) diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index b232f36a46..20f2212861 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "context_gl_x11.h" #ifdef X11_ENABLED diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h index efebd3f78d..c969f0044d 100644 --- a/platform/x11/context_gl_x11.h +++ b/platform/x11/context_gl_x11.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef CONTEXT_GL_X11_H #define CONTEXT_GL_X11_H diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp index f0eb8a6d5b..43b9051ea7 100644 --- a/platform/x11/crash_handler_x11.cpp +++ b/platform/x11/crash_handler_x11.cpp @@ -27,6 +27,7 @@ /* 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 diff --git a/platform/x11/crash_handler_x11.h b/platform/x11/crash_handler_x11.h index 36ab29b597..49ca0df9a8 100644 --- a/platform/x11/crash_handler_x11.h +++ b/platform/x11/crash_handler_x11.h @@ -27,6 +27,7 @@ /* 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 diff --git a/platform/x11/detect.py b/platform/x11/detect.py index cb45fed1be..c5ef82150b 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -55,6 +55,7 @@ def get_opts(): BoolVariable('pulseaudio', 'Detect & use pulseaudio', True), BoolVariable('udev', 'Use udev for gamepad connection callbacks', False), EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')), + BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False), BoolVariable('touch', 'Enable touch events', True), ] @@ -64,7 +65,6 @@ def get_flags(): return [ ('builtin_freetype', False), ('builtin_libpng', False), - ('builtin_openssl', False), ('builtin_zlib', False), ] @@ -109,7 +109,7 @@ def configure(env): if ('clang++' not in env['CXX']): env["CC"] = "clang" env["CXX"] = "clang++" - env["LD"] = "clang++" + env["LINK"] = "clang++" env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix @@ -152,8 +152,9 @@ def configure(env): # FIXME: Check for existence of the libs before parsing their flags with pkg-config - if not env['builtin_openssl']: - env.ParseConfig('pkg-config openssl --cflags --libs') + if not env['builtin_mbedtls']: + # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 + env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509']) if not env['builtin_libwebp']: env.ParseConfig('pkg-config libwebp --cflags --libs') @@ -172,6 +173,16 @@ def configure(env): if not env['builtin_libpng']: env.ParseConfig('pkg-config libpng --cflags --libs') + if not env['builtin_bullet']: + # We need at least version 2.88 + import subprocess + bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip() + if bullet_version < "2.88": + # Abort as system bullet was requested but too old + print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88")) + sys.exit(255) + env.ParseConfig('pkg-config bullet --cflags --libs') + if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp index 3a8786f296..904aceaca0 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "export.h" #include "editor/editor_export.h" diff --git a/platform/x11/export/export.h b/platform/x11/export/export.h index 152a64df86..ac44cef8f7 100644 --- a/platform/x11/export/export.h +++ b/platform/x11/export/export.h @@ -27,4 +27,5 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + void register_x11_exporter(); diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp index c7d7bb643b..3241cbcbf9 100644 --- a/platform/x11/godot_x11.cpp +++ b/platform/x11/godot_x11.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include <limits.h> #include <locale.h> #include <stdlib.h> diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp index 5e15768d66..423e2737ee 100644 --- a/platform/x11/key_mapping_x11.cpp +++ b/platform/x11/key_mapping_x11.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "key_mapping_x11.h" /***** SCAN CODE CONVERSION ******/ diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h index 022affcbea..62dfcf3a4d 100644 --- a/platform/x11/key_mapping_x11.h +++ b/platform/x11/key_mapping_x11.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef KEY_MAPPING_X11_H #define KEY_MAPPING_X11_H diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 240d6638a9..2d8e32137f 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "os_x11.h" #include "drivers/gles3/rasterizer_gles3.h" #include "errno.h" @@ -100,7 +101,7 @@ void OS_X11::initialize_core() { OS_Unix::initialize_core(); } -void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { +Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { long im_event_mask = 0; last_button_state = 0; @@ -123,21 +124,24 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au /** XLIB INITIALIZATION **/ x11_display = XOpenDisplay(NULL); + if (!x11_display) { + ERR_PRINT("X11 Display is not available"); + return ERR_UNAVAILABLE; + } + char *modifiers = NULL; Bool xkb_dar = False; - if (x11_display) { - XAutoRepeatOn(x11_display); - xkb_dar = XkbSetDetectableAutoRepeat(x11_display, True, NULL); + XAutoRepeatOn(x11_display); + xkb_dar = XkbSetDetectableAutoRepeat(x11_display, True, NULL); - // Try to support IME if detectable auto-repeat is supported - if (xkb_dar == True) { + // Try to support IME if detectable auto-repeat is supported + if (xkb_dar == True) { #ifdef X_HAVE_UTF8_STRING - // Xutf8LookupString will be used later instead of XmbLookupString before - // the multibyte sequences can be converted to unicode string. - modifiers = XSetLocaleModifiers(""); + // Xutf8LookupString will be used later instead of XmbLookupString before + // the multibyte sequences can be converted to unicode string. + modifiers = XSetLocaleModifiers(""); #endif - } } if (modifiers == NULL) { @@ -213,7 +217,7 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au XIFreeDeviceInfo(info); - if (!touch.devices.size()) { + if (is_stdout_verbose() && !touch.devices.size()) { fprintf(stderr, "No touch devices found\n"); } } @@ -329,10 +333,15 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au XFree(xsh); } + if (current_videomode.always_on_top) { + current_videomode.always_on_top = false; + set_window_always_on_top(true); + } + AudioDriverManager::initialize(p_audio_driver); - ERR_FAIL_COND(!visual_server); - ERR_FAIL_COND(x11_window == 0); + ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE); + ERR_FAIL_COND_V(x11_window == 0, ERR_UNAVAILABLE); XSetWindowAttributes new_attr; @@ -519,6 +528,8 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au _window_changed(&xevent); } } + + return OK; } void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data, @@ -543,6 +554,21 @@ void OS_X11::set_ime_position(const Point2 &p_pos) { XFree(preedit_attr); } +String OS_X11::get_unique_id() const { + + static String machine_id; + if (machine_id.empty()) { + if (FileAccess *f = FileAccess::open("/etc/machine-id", FileAccess::READ)) { + while (machine_id.empty() && !f->eof_reached()) { + machine_id = f->get_line().strip_edges(); + } + f->close(); + memdelete(f); + } + } + return machine_id; +} + void OS_X11::finalize() { if (main_loop) @@ -704,9 +730,6 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con } void OS_X11::set_wm_fullscreen(bool p_enabled) { - if (current_videomode.fullscreen == p_enabled) - return; - if (p_enabled && !is_window_resizable()) { // Set the window as resizable to prevent window managers to ignore the fullscreen state flag. XSizeHints *xsh; @@ -767,6 +790,22 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { } } +void OS_X11::set_wm_above(bool p_enabled) { + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_above = XInternAtom(x11_display, "_NET_WM_STATE_ABOVE", False); + + XClientMessageEvent xev; + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.window = x11_window; + xev.message_type = wm_state; + xev.format = 32; + xev.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.data.l[1] = wm_above; + xev.data.l[3] = 1; + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xev); +} + int OS_X11::get_screen_count() const { // Using Xinerama Extension int event_base, error_base; @@ -918,6 +957,26 @@ Size2 OS_X11::get_window_size() const { return Size2i(current_videomode.width, current_videomode.height); } +Size2 OS_X11::get_real_window_size() const { + XWindowAttributes xwa; + XSync(x11_display, False); + XGetWindowAttributes(x11_display, x11_window, &xwa); + int w = xwa.width; + int h = xwa.height; + Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + if (XGetWindowProperty(x11_display, x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + long *extents = (long *)data; + w += extents[0] + extents[1]; // left, right + h += extents[2] + extents[3]; // top, bottom + } + return Size2(w, h); +} + void OS_X11::set_window_size(const Size2 p_size) { // If window resizable is disabled we need to update the attributes first if (is_window_resizable() == false) { @@ -941,7 +1000,19 @@ void OS_X11::set_window_size(const Size2 p_size) { } void OS_X11::set_window_fullscreen(bool p_enabled) { + if (current_videomode.fullscreen == p_enabled) + return; + + if (p_enabled && current_videomode.always_on_top) { + // Fullscreen + Always-on-top requires a maximized window on some window managers (Metacity) + set_window_maximized(true); + } set_wm_fullscreen(p_enabled); + if (!p_enabled && !current_videomode.always_on_top) { + // Restore + set_window_maximized(false); + } + current_videomode.fullscreen = p_enabled; } @@ -1050,13 +1121,59 @@ void OS_X11::set_window_maximized(bool p_enabled) { XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); - while (p_enabled && !is_window_maximized()) { - // Wait for effective resizing (so the GLX context is too). + if (is_window_maximize_allowed()) { + while (p_enabled && !is_window_maximized()) { + // Wait for effective resizing (so the GLX context is too). + } } maximized = p_enabled; } +bool OS_X11::is_window_maximize_allowed() { + Atom property = XInternAtom(x11_display, "_NET_WM_ALLOWED_ACTIONS", False); + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = NULL; + + int result = XGetWindowProperty( + x11_display, + x11_window, + property, + 0, + 1024, + False, + XA_ATOM, + &type, + &format, + &len, + &remaining, + &data); + + if (result == Success) { + Atom *atoms = (Atom *)data; + Atom wm_act_max_horz = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_HORZ", False); + Atom wm_act_max_vert = XInternAtom(x11_display, "_NET_WM_ACTION_MAXIMIZE_VERT", False); + bool found_wm_act_max_horz = false; + bool found_wm_act_max_vert = false; + + for (unsigned int i = 0; i < len; i++) { + if (atoms[i] == wm_act_max_horz) + found_wm_act_max_horz = true; + if (atoms[i] == wm_act_max_vert) + found_wm_act_max_vert = true; + + if (found_wm_act_max_horz || found_wm_act_max_vert) + return true; + } + XFree(atoms); + } + + return false; +} + bool OS_X11::is_window_maximized() const { // Using EWMH -- Extended Window Manager Hints Atom property = XInternAtom(x11_display, "_NET_WM_STATE", False); @@ -1102,6 +1219,27 @@ bool OS_X11::is_window_maximized() const { return false; } +void OS_X11::set_window_always_on_top(bool p_enabled) { + if (is_window_always_on_top() == p_enabled) + return; + + if (p_enabled && current_videomode.fullscreen) { + // Fullscreen + Always-on-top requires a maximized window on some window managers (Metacity) + set_window_maximized(true); + } + set_wm_above(p_enabled); + if (!p_enabled && !current_videomode.fullscreen) { + // Restore + set_window_maximized(false); + } + + current_videomode.always_on_top = p_enabled; +} + +bool OS_X11::is_window_always_on_top() const { + return current_videomode.always_on_top; +} + void OS_X11::set_borderless_window(bool p_borderless) { if (current_videomode.borderless_window == p_borderless) @@ -1810,8 +1948,12 @@ void OS_X11::process_xevents() { e = event; req = &(e.xselectionrequest); - if (req->target == XA_STRING || req->target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) || - req->target == XInternAtom(x11_display, "UTF8_STRING", 0)) { + if (req->target == XInternAtom(x11_display, "UTF8_STRING", 0) || + req->target == XInternAtom(x11_display, "COMPOUND_TEXT", 0) || + req->target == XInternAtom(x11_display, "TEXT", 0) || + req->target == XA_STRING || + req->target == XInternAtom(x11_display, "text/plain;charset=utf-8", 0) || + req->target == XInternAtom(x11_display, "text/plain", 0)) { CharString clip = OS::get_clipboard().utf8(); XChangeProperty(x11_display, req->requestor, @@ -1824,26 +1966,40 @@ void OS_X11::process_xevents() { respond.xselection.property = req->property; } else if (req->target == XInternAtom(x11_display, "TARGETS", 0)) { - Atom data[2]; - data[0] = XInternAtom(x11_display, "UTF8_STRING", 0); - data[1] = XA_STRING; - XChangeProperty(x11_display, req->requestor, req->property, req->target, - 8, PropModeReplace, (unsigned char *)&data, - sizeof(data)); + Atom data[7]; + data[0] = XInternAtom(x11_display, "TARGETS", 0); + data[1] = XInternAtom(x11_display, "UTF8_STRING", 0); + data[2] = XInternAtom(x11_display, "COMPOUND_TEXT", 0); + data[3] = XInternAtom(x11_display, "TEXT", 0); + data[4] = XA_STRING; + data[5] = XInternAtom(x11_display, "text/plain;charset=utf-8", 0); + data[6] = XInternAtom(x11_display, "text/plain", 0); + + XChangeProperty(x11_display, + req->requestor, + req->property, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char *)&data, + sizeof(data) / sizeof(data[0])); respond.xselection.property = req->property; } else { - printf("No String %x\n", - (int)req->target); + char *targetname = XGetAtomName(x11_display, req->target); + printf("No Target '%s'\n", targetname); + if (targetname) + XFree(targetname); respond.xselection.property = None; } + respond.xselection.type = SelectionNotify; respond.xselection.display = req->display; respond.xselection.requestor = req->requestor; respond.xselection.selection = req->selection; respond.xselection.target = req->target; respond.xselection.time = req->time; - XSendEvent(x11_display, req->requestor, 0, 0, &respond); + XSendEvent(x11_display, req->requestor, True, NoEventMask, &respond); XFlush(x11_display); } break; @@ -2205,6 +2361,48 @@ void OS_X11::set_cursor_shape(CursorShape p_shape) { current_cursor = p_shape; } +void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + Ref<Texture> texture = p_cursor; + Ref<Image> image = texture->get_data(); + + ERR_FAIL_COND(texture->get_width() != 32 || texture->get_height() != 32); + + // Create the cursor structure + XcursorImage *cursor_image = XcursorImageCreate(texture->get_width(), texture->get_height()); + XcursorUInt image_size = 32 * 32; + XcursorDim size = sizeof(XcursorPixel) * image_size; + + cursor_image->version = 1; + cursor_image->size = size; + cursor_image->xhot = p_hotspot.x; + cursor_image->yhot = p_hotspot.y; + + // allocate memory to contain the whole file + cursor_image->pixels = (XcursorPixel *)malloc(size); + + image->lock(); + + for (XcursorPixel index = 0; index < image_size; index++) { + int column_index = floor(index / 32); + int row_index = index % 32; + + *(cursor_image->pixels + index) = image->get_pixel(row_index, column_index).to_argb32(); + } + + image->unlock(); + + ERR_FAIL_COND(cursor_image->pixels == NULL); + + // Save it for a further usage + cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_image); + + if (p_shape == CURSOR_ARROW) { + XDefineCursor(x11_display, x11_window, cursors[p_shape]); + } + } +} + void OS_X11::release_rendering_thread() { context_gl->release_current(); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 59b9c8caa8..494845bc56 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef OS_X11_H #define OS_X11_H @@ -177,6 +178,7 @@ class OS_X11 : public OS_Unix { bool maximized; //void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); + void set_wm_above(bool p_enabled); typedef xrr_monitor_info *(*xrr_get_monitors_t)(Display *dpy, Window window, Bool get_active, int *nmonitors); typedef void (*xrr_free_monitors_t)(xrr_monitor_info *monitors); @@ -193,17 +195,20 @@ protected: 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 Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); virtual void finalize(); virtual void set_main_loop(MainLoop *p_main_loop); - void _window_changed(XEvent *xevent); + void _window_changed(XEvent *event); + + bool is_window_maximize_allowed(); public: virtual String get_name(); virtual void set_cursor_shape(CursorShape p_shape); + virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot); void set_mouse_mode(MouseMode p_mode); MouseMode get_mouse_mode() const; @@ -247,6 +252,7 @@ public: virtual Point2 get_window_position() const; virtual void set_window_position(const Point2 &p_position); virtual Size2 get_window_size() const; + virtual Size2 get_real_window_size() const; virtual void set_window_size(const Size2 p_size); virtual void set_window_fullscreen(bool p_enabled); virtual bool is_window_fullscreen() const; @@ -256,12 +262,16 @@ public: virtual bool is_window_minimized() const; virtual void set_window_maximized(bool p_enabled); virtual bool is_window_maximized() const; + virtual void set_window_always_on_top(bool p_enabled); + virtual bool is_window_always_on_top() const; virtual void request_attention(); virtual void set_borderless_window(bool p_borderless); virtual bool get_borderless_window(); virtual void set_ime_position(const Point2 &p_pos); + virtual String get_unique_id() const; + virtual void move_window_to_foreground(); virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); diff --git a/platform/x11/platform_config.h b/platform/x11/platform_config.h index 0ad94803c2..58d6b210ee 100644 --- a/platform/x11/platform_config.h +++ b/platform/x11/platform_config.h @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifdef __linux__ #include <alloca.h> #endif |