summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/export/export.cpp21
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java30
-rw-r--r--platform/android/os_android.cpp5
-rw-r--r--platform/android/os_android.h3
-rw-r--r--platform/haiku/os_haiku.cpp4
-rw-r--r--platform/haiku/os_haiku.h2
-rw-r--r--platform/iphone/SCsub1
-rw-r--r--platform/iphone/camera_ios.h45
-rw-r--r--platform/iphone/camera_ios.mm436
-rw-r--r--platform/iphone/export/export.cpp64
-rw-r--r--platform/iphone/gl_view.h2
-rw-r--r--platform/iphone/gl_view.mm49
-rw-r--r--platform/iphone/godot_iphone.cpp2
-rw-r--r--platform/iphone/in_app_store.mm2
-rw-r--r--platform/iphone/ios.h1
-rw-r--r--platform/iphone/ios.mm16
-rw-r--r--platform/iphone/os_iphone.cpp21
-rw-r--r--platform/iphone/os_iphone.h6
-rw-r--r--platform/javascript/detect.py17
-rw-r--r--platform/javascript/http_client_javascript.cpp4
-rw-r--r--platform/javascript/os_javascript.cpp5
-rw-r--r--platform/javascript/os_javascript.h3
-rw-r--r--platform/osx/SCsub1
-rw-r--r--platform/osx/camera_osx.h47
-rw-r--r--platform/osx/camera_osx.mm362
-rw-r--r--platform/osx/crash_handler_osx.mm4
-rw-r--r--platform/osx/detect.py3
-rw-r--r--platform/osx/joypad_osx.cpp2
-rw-r--r--platform/osx/os_osx.h9
-rw-r--r--platform/osx/os_osx.mm92
-rw-r--r--platform/server/os_server.cpp4
-rw-r--r--platform/server/os_server.h1
-rw-r--r--platform/uwp/detect.py1
-rw-r--r--platform/uwp/export/export.cpp12
-rw-r--r--platform/uwp/os_uwp.cpp5
-rw-r--r--platform/uwp/os_uwp.h3
-rw-r--r--platform/windows/SCsub1
-rw-r--r--platform/windows/camera_win.cpp98
-rw-r--r--platform/windows/camera_win.h46
-rw-r--r--platform/windows/context_gl_windows.cpp41
-rw-r--r--platform/windows/context_gl_windows.h3
-rw-r--r--platform/windows/detect.py7
-rw-r--r--platform/windows/export/export.cpp77
-rw-r--r--platform/windows/godot.natvis8
-rwxr-xr-x[-rw-r--r--]platform/windows/os_windows.cpp153
-rw-r--r--platform/windows/os_windows.h76
-rw-r--r--platform/x11/os_x11.cpp81
-rw-r--r--platform/x11/os_x11.h6
48 files changed, 593 insertions, 1289 deletions
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 6d021ad33a..4194e129ef 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -220,6 +220,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String name;
String description;
int api_level;
+ bool usb;
};
struct APKExportData {
@@ -246,17 +247,20 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String devices;
List<String> args;
args.push_back("devices");
+ args.push_back("-l");
int ec;
OS::get_singleton()->execute(adb, args, true, NULL, &devices, &ec);
Vector<String> ds = devices.split("\n");
Vector<String> ldevices;
+ Vector<bool> ldevices_usbconnection;
for (int i = 1; i < ds.size(); i++) {
String d = ds[i];
- int dpos = d.find("device");
+ int dpos = d.find(" device ");
if (dpos == -1)
continue;
+ ldevices_usbconnection.push_back(d.find(" usb:") != -1);
d = d.substr(0, dpos).strip_edges();
ldevices.push_back(d);
}
@@ -287,6 +291,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
Device d;
d.id = ldevices[i];
+ d.usb = ldevices_usbconnection[i];
for (int j = 0; j < ea->devices.size(); j++) {
if (ea->devices[j].id == ldevices[i]) {
d.description = ea->devices[j].description;
@@ -341,9 +346,17 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
} else if (p.begins_with("ro.opengles.version=")) {
uint32_t opengl = p.get_slice("=", 1).to_int();
d.description += "OpenGL: " + itos(opengl >> 16) + "." + itos((opengl >> 8) & 0xFF) + "." + itos((opengl)&0xFF) + "\n";
+ } else if (p.begins_with("ro.boot.serialno=")) {
+ d.description += "Serial: " + p.get_slice("=", 1).strip_edges() + "\n";
}
}
+ if (d.usb) {
+ d.description += "Connection: USB\n";
+ } else {
+ d.description += "Connection: " + d.id + "\n";
+ }
+
d.name = vendor + " " + device;
if (device == String()) continue;
}
@@ -1415,7 +1428,9 @@ public:
}
const bool use_remote = (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) || (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT);
- const bool use_reverse = devices[p_device].api_level >= 21;
+ const bool use_reverse = devices[p_device].api_level >= 21 && devices[p_device].usb;
+ // Note: Reverse can still fail if device is connected by both usb and network
+ // Ideally we'd know for sure whether adb reverse would work before we build the APK
if (use_reverse)
p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST;
@@ -1520,7 +1535,7 @@ public:
}
} else {
- static const char *const msg = "--- Device API < 21; debugging over Wi-Fi ---";
+ static const char *const msg = "--- Device API < 21 or no USB connection; debugging over Wi-Fi ---";
EditorNode::get_singleton()->get_log()->add_message(msg, EditorLog::MSG_TYPE_EDITOR);
print_line(String(msg).to_upper());
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
index 2c4a444e5a..21df5a91b0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* PermissionsUtil.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
package org.godotengine.godot.utils;
import android.Manifest;
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index defee8f1f1..9068b76cfb 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -175,9 +175,6 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
input = memnew(InputDefault);
input->set_fallback_mapping(godot_java->get_input_fallback_mapping());
- ///@TODO implement a subclass for Android and instantiate that instead
- camera_server = memnew(CameraServer);
-
//power_manager = memnew(PowerAndroid);
return OK;
@@ -196,8 +193,6 @@ void OS_Android::delete_main_loop() {
void OS_Android::finalize() {
- memdelete(camera_server);
-
memdelete(input);
}
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index a290c0cedd..16b5c8c3a3 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -39,7 +39,6 @@
#include "main/input_default.h"
//#include "power_android.h"
#include "servers/audio_server.h"
-#include "servers/camera_server.h"
#include "servers/visual/rasterizer.h"
class GodotJavaWrapper;
@@ -79,8 +78,6 @@ private:
VisualServer *visual_server;
- CameraServer *camera_server;
-
mutable String data_dir_cache;
//AudioDriverAndroid audio_driver_android;
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 9c07535c85..438b50053f 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -133,8 +133,6 @@ Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p
window->Show();
visual_server->init();
- camera_server = memnew(CameraServer);
-
AudioDriverManager::initialize(p_audio_driver);
return OK;
@@ -150,8 +148,6 @@ void OS_Haiku::finalize() {
visual_server->finish();
memdelete(visual_server);
- memdelete(camera_server);
-
memdelete(input);
#if defined(OPENGL_ENABLED)
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
index 70d78a1978..e1d4cf8d87 100644
--- a/platform/haiku/os_haiku.h
+++ b/platform/haiku/os_haiku.h
@@ -38,7 +38,6 @@
#include "haiku_direct_window.h"
#include "main/input_default.h"
#include "servers/audio_server.h"
-#include "servers/camera_server.h"
#include "servers/visual_server.h"
class OS_Haiku : public OS_Unix {
@@ -50,7 +49,6 @@ private:
VisualServer *visual_server;
VideoMode current_video_mode;
int video_driver_index;
- CameraServer *camera_server;
#ifdef MEDIA_KIT_ENABLED
AudioDriverMediaKit driver_media_kit;
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 85ba56165b..fa1b124561 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -14,7 +14,6 @@ iphone_lib = [
'in_app_store.mm',
'icloud.mm',
'ios.mm',
- 'camera_ios.mm',
]
env_ios = env.Clone()
diff --git a/platform/iphone/camera_ios.h b/platform/iphone/camera_ios.h
deleted file mode 100644
index ceabdba6a3..0000000000
--- a/platform/iphone/camera_ios.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*************************************************************************/
-/* camera_ios.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef CAMERAIOS_H
-#define CAMERAIOS_H
-
-#include "servers/camera_server.h"
-
-class CameraIOS : public CameraServer {
-private:
-public:
- CameraIOS();
- ~CameraIOS();
-
- void update_feeds();
-};
-
-#endif /* CAMERAIOS_H */ \ No newline at end of file
diff --git a/platform/iphone/camera_ios.mm b/platform/iphone/camera_ios.mm
deleted file mode 100644
index ff84df66ff..0000000000
--- a/platform/iphone/camera_ios.mm
+++ /dev/null
@@ -1,436 +0,0 @@
-/*************************************************************************/
-/* camera_ios.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-///@TODO this is a near duplicate of CameraOSX, we should find a way to combine those to minimise code duplication!!!!
-// If you fix something here, make sure you fix it there as wel!
-
-#include "camera_ios.h"
-#include "servers/camera/camera_feed.h"
-
-#import <AVFoundation/AVFoundation.h>
-#import <UIKit/UIKit.h>
-
-//////////////////////////////////////////////////////////////////////////
-// MyCaptureSession - This is a little helper class so we can capture our frames
-
-@interface MyCaptureSession : AVCaptureSession <AVCaptureVideoDataOutputSampleBufferDelegate> {
- Ref<CameraFeed> feed;
- size_t width[2];
- size_t height[2];
- PoolVector<uint8_t> img_data[2];
-
- AVCaptureDeviceInput *input;
- AVCaptureVideoDataOutput *output;
-}
-
-@end
-
-@implementation MyCaptureSession
-
-- (id)initForFeed:(Ref<CameraFeed>)p_feed andDevice:(AVCaptureDevice *)p_device {
- if (self = [super init]) {
- NSError *error;
- feed = p_feed;
- width[0] = 0;
- height[0] = 0;
- width[1] = 0;
- height[1] = 0;
-
- // prepare our device
- [p_device lockForConfiguration:&error];
-
- [p_device setFocusMode:AVCaptureFocusModeLocked];
- [p_device setExposureMode:AVCaptureExposureModeLocked];
- [p_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked];
-
- [p_device unlockForConfiguration];
-
- [self beginConfiguration];
-
- // setup our capture
- self.sessionPreset = AVCaptureSessionPreset1280x720;
-
- input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error];
- if (!input) {
- print_line("Couldn't get input device for camera");
- } else {
- [self addInput:input];
- }
-
- output = [AVCaptureVideoDataOutput new];
- if (!output) {
- print_line("Couldn't get output device for camera");
- } else {
- NSDictionary *settings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) };
- output.videoSettings = settings;
-
- // discard if the data output queue is blocked (as we process the still image)
- [output setAlwaysDiscardsLateVideoFrames:YES];
-
- // now set ourselves as the delegate to receive new frames. Note that we're doing this on the main thread at the moment, we may need to change this..
- [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
-
- [self addOutput:output];
- }
-
- [self commitConfiguration];
-
- // kick off our session..
- [self startRunning];
- };
- return self;
-}
-
-- (void)cleanup {
- // stop running
- [self stopRunning];
-
- // cleanup
- [self beginConfiguration];
-
- if (input) {
- [self removeInput:input];
- // don't release this
- input = nil;
- }
-
- if (output) {
- [self removeOutput:output];
- [output setSampleBufferDelegate:nil queue:NULL];
- [output release];
- output = nil;
- }
-
- [self commitConfiguration];
-}
-
-- (void)dealloc {
- // bye bye
- [super dealloc];
-}
-
-- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
- // This gets called every time our camera has a new image for us to process.
- // May need to investigate in a way to throttle this if we get more images then we're rendering frames..
-
- // For now, version 1, we're just doing the bare minimum to make this work...
-
- CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
- // int width = CVPixelBufferGetWidth(pixelBuffer);
- // int height = CVPixelBufferGetHeight(pixelBuffer);
-
- // It says that we need to lock this on the documentation pages but it's not in the samples
- // need to lock our base address so we can access our pixel buffers, better safe then sorry?
- CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
-
- // get our buffers
- unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
- unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
- if (dataY == NULL) {
- print_line("Couldn't access Y pixel buffer data");
- } else if (dataCbCr == NULL) {
- print_line("Couldn't access CbCr pixel buffer data");
- } else {
- UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
- Ref<Image> img[2];
-
- {
- // do Y
- int new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
- int new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
- int _bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0);
-
- if ((width[0] != new_width) || (height[0] != new_height)) {
- // printf("Camera Y plane %i, %i - %i\n", new_width, new_height, bytes_per_row);
-
- width[0] = new_width;
- height[0] = new_height;
- img_data[0].resize(new_width * new_height);
- }
-
- PoolVector<uint8_t>::Write w = img_data[0].write();
- memcpy(w.ptr(), dataY, new_width * new_height);
-
- img[0].instance();
- img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]);
- }
-
- {
- // do CbCr
- int new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
- int new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
- int bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1);
-
- if ((width[1] != new_width) || (height[1] != new_height)) {
- // printf("Camera CbCr plane %i, %i - %i\n", new_width, new_height, bytes_per_row);
-
- width[1] = new_width;
- height[1] = new_height;
- img_data[1].resize(2 * new_width * new_height);
- }
-
- PoolVector<uint8_t>::Write w = img_data[1].write();
- memcpy(w.ptr(), dataCbCr, 2 * new_width * new_height);
-
- ///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion
- img[1].instance();
- img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]);
- }
-
- // set our texture...
- feed->set_YCbCr_imgs(img[0], img[1]);
-
- // update our matrix to match the orientation, note, before changing anything
- // here, be aware that the project orientation settings must match your xcode
- // settings or this will go wrong!
- Transform2D display_transform;
- switch (orientation) {
- case UIInterfaceOrientationPortrait: {
- display_transform = Transform2D(0.0, -1.0, -1.0, 0.0, 1.0, 1.0);
- } break;
- case UIInterfaceOrientationLandscapeRight: {
- display_transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0);
- } break;
- case UIInterfaceOrientationLandscapeLeft: {
- display_transform = Transform2D(-1.0, 0.0, 0.0, 1.0, 1.0, 0.0);
- } break;
- default: {
- display_transform = Transform2D(0.0, 1.0, 1.0, 0.0, 0.0, 0.0);
- } break;
- }
-
- //TODO: this is correct for the camera on the back, I have a feeling this needs to be inversed for the camera on the front!
- feed->set_transform(display_transform);
- }
-
- // and unlock
- CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
-}
-
-@end
-
-//////////////////////////////////////////////////////////////////////////
-// CameraFeedIOS - Subclass for camera feeds in iOS
-
-class CameraFeedIOS : public CameraFeed {
-private:
- AVCaptureDevice *device;
- MyCaptureSession *capture_session;
-
-public:
- bool get_is_arkit() const;
- AVCaptureDevice *get_device() const;
-
- CameraFeedIOS();
- ~CameraFeedIOS();
-
- void set_device(AVCaptureDevice *p_device);
-
- bool activate_feed();
- void deactivate_feed();
-};
-
-AVCaptureDevice *CameraFeedIOS::get_device() const {
- return device;
-};
-
-CameraFeedIOS::CameraFeedIOS() {
- capture_session = NULL;
- device = NULL;
- transform = Transform2D(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); /* should re-orientate this based on device orientation */
-};
-
-void CameraFeedIOS::set_device(AVCaptureDevice *p_device) {
- device = p_device;
- [device retain];
-
- // get some info
- NSString *device_name = p_device.localizedName;
- name = device_name.UTF8String;
- position = CameraFeed::FEED_UNSPECIFIED;
- if ([p_device position] == AVCaptureDevicePositionBack) {
- position = CameraFeed::FEED_BACK;
- } else if ([p_device position] == AVCaptureDevicePositionFront) {
- position = CameraFeed::FEED_FRONT;
- };
-};
-
-CameraFeedIOS::~CameraFeedIOS() {
- if (capture_session != NULL) {
- [capture_session release];
- capture_session = NULL;
- };
-
- if (device != NULL) {
- [device release];
- device = NULL;
- };
-};
-
-bool CameraFeedIOS::activate_feed() {
- if (capture_session) {
- // already recording!
- } else {
- // start camera capture
- capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device];
- };
-
- return true;
-};
-
-void CameraFeedIOS::deactivate_feed() {
- // end camera capture if we have one
- if (capture_session) {
- [capture_session cleanup];
- [capture_session release];
- capture_session = NULL;
- };
-};
-
-//////////////////////////////////////////////////////////////////////////
-// MyDeviceNotifications - This is a little helper class gets notifications
-// when devices are connected/disconnected
-
-@interface MyDeviceNotifications : NSObject {
- CameraIOS *camera_server;
-}
-
-@end
-
-@implementation MyDeviceNotifications
-
-- (void)devices_changed:(NSNotification *)notification {
- camera_server->update_feeds();
-}
-
-- (id)initForServer:(CameraIOS *)p_server {
- if (self = [super init]) {
- camera_server = p_server;
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasConnectedNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasDisconnectedNotification object:nil];
- };
- return self;
-}
-
-- (void)dealloc {
- // remove notifications
- [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil];
-
- [super dealloc];
-}
-
-@end
-
-MyDeviceNotifications *device_notifications = nil;
-
-//////////////////////////////////////////////////////////////////////////
-// CameraIOS - Subclass for our camera server on iPhone
-
-void CameraIOS::update_feeds() {
- // this way of doing things is deprecated but still works,
- // rewrite to using AVCaptureDeviceDiscoverySession
-
- AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeBuiltInTelephotoCamera, AVCaptureDeviceTypeBuiltInDualCamera, AVCaptureDeviceTypeBuiltInTrueDepthCamera, AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
-
- // remove devices that are gone..
- for (int i = feeds.size() - 1; i >= 0; i--) {
- Ref<CameraFeedIOS> feed(feeds[i]);
-
- if (feed.is_null()) {
- // feed not managed by us
- } else if (![session.devices containsObject:feed->get_device()]) {
- // remove it from our array, this will also destroy it ;)
- remove_feed(feed);
- };
- };
-
- // add new devices..
- for (AVCaptureDevice *device in session.devices) {
- bool found = false;
-
- for (int i = 0; i < feeds.size() && !found; i++) {
- Ref<CameraFeedIOS> feed(feeds[i]);
-
- if (feed.is_null()) {
- // feed not managed by us
- } else if (feed->get_device() == device) {
- found = true;
- };
- };
-
- if (!found) {
- Ref<CameraFeedIOS> newfeed;
- newfeed.instance();
- newfeed->set_device(device);
- add_feed(newfeed);
- };
- };
-};
-
-CameraIOS::CameraIOS() {
- // check if we have our usage description
- NSString *usage_desc = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSCameraUsageDescription"];
- if (usage_desc == NULL) {
- // don't initialise if we don't get anything
- print_line("No NSCameraUsageDescription key in pList, no access to cameras.");
- return;
- } else if (usage_desc.length == 0) {
- // don't initialise if we don't get anything
- print_line("Empty NSCameraUsageDescription key in pList, no access to cameras.");
- return;
- }
-
- // now we'll request access.
- // If this is the first time the user will be prompted with the string (iOS will read it).
- // Once a decision is made it is returned. If the user wants to change it later on they
- // need to go into setting.
- print_line("Requesting Camera permissions");
-
- [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
- completionHandler:^(BOOL granted) {
- if (granted) {
- print_line("Access to cameras granted!");
-
- // Find available cameras we have at this time
- update_feeds();
-
- // should only have one of these....
- device_notifications = [[MyDeviceNotifications alloc] initForServer:this];
- } else {
- print_line("No access to cameras!");
- }
- }];
-};
-
-CameraIOS::~CameraIOS() {
- [device_notifications release];
-};
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index baae13c53d..4f4439bc60 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -63,6 +63,10 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
String architectures;
String linker_flags;
String cpp_code;
+ String modules_buildfile;
+ String modules_fileref;
+ String modules_buildphase;
+ String modules_buildgrp;
};
struct ExportArchitecture {
@@ -178,6 +182,7 @@ public:
return list;
}
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
+ virtual void add_module_code(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid);
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
@@ -214,7 +219,7 @@ void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset>
Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_get_supported_architectures() {
Vector<ExportArchitecture> archs;
- archs.push_back(ExportArchitecture("armv7", true));
+ archs.push_back(ExportArchitecture("armv7", false)); // Disabled by default, not included in official templates.
archs.push_back(ExportArchitecture("arm64", true));
return archs;
}
@@ -263,11 +268,16 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/arkit"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/camera"), false));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/access_wifi"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/game_center"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/in_app_purchases"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/push_notifications"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data/accessible_from_files_app"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data/accessible_from_itunes_sharing"), false));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the camera"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need access to the photo library"), ""));
@@ -311,6 +321,14 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
for (int i = 0; i < lines.size(); i++) {
if (lines[i].find("$binary") != -1) {
strnew += lines[i].replace("$binary", p_config.binary_name) + "\n";
+ } else if (lines[i].find("$modules_buildfile") != -1) {
+ strnew += lines[i].replace("$modules_buildfile", p_config.modules_buildfile) + "\n";
+ } else if (lines[i].find("$modules_fileref") != -1) {
+ strnew += lines[i].replace("$modules_fileref", p_config.modules_fileref) + "\n";
+ } else if (lines[i].find("$modules_buildphase") != -1) {
+ strnew += lines[i].replace("$modules_buildphase", p_config.modules_buildphase) + "\n";
+ } else if (lines[i].find("$modules_buildgrp") != -1) {
+ strnew += lines[i].replace("$modules_buildgrp", p_config.modules_buildgrp) + "\n";
} else if (lines[i].find("$name") != -1) {
strnew += lines[i].replace("$name", p_config.pkg_name) + "\n";
} else if (lines[i].find("$info") != -1) {
@@ -349,6 +367,10 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
strnew += lines[i].replace("$linker_flags", p_config.linker_flags) + "\n";
} else if (lines[i].find("$cpp_code") != -1) {
strnew += lines[i].replace("$cpp_code", p_config.cpp_code) + "\n";
+ } else if (lines[i].find("$docs_in_place") != -1) {
+ strnew += lines[i].replace("$docs_in_place", ((bool)p_preset->get("user_data/accessible_from_files_app")) ? "<true/>" : "<false/>") + "\n";
+ } else if (lines[i].find("$docs_sharing") != -1) {
+ strnew += lines[i].replace("$docs_sharing", ((bool)p_preset->get("user_data/accessible_from_itunes_sharing")) ? "<true/>" : "<false/>") + "\n";
} else if (lines[i].find("$access_wifi") != -1) {
bool is_on = p_preset->get("capabilities/access_wifi");
strnew += lines[i].replace("$access_wifi", is_on ? "1" : "0") + "\n";
@@ -837,6 +859,22 @@ Vector<String> EditorExportPlatformIOS::_get_preset_architectures(const Ref<Edit
return enabled_archs;
}
+void EditorExportPlatformIOS::add_module_code(const Ref<EditorExportPreset> &p_preset, EditorExportPlatformIOS::IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid) {
+ if ((bool)p_preset->get("capabilities/" + p_name)) {
+ //add module static library
+ print_line("ADDING MODULE: " + p_name);
+
+ p_config_data.modules_buildfile += p_gid + " /* libgodot_" + p_name + "_module.a in Frameworks */ = {isa = PBXBuildFile; fileRef = " + p_fid + " /* libgodot_" + p_name + "_module.a */; };\n\t\t";
+ p_config_data.modules_fileref += p_fid + " /* libgodot_" + p_name + "_module.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot_" + p_name + "_module ; path = \"libgodot_" + p_name + "_module.a\"; sourceTree = \"<group>\"; };\n\t\t";
+ p_config_data.modules_buildphase += p_gid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t";
+ p_config_data.modules_buildgrp += p_fid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t";
+ } else {
+ //add stub function for disabled module
+ p_config_data.cpp_code += "void register_" + p_name + "_types() { /*stub*/ };\n";
+ p_config_data.cpp_code += "void unregister_" + p_name + "_types() { /*stub*/ };\n";
+ }
+}
+
Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
@@ -934,7 +972,11 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
_get_additional_plist_content(),
String(" ").join(_get_preset_architectures(p_preset)),
_get_linker_flags(),
- _get_cpp_code()
+ _get_cpp_code(),
+ "",
+ "",
+ "",
+ ""
};
DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir);
@@ -949,6 +991,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
return ERR_CANT_OPEN;
}
+ add_module_code(p_preset, config_data, "arkit", "F9B95E6E2391205500AF0000", "F9C95E812391205C00BF0000");
+ add_module_code(p_preset, config_data, "camera", "F9B95E6E2391205500AF0001", "F9C95E812391205C00BF0001");
+
+ //export rest of the files
int ret = unzGoToFirstFile(src_pkg_zip);
Vector<uint8_t> project_file_data;
while (ret == UNZ_OK) {
@@ -988,6 +1034,20 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
is_execute = true;
#endif
file = "godot_ios.a";
+ } else if (file.begins_with("libgodot_arkit")) {
+ if ((bool)p_preset->get("capabilities/arkit") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) {
+ file = "libgodot_arkit_module.a";
+ } else {
+ ret = unzGoToNextFile(src_pkg_zip);
+ continue; //ignore!
+ }
+ } else if (file.begins_with("libgodot_camera")) {
+ if ((bool)p_preset->get("capabilities/camera") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) {
+ file = "libgodot_camera_module.a";
+ } else {
+ ret = unzGoToNextFile(src_pkg_zip);
+ continue; //ignore!
+ }
}
if (file == project_file) {
project_file_data = data;
diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h
index 4fb721f159..e3c9d212f0 100644
--- a/platform/iphone/gl_view.h
+++ b/platform/iphone/gl_view.h
@@ -79,8 +79,6 @@
@property(strong, nonatomic) AVPlayer *avPlayer;
@property(strong, nonatomic) AVPlayerLayer *avPlayerLayer;
-// Old videoplayer properties
-@property(strong, nonatomic) MPMoviePlayerController *moviePlayerController;
@property(strong, nonatomic) UIWindow *backgroundWindow;
@property(nonatomic) UITextAutocorrectionType autocorrectionType;
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index dfca2e3dd7..4e6b8e1ada 100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -340,6 +340,7 @@ static void clear_touches() {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
+ [self drawView];
}
- (BOOL)createFramebuffer {
@@ -455,23 +456,23 @@ static void clear_touches() {
// Updates the OpenGL view when the timer fires
- (void)drawView {
+
+ if (!active) {
+ printf("draw view not active!\n");
+ return;
+ };
if (useCADisplayLink) {
// Pause the CADisplayLink to avoid recursion
[displayLink setPaused:YES];
// Process all input events
- while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource)
+ while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, TRUE) == kCFRunLoopRunHandledSource)
;
// We are good to go, resume the CADisplayLink
[displayLink setPaused:NO];
}
- if (!active) {
- printf("draw view not active!\n");
- return;
- };
-
// Make sure that you are drawing to the current context
[EAGLContext setCurrentContext:context];
@@ -729,40 +730,4 @@ static void clear_touches() {
_stop_video();
}
-/*
-- (void)moviePlayBackDidFinish:(NSNotification*)notification {
-
-
- NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
- switch ([reason intValue]) {
- case MPMovieFinishReasonPlaybackEnded:
- //NSLog(@"Playback Ended");
- break;
- case MPMovieFinishReasonPlaybackError:
- //NSLog(@"Playback Error");
- video_found_error = true;
- break;
- case MPMovieFinishReasonUserExited:
- //NSLog(@"User Exited");
- video_found_error = true;
- break;
- default:
- //NSLog(@"Unsupported reason!");
- break;
- }
-
- MPMoviePlayerController *player = [notification object];
-
- [[NSNotificationCenter defaultCenter]
- removeObserver:self
- name:MPMoviePlayerPlaybackDidFinishNotification
- object:player];
-
- [_instance.moviePlayerController stop];
- [_instance.moviePlayerController.view removeFromSuperview];
-
- video_playing = false;
-}
-*/
-
@end
diff --git a/platform/iphone/godot_iphone.cpp b/platform/iphone/godot_iphone.cpp
index db93db5021..992da2818b 100644
--- a/platform/iphone/godot_iphone.cpp
+++ b/platform/iphone/godot_iphone.cpp
@@ -47,7 +47,7 @@ int iphone_main(int, int, int, char **, String);
int iphone_main(int width, int height, int argc, char **argv, String data_dir) {
- int len = strlen(argv[0]);
+ size_t len = strlen(argv[0]);
while (len--) {
if (argv[0][len] == '/') break;
diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm
index 490e84c571..8eef430621 100644
--- a/platform/iphone/in_app_store.mm
+++ b/platform/iphone/in_app_store.mm
@@ -92,7 +92,7 @@ void InAppStore::_bind_methods() {
PoolStringArray localized_prices;
PoolStringArray currency_codes;
- for (int i = 0; i < [products count]; i++) {
+ for (NSUInteger i = 0; i < [products count]; i++) {
SKProduct *product = [products objectAtIndex:i];
diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h
index 91c4725b35..ef45fc7ac3 100644
--- a/platform/iphone/ios.h
+++ b/platform/iphone/ios.h
@@ -42,6 +42,7 @@ class iOS : public Object {
public:
static void alert(const char *p_alert, const char *p_title);
+ String get_model() const;
String get_rate_url(int p_app_id) const;
iOS();
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index 686422ceb2..6e986df493 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "ios.h"
+#include <sys/sysctl.h>
#import <UIKit/UIKit.h>
@@ -42,6 +43,21 @@ void iOS::alert(const char *p_alert, const char *p_title) {
[alert show];
}
+String iOS::get_model() const {
+ // [[UIDevice currentDevice] model] only returns "iPad" or "iPhone".
+ size_t size;
+ sysctlbyname("hw.machine", NULL, &size, NULL, 0);
+ char *model = (char *)malloc(size);
+ if (model == NULL) {
+ return "";
+ }
+ sysctlbyname("hw.machine", model, &size, NULL, 0);
+ NSString *platform = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
+ free(model);
+ const char *str = [platform UTF8String];
+ return String(str != NULL ? str : "");
+}
+
String iOS::get_rate_url(int p_app_id) const {
String templ = "itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
String templ_iOS7 = "itms-apps://itunes.apple.com/app/idAPP_ID";
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 353078c51c..8984ed1d7b 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -47,8 +47,6 @@
#include "semaphore_iphone.h"
-#include "ios.h"
-
#include <dlfcn.h>
int OSIPhone::get_video_driver_count() const {
@@ -166,8 +164,6 @@ Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p
input = memnew(InputDefault);
- camera_server = memnew(CameraIOS);
-
#ifdef GAME_CENTER_ENABLED
game_center = memnew(GameCenter);
Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center));
@@ -184,7 +180,8 @@ Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p
Engine::get_singleton()->add_singleton(Engine::Singleton("ICloud", icloud));
//icloud->connect();
#endif
- Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", memnew(iOS)));
+ ios = memnew(iOS);
+ Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", ios));
return OK;
};
@@ -362,11 +359,6 @@ void OSIPhone::finalize() {
if (main_loop) // should not happen?
memdelete(main_loop);
- if (camera_server) {
- memdelete(camera_server);
- camera_server = NULL;
- }
-
visual_server->finish();
memdelete(visual_server);
// memdelete(rasterizer);
@@ -507,6 +499,15 @@ String OSIPhone::get_name() const {
return "iOS";
};
+String OSIPhone::get_model_name() const {
+
+ String model = ios->get_model();
+ if (model != "")
+ return model;
+
+ return OS_Unix::get_model_name();
+}
+
Size2 OSIPhone::get_window_size() const {
return Vector2(video_mode.width, video_mode.height);
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 804ba0b1af..1f49062cfc 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -37,10 +37,10 @@
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/unix/os_unix.h"
-#include "camera_ios.h"
#include "game_center.h"
#include "icloud.h"
#include "in_app_store.h"
+#include "ios.h"
#include "main/input_default.h"
#include "servers/audio_server.h"
#include "servers/visual/rasterizer.h"
@@ -61,8 +61,6 @@ private:
AudioDriverCoreAudio audio_driver;
- CameraServer *camera_server;
-
#ifdef GAME_CENTER_ENABLED
GameCenter *game_center;
#endif
@@ -72,6 +70,7 @@ private:
#ifdef ICLOUD_ENABLED
ICloud *icloud;
#endif
+ iOS *ios;
MainLoop *main_loop;
@@ -178,6 +177,7 @@ public:
void set_data_dir(String p_dir);
virtual String get_name() const;
+ virtual String get_model_name() const;
Error shell_open(String p_uri);
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index a0d6ac9214..7bf3e1bc1d 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -24,6 +24,7 @@ def get_opts():
def get_flags():
return [
('tools', False),
+ ('builtin_pcre2_with_jit', 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
@@ -82,10 +83,7 @@ def configure(env):
env['CXX'] = 'em++'
env['LINK'] = 'emcc'
- # Emscripten's ar has issues with duplicate file names, so use cc.
- env['AR'] = 'emcc'
- env['ARFLAGS'] = '-o'
- # emranlib is a noop, so it's safe to use with AR=emcc.
+ env['AR'] = 'emar'
env['RANLIB'] = 'emranlib'
# Use TempFileMunge since some AR invocations are too long for cmd.exe.
@@ -127,8 +125,19 @@ def configure(env):
## Link flags
+ # We use IDBFS in javascript_main.cpp. Since Emscripten 1.39.1 it needs to
+ # be linked explicitly.
+ env.Append(LIBS=['idbfs.js'])
+
env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
+ # This needs to be defined for Emscripten using 'fastcomp' (default pre-1.39.0)
+ # and undefined if using 'upstream'. And to make things simple, earlier
+ # Emscripten versions didn't include 'fastcomp' in their path, so we check
+ # against the presence of 'upstream' to conditionally add the flag.
+ if not "upstream" in em_config['EMSCRIPTEN_ROOT']:
+ env.Append(LINKFLAGS=['-s', 'BINARYEN_TRAP_MODE=\'clamp\''])
+
# Allow increasing memory buffer size during runtime. This is efficient
# when using WebAssembly (in comparison to asm.js) and works well for
# us since we don't know requirements at compile-time.
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index e6e933811f..1f3f2ed53c 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -211,6 +211,10 @@ void HTTPClient::set_read_chunk_size(int p_size) {
read_limit = p_size;
}
+int HTTPClient::get_read_chunk_size() const {
+ return read_limit;
+}
+
Error HTTPClient::poll() {
switch (status) {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index b0661cb4dd..61919bb24a 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -837,7 +837,7 @@ void OS_JavaScript::set_clipboard(const String &p_text) {
var text = UTF8ToString($0);
if (!navigator.clipboard || !navigator.clipboard.writeText)
return 1;
- navigator.clipboard.writeText(text).catch(e => {
+ navigator.clipboard.writeText(text).catch(function(e) {
// Setting OS clipboard is only possible from an input callback.
console.error("Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:", e);
});
@@ -970,8 +970,6 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
VisualServer *visual_server = memnew(VisualServerRaster());
input = memnew(InputDefault);
- camera_server = memnew(CameraServer);
-
EMSCRIPTEN_RESULT result;
#define EM_CHECK(ev) \
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
@@ -1106,7 +1104,6 @@ void OS_JavaScript::delete_main_loop() {
void OS_JavaScript::finalize() {
- memdelete(camera_server);
memdelete(input);
}
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 10676c49f7..7c97e302e9 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -35,7 +35,6 @@
#include "drivers/unix/os_unix.h"
#include "main/input_default.h"
#include "servers/audio_server.h"
-#include "servers/camera_server.h"
#include "servers/visual/rasterizer.h"
#include <emscripten/html5.h>
@@ -67,8 +66,6 @@ class OS_JavaScript : public OS_Unix {
int64_t sync_wait_time;
int64_t last_sync_check_time;
- CameraServer *camera_server;
-
static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data);
static EM_BOOL keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 9620863b96..e15b4339a7 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -13,7 +13,6 @@ files = [
'dir_access_osx.mm',
'joypad_osx.cpp',
'power_osx.cpp',
- 'camera_osx.mm',
]
prog = env.add_program('#bin/godot', files)
diff --git a/platform/osx/camera_osx.h b/platform/osx/camera_osx.h
deleted file mode 100644
index 80ca3759ba..0000000000
--- a/platform/osx/camera_osx.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*************************************************************************/
-/* camera_osx.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef CAMERAOSX_H
-#define CAMERAOSX_H
-
-///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimise code duplication!!!!
-// If you fix something here, make sure you fix it there as wel!
-
-#include "servers/camera_server.h"
-
-class CameraOSX : public CameraServer {
-public:
- CameraOSX();
- ~CameraOSX();
-
- void update_feeds();
-};
-
-#endif /* CAMERAOSX_H */ \ No newline at end of file
diff --git a/platform/osx/camera_osx.mm b/platform/osx/camera_osx.mm
deleted file mode 100644
index f13cf76beb..0000000000
--- a/platform/osx/camera_osx.mm
+++ /dev/null
@@ -1,362 +0,0 @@
-/*************************************************************************/
-/* camera_osx.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimise code duplication!!!!
-// If you fix something here, make sure you fix it there as wel!
-
-#include "camera_osx.h"
-#include "servers/camera/camera_feed.h"
-#import <AVFoundation/AVFoundation.h>
-
-//////////////////////////////////////////////////////////////////////////
-// MyCaptureSession - This is a little helper class so we can capture our frames
-
-@interface MyCaptureSession : AVCaptureSession <AVCaptureVideoDataOutputSampleBufferDelegate> {
- Ref<CameraFeed> feed;
- size_t width[2];
- size_t height[2];
- PoolVector<uint8_t> img_data[2];
-
- AVCaptureDeviceInput *input;
- AVCaptureVideoDataOutput *output;
-}
-
-@end
-
-@implementation MyCaptureSession
-
-- (id)initForFeed:(Ref<CameraFeed>)p_feed andDevice:(AVCaptureDevice *)p_device {
- if (self = [super init]) {
- NSError *error;
- feed = p_feed;
- width[0] = 0;
- height[0] = 0;
- width[1] = 0;
- height[1] = 0;
-
- [self beginConfiguration];
-
- input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error];
- if (!input) {
- print_line("Couldn't get input device for camera");
- } else {
- [self addInput:input];
- }
-
- output = [AVCaptureVideoDataOutput new];
- if (!output) {
- print_line("Couldn't get output device for camera");
- } else {
- NSDictionary *settings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) };
- output.videoSettings = settings;
-
- // discard if the data output queue is blocked (as we process the still image)
- [output setAlwaysDiscardsLateVideoFrames:YES];
-
- // now set ourselves as the delegate to receive new frames.
- [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
-
- // this takes ownership
- [self addOutput:output];
- }
-
- [self commitConfiguration];
-
- // kick off our session..
- [self startRunning];
- };
- return self;
-}
-
-- (void)cleanup {
- // stop running
- [self stopRunning];
-
- // cleanup
- [self beginConfiguration];
-
- // remove input
- if (input) {
- [self removeInput:input];
- // don't release this
- input = NULL;
- }
-
- // free up our output
- if (output) {
- [self removeOutput:output];
- [output setSampleBufferDelegate:nil queue:NULL];
- [output release];
- output = NULL;
- }
-
- [self commitConfiguration];
-}
-
-- (void)dealloc {
- // bye bye
- [super dealloc];
-}
-
-- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
- // This gets called every time our camera has a new image for us to process.
- // May need to investigate in a way to throttle this if we get more images then we're rendering frames..
-
- // For now, version 1, we're just doing the bare minimum to make this work...
- CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
- // int _width = CVPixelBufferGetWidth(pixelBuffer);
- // int _height = CVPixelBufferGetHeight(pixelBuffer);
-
- // It says that we need to lock this on the documentation pages but it's not in the samples
- // need to lock our base address so we can access our pixel buffers, better safe then sorry?
- CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
-
- // get our buffers
- unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
- unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1);
- if (dataY == NULL) {
- print_line("Couldn't access Y pixel buffer data");
- } else if (dataCbCr == NULL) {
- print_line("Couldn't access CbCr pixel buffer data");
- } else {
- Ref<Image> img[2];
-
- {
- // do Y
- int new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0);
- int new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0);
-
- if ((width[0] != new_width) || (height[0] != new_height)) {
- width[0] = new_width;
- height[0] = new_height;
- img_data[0].resize(new_width * new_height);
- }
-
- PoolVector<uint8_t>::Write w = img_data[0].write();
- memcpy(w.ptr(), dataY, new_width * new_height);
-
- img[0].instance();
- img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]);
- }
-
- {
- // do CbCr
- int new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1);
- int new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1);
-
- if ((width[1] != new_width) || (height[1] != new_height)) {
- width[1] = new_width;
- height[1] = new_height;
- img_data[1].resize(2 * new_width * new_height);
- }
-
- PoolVector<uint8_t>::Write w = img_data[1].write();
- memcpy(w.ptr(), dataCbCr, 2 * new_width * new_height);
-
- ///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion
- img[1].instance();
- img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]);
- }
-
- // set our texture...
- feed->set_YCbCr_imgs(img[0], img[1]);
- }
-
- // and unlock
- CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
-}
-
-@end
-
-//////////////////////////////////////////////////////////////////////////
-// CameraFeedOSX - Subclass for camera feeds in OSX
-
-class CameraFeedOSX : public CameraFeed {
-private:
- AVCaptureDevice *device;
- MyCaptureSession *capture_session;
-
-public:
- AVCaptureDevice *get_device() const;
-
- CameraFeedOSX();
- ~CameraFeedOSX();
-
- void set_device(AVCaptureDevice *p_device);
-
- bool activate_feed();
- void deactivate_feed();
-};
-
-AVCaptureDevice *CameraFeedOSX::get_device() const {
- return device;
-};
-
-CameraFeedOSX::CameraFeedOSX() {
- device = NULL;
- capture_session = NULL;
-};
-
-void CameraFeedOSX::set_device(AVCaptureDevice *p_device) {
- device = p_device;
- [device retain];
-
- // get some info
- NSString *device_name = p_device.localizedName;
- name = device_name.UTF8String;
- position = CameraFeed::FEED_UNSPECIFIED;
- if ([p_device position] == AVCaptureDevicePositionBack) {
- position = CameraFeed::FEED_BACK;
- } else if ([p_device position] == AVCaptureDevicePositionFront) {
- position = CameraFeed::FEED_FRONT;
- };
-};
-
-CameraFeedOSX::~CameraFeedOSX() {
- if (capture_session != NULL) {
- [capture_session release];
- capture_session = NULL;
- };
-
- if (device != NULL) {
- [device release];
- device = NULL;
- };
-};
-
-bool CameraFeedOSX::activate_feed() {
- if (capture_session) {
- // already recording!
- } else {
- // start camera capture
- capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device];
- };
-
- return true;
-};
-
-void CameraFeedOSX::deactivate_feed() {
- // end camera capture if we have one
- if (capture_session) {
- [capture_session cleanup];
- [capture_session release];
- capture_session = NULL;
- };
-};
-
-//////////////////////////////////////////////////////////////////////////
-// MyDeviceNotifications - This is a little helper class gets notifications
-// when devices are connected/disconnected
-
-@interface MyDeviceNotifications : NSObject {
- CameraOSX *camera_server;
-}
-
-@end
-
-@implementation MyDeviceNotifications
-
-- (void)devices_changed:(NSNotification *)notification {
- camera_server->update_feeds();
-}
-
-- (id)initForServer:(CameraOSX *)p_server {
- if (self = [super init]) {
- camera_server = p_server;
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasConnectedNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasDisconnectedNotification object:nil];
- };
- return self;
-}
-
-- (void)dealloc {
- // remove notifications
- [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil];
-
- [super dealloc];
-}
-
-@end
-
-MyDeviceNotifications *device_notifications = nil;
-
-//////////////////////////////////////////////////////////////////////////
-// CameraOSX - Subclass for our camera server on OSX
-
-void CameraOSX::update_feeds() {
- NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
-
- // remove devices that are gone..
- for (int i = feeds.size() - 1; i >= 0; i--) {
- Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i];
-
- if (![devices containsObject:feed->get_device()]) {
- // remove it from our array, this will also destroy it ;)
- remove_feed(feed);
- };
- };
-
- // add new devices..
- for (AVCaptureDevice *device in devices) {
- bool found = false;
- for (int i = 0; i < feeds.size() && !found; i++) {
- Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i];
- if (feed->get_device() == device) {
- found = true;
- };
- };
-
- if (!found) {
- Ref<CameraFeedOSX> newfeed;
- newfeed.instance();
- newfeed->set_device(device);
-
- // assume display camera so inverse
- Transform2D transform = Transform2D(-1.0, 0.0, 0.0, -1.0, 1.0, 1.0);
- newfeed->set_transform(transform);
-
- add_feed(newfeed);
- };
- };
-};
-
-CameraOSX::CameraOSX() {
- // Find available cameras we have at this time
- update_feeds();
-
- // should only have one of these....
- device_notifications = [[MyDeviceNotifications alloc] initForServer:this];
-};
-
-CameraOSX::~CameraOSX() {
- [device_notifications release];
-};
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
index e19fdf1b9f..015859b3c0 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/osx/crash_handler_osx.mm
@@ -95,7 +95,7 @@ static void handle_crash(int sig) {
if (strings) {
void *load_addr = (void *)load_address();
- for (int i = 1; i < size; i++) {
+ for (size_t i = 1; i < size; i++) {
char fname[1024];
Dl_info info;
@@ -142,7 +142,7 @@ static void handle_crash(int sig) {
}
}
- fprintf(stderr, "[%d] %ls\n", i, output.c_str());
+ fprintf(stderr, "[%zu] %ls\n", i, output.c_str());
}
free(strings);
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 881ed05025..7882253e7a 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -91,6 +91,9 @@ def configure(env):
env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib"
env['AS'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as"
env.Append(CPPDEFINES=['__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define
+ else:
+ env['CC'] = 'clang'
+ env['CXX'] = 'clang++'
detect_darwin_sdk_path('osx', env)
env.Append(CCFLAGS=['-isysroot', '$MACOS_SDK_PATH'])
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp
index fa124dac11..4edf347f61 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/osx/joypad_osx.cpp
@@ -578,7 +578,7 @@ JoypadOSX::JoypadOSX() {
const size_t n_elements = sizeof(vals) / sizeof(vals[0]);
CFArrayRef array = okay ? CFArrayCreate(kCFAllocatorDefault, vals, n_elements, &kCFTypeArrayCallBacks) : NULL;
- for (int i = 0; i < n_elements; i++) {
+ for (size_t i = 0; i < n_elements; i++) {
if (vals[i]) {
CFRelease((CFTypeRef)vals[i]);
}
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index f1f37e24d2..78e1aa6c0a 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -31,7 +31,8 @@
#ifndef OS_OSX_H
#define OS_OSX_H
-#include "camera_osx.h"
+#define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
+
#include "core/os/input.h"
#include "crash_handler_osx.h"
#include "drivers/coreaudio/audio_driver_coreaudio.h"
@@ -50,6 +51,7 @@
#include <ApplicationServices/ApplicationServices.h>
#include <CoreVideo/CoreVideo.h>
+#undef BitMap
#undef CursorShape
class OS_OSX : public OS_Unix {
@@ -71,8 +73,6 @@ public:
//Rasterizer *rasterizer;
VisualServer *visual_server;
- CameraServer *camera_server;
-
List<String> args;
MainLoop *main_loop;
@@ -110,9 +110,6 @@ public:
NSOpenGLContext *context;
bool layered_window;
- bool waiting_for_vsync;
- NSCondition *vsync_condition;
- CVDisplayLinkRef displayLink;
CursorShape cursor_shape;
NSCursor *cursors[CURSOR_MAX];
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 51ae264cf7..122e8274b9 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -115,21 +115,6 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto
return Vector2(mouse_x, mouse_y);
}
-// DisplayLinkCallback is called from our DisplayLink OS thread informing us right before
-// a screen update is required. We can use it to work around the broken vsync.
-static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) {
- OS_OSX *os = (OS_OSX *)displayLinkContext;
-
- // Set flag so we know we can output our next frame and signal our conditional lock
- // if we're not doing vsync this will be ignored
- [os->vsync_condition lock];
- os->waiting_for_vsync = false;
- [os->vsync_condition signal];
- [os->vsync_condition unlock];
-
- return kCVReturnSuccess;
-}
-
@interface GodotApplication : NSApplication
@end
@@ -355,12 +340,8 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
//Update context
if (OS_OSX::singleton->main_loop) {
- [OS_OSX::singleton->context update];
-
- //Force window resize ???
- NSRect frame = [OS_OSX::singleton->window_object frame];
- [OS_OSX::singleton->window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES];
- [OS_OSX::singleton->window_object setFrame:frame display:YES];
+ //Force window resize event
+ [self windowDidResize:notification];
}
}
}
@@ -620,7 +601,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
Vector<String> files;
- for (int i = 0; i < filenames.count; i++) {
+ for (NSUInteger i = 0; i < filenames.count; i++) {
NSString *ns = [filenames objectAtIndex:i];
char *utfs = strdup([ns UTF8String]);
String ret;
@@ -709,6 +690,11 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
const CGFloat backingScaleFactor = [[event window] backingScaleFactor];
const Vector2 pos = get_mouse_pos([event locationInWindow], backingScaleFactor);
mm->set_position(pos);
+ mm->set_pressure([event pressure]);
+ if ([event subtype] == NSTabletPointEventSubtype) {
+ const NSPoint p = [event tilt];
+ mm->set_tilt(Vector2(p.x, p.y));
+ }
mm->set_global_position(pos);
mm->set_speed(OS_OSX::singleton->input->get_last_mouse_speed());
Vector2 relativeMotion = Vector2();
@@ -1502,7 +1488,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
[window_object setContentView:window_view];
[window_object setDelegate:window_delegate];
[window_object setAcceptsMouseMovedEvents:YES];
- [window_object center];
+ [(NSWindow *)window_object center];
[window_object setRestorable:NO];
@@ -1576,15 +1562,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
[context makeCurrentContext];
- // setup our display link, this will inform us when a refresh is needed
- CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
- CVDisplayLinkSetOutputCallback(displayLink, &DisplayLinkCallback, this);
- CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, context.CGLContextObj, pixelFormat.CGLPixelFormatObj);
- CVDisplayLinkStart(displayLink);
-
- // initialise a conditional lock object
- vsync_condition = [[NSCondition alloc] init];
-
set_use_vsync(p_desired.use_vsync);
[NSApp activateIgnoringOtherApps:YES];
@@ -1651,8 +1628,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
visual_server->init();
AudioDriverManager::initialize(p_audio_driver);
- camera_server = memnew(CameraOSX);
-
input = memnew(InputDefault);
joypad_osx = memnew(JoypadOSX);
@@ -1677,21 +1652,11 @@ void OS_OSX::finalize() {
midi_driver.close();
#endif
- if (displayLink) {
- CVDisplayLinkRelease(displayLink);
- }
- [vsync_condition release];
-
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL);
delete_main_loop();
- if (camera_server) {
- memdelete(camera_server);
- camera_server = NULL;
- }
-
memdelete(joypad_osx);
memdelete(input);
@@ -2248,23 +2213,11 @@ Error OS_OSX::shell_open(String p_uri) {
}
String OS_OSX::get_locale() const {
- NSString *locale_code = [[NSLocale currentLocale] localeIdentifier];
+ NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0];
return [locale_code UTF8String];
}
void OS_OSX::swap_buffers() {
- if (is_vsync_enabled()) {
- // Wait until our DisplayLink callback unsets our flag...
- [vsync_condition lock];
- while (waiting_for_vsync)
- [vsync_condition wait];
-
- // Make sure we wait again next frame around
- waiting_for_vsync = true;
-
- [vsync_condition unlock];
- }
-
[context flushBuffer];
}
@@ -2338,12 +2291,12 @@ void OS_OSX::set_current_screen(int p_screen) {
};
Point2 OS_OSX::get_native_screen_position(int p_screen) const {
- if (p_screen == -1) {
+ if (p_screen < 0) {
p_screen = get_current_screen();
}
NSArray *screenArray = [NSScreen screens];
- if (p_screen < [screenArray count]) {
+ if ((NSUInteger)p_screen < [screenArray count]) {
float display_scale = _display_scale([screenArray objectAtIndex:p_screen]);
NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
// Return the top-left corner of the screen, for OS X the y starts at the bottom
@@ -2362,12 +2315,12 @@ Point2 OS_OSX::get_screen_position(int p_screen) const {
}
int OS_OSX::get_screen_dpi(int p_screen) const {
- if (p_screen == -1) {
+ if (p_screen < 0) {
p_screen = get_current_screen();
}
NSArray *screenArray = [NSScreen screens];
- if (p_screen < [screenArray count]) {
+ if ((NSUInteger)p_screen < [screenArray count]) {
float displayScale = _display_scale([screenArray objectAtIndex:p_screen]);
NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription];
NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
@@ -2381,12 +2334,12 @@ int OS_OSX::get_screen_dpi(int p_screen) const {
}
Size2 OS_OSX::get_screen_size(int p_screen) const {
- if (p_screen == -1) {
+ if (p_screen < 0) {
p_screen = get_current_screen();
}
NSArray *screenArray = [NSScreen screens];
- if (p_screen < [screenArray count]) {
+ if ((NSUInteger)p_screen < [screenArray count]) {
float displayScale = _display_scale([screenArray objectAtIndex:p_screen]);
// Note: Use frame to get the whole screen size
NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
@@ -3004,20 +2957,11 @@ Error OS_OSX::move_to_trash(const String &p_path) {
}
void OS_OSX::_set_use_vsync(bool p_enable) {
- // CGLCPSwapInterval broke in OSX 10.14 and it seems Apple is not interested in fixing
- // it as OpenGL is now deprecated and Metal solves this differently.
- // Following SDLs example we're working around this using DisplayLink
- // When vsync is enabled we set a flag "waiting_for_vsync" to true.
- // This flag is set to false when DisplayLink informs us our display is about to refresh.
-
- /* CGLContextObj ctx = CGLGetCurrentContext();
+ CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_enable ? 1 : 0;
CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
- }*/
-
- ///TODO Maybe pause/unpause display link?
- waiting_for_vsync = p_enable;
+ }
}
OS_OSX *OS_OSX::singleton = NULL;
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 87dc6421ac..12e53054bc 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -88,8 +88,6 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
visual_server = memnew(VisualServerRaster);
visual_server->init();
- camera_server = memnew(CameraServer);
-
AudioDriverManager::initialize(p_audio_driver);
input = memnew(InputDefault);
@@ -119,8 +117,6 @@ void OS_Server::finalize() {
memdelete(input);
- memdelete(camera_server);
-
memdelete(power_manager);
ResourceLoader::remove_resource_format_loader(resource_loader_dummy);
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index b8119288ff..6d975ca7e0 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -71,7 +71,6 @@ class OS_Server : public OS_Unix {
#endif
CrashHandler crash_handler;
- CameraServer *camera_server;
int video_driver_index;
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 7da93eafae..000bd18e7d 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -34,6 +34,7 @@ def get_flags():
return [
('tools', False),
('xaudio2', True),
+ ('builtin_pcre2_with_jit', False),
]
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index fefad3584b..be78e4db20 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -517,7 +517,7 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
int total_out_before = strm.total_out;
int err = deflate(&strm, Z_FULL_FLUSH);
- ERR_FAIL_COND_V(err >= 0, ERR_BUG); // Negative means bug
+ ERR_FAIL_COND_V(err < 0, ERR_BUG); // Negative means bug
bh.compressed_size = strm.total_out - total_out_before;
@@ -1144,11 +1144,21 @@ public:
return valid;
}
+ if (!_valid_resource_name(p_preset->get("package/short_name"))) {
+ valid = false;
+ err += TTR("Invalid package short name.") + "\n";
+ }
+
if (!_valid_resource_name(p_preset->get("package/unique_name"))) {
valid = false;
err += TTR("Invalid package unique name.") + "\n";
}
+ if (!_valid_resource_name(p_preset->get("package/publisher_display_name"))) {
+ valid = false;
+ err += TTR("Invalid package publisher display name.") + "\n";
+ }
+
if (!_valid_guid(p_preset->get("identity/product_guid"))) {
valid = false;
err += TTR("Invalid product GUID.") + "\n";
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 60f2290355..eb0ae96111 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -303,9 +303,6 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
visual_server->init();
- ///@TODO implement a subclass for UWP and instantiate that instead
- camera_server = memnew(CameraServer);
-
input = memnew(InputDefault);
joypad = ref new JoypadUWP(input);
@@ -404,8 +401,6 @@ void OS_UWP::finalize() {
memdelete(input);
- memdelete(camera_server);
-
joypad = nullptr;
}
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 370cab6a9b..adca7d18cc 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -41,7 +41,6 @@
#include "main/input_default.h"
#include "power_uwp.h"
#include "servers/audio_server.h"
-#include "servers/camera_server.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
@@ -93,8 +92,6 @@ private:
VisualServer *visual_server;
int pressrc;
- CameraServer *camera_server;
-
ContextEGL_UWP *gl_context;
Windows::UI::Core::CoreWindow ^ window;
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index 8426ccbb89..892d734734 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -8,7 +8,6 @@ import platform_windows_builders
common_win = [
"godot_windows.cpp",
- "camera_win.cpp",
"context_gl_windows.cpp",
"crash_handler_windows.cpp",
"os_windows.cpp",
diff --git a/platform/windows/camera_win.cpp b/platform/windows/camera_win.cpp
deleted file mode 100644
index 10787d0d0a..0000000000
--- a/platform/windows/camera_win.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*************************************************************************/
-/* camera_win.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "camera_win.h"
-
-///@TODO sorry guys, I got about 80% through implementing this using DirectShow only
-// to find out Microsoft deprecated half the API and its replacement is as confusing
-// as they could make it. Joey suggested looking into libuvc which offers a more direct
-// route to webcams over USB and this is very promising but it wouldn't compile on
-// windows for me...I've gutted the classes I implemented DirectShow in just to have
-// a skeleton for someone to work on, mail me for more details or if you want a copy....
-
-//////////////////////////////////////////////////////////////////////////
-// CameraFeedWindows - Subclass for our camera feed on windows
-
-/// @TODO need to implement this
-
-class CameraFeedWindows : public CameraFeed {
-private:
-protected:
-public:
- CameraFeedWindows();
- virtual ~CameraFeedWindows();
-
- bool activate_feed();
- void deactivate_feed();
-};
-
-CameraFeedWindows::CameraFeedWindows(){
- ///@TODO implement this, should store information about our available camera
-};
-
-CameraFeedWindows::~CameraFeedWindows() {
- // make sure we stop recording if we are!
- if (is_active()) {
- deactivate_feed();
- };
-
- ///@TODO free up anything used by this
-};
-
-bool CameraFeedWindows::activate_feed() {
- ///@TODO this should activate our camera and start the process of capturing frames
-
- return true;
-};
-
-///@TODO we should probably have a callback method here that is being called by the
-// camera API which provides frames and call back into the CameraServer to update our texture
-
-void CameraFeedWindows::deactivate_feed(){
- ///@TODO this should deactivate our camera and stop the process of capturing frames
-};
-
-//////////////////////////////////////////////////////////////////////////
-// CameraWindows - Subclass for our camera server on windows
-
-void CameraWindows::add_active_cameras(){
- ///@TODO scan through any active cameras and create CameraFeedWindows objects for them
-};
-
-CameraWindows::CameraWindows() {
- // Find cameras active right now
- add_active_cameras();
-
- // need to add something that will react to devices being connected/removed...
-};
-
-CameraWindows::~CameraWindows(){
-
-};
diff --git a/platform/windows/camera_win.h b/platform/windows/camera_win.h
deleted file mode 100644
index 22ce9aa43f..0000000000
--- a/platform/windows/camera_win.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*************************************************************************/
-/* camera_win.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef CAMERAWIN_H
-#define CAMERAWIN_H
-
-#include "servers/camera/camera_feed.h"
-#include "servers/camera_server.h"
-
-class CameraWindows : public CameraServer {
-private:
- void add_active_cameras();
-
-public:
- CameraWindows();
- ~CameraWindows();
-};
-
-#endif /* CAMERAWIN_H */
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index e715999378..34a5698394 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -34,6 +34,8 @@
#include "context_gl_windows.h"
+#include <dwmapi.h>
+
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
@@ -63,16 +65,52 @@ int ContextGL_Windows::get_window_height() {
return OS::get_singleton()->get_video_mode().height;
}
+bool ContextGL_Windows::should_vsync_via_compositor() {
+
+ if (OS::get_singleton()->is_window_fullscreen() || !OS::get_singleton()->is_vsync_via_compositor_enabled()) {
+ return false;
+ }
+
+ // Note: All Windows versions supported by Godot have a compositor.
+ // It can be disabled on earlier Windows versions.
+ BOOL dwm_enabled;
+
+ if (SUCCEEDED(DwmIsCompositionEnabled(&dwm_enabled))) {
+ return dwm_enabled;
+ }
+
+ return false;
+}
+
void ContextGL_Windows::swap_buffers() {
SwapBuffers(hDC);
+
+ if (use_vsync) {
+ bool vsync_via_compositor_now = should_vsync_via_compositor();
+
+ if (vsync_via_compositor_now) {
+ DwmFlush();
+ }
+
+ if (vsync_via_compositor_now != vsync_via_compositor) {
+ // The previous frame had a different operating mode than this
+ // frame. Set the 'vsync_via_compositor' member variable and the
+ // OpenGL swap interval to their proper values.
+ set_use_vsync(true);
+ }
+ }
}
void ContextGL_Windows::set_use_vsync(bool p_use) {
+ vsync_via_compositor = p_use && should_vsync_via_compositor();
+
if (wglSwapIntervalEXT) {
- wglSwapIntervalEXT(p_use ? 1 : 0);
+ int swap_interval = (p_use && !vsync_via_compositor) ? 1 : 0;
+ wglSwapIntervalEXT(swap_interval);
}
+
use_vsync = p_use;
}
@@ -177,6 +215,7 @@ ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
opengl_3_context = p_opengl_3_context;
hWnd = hwnd;
use_vsync = false;
+ vsync_via_compositor = false;
}
ContextGL_Windows::~ContextGL_Windows() {
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index d23fba50e1..e65ea1928f 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -50,9 +50,12 @@ class ContextGL_Windows {
HWND hWnd;
bool opengl_3_context;
bool use_vsync;
+ bool vsync_via_compositor;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+ static bool should_vsync_via_compositor();
+
public:
void release_current();
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index f4390a9882..b37a21f37f 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -221,7 +221,8 @@ def configure_msvc(env, manual_msvc_config):
LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32',
'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32',
- 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt','Avrt']
+ 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt','Avrt',
+ 'dwmapi']
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS])
if manual_msvc_config:
@@ -348,9 +349,9 @@ def configure_mingw(env):
env.Append(CCFLAGS=['-mwindows'])
env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'OPENGL_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED'])
env.Append(CPPDEFINES=[('WINVER', env['target_win_version']), ('_WIN32_WINNT', env['target_win_version'])])
- env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid'])
+ env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid', 'dwmapi'])
- env.Append(CPPDEFINES=['MINGW_ENABLED'])
+ env.Append(CPPDEFINES=['MINGW_ENABLED', ('MINGW_HAS_SECURE_API', 1)])
# resrc
env.Append(BUILDERS={'RES': env.Builder(action=build_res_file, suffix='.o', src_suffix='.rc')})
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 3abb05b494..858453ddfd 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -39,6 +39,7 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start,
class EditorExportPlatformWindows : public EditorExportPlatformPC {
+ void _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
public:
@@ -62,15 +63,50 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
return err;
}
+ _rcedit_add_data(p_preset, p_path);
+
+ if (p_preset->get("codesign/enable") && err == OK) {
+ err = _code_sign(p_preset, p_path);
+ }
+
+ return err;
+}
+
+void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) {
+ EditorExportPlatformPC::get_export_options(r_options);
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false));
+#ifdef WINDOWS_ENABLED
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0));
+#endif
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
+}
+
+void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
if (rcedit_path == String()) {
- return OK;
+ return;
}
if (!FileAccess::exists(rcedit_path)) {
- ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", aborting.");
- return ERR_FILE_NOT_FOUND;
+ ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", no icon or app information data will be included.");
+ return;
}
#ifndef WINDOWS_ENABLED
@@ -78,8 +114,8 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
if (wine_path != String() && !FileAccess::exists(wine_path)) {
- ERR_PRINTS("Could not find wine executable at " + wine_path + ", aborting.");
- return ERR_FILE_NOT_FOUND;
+ ERR_PRINTS("Could not find wine executable at " + wine_path + ", no icon or app information data will be included.");
+ return;
}
if (wine_path == String()) {
@@ -144,37 +180,6 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
args.push_front(rcedit_path);
OS::get_singleton()->execute(wine_path, args, true);
#endif
-
- if (p_preset->get("codesign/enable") && err == OK) {
- err = _code_sign(p_preset, p_path);
- }
-
- return err;
-}
-
-void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) {
- EditorExportPlatformPC::get_export_options(r_options);
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false));
-#ifdef WINDOWS_ENABLED
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0));
-#endif
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray()));
-
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
}
Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis
index 55c83c3f3c..593557cc69 100644
--- a/platform/windows/godot.natvis
+++ b/platform/windows/godot.natvis
@@ -143,4 +143,12 @@
<Item Name="alpha">a</Item>
</Expand>
</Type>
+
+ <Type Name="Node" Inheritable="false">
+ <Expand>
+ <Item Name="Object">(Object*)this</Item>
+ <Item Name="class_name">(StringName*)(((char*)this) + sizeof(Object))</Item>
+ <Item Name="data">(Node::Data*)(((char*)this) + sizeof(Object) + sizeof(StringName))</Item>
+ </Expand>
+ </Type>
</AutoVisualizer>
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 81b8d08b3d..f749134f3c 100644..100755
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -70,6 +70,10 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#define WM_TOUCH 576
#endif
+#ifndef WM_POINTERUPDATE
+#define WM_POINTERUPDATE 0x0245
+#endif
+
typedef struct {
int count;
int screen;
@@ -192,6 +196,9 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
}
}
+GetPointerTypePtr OS_Windows::win8p_GetPointerType = NULL;
+GetPointerPenInfoPtr OS_Windows::win8p_GetPointerPenInfo = NULL;
+
void OS_Windows::initialize_debugging() {
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
@@ -288,15 +295,16 @@ void OS_Windows::_drag_event(float p_x, float p_y, int idx) {
if (curr->get() == Vector2(p_x, p_y))
return;
- curr->get() = Vector2(p_x, p_y);
-
Ref<InputEventScreenDrag> event;
event.instance();
event->set_index(idx);
event->set_position(Vector2(p_x, p_y));
+ event->set_relative(Vector2(p_x, p_y) - curr->get());
if (main_loop)
input->accumulate_input_event(event);
+
+ curr->get() = Vector2(p_x, p_y);
};
LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
@@ -480,6 +488,119 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
delete[] lpb;
} break;
+ case WM_POINTERUPDATE: {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
+ break;
+ }
+
+ if (!win8p_GetPointerType || !win8p_GetPointerPenInfo) {
+ break;
+ }
+
+ uint32_t pointer_id = LOWORD(wParam);
+ POINTER_INPUT_TYPE pointer_type = PT_POINTER;
+ if (!win8p_GetPointerType(pointer_id, &pointer_type)) {
+ break;
+ }
+
+ if (pointer_type != PT_PEN) {
+ break;
+ }
+
+ POINTER_PEN_INFO pen_info;
+ if (!win8p_GetPointerPenInfo(pointer_id, &pen_info)) {
+ break;
+ }
+
+ if (input->is_emulating_mouse_from_touch()) {
+ // Universal translation enabled; ignore OS translation
+ LPARAM extra = GetMessageExtraInfo();
+ if (IsTouchEvent(extra)) {
+ break;
+ }
+ }
+
+ if (outside) {
+ //mouse enter
+
+ if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
+ main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
+
+ CursorShape c = cursor_shape;
+ cursor_shape = CURSOR_MAX;
+ set_cursor_shape(c);
+ outside = false;
+
+ //Once-Off notification, must call again....
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hWnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+ }
+
+ // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
+ if (!window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED)
+ break;
+
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ mm->set_pressure(pen_info.pressure ? (float)pen_info.pressure / 1024 : 0);
+ mm->set_tilt(Vector2(pen_info.tiltX ? (float)pen_info.tiltX / 90 : 0, pen_info.tiltY ? (float)pen_info.tiltY / 90 : 0));
+
+ mm->set_control((wParam & MK_CONTROL) != 0);
+ mm->set_shift((wParam & MK_SHIFT) != 0);
+ mm->set_alt(alt_mem);
+
+ mm->set_button_mask(last_button_state);
+
+ POINT coords; //client coords
+ coords.x = GET_X_LPARAM(lParam);
+ coords.y = GET_Y_LPARAM(lParam);
+
+ ScreenToClient(hWnd, &coords);
+
+ mm->set_position(Vector2(coords.x, coords.y));
+ mm->set_global_position(Vector2(coords.x, coords.y));
+
+ if (mouse_mode == MOUSE_MODE_CAPTURED) {
+
+ Point2i c(video_mode.width / 2, video_mode.height / 2);
+ old_x = c.x;
+ old_y = c.y;
+
+ if (mm->get_position() == c) {
+ center = c;
+ return 0;
+ }
+
+ Point2i ncenter = mm->get_position();
+ center = ncenter;
+ POINT pos = { (int)c.x, (int)c.y };
+ ClientToScreen(hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+ }
+
+ input->set_mouse_position(mm->get_position());
+ mm->set_speed(input->get_last_mouse_speed());
+
+ if (old_invalid) {
+
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
+ old_invalid = false;
+ }
+
+ mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
+ if (window_has_focus && main_loop)
+ input->parse_input_event(mm);
+
+ return 0; //Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event
+ } break;
case WM_MOUSEMOVE: {
if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
break;
@@ -1359,6 +1480,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
video_driver_index = p_video_driver;
gl_context->set_use_vsync(video_mode.use_vsync);
+ set_vsync_via_compositor(video_mode.vsync_via_compositor);
#endif
visual_server = memnew(VisualServerRaster);
@@ -1373,8 +1495,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
power_manager = memnew(PowerWindows);
- camera_server = memnew(CameraWindows);
-
AudioDriverManager::initialize(p_audio_driver);
TRACKMOUSEEVENT tme;
@@ -1528,7 +1648,6 @@ void OS_Windows::finalize() {
memdelete(joypad);
memdelete(input);
- memdelete(camera_server);
touch_state.clear();
cursors_cache.clear();
@@ -1875,6 +1994,8 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) {
if (p_enabled) {
+ was_maximized = maximized;
+
if (pre_fs_valid) {
GetWindowRect(hWnd, &pre_fs_rect);
}
@@ -1904,7 +2025,7 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) {
rect.bottom = video_mode.height;
}
- _update_window_style(false);
+ _update_window_style(false, was_maximized);
MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
@@ -2086,12 +2207,16 @@ bool OS_Windows::get_borderless_window() {
return video_mode.borderless_window;
}
-void OS_Windows::_update_window_style(bool repaint) {
+void OS_Windows::_update_window_style(bool p_repaint, bool p_maximized) {
if (video_mode.fullscreen || video_mode.borderless_window) {
SetWindowLongPtr(hWnd, GWL_STYLE, WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE);
} else {
if (video_mode.resizable) {
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
+ if (p_maximized) {
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE);
+ } else {
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
+ }
} else {
SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_VISIBLE);
}
@@ -2099,7 +2224,7 @@ void OS_Windows::_update_window_style(bool repaint) {
SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
- if (repaint) {
+ if (p_repaint) {
RECT rect;
GetWindowRect(hWnd, &rect);
MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
@@ -2861,7 +2986,7 @@ void OS_Windows::move_window_to_foreground() {
Error OS_Windows::shell_open(String p_uri) {
- ShellExecuteW(NULL, L"open", p_uri.c_str(), NULL, NULL, SW_SHOWNORMAL);
+ ShellExecuteW(NULL, NULL, p_uri.c_str(), NULL, NULL, SW_SHOWNORMAL);
return OK;
}
@@ -3246,8 +3371,16 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
control_mem = false;
meta_mem = false;
minimized = false;
+ was_maximized = false;
console_visible = IsWindowVisible(GetConsoleWindow());
+ //Note: Functions for pen input, available on Windows 8+
+ HMODULE user32_lib = LoadLibraryW(L"user32.dll");
+ if (user32_lib) {
+ win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
+ win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
+ }
+
hInstance = _hInstance;
pressrc = 0;
old_invalid = true;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 915d025e3b..28fec27216 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -31,7 +31,6 @@
#ifndef OS_WINDOWS_H
#define OS_WINDOWS_H
-#include "camera_win.h"
#include "context_gl_windows.h"
#include "core/os/input.h"
#include "core/os/os.h"
@@ -56,6 +55,71 @@
#include <windows.h>
#include <windowsx.h>
+#ifndef POINTER_STRUCTURES
+
+#define POINTER_STRUCTURES
+
+typedef DWORD POINTER_INPUT_TYPE;
+typedef UINT32 POINTER_FLAGS;
+typedef UINT32 PEN_FLAGS;
+typedef UINT32 PEN_MASK;
+
+enum tagPOINTER_INPUT_TYPE {
+ PT_POINTER = 0x00000001,
+ PT_TOUCH = 0x00000002,
+ PT_PEN = 0x00000003,
+ PT_MOUSE = 0x00000004,
+ PT_TOUCHPAD = 0x00000005
+};
+
+typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
+ POINTER_CHANGE_NONE,
+ POINTER_CHANGE_FIRSTBUTTON_DOWN,
+ POINTER_CHANGE_FIRSTBUTTON_UP,
+ POINTER_CHANGE_SECONDBUTTON_DOWN,
+ POINTER_CHANGE_SECONDBUTTON_UP,
+ POINTER_CHANGE_THIRDBUTTON_DOWN,
+ POINTER_CHANGE_THIRDBUTTON_UP,
+ POINTER_CHANGE_FOURTHBUTTON_DOWN,
+ POINTER_CHANGE_FOURTHBUTTON_UP,
+ POINTER_CHANGE_FIFTHBUTTON_DOWN,
+ POINTER_CHANGE_FIFTHBUTTON_UP,
+} POINTER_BUTTON_CHANGE_TYPE;
+
+typedef struct tagPOINTER_INFO {
+ POINTER_INPUT_TYPE pointerType;
+ UINT32 pointerId;
+ UINT32 frameId;
+ POINTER_FLAGS pointerFlags;
+ HANDLE sourceDevice;
+ HWND hwndTarget;
+ POINT ptPixelLocation;
+ POINT ptHimetricLocation;
+ POINT ptPixelLocationRaw;
+ POINT ptHimetricLocationRaw;
+ DWORD dwTime;
+ UINT32 historyCount;
+ INT32 InputData;
+ DWORD dwKeyStates;
+ UINT64 PerformanceCount;
+ POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
+} POINTER_INFO;
+
+typedef struct tagPOINTER_PEN_INFO {
+ POINTER_INFO pointerInfo;
+ PEN_FLAGS penFlags;
+ PEN_MASK penMask;
+ UINT32 pressure;
+ UINT32 rotation;
+ INT32 tiltX;
+ INT32 tiltY;
+} POINTER_PEN_INFO;
+
+#endif
+
+typedef BOOL(WINAPI *GetPointerTypePtr)(uint32_t p_id, POINTER_INPUT_TYPE *p_type);
+typedef BOOL(WINAPI *GetPointerPenInfoPtr)(uint32_t p_id, POINTER_PEN_INFO *p_pen_info);
+
typedef struct {
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
@@ -77,11 +141,16 @@ typedef struct {
class JoypadWindows;
class OS_Windows : public OS {
+ static GetPointerTypePtr win8p_GetPointerType;
+ static GetPointerPenInfoPtr win8p_GetPointerPenInfo;
+
enum {
KEY_EVENT_BUFFER_SIZE = 512
};
+#ifdef STDOUT_FILE
FILE *stdo;
+#endif
struct KeyEvent {
@@ -105,9 +174,7 @@ class OS_Windows : public OS {
ContextGL_Windows *gl_context;
#endif
VisualServer *visual_server;
- CameraWindows *camera_server;
int pressrc;
- HDC hDC; // Private GDI Device Context
HINSTANCE hInstance; // Holds The Instance Of The Application
HWND hWnd;
Point2 last_pos;
@@ -175,7 +242,7 @@ class OS_Windows : public OS {
void _drag_event(float p_x, float p_y, int idx);
void _touch_event(bool p_pressed, float p_x, float p_y, int idx);
- void _update_window_style(bool repaint = true);
+ void _update_window_style(bool p_repaint = true, bool p_maximized = false);
void _set_mouse_mode_impl(MouseMode p_mode);
@@ -208,6 +275,7 @@ protected:
bool minimized;
bool borderless;
bool console_visible;
+ bool was_maximized;
public:
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 694aea7462..39d5c0e84e 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -83,6 +83,12 @@
#define XINPUT_CLIENT_VERSION_MAJOR 2
#define XINPUT_CLIENT_VERSION_MINOR 2
+#define VALUATOR_ABSX 0
+#define VALUATOR_ABSY 1
+#define VALUATOR_PRESSURE 2
+#define VALUATOR_TILTX 3
+#define VALUATOR_TILTY 4
+
static const double abs_resolution_mult = 10000.0;
static const double abs_resolution_range_mult = 10.0;
@@ -590,9 +596,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
AudioDriverManager::initialize(p_audio_driver);
- ///@TODO implement a subclass for Linux and instantiate that instead
- camera_server = memnew(CameraServer);
-
input = memnew(InputDefault);
window_has_focus = true; // Set focus to true at init
@@ -665,6 +668,15 @@ bool OS_X11::refresh_device_info() {
int range_min_y = 0;
int range_max_x = 0;
int range_max_y = 0;
+ int pressure_resolution = 0;
+ int pressure_min = 0;
+ int pressure_max = 0;
+ int tilt_resolution_x = 0;
+ int tilt_resolution_y = 0;
+ int tilt_range_min_x = 0;
+ int tilt_range_min_y = 0;
+ int tilt_range_max_x = 0;
+ int tilt_range_max_y = 0;
for (int j = 0; j < dev->num_classes; j++) {
#ifdef TOUCH_ENABLED
if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) {
@@ -674,16 +686,28 @@ bool OS_X11::refresh_device_info() {
if (dev->classes[j]->type == XIValuatorClass) {
XIValuatorClassInfo *class_info = (XIValuatorClassInfo *)dev->classes[j];
- if (class_info->number == 0 && class_info->mode == XIModeAbsolute) {
+ if (class_info->number == VALUATOR_ABSX && class_info->mode == XIModeAbsolute) {
resolution_x = class_info->resolution;
range_min_x = class_info->min;
range_max_x = class_info->max;
absolute_mode = true;
- } else if (class_info->number == 1 && class_info->mode == XIModeAbsolute) {
+ } else if (class_info->number == VALUATOR_ABSY && class_info->mode == XIModeAbsolute) {
resolution_y = class_info->resolution;
range_min_y = class_info->min;
range_max_y = class_info->max;
absolute_mode = true;
+ } else if (class_info->number == VALUATOR_PRESSURE && class_info->mode == XIModeAbsolute) {
+ pressure_resolution = class_info->resolution;
+ pressure_min = class_info->min;
+ pressure_max = class_info->max;
+ } else if (class_info->number == VALUATOR_TILTX && class_info->mode == XIModeAbsolute) {
+ tilt_resolution_x = class_info->resolution;
+ tilt_range_min_x = class_info->min;
+ tilt_range_max_x = class_info->max;
+ } else if (class_info->number == VALUATOR_TILTY && class_info->mode == XIModeAbsolute) {
+ tilt_resolution_y = class_info->resolution;
+ tilt_range_min_y = class_info->min;
+ tilt_range_max_y = class_info->max;
}
}
}
@@ -703,6 +727,18 @@ bool OS_X11::refresh_device_info() {
xi.absolute_devices[dev->deviceid] = Vector2(abs_resolution_mult / resolution_x, abs_resolution_mult / resolution_y);
print_verbose("XInput: Absolute pointing device: " + String(dev->name));
}
+
+ if (pressure_resolution <= 0) {
+ pressure_resolution = (pressure_max - pressure_min);
+ }
+ if (tilt_resolution_x <= 0) {
+ tilt_resolution_x = (tilt_range_max_x - tilt_range_min_x);
+ }
+ if (tilt_resolution_y <= 0) {
+ tilt_resolution_y = (tilt_range_max_y - tilt_range_min_y);
+ }
+ xi.pressure = 0;
+ xi.pen_devices[dev->deviceid] = Vector3(pressure_resolution, tilt_resolution_x, tilt_resolution_y);
}
XIFreeDeviceInfo(info);
@@ -793,8 +829,6 @@ void OS_X11::finalize() {
memdelete(input);
- memdelete(camera_server);
-
cursors_cache.clear();
visual_server->finish();
memdelete(visual_server);
@@ -1827,6 +1861,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
input->accumulate_input_event(k);
}
+ memfree(utf8string);
return;
}
memfree(utf8string);
@@ -2095,14 +2130,39 @@ void OS_X11::process_xevents() {
double rel_x = 0.0;
double rel_y = 0.0;
+ double pressure = 0.0;
+ double tilt_x = 0.0;
+ double tilt_y = 0.0;
- if (XIMaskIsSet(raw_event->valuators.mask, 0)) {
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_ABSX)) {
rel_x = *values;
values++;
}
- if (XIMaskIsSet(raw_event->valuators.mask, 1)) {
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_ABSY)) {
rel_y = *values;
+ values++;
+ }
+
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_PRESSURE)) {
+ pressure = *values;
+ values++;
+ }
+
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTX)) {
+ tilt_x = *values;
+ values++;
+ }
+
+ if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTY)) {
+ tilt_y = *values;
+ }
+
+ Map<int, Vector3>::Element *pen_info = xi.pen_devices.find(device_id);
+ if (pen_info) {
+ Vector3 mult = pen_info->value();
+ if (mult.x != 0.0) xi.pressure = pressure / mult.x;
+ if ((mult.y != 0.0) && (mult.z != 0.0)) xi.tilt = Vector2(tilt_x / mult.y, tilt_y / mult.z);
}
// https://bugs.freedesktop.org/show_bug.cgi?id=71609
@@ -2417,6 +2477,9 @@ void OS_X11::process_xevents() {
Ref<InputEventMouseMotion> mm;
mm.instance();
+ mm->set_pressure(xi.pressure);
+ mm->set_tilt(xi.tilt);
+
// Make the absolute position integral so it doesn't look _too_ weird :)
Point2i posi(pos);
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index e6c2effacf..d02160fab7 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -42,7 +42,6 @@
#include "main/input_default.h"
#include "power_x11.h"
#include "servers/audio_server.h"
-#include "servers/camera_server.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
//#include "servers/visual/visual_server_wrap_mt.h"
@@ -131,9 +130,12 @@ class OS_X11 : public OS_Unix {
int opcode;
Vector<int> touch_devices;
Map<int, Vector2> absolute_devices;
+ Map<int, Vector3> pen_devices;
XIEventMask all_event_mask;
XIEventMask all_master_event_mask;
Map<int, Vector2> state;
+ double pressure;
+ Vector2 tilt;
Vector2 mouse_pos_to_filter;
Vector2 relative_motion;
Vector2 raw_pos;
@@ -147,8 +149,6 @@ class OS_X11 : public OS_Unix {
void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
void flush_mouse_motion();
- CameraServer *camera_server;
-
MouseMode mouse_mode;
Point2i center;