summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/export/export.cpp2
-rw-r--r--platform/haiku/detect.py2
-rw-r--r--platform/javascript/audio_driver_javascript.cpp149
-rw-r--r--platform/javascript/audio_driver_javascript.h11
-rw-r--r--platform/javascript/javascript_main.cpp2
-rw-r--r--platform/osx/detect.py4
-rw-r--r--platform/osx/os_osx.h3
-rw-r--r--platform/osx/os_osx.mm37
-rw-r--r--platform/server/detect.py18
-rw-r--r--platform/uwp/detect.py6
-rw-r--r--platform/windows/detect.py4
-rw-r--r--platform/windows/os_windows.cpp68
-rw-r--r--platform/windows/os_windows.h6
-rw-r--r--platform/x11/detect.py34
-rw-r--r--platform/x11/os_x11.cpp34
-rw-r--r--platform/x11/os_x11.h5
16 files changed, 258 insertions, 127 deletions
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 6fe137a386..9e6377f4fe 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1023,7 +1023,7 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,65535,1"), 1));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name"), "org.godotengine.$genname"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name"), ""));
diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py
index 7c62654ef6..2959023204 100644
--- a/platform/haiku/detect.py
+++ b/platform/haiku/detect.py
@@ -22,7 +22,7 @@ def get_opts():
from SCons.Variables import EnumVariable
return [
- EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')),
+ EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
]
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index 5bf345e6cd..7a6613bb32 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -32,113 +32,134 @@
#include <emscripten.h>
-AudioDriverJavaScript *AudioDriverJavaScript::singleton_js = NULL;
+AudioDriverJavaScript *AudioDriverJavaScript::singleton = NULL;
const char *AudioDriverJavaScript::get_name() const {
return "JavaScript";
}
-extern "C" EMSCRIPTEN_KEEPALIVE void js_audio_driver_mix_function(int p_frames) {
+extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_js_mix() {
- //print_line("MIXI! "+itos(p_frames));
- AudioDriverJavaScript::singleton_js->mix_to_js(p_frames);
+ AudioDriverJavaScript::singleton->mix_to_js();
}
-void AudioDriverJavaScript::mix_to_js(int p_frames) {
+void AudioDriverJavaScript::mix_to_js() {
- int todo = p_frames;
- int offset = 0;
+ int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());
+ int sample_count = memarr_len(internal_buffer) / channel_count;
+ int32_t *stream_buffer = reinterpret_cast<int32_t *>(internal_buffer);
+ audio_server_process(sample_count, stream_buffer);
+ for (int i = 0; i < sample_count * channel_count; i++) {
+ internal_buffer[i] = float(stream_buffer[i] >> 16) / 32768.0;
+ }
+}
- while (todo) {
+Error AudioDriverJavaScript::init() {
- int tomix = MIN(todo, INTERNAL_BUFFER_SIZE);
+ /* clang-format off */
+ EM_ASM({
+ _audioDriver_audioContext = new (window.AudioContext || window.webkitAudioContext);
+ _audioDriver_scriptNode = null;
+ });
+ /* clang-format on */
- audio_server_process(p_frames, stream_buffer);
- for (int i = 0; i < tomix * internal_buffer_channels; i++) {
- internal_buffer[i] = float(stream_buffer[i] >> 16) / 32768.0;
+ int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());
+ /* clang-format off */
+ int buffer_length = EM_ASM_INT({
+ var CHANNEL_COUNT = $0;
+
+ var channelCount = _audioDriver_audioContext.destination.channelCount;
+ try {
+ // Try letting the browser recommend a buffer length.
+ _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(0, 0, channelCount);
+ } catch (e) {
+ // ...otherwise, default to 4096.
+ _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(4096, 0, channelCount);
}
+ _audioDriver_scriptNode.connect(_audioDriver_audioContext.destination);
- /* clang-format off */
- EM_ASM_ARGS({
- var data = HEAPF32.subarray($0 / 4, $0 / 4 + $2 * 2);
-
- for (var channel = 0; channel < _as_output_buffer.numberOfChannels; channel++) {
- var outputData = _as_output_buffer.getChannelData(channel);
- // Loop through samples
- for (var sample = 0; sample < $2; sample++) {
- // make output equal to the same as the input
- outputData[sample + $1] = data[sample * 2 + channel];
- }
- }
- }, internal_buffer, offset, tomix);
- /* clang-format on */
-
- todo -= tomix;
- offset += tomix;
+ return _audioDriver_scriptNode.bufferSize;
+ }, channel_count);
+ /* clang-format on */
+ if (!buffer_length) {
+ return FAILED;
}
-}
-
-Error AudioDriverJavaScript::init() {
- return OK;
+ if (!internal_buffer || memarr_len(internal_buffer) != buffer_length * channel_count) {
+ if (internal_buffer)
+ memdelete_arr(internal_buffer);
+ internal_buffer = memnew_arr(float, buffer_length *channel_count);
+ }
+ return internal_buffer ? OK : ERR_OUT_OF_MEMORY;
}
void AudioDriverJavaScript::start() {
- internal_buffer = memnew_arr(float, INTERNAL_BUFFER_SIZE *internal_buffer_channels);
- stream_buffer = memnew_arr(int32_t, INTERNAL_BUFFER_SIZE * 4); //max 4 channels
-
/* clang-format off */
- mix_rate = EM_ASM_INT({
- _as_audioctx = new (window.AudioContext || window.webkitAudioContext);
- _as_script_node = _as_audioctx.createScriptProcessor($0, 0, $1);
- _as_script_node.connect(_as_audioctx.destination);
- console.log(_as_script_node.bufferSize);
- var jsAudioDriverMixFunction = cwrap('js_audio_driver_mix_function', null, ['number']);
-
- _as_script_node.onaudioprocess = function(audioProcessingEvent) {
- // The output buffer contains the samples that will be modified and played
- _as_output_buffer = audioProcessingEvent.outputBuffer;
- jsAudioDriverMixFunction([_as_output_buffer.getChannelData(0).length]);
+ EM_ASM({
+ var INTERNAL_BUFFER_PTR = $0;
+
+ var audioDriverMixFunction = cwrap('audio_driver_js_mix');
+ _audioDriver_scriptNode.onaudioprocess = function(audioProcessingEvent) {
+ audioDriverMixFunction();
+ // The output buffer contains the samples that will be modified and played.
+ var output = audioProcessingEvent.outputBuffer;
+ var input = HEAPF32.subarray(
+ INTERNAL_BUFFER_PTR / HEAPF32.BYTES_PER_ELEMENT,
+ INTERNAL_BUFFER_PTR / HEAPF32.BYTES_PER_ELEMENT + output.length * output.numberOfChannels);
+
+ for (var channel = 0; channel < output.numberOfChannels; channel++) {
+ var outputData = output.getChannelData(channel);
+ // Loop through samples.
+ for (var sample = 0; sample < outputData.length; sample++) {
+ // Set output equal to input.
+ outputData[sample] = input[sample * output.numberOfChannels + channel];
+ }
+ }
};
- return _as_audioctx.sampleRate;
- }, INTERNAL_BUFFER_SIZE, internal_buffer_channels);
+ }, internal_buffer);
/* clang-format on */
}
int AudioDriverJavaScript::get_mix_rate() const {
- return mix_rate;
+ /* clang-format off */
+ return EM_ASM_INT_V({
+ return _audioDriver_audioContext.sampleRate;
+ });
+ /* clang-format on */
}
AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const {
- return SPEAKER_MODE_STEREO;
+ /* clang-format off */
+ return get_speaker_mode_by_total_channels(EM_ASM_INT_V({
+ return _audioDriver_audioContext.destination.channelCount;
+ }));
+ /* clang-format on */
}
+// No locking, as threads are not supported.
void AudioDriverJavaScript::lock() {
-
- /*no locking, as threads are not supported
- if (active && mutex)
- mutex->lock();
- */
}
void AudioDriverJavaScript::unlock() {
-
- /*no locking, as threads are not supported
- if (active && mutex)
- mutex->unlock();
- */
}
void AudioDriverJavaScript::finish() {
+
+ /* clang-format off */
+ EM_ASM({
+ _audioDriver_audioContext = null;
+ _audioDriver_scriptNode = null;
+ });
+ /* clang-format on */
+ memdelete_arr(internal_buffer);
+ internal_buffer = NULL;
}
AudioDriverJavaScript::AudioDriverJavaScript() {
- internal_buffer_channels = 2;
- mix_rate = DEFAULT_MIX_RATE;
- singleton_js = this;
+ singleton = this;
}
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index d78ab8eea4..a65a8ec29f 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -35,18 +35,11 @@
class AudioDriverJavaScript : public AudioDriver {
- enum {
- INTERNAL_BUFFER_SIZE = 4096,
- };
-
- int mix_rate;
float *internal_buffer;
- int internal_buffer_channels;
- int32_t *stream_buffer;
public:
- void mix_to_js(int p_frames);
- static AudioDriverJavaScript *singleton_js;
+ void mix_to_js();
+ static AudioDriverJavaScript *singleton;
virtual const char *get_name() const;
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index 54d4755bd7..68a2d72464 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -56,8 +56,6 @@ extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
int main(int argc, char *argv[]) {
- printf("let it go dude!\n");
-
// sync from persistent state into memory and then
// run the 'main_after_fs_sync' function
/* clang-format off */
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 1e9631fae0..72b8aa99f8 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -23,8 +23,8 @@ def get_opts():
return [
('osxcross_sdk', 'OSXCross SDK version', 'darwin14'),
- EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')),
- BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False),
+ EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
+ BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False),
]
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index c1022a1aca..7bd5b16f36 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -109,6 +109,7 @@ public:
bool minimized;
bool maximized;
bool zoomed;
+ bool resizable;
Size2 window_size;
Rect2 restore_rect;
@@ -116,6 +117,7 @@ public:
String open_with_filename;
Point2 im_position;
+ bool im_active;
ImeCallback im_callback;
void *im_target;
@@ -232,6 +234,7 @@ public:
virtual bool get_window_per_pixel_transparency_enabled() const;
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
+ virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index bde0b4e898..4ece1e0325 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -913,7 +913,7 @@ static int remapKey(unsigned int key) {
CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
if (!layoutData)
- return nil;
+ return 0;
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
@@ -959,7 +959,7 @@ static int remapKey(unsigned int key) {
push_to_key_event_buffer(ke);
}
- if ((OS_OSX::singleton->im_position.x != 0) && (OS_OSX::singleton->im_position.y != 0))
+ if (OS_OSX::singleton->im_active == true)
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
@@ -1129,6 +1129,10 @@ String OS_OSX::get_unique_id() const {
return serial_number;
}
+void OS_OSX::set_ime_active(const bool p_active) {
+ im_active = p_active;
+}
+
void OS_OSX::set_ime_position(const Point2 &p_pos) {
im_position = p_pos;
}
@@ -1184,6 +1188,7 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
if (p_desired.borderless_window) {
styleMask = NSWindowStyleMaskBorderless;
} else {
+ resizable = p_desired.resizable;
styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (p_desired.resizable ? NSWindowStyleMaskResizable : 0);
}
@@ -1480,7 +1485,7 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
if (cursor_shape == p_shape)
return;
- if (mouse_mode != MOUSE_MODE_VISIBLE) {
+ if (mouse_mode != MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) {
cursor_shape = p_shape;
return;
}
@@ -1545,7 +1550,9 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
image = texture->get_data();
- NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
+ ERR_FAIL_COND(!image.is_valid());
+
+ NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
pixelsWide:int(texture_size.width)
pixelsHigh:int(texture_size.height)
@@ -1555,7 +1562,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:int(texture_size.width) * 4
- bitsPerPixel:32] autorelease];
+ bitsPerPixel:32];
ERR_FAIL_COND(imgrep == nil);
uint8_t *pixels = [imgrep bitmapData];
@@ -1587,16 +1594,20 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
image->unlock();
- NSImage *nsimage = [[[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)] autorelease];
+ NSImage *nsimage = [[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)];
[nsimage addRepresentation:imgrep];
NSCursor *cursor = [[NSCursor alloc] initWithImage:nsimage hotSpot:NSMakePoint(p_hotspot.x, p_hotspot.y)];
+ [cursors[p_shape] release];
cursors[p_shape] = cursor;
if (p_shape == CURSOR_ARROW) {
[cursor set];
}
+
+ [imgrep release];
+ [nsimage release];
} else {
// Reset to default system cursor
cursors[p_shape] = NULL;
@@ -1740,7 +1751,8 @@ String OS_OSX::get_godot_dir_name() const {
String OS_OSX::get_system_dir(SystemDir p_dir) const {
- NSSearchPathDirectory id = 0;
+ NSSearchPathDirectory id;
+ bool found = true;
switch (p_dir) {
case SYSTEM_DIR_DESKTOP: {
@@ -1761,10 +1773,13 @@ String OS_OSX::get_system_dir(SystemDir p_dir) const {
case SYSTEM_DIR_PICTURES: {
id = NSPicturesDirectory;
} break;
+ default: {
+ found = false;
+ }
}
String ret;
- if (id) {
+ if (found) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(id, NSUserDomainMask, YES);
if (paths && [paths count] >= 1) {
@@ -2110,6 +2125,8 @@ void OS_OSX::set_window_resizable(bool p_enabled) {
[window_object setStyleMask:[window_object styleMask] | NSWindowStyleMaskResizable];
else
[window_object setStyleMask:[window_object styleMask] & ~NSWindowStyleMaskResizable];
+
+ resizable = p_enabled;
};
bool OS_OSX::is_window_resizable() const {
@@ -2219,7 +2236,7 @@ void OS_OSX::set_borderless_window(bool p_borderless) {
if (layered_window)
set_window_per_pixel_transparency_enabled(false);
- [window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable];
+ [window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (resizable ? NSWindowStyleMaskResizable : 0)];
// Force update of the window styles
NSRect frameRect = [window_object frame];
@@ -2529,6 +2546,7 @@ OS_OSX::OS_OSX() {
mouse_mode = OS::MOUSE_MODE_VISIBLE;
main_loop = NULL;
singleton = this;
+ im_active = false;
im_position = Point2();
im_callback = NULL;
im_target = NULL;
@@ -2615,6 +2633,7 @@ OS_OSX::OS_OSX() {
minimized = false;
window_size = Vector2(1024, 600);
zoomed = false;
+ resizable = false;
Vector<Logger *> loggers;
loggers.push_back(memnew(OSXTerminalLogger));
diff --git a/platform/server/detect.py b/platform/server/detect.py
index 7bf445b43f..266b0c5cc9 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -67,9 +67,6 @@ def configure(env):
# FIXME: Check for existence of the libs before parsing their flags with pkg-config
- if not env['builtin_libwebp']:
- env.ParseConfig('pkg-config libwebp --cflags --libs')
-
# freetype depends on libpng and zlib, so bundling one of them while keeping others
# as shared libraries leads to weird issues
if env['builtin_freetype'] or env['builtin_libpng'] or env['builtin_zlib']:
@@ -124,6 +121,21 @@ def configure(env):
if not env['builtin_libogg']:
env.ParseConfig('pkg-config ogg --cflags --libs')
+ if not env['builtin_libwebp']:
+ env.ParseConfig('pkg-config libwebp --cflags --libs')
+
+ if not env['builtin_mbedtls']:
+ # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228
+ env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509'])
+
+ if not env['builtin_libwebsockets']:
+ env.ParseConfig('pkg-config libwebsockets --cflags --libs')
+
+ if not env['builtin_miniupnpc']:
+ # No pkgconfig file so far, hardcode default paths.
+ env.Append(CPPPATH=["/usr/include/miniupnpc"])
+ env.Append(LIBS=["miniupnpc"])
+
# On Linux wchar_t should be 32-bits
# 16-bit library shouldn't be required due to compiler optimisations
if not env['builtin_pcre2']:
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 0e7b125dc5..559f23ca5b 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -28,8 +28,8 @@ def get_opts():
from SCons.Variables import BoolVariable
return [
- ('msvc_version', 'MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.', None),
- BoolVariable('use_mingw', 'Use the Mingw compiler, even if MSVC is installed. Only used on Windows.', False),
+ ('msvc_version', 'MSVC version to use (ignored if the VCINSTALLDIR environment variable is set)', None),
+ BoolVariable('use_mingw', 'Use the MinGW compiler even if MSVC is installed (only used on Windows)', False),
]
@@ -112,7 +112,7 @@ def configure(env):
env["bits"] = "32"
print("Compiled program architecture will be a x86 executable. (forcing bits=32).")
else:
- print("Failed to detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup.")
+ print("Failed to detect MSVC compiler architecture version... Defaulting to 32-bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup.")
env["bits"] = "32"
if (env["bits"] == "32"):
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 6d559520d7..05806d2fe8 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -62,8 +62,8 @@ def get_opts():
# XP support dropped after EOL due to missing API for IPv6 and other issues
# Vista support dropped after EOL due to GH-10243
('target_win_version', 'Targeted Windows version, >= 0x0601 (Windows 7)', '0x0601'),
- EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')),
- BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False),
+ EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
+ BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False),
('msvc_version', 'MSVC version to use. Ignored if VCINSTALLDIR is set in shell env.', None),
BoolVariable('use_mingw', 'Use the Mingw compiler, even if MSVC is installed. Only used on Windows.', False),
]
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index d6cdea7b88..ca6c793d5d 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -623,9 +623,12 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_SIZE: {
int window_w = LOWORD(lParam);
int window_h = HIWORD(lParam);
- if (window_w > 0 && window_h > 0) {
+ if (window_w > 0 && window_h > 0 && !preserve_window_size) {
video_mode.width = window_w;
video_mode.height = window_h;
+ } else {
+ preserve_window_size = false;
+ set_window_size(Size2(video_mode.width, video_mode.height));
}
if (wParam == SIZE_MAXIMIZED) {
maximized = true;
@@ -777,7 +780,9 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
SetCursor(NULL);
} else {
if (hCursor != NULL) {
- SetCursor(hCursor);
+ CursorShape c = cursor_shape;
+ cursor_shape = CURSOR_MAX;
+ set_cursor_shape(c);
hCursor = NULL;
}
}
@@ -1176,6 +1181,15 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
if (p_desired.layered_splash) {
set_window_per_pixel_transparency_enabled(true);
}
+
+ // IME
+ im_himc = ImmGetContext(hWnd);
+ ImmReleaseContext(hWnd, im_himc);
+
+ im_position = Vector2();
+
+ set_ime_active(false);
+
return OK;
}
@@ -1561,6 +1575,15 @@ void OS_Windows::set_window_size(const Size2 p_size) {
}
MoveWindow(hWnd, rect.left, rect.top, w, h, TRUE);
+
+ // Don't let the mouse leave the window when resizing to a smaller resolution
+ if (mouse_mode == MOUSE_MODE_CONFINED) {
+ RECT rect;
+ GetClientRect(hWnd, &rect);
+ ClientToScreen(hWnd, (POINT *)&rect.left);
+ ClientToScreen(hWnd, (POINT *)&rect.right);
+ ClipCursor(&rect);
+ }
}
void OS_Windows::set_window_fullscreen(bool p_enabled) {
@@ -1767,6 +1790,7 @@ void OS_Windows::set_borderless_window(bool p_borderless) {
video_mode.borderless_window = p_borderless;
+ preserve_window_size = true;
_update_window_style();
}
@@ -1785,7 +1809,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_NOMOVE | SWP_NOSIZE);
+ SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
if (repaint) {
RECT rect;
@@ -1996,7 +2020,7 @@ void OS_Windows::set_cursor_shape(CursorShape p_shape) {
if (cursor_shape == p_shape)
return;
- if (mouse_mode != MOUSE_MODE_VISIBLE) {
+ if (mouse_mode != MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) {
cursor_shape = p_shape;
return;
}
@@ -2062,11 +2086,13 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
image = texture->get_data();
+ ERR_FAIL_COND(!image.is_valid());
+
UINT image_size = texture_size.width * texture_size.height;
UINT size = sizeof(UINT) * image_size;
// Create the BITMAP with alpha channel
- COLORREF *buffer = (COLORREF *)malloc(sizeof(COLORREF) * image_size);
+ COLORREF *buffer = (COLORREF *)memalloc(sizeof(COLORREF) * image_size);
image->lock();
for (UINT index = 0; index < image_size; index++) {
@@ -2093,6 +2119,8 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
GetMaskBitmaps(bitmap, clrTransparent, hAndMask, hXorMask);
if (NULL == hAndMask || NULL == hXorMask) {
+ memfree(buffer);
+ DeleteObject(bitmap);
return;
}
@@ -2117,6 +2145,9 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
if (hXorMask != NULL) {
DeleteObject(hXorMask);
}
+
+ memfree(buffer);
+ DeleteObject(bitmap);
} else {
// Reset to default system cursor
cursors[p_shape] = NULL;
@@ -2187,10 +2218,6 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
argss += String(" \"") + E->get() + "\"";
}
- //print_line("ARGS: "+argss);
- //argss+"\"";
- //argss+=" 2>nul";
-
FILE *f = _wpopen(argss.c_str(), L"r");
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
@@ -2217,15 +2244,12 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
I = I->next();
};
- //cmdline+="\"";
-
ProcessInfo pi;
ZeroMemory(&pi.si, sizeof(pi.si));
pi.si.cb = sizeof(pi.si);
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- print_line("running cmdline: " + cmdline);
Vector<CharType> modstr; //windows wants to change this no idea why
modstr.resize(cmdline.size());
for (int i = 0; i < cmdline.size(); i++)
@@ -2644,13 +2668,29 @@ String OS_Windows::get_unique_id() const {
return String(HwProfInfo.szHwProfileGuid);
}
+void OS_Windows::set_ime_active(const bool p_active) {
+
+ if (p_active) {
+ ImmAssociateContext(hWnd, im_himc);
+
+ set_ime_position(im_position);
+ } else {
+ ImmAssociateContext(hWnd, (HIMC)0);
+ }
+}
+
void OS_Windows::set_ime_position(const Point2 &p_pos) {
+ im_position = p_pos;
+
HIMC himc = ImmGetContext(hWnd);
+ if (himc == (HIMC)0)
+ return;
+
COMPOSITIONFORM cps;
cps.dwStyle = CFS_FORCE_POSITION;
- cps.ptCurrentPos.x = p_pos.x;
- cps.ptCurrentPos.y = p_pos.y;
+ cps.ptCurrentPos.x = im_position.x;
+ cps.ptCurrentPos.y = im_position.y;
ImmSetCompositionWindow(himc, &cps);
ImmReleaseContext(hWnd, himc);
}
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 221109318e..19af63bae0 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -105,11 +105,16 @@ class OS_Windows : public OS {
Size2 window_rect;
VideoMode video_mode;
+ bool preserve_window_size = false;
MainLoop *main_loop;
WNDPROC user_proc;
+ // IME
+ HIMC im_himc;
+ Vector2 im_position;
+
MouseMode mouse_mode;
bool alt_mem;
bool gr_mem;
@@ -281,6 +286,7 @@ public:
virtual String get_unique_id() const;
+ virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
virtual void release_rendering_thread();
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index ad2620c9f5..09e16ad078 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -59,8 +59,8 @@ def get_opts():
BoolVariable('use_leak_sanitizer', 'Use LLVM compiler memory leaks sanitizer (implies use_sanitizer)', False),
BoolVariable('pulseaudio', 'Detect & use pulseaudio', True),
BoolVariable('udev', 'Use udev for gamepad connection callbacks', False),
- EnumVariable('debug_symbols', 'Add debug symbols to release version', 'yes', ('yes', 'no', 'full')),
- BoolVariable('separate_debug_symbols', 'Create a separate file with the debug symbols', False),
+ EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
+ BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False),
BoolVariable('touch', 'Enable touch events', True),
]
@@ -158,14 +158,6 @@ def configure(env):
# FIXME: Check for existence of the libs before parsing their flags with pkg-config
- if not env['builtin_mbedtls']:
- # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228
- env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509'])
-
- if not env['builtin_libwebp']:
- env.ParseConfig('pkg-config libwebp --cflags --libs')
-
-
# freetype depends on libpng and zlib, so bundling one of them while keeping others
# as shared libraries leads to weird issues
if env['builtin_freetype'] or env['builtin_libpng'] or env['builtin_zlib']:
@@ -205,6 +197,10 @@ def configure(env):
env['builtin_libogg'] = False # Needed to link against system libtheora
env['builtin_libvorbis'] = False # Needed to link against system libtheora
env.ParseConfig('pkg-config theora theoradec --cflags --libs')
+ else:
+ list_of_x86 = ['x86_64', 'x86', 'i386', 'i586']
+ if any(platform.machine() in s for s in list_of_x86):
+ env["x86_libtheora_opt_gcc"] = True
if not env['builtin_libvpx']:
env.ParseConfig('pkg-config vpx --cflags --libs')
@@ -220,10 +216,20 @@ def configure(env):
if not env['builtin_libogg']:
env.ParseConfig('pkg-config ogg --cflags --libs')
- if env['builtin_libtheora']:
- list_of_x86 = ['x86_64', 'x86', 'i386', 'i586']
- if any(platform.machine() in s for s in list_of_x86):
- env["x86_libtheora_opt_gcc"] = True
+ if not env['builtin_libwebp']:
+ env.ParseConfig('pkg-config libwebp --cflags --libs')
+
+ if not env['builtin_mbedtls']:
+ # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228
+ env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509'])
+
+ if not env['builtin_libwebsockets']:
+ env.ParseConfig('pkg-config libwebsockets --cflags --libs')
+
+ if not env['builtin_miniupnpc']:
+ # No pkgconfig file so far, hardcode default paths.
+ env.Append(CPPPATH=["/usr/include/miniupnpc"])
+ env.Append(LIBS=["miniupnpc"])
# On Linux wchar_t should be 32-bits
# 16-bit library shouldn't be required due to compiler optimisations
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index eec371865e..d7f042b4fe 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -391,6 +391,9 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);
XSetWMProtocols(x11_display, x11_window, &wm_delete, 1);
+ im_active = false;
+ im_position = Vector2();
+
if (xim && xim_style) {
xic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, x11_window, XNFocusWindow, x11_window, (char *)NULL);
@@ -400,7 +403,7 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
xic = NULL;
}
if (xic) {
- XSetICFocus(xic);
+ XUnsetICFocus(xic);
} else {
WARN_PRINT("XCreateIC couldn't create xic");
}
@@ -541,8 +544,25 @@ void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data,
os->xic = NULL;
}
+void OS_X11::set_ime_active(const bool p_active) {
+
+ im_active = p_active;
+
+ if (!xic)
+ return;
+
+ if (p_active) {
+ XSetICFocus(xic);
+ set_ime_position(im_position);
+ } else {
+ XUnsetICFocus(xic);
+ }
+}
+
void OS_X11::set_ime_position(const Point2 &p_pos) {
+ im_position = p_pos;
+
if (!xic)
return;
@@ -1292,6 +1312,9 @@ void OS_X11::set_borderless_window(bool p_borderless) {
hints.decorations = current_videomode.borderless_window ? 0 : 1;
property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
+
+ // Preserve window size
+ set_window_size(Size2(current_videomode.width, current_videomode.height));
}
bool OS_X11::get_borderless_window() {
@@ -2407,7 +2430,7 @@ void OS_X11::set_cursor_shape(CursorShape p_shape) {
if (p_shape == current_cursor)
return;
- if (mouse_mode == MOUSE_MODE_VISIBLE) {
+ if (mouse_mode == MOUSE_MODE_VISIBLE && mouse_mode != MOUSE_MODE_CONFINED) {
if (cursors[p_shape] != None)
XDefineCursor(x11_display, x11_window, cursors[p_shape]);
else if (cursors[CURSOR_ARROW] != None)
@@ -2449,6 +2472,8 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
image = texture->get_data();
+ ERR_FAIL_COND(!image.is_valid());
+
// Create the cursor structure
XcursorImage *cursor_image = XcursorImageCreate(texture_size.width, texture_size.height);
XcursorUInt image_size = texture_size.width * texture_size.height;
@@ -2460,7 +2485,7 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
cursor_image->yhot = p_hotspot.y;
// allocate memory to contain the whole file
- cursor_image->pixels = (XcursorPixel *)malloc(size);
+ cursor_image->pixels = (XcursorPixel *)memalloc(size);
image->lock();
@@ -2486,6 +2511,9 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
if (p_shape == CURSOR_ARROW) {
XDefineCursor(x11_display, x11_window, cursors[p_shape]);
}
+
+ memfree(cursor_image->pixels);
+ XcursorImageDestroy(cursor_image);
} else {
// Reset to default system cursor
if (img[p_shape]) {
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 09ed9588c4..8cab23fe63 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -116,6 +116,10 @@ class OS_X11 : public OS_Unix {
static void xim_destroy_callback(::XIM im, ::XPointer client_data,
::XPointer call_data);
+ // IME
+ bool im_active;
+ Vector2 im_position;
+
Point2i last_mouse_pos;
bool last_mouse_pos_valid;
Point2i last_click_pos;
@@ -269,6 +273,7 @@ public:
virtual bool get_window_per_pixel_transparency_enabled() const;
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
+ virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
virtual String get_unique_id() const;