summaryrefslogtreecommitdiff
path: root/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows')
-rw-r--r--platform/windows/context_gl_windows.h21
-rw-r--r--platform/windows/crash_handler_windows.cpp9
-rw-r--r--platform/windows/detect.py28
-rw-r--r--platform/windows/godot.natvis147
-rw-r--r--platform/windows/os_windows.cpp184
-rw-r--r--platform/windows/os_windows.h26
6 files changed, 298 insertions, 117 deletions
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index 09801b9146..d23fba50e1 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -37,13 +37,12 @@
#include "core/error_list.h"
#include "core/os/os.h"
-#include "drivers/gl_context/context_gl.h"
#include <windows.h>
typedef bool(APIENTRY *PFNWGLSWAPINTERVALEXTPROC)(int interval);
-class ContextGL_Windows : public ContextGL {
+class ContextGL_Windows {
HDC hDC;
HGLRC hRC;
@@ -55,21 +54,21 @@ class ContextGL_Windows : public ContextGL {
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
public:
- virtual void release_current();
+ void release_current();
- virtual void make_current();
+ void make_current();
- virtual int get_window_width();
- virtual int get_window_height();
- virtual void swap_buffers();
+ int get_window_width();
+ int get_window_height();
+ void swap_buffers();
- virtual Error initialize();
+ Error initialize();
- virtual void set_use_vsync(bool p_use);
- virtual bool is_using_vsync() const;
+ void set_use_vsync(bool p_use);
+ bool is_using_vsync() const;
ContextGL_Windows(HWND hwnd, bool p_opengl_3_context);
- virtual ~ContextGL_Windows();
+ ~ContextGL_Windows();
};
#endif
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index 4006c4c60e..0716ee67f4 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -166,11 +166,16 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
line.SizeOfStruct = sizeof(line);
IMAGE_NT_HEADERS *h = ImageNtHeader(base);
DWORD image_type = h->FileHeader.Machine;
- int n = 0;
- String msg = GLOBAL_GET("debug/settings/crash_handler/message");
+
+ String msg;
+ const ProjectSettings *proj_settings = ProjectSettings::get_singleton();
+ if (proj_settings) {
+ msg = proj_settings->get("debug/settings/crash_handler/message");
+ }
fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
+ int n = 0;
do {
if (skip_first) {
skip_first = false;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 426a5e9e61..4b4b507499 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -1,6 +1,5 @@
import methods
import os
-import sys
def is_active():
@@ -197,10 +196,12 @@ def configure_msvc(env, manual_msvc_config):
## Compile/link flags
env.AppendUnique(CCFLAGS=['/MT', '/Gd', '/GR', '/nologo'])
+ if int(env['MSVC_VERSION'].split('.')[0]) >= 14: #vs2015 and later
+ env.AppendUnique(CCFLAGS=['/utf-8'])
env.AppendUnique(CXXFLAGS=['/TP']) # assume all sources are C++
if manual_msvc_config: # should be automatic if SCons found it
if os.getenv("WindowsSdkDir") is not None:
- env.Append(CPPPATH=[os.getenv("WindowsSdkDir") + "/Include"])
+ env.Prepend(CPPPATH=[os.getenv("WindowsSdkDir") + "/Include"])
else:
print("Missing environment variable: WindowsSdkDir")
@@ -238,7 +239,7 @@ def configure_msvc(env, manual_msvc_config):
env.AppendUnique(LINKFLAGS=['/LTCG'])
if manual_msvc_config:
- env.Append(CPPPATH=[p for p in os.getenv("INCLUDE").split(";")])
+ env.Prepend(CPPPATH=[p for p in os.getenv("INCLUDE").split(";")])
env.Append(LIBPATH=[p for p in os.getenv("LIB").split(";")])
# Incremental linking fix
@@ -272,7 +273,8 @@ def configure_mingw(env):
env.Prepend(CCFLAGS=['-g2'])
elif (env["target"] == "release_debug"):
- env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
+ env.Append(CCFLAGS=['-O2'])
+ env.Append(CPPFLAGS=['-DDEBUG_ENABLED'])
if (env["debug_symbols"] == "yes"):
env.Prepend(CCFLAGS=['-g1'])
if (env["debug_symbols"] == "full"):
@@ -283,7 +285,8 @@ def configure_mingw(env):
env.Prepend(CCFLAGS=['-Os'])
elif (env["target"] == "debug"):
- env.Append(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+ env.Append(CCFLAGS=['-g3'])
+ env.Append(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
## Compiler configuration
@@ -324,12 +327,13 @@ def configure_mingw(env):
## Compile flags
- env.Append(CCFLAGS=['-DWINDOWS_ENABLED', '-mwindows'])
- env.Append(CCFLAGS=['-DOPENGL_ENABLED'])
- env.Append(CCFLAGS=['-DWASAPI_ENABLED'])
- env.Append(CCFLAGS=['-DWINMIDI_ENABLED'])
- env.Append(CCFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']])
- env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt','avrt'])
+ env.Append(CCFLAGS=['-mwindows'])
+ env.Append(CPPFLAGS=['-DWINDOWS_ENABLED'])
+ env.Append(CPPFLAGS=['-DOPENGL_ENABLED'])
+ env.Append(CPPFLAGS=['-DWASAPI_ENABLED'])
+ env.Append(CPPFLAGS=['-DWINMIDI_ENABLED'])
+ env.Append(CPPFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']])
+ env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid'])
env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
@@ -338,7 +342,7 @@ def configure_mingw(env):
def configure(env):
# At this point the env has been set up with basic tools/compilers.
- env.Append(CPPPATH=['#platform/windows'])
+ env.Prepend(CPPPATH=['#platform/windows'])
print("Configuring for Windows: target=%s, bits=%s" % (env['target'], env['bits']))
diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis
index 01963035a1..55c83c3f3c 100644
--- a/platform/windows/godot.natvis
+++ b/platform/windows/godot.natvis
@@ -2,92 +2,109 @@
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="Vector&lt;*&gt;">
<Expand>
- <Item Name="size">(_cowdata &amp;&amp; _cowdata-&gt;_ptr) ? (((const unsigned int *)(_cowdata-&gt;_ptr))[-1]) : 0</Item>
+ <Item Name="[size]">_cowdata._ptr ? (((const unsigned int *)(_cowdata._ptr))[-1]) : 0</Item>
<ArrayItems>
- <Size>(_cowdata &amp;&amp; _cowdata-&gt;_ptr) ? (((const unsigned int *)(_cowdata-&gt;_ptr))[-1]) : 0</Size>
- <ValuePointer>(_cowdata) ? (_cowdata-&gt;_ptr) : 0</ValuePointer>
+ <Size>_cowdata._ptr ? (((const unsigned int *)(_cowdata._ptr))[-1]) : 0</Size>
+ <ValuePointer>_cowdata._ptr</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="PoolVector&lt;*&gt;">
<Expand>
- <Item Name="size">alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Item>
+ <Item Name="[size]">alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Item>
<ArrayItems>
<Size>alloc ? (alloc-&gt;size / sizeof($T1)) : 0</Size>
<ValuePointer>alloc ? (($T1 *)alloc-&gt;mem) : 0</ValuePointer>
</ArrayItems>
</Expand>
</Type>
+
+ <Type Name="List&lt;*&gt;">
+ <Expand>
+ <Item Name="[size]">_data ? (_data->size_cache) : 0</Item>
+ <LinkedListItems>
+ <Size>_data ? (_data->size_cache) : 0</Size>
+ <HeadPointer>_data->first</HeadPointer>
+ <NextPointer>next_ptr</NextPointer>
+ <ValueNode>value</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
<Type Name="Variant">
- <DisplayString Condition="this-&gt;type == Variant::NIL">nil</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::BOOL">{_data._bool}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::INT">{_data._int}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::REAL">{_data._real}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::TRANSFORM2D">{_data._transform2d}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::AABB">{_data._aabb}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::BASIS">{_data._basis}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::TRANSFORM">{_data._transform}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::STRING &amp;&amp; ((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr == 0">""</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::STRING &amp;&amp; ((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr != 0">{((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr,su}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::RECT2">{*(Rect2 *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::VECTOR3">{*(Vector3 *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::PLANE">{*(Plane *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::QUAT">{*(Quat *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::NODE_PATH">{*(NodePath *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::_RID">{*(RID *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::OBJECT">{*(Object *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::DICTIONARY">{*(Dictionary *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::POOL_BYTE_ARRAY">{*(PoolByteArray *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::POOL_INT_ARRAY">{*(PoolIntArray *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::POOL_REAL_ARRAY">{*(PoolRealArray *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::POOL_STRING_ARRAY">{*(PoolStringArray *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::POOL_VECTOR2_ARRAY">{*(PoolVector2Array *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::POOL_VECTOR3_ARRAY">{*(PoolVector3Array *)_data._mem}</DisplayString>
- <DisplayString Condition="this-&gt;type == Variant::POOL_COLOR_ARRAY">{*(PoolColorArray *)_data._mem}</DisplayString>
-
- <StringView Condition="this-&gt;type == Variant::STRING &amp;&amp; ((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr != 0">((String *)(&amp;_data._mem[0]))-&gt;_cowdata._ptr,su</StringView>
+ <DisplayString Condition="type == Variant::NIL">nil</DisplayString>
+ <DisplayString Condition="type == Variant::BOOL">{_data._bool}</DisplayString>
+ <DisplayString Condition="type == Variant::INT">{_data._int}</DisplayString>
+ <DisplayString Condition="type == Variant::REAL">{_data._real}</DisplayString>
+ <DisplayString Condition="type == Variant::TRANSFORM2D">{_data._transform2d}</DisplayString>
+ <DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString>
+ <DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString>
+ <DisplayString Condition="type == Variant::TRANSFORM">{_data._transform}</DisplayString>
+ <DisplayString Condition="type == Variant::STRING">{*(String *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::RECT2">{*(Rect2 *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::VECTOR3">{*(Vector3 *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::PLANE">{*(Plane *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::QUAT">{*(Quat *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::NODE_PATH">{*(NodePath *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::_RID">{*(RID *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::OBJECT">{*(Object *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::DICTIONARY">{*(Dictionary *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::ARRAY">{*(Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::POOL_BYTE_ARRAY">{*(PoolByteArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::POOL_INT_ARRAY">{*(PoolIntArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::POOL_REAL_ARRAY">{*(PoolRealArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::POOL_STRING_ARRAY">{*(PoolStringArray *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::POOL_VECTOR2_ARRAY">{*(PoolVector2Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::POOL_VECTOR3_ARRAY">{*(PoolVector3Array *)_data._mem}</DisplayString>
+ <DisplayString Condition="type == Variant::POOL_COLOR_ARRAY">{*(PoolColorArray *)_data._mem}</DisplayString>
+ <StringView Condition="type == Variant::STRING &amp;&amp; ((String *)(_data._mem))->_cowdata._ptr">((String *)(_data._mem))->_cowdata._ptr,su</StringView>
+
<Expand>
- <Item Name="value" Condition="this-&gt;type == Variant::BOOL">_data._bool</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::INT">_data._int</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::REAL">_data._real</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::TRANSFORM2D">_data._transform2d</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::AABB">_data._aabb</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::BASIS">_data._basis</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::TRANSFORM">_data._transform</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::ARRAY">*(Array *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::STRING">*(String *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::VECTOR2">*(Vector2 *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::RECT2">*(Rect2 *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::VECTOR3">*(Vector3 *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::PLANE">*(Plane *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::QUAT">*(Quat *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::COLOR">*(Color *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::NODE_PATH">*(NodePath *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::_RID">*(RID *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::OBJECT">*(Object *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::DICTIONARY">*(Dictionary *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::ARRAY">*(Array *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::POOL_BYTE_ARRAY">*(PoolByteArray *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::POOL_INT_ARRAY">*(PoolIntArray *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::POOL_REAL_ARRAY">*(PoolRealArray *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::POOL_STRING_ARRAY">*(PoolStringArray *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::POOL_VECTOR2_ARRAY">*(PoolVector2Array *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::POOL_VECTOR3_ARRAY">*(PoolVector3Array *)_data._mem</Item>
- <Item Name="value" Condition="this-&gt;type == Variant::POOL_COLOR_ARRAY">*(PoolColorArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::BOOL">_data._bool</Item>
+ <Item Name="[value]" Condition="type == Variant::INT">_data._int</Item>
+ <Item Name="[value]" Condition="type == Variant::REAL">_data._real</Item>
+ <Item Name="[value]" Condition="type == Variant::TRANSFORM2D">_data._transform2d</Item>
+ <Item Name="[value]" Condition="type == Variant::AABB">_data._aabb</Item>
+ <Item Name="[value]" Condition="type == Variant::BASIS">_data._basis</Item>
+ <Item Name="[value]" Condition="type == Variant::TRANSFORM">_data._transform</Item>
+ <Item Name="[value]" Condition="type == Variant::STRING">*(String *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::VECTOR2">*(Vector2 *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::RECT2">*(Rect2 *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::VECTOR3">*(Vector3 *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::PLANE">*(Plane *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::QUAT">*(Quat *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::COLOR">*(Color *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::NODE_PATH">*(NodePath *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::_RID">*(RID *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::OBJECT">*(Object *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::DICTIONARY">*(Dictionary *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::ARRAY">*(Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::POOL_BYTE_ARRAY">*(PoolByteArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::POOL_INT_ARRAY">*(PoolIntArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::POOL_REAL_ARRAY">*(PoolRealArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::POOL_STRING_ARRAY">*(PoolStringArray *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::POOL_VECTOR2_ARRAY">*(PoolVector2Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::POOL_VECTOR3_ARRAY">*(PoolVector3Array *)_data._mem</Item>
+ <Item Name="[value]" Condition="type == Variant::POOL_COLOR_ARRAY">*(PoolColorArray *)_data._mem</Item>
</Expand>
</Type>
<Type Name="String">
- <DisplayString Condition="this-&gt;_cowdata._ptr == 0">empty</DisplayString>
- <DisplayString Condition="this-&gt;_cowdata._ptr != 0">{this->_cowdata._ptr,su}</DisplayString>
- <StringView Condition="this-&gt;_cowdata._ptr != 0">this->_cowdata._ptr,su</StringView>
+ <DisplayString Condition="_cowdata._ptr == 0">[empty]</DisplayString>
+ <DisplayString Condition="_cowdata._ptr != 0">{_cowdata._ptr,su}</DisplayString>
+ <StringView Condition="_cowdata._ptr != 0">_cowdata._ptr,su</StringView>
+ </Type>
+
+ <Type Name="StringName">
+ <DisplayString Condition="_data &amp;&amp; _data->cname">{_data->cname}</DisplayString>
+ <DisplayString Condition="_data &amp;&amp; !_data->cname">{_data->name,su}</DisplayString>
+ <DisplayString Condition="!_data">[empty]</DisplayString>
+ <StringView Condition="_data &amp;&amp; _data->cname">_data->cname</StringView>
+ <StringView Condition="_data &amp;&amp; !_data->cname">_data->name,su</StringView>
</Type>
<Type Name="Vector2">
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 6125455e74..6df2ad4821 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -53,6 +53,7 @@
#include <avrt.h>
#include <direct.h>
+#include <knownfolders.h>
#include <process.h>
#include <regstr.h>
#include <shlobj.h>
@@ -345,6 +346,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
control_mem = false;
shift_mem = false;
} else { // WM_INACTIVE
+ input->release_pressed_events();
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
alt_mem = false;
};
@@ -384,8 +386,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
outside = true;
if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
- if (input)
- input->set_mouse_in_window(false);
} break;
case WM_INPUT: {
@@ -480,8 +480,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (main_loop && mouse_mode != MOUSE_MODE_CAPTURED)
main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
- if (input)
- input->set_mouse_in_window(true);
CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
@@ -670,7 +668,9 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
mb->set_button_index(BUTTON_XBUTTON2);
mb->set_doubleclick(true);
} break;
- default: { return 0; }
+ default: {
+ return 0;
+ }
}
mb->set_control((wParam & MK_CONTROL) != 0);
@@ -705,7 +705,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
}
} else if (mouse_mode != MOUSE_MODE_CAPTURED) {
- // for reasons unknown to mankind, wheel comes in screen cordinates
+ // for reasons unknown to mankind, wheel comes in screen coordinates
POINT coords;
coords.x = mb->get_position().x;
coords.y = mb->get_position().y;
@@ -787,6 +787,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} break;
case WM_ENTERSIZEMOVE: {
+ input->release_pressed_events();
move_timer_id = SetTimer(hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC)NULL);
} break;
case WM_EXITSIZEMOVE: {
@@ -1412,26 +1413,29 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
void OS_Windows::set_clipboard(const String &p_text) {
+ // Convert LF line endings to CRLF in clipboard content
+ // Otherwise, line endings won't be visible when pasted in other software
+ String text = p_text.replace("\n", "\r\n");
+
if (!OpenClipboard(hWnd)) {
ERR_EXPLAIN("Unable to open clipboard.");
ERR_FAIL();
};
EmptyClipboard();
- HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (p_text.length() + 1) * sizeof(CharType));
+ HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(CharType));
if (mem == NULL) {
ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
ERR_FAIL();
};
LPWSTR lptstrCopy = (LPWSTR)GlobalLock(mem);
- memcpy(lptstrCopy, p_text.c_str(), (p_text.length() + 1) * sizeof(CharType));
- //memset((lptstrCopy + p_text.length()), 0, sizeof(CharType));
+ memcpy(lptstrCopy, text.c_str(), (text.length() + 1) * sizeof(CharType));
GlobalUnlock(mem);
SetClipboardData(CF_UNICODETEXT, mem);
// set the CF_TEXT version (not needed?)
- CharString utf8 = p_text.utf8();
+ CharString utf8 = text.utf8();
mem = GlobalAlloc(GMEM_MOVEABLE, utf8.length() + 1);
if (mem == NULL) {
ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
@@ -2115,7 +2119,7 @@ void OS_Windows::request_attention() {
FlashWindowEx(&info);
}
-String OS_Windows::get_name() {
+String OS_Windows::get_name() const {
return "Windows";
}
@@ -2297,6 +2301,11 @@ void OS_Windows::set_cursor_shape(CursorShape p_shape) {
cursor_shape = p_shape;
}
+OS::CursorShape OS_Windows::get_cursor_shape() const {
+
+ return cursor_shape;
+}
+
void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
if (p_cursor.is_valid()) {
Ref<Texture> texture = p_cursor;
@@ -2457,7 +2466,7 @@ void OS_Windows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent,
DeleteDC(hMainDC);
}
-Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) {
+Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
if (p_blocking && r_pipe) {
@@ -2466,7 +2475,13 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
- argss += String(" \"") + E->get() + "\"";
+ argss += " \"" + E->get() + "\"";
+ }
+
+ argss += "\"";
+
+ if (read_stderr) {
+ argss += " 2>&1"; // Read stderr too
}
FILE *f = _wpopen(argss.c_str(), L"r");
@@ -2476,7 +2491,13 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
char buf[65535];
while (fgets(buf, 65535, f)) {
+ if (p_pipe_mutex) {
+ p_pipe_mutex->lock();
+ }
(*r_pipe) += buf;
+ if (p_pipe_mutex) {
+ p_pipe_mutex->unlock();
+ }
}
int rv = _pclose(f);
@@ -2562,6 +2583,117 @@ String OS_Windows::get_executable_path() const {
return s;
}
+void OS_Windows::set_native_icon(const String &p_filename) {
+
+ FileAccess *f = FileAccess::open(p_filename, FileAccess::READ);
+ ERR_FAIL_COND(!f);
+
+ ICONDIR *icon_dir = (ICONDIR *)memalloc(sizeof(ICONDIR));
+ int pos = 0;
+
+ icon_dir->idReserved = f->get_32();
+ pos += sizeof(WORD);
+ f->seek(pos);
+
+ icon_dir->idType = f->get_32();
+ pos += sizeof(WORD);
+ f->seek(pos);
+
+ if (icon_dir->idType != 1) {
+ ERR_EXPLAIN("Invalid icon file format!");
+ ERR_FAIL();
+ }
+
+ icon_dir->idCount = f->get_32();
+ pos += sizeof(WORD);
+ f->seek(pos);
+
+ icon_dir = (ICONDIR *)memrealloc(icon_dir, 3 * sizeof(WORD) + icon_dir->idCount * sizeof(ICONDIRENTRY));
+ f->get_buffer((uint8_t *)&icon_dir->idEntries[0], icon_dir->idCount * sizeof(ICONDIRENTRY));
+
+ int small_icon_index = -1; // Select 16x16 with largest color count
+ int small_icon_cc = 0;
+ int big_icon_index = -1; // Select largest
+ int big_icon_width = 16;
+ int big_icon_cc = 0;
+
+ for (int i = 0; i < icon_dir->idCount; i++) {
+ int colors = (icon_dir->idEntries[i].bColorCount == 0) ? 32768 : icon_dir->idEntries[i].bColorCount;
+ int width = (icon_dir->idEntries[i].bWidth == 0) ? 256 : icon_dir->idEntries[i].bWidth;
+ if (width == 16) {
+ if (colors >= small_icon_cc) {
+ small_icon_index = i;
+ small_icon_cc = colors;
+ }
+ }
+ if (width >= big_icon_width) {
+ if (colors >= big_icon_cc) {
+ big_icon_index = i;
+ big_icon_width = width;
+ big_icon_cc = colors;
+ }
+ }
+ }
+
+ if (big_icon_index == -1) {
+ ERR_EXPLAIN("No valid icons found!");
+ ERR_FAIL();
+ }
+
+ if (small_icon_index == -1) {
+ WARN_PRINTS("No small icon found, reusing " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon!");
+ small_icon_index = big_icon_index;
+ small_icon_cc = big_icon_cc;
+ }
+
+ // Read the big icon
+ DWORD bytecount_big = icon_dir->idEntries[big_icon_index].dwBytesInRes;
+ Vector<uint8_t> data_big;
+ data_big.resize(bytecount_big);
+ pos = icon_dir->idEntries[big_icon_index].dwImageOffset;
+ f->seek(pos);
+ f->get_buffer((uint8_t *)&data_big.write[0], bytecount_big);
+ HICON icon_big = CreateIconFromResource((PBYTE)&data_big.write[0], bytecount_big, TRUE, 0x00030000);
+ if (!icon_big) {
+ ERR_EXPLAIN("Could not create " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon, error: " + format_error_message(GetLastError()));
+ ERR_FAIL();
+ }
+
+ // Read the small icon
+ DWORD bytecount_small = icon_dir->idEntries[small_icon_index].dwBytesInRes;
+ Vector<uint8_t> data_small;
+ data_small.resize(bytecount_small);
+ pos = icon_dir->idEntries[small_icon_index].dwImageOffset;
+ f->seek(pos);
+ f->get_buffer((uint8_t *)&data_small.write[0], bytecount_small);
+ HICON icon_small = CreateIconFromResource((PBYTE)&data_small.write[0], bytecount_small, TRUE, 0x00030000);
+ if (!icon_small) {
+ ERR_EXPLAIN("Could not create 16x16 @" + itos(small_icon_cc) + " icon, error: " + format_error_message(GetLastError()));
+ ERR_FAIL();
+ }
+
+ // Online tradition says to be sure last error is cleared and set the small icon first
+ int err = 0;
+ SetLastError(err);
+
+ SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)icon_small);
+ err = GetLastError();
+ if (err) {
+ ERR_EXPLAIN("Error setting ICON_SMALL: " + format_error_message(err));
+ ERR_FAIL();
+ }
+
+ SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)icon_big);
+ err = GetLastError();
+ if (err) {
+ ERR_EXPLAIN("Error setting ICON_BIG: " + format_error_message(err));
+ ERR_FAIL();
+ }
+
+ memdelete(f);
+ memdelete(icon_dir);
+}
+
void OS_Windows::set_icon(const Ref<Image> &p_icon) {
ERR_FAIL_COND(!p_icon.is_valid());
@@ -2867,39 +2999,41 @@ String OS_Windows::get_godot_dir_name() const {
String OS_Windows::get_system_dir(SystemDir p_dir) const {
- int id;
+ KNOWNFOLDERID id;
switch (p_dir) {
case SYSTEM_DIR_DESKTOP: {
- id = CSIDL_DESKTOPDIRECTORY;
+ id = FOLDERID_Desktop;
} break;
case SYSTEM_DIR_DCIM: {
- id = CSIDL_MYPICTURES;
+ id = FOLDERID_Pictures;
} break;
case SYSTEM_DIR_DOCUMENTS: {
- id = CSIDL_PERSONAL;
+ id = FOLDERID_Documents;
} break;
case SYSTEM_DIR_DOWNLOADS: {
- id = 0x000C;
+ id = FOLDERID_Downloads;
} break;
case SYSTEM_DIR_MOVIES: {
- id = CSIDL_MYVIDEO;
+ id = FOLDERID_Videos;
} break;
case SYSTEM_DIR_MUSIC: {
- id = CSIDL_MYMUSIC;
+ id = FOLDERID_Music;
} break;
case SYSTEM_DIR_PICTURES: {
- id = CSIDL_MYPICTURES;
+ id = FOLDERID_Pictures;
} break;
case SYSTEM_DIR_RINGTONES: {
- id = CSIDL_MYMUSIC;
+ id = FOLDERID_Music;
} break;
}
- WCHAR szPath[MAX_PATH];
- HRESULT res = SHGetFolderPathW(NULL, id, NULL, 0, szPath);
+ PWSTR szPath;
+ HRESULT res = SHGetKnownFolderPath(id, 0, NULL, &szPath);
ERR_FAIL_COND_V(res != S_OK, String());
- return String(szPath);
+ String path = String(szPath);
+ CoTaskMemFree(szPath);
+ return path;
}
String OS_Windows::get_user_data_dir() const {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 2d03532c69..0aacbcb9ff 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -58,6 +58,25 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
+typedef struct {
+ BYTE bWidth; // Width, in pixels, of the image
+ BYTE bHeight; // Height, in pixels, of the image
+ BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
+ BYTE bReserved; // Reserved ( must be 0)
+ WORD wPlanes; // Color Planes
+ WORD wBitCount; // Bits per pixel
+ DWORD dwBytesInRes; // How many bytes in this resource?
+ DWORD dwImageOffset; // Where in the file is this image?
+} ICONDIRENTRY, *LPICONDIRENTRY;
+
+typedef struct {
+ WORD idReserved; // Reserved (must be 0)
+ WORD idType; // Resource Type (1 for icons)
+ WORD idCount; // How many images?
+ ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em)
+} ICONDIR, *LPICONDIR;
+
class JoypadWindows;
class OS_Windows : public OS {
@@ -246,7 +265,7 @@ public:
virtual MainLoop *get_main_loop() const;
- virtual String get_name();
+ virtual String get_name() const;
virtual Date get_date(bool utc) const;
virtual Time get_time(bool utc) const;
@@ -261,7 +280,7 @@ public:
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
- virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false);
+ virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL);
virtual Error kill(const ProcessID &p_pid);
virtual int get_process_id() const;
@@ -273,8 +292,11 @@ public:
virtual String get_clipboard() const;
void set_cursor_shape(CursorShape p_shape);
+ CursorShape get_cursor_shape() const;
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
void GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap);
+
+ void set_native_icon(const String &p_filename);
void set_icon(const Ref<Image> &p_icon);
virtual String get_executable_path() const;