summaryrefslogtreecommitdiff
path: root/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows')
-rw-r--r--platform/windows/crash_handler_windows.cpp9
-rw-r--r--platform/windows/detect.py23
-rw-r--r--platform/windows/os_windows.cpp138
-rw-r--r--platform/windows/os_windows.h23
4 files changed, 172 insertions, 21 deletions
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 e986c47b40..4b4b507499 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -201,7 +201,7 @@ def configure_msvc(env, manual_msvc_config):
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")
@@ -239,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
@@ -273,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"):
@@ -284,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
@@ -325,11 +327,12 @@ 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(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'])
@@ -339,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/os_windows.cpp b/platform/windows/os_windows.cpp
index a6a947761b..6df2ad4821 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -346,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;
};
@@ -704,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;
@@ -786,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: {
@@ -1411,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.");
@@ -2114,7 +2119,7 @@ void OS_Windows::request_attention() {
FlashWindowEx(&info);
}
-String OS_Windows::get_name() {
+String OS_Windows::get_name() const {
return "Windows";
}
@@ -2470,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");
@@ -2485,7 +2496,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
}
(*r_pipe) += buf;
if (p_pipe_mutex) {
- p_pipe_mutex->lock();
+ p_pipe_mutex->unlock();
}
}
@@ -2572,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());
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 0e0b9bf3f6..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;
@@ -276,6 +295,8 @@ public:
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;