summaryrefslogtreecommitdiff
path: root/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows')
-rw-r--r--platform/windows/SCsub4
-rw-r--r--platform/windows/crash_handler_win.cpp8
-rw-r--r--platform/windows/detect.py13
-rw-r--r--platform/windows/export/export.cpp126
-rw-r--r--platform/windows/os_windows.cpp94
-rw-r--r--platform/windows/os_windows.h7
-rw-r--r--platform/windows/power_windows.cpp6
-rw-r--r--platform/windows/stream_peer_winsock.cpp4
8 files changed, 224 insertions, 38 deletions
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index aa9eb3e69b..5a253d5db5 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -28,7 +28,7 @@ obj = env.RES(restarget, 'godot_res.rc')
common_win.append(obj)
-binary = env.Program('#bin/godot', ['godot_win.cpp'] + common_win, PROGSUFFIX=env["PROGSUFFIX"])
+prog = env.add_program('#bin/godot', ['godot_win.cpp'] + common_win, PROGSUFFIX=env["PROGSUFFIX"])
# Microsoft Visual Studio Project Generation
if env['vsproj']:
@@ -38,4 +38,4 @@ if env['vsproj']:
if not os.getenv("VCINSTALLDIR"):
if env["debug_symbols"] == "full" or env["debug_symbols"] == "yes":
- env.AddPostAction(binary, make_debug_mingw)
+ env.AddPostAction(prog, make_debug_mingw)
diff --git a/platform/windows/crash_handler_win.cpp b/platform/windows/crash_handler_win.cpp
index feea3911b2..5657036693 100644
--- a/platform/windows/crash_handler_win.cpp
+++ b/platform/windows/crash_handler_win.cpp
@@ -61,8 +61,8 @@ class symbol {
static const int max_name_len = 1024;
public:
- symbol(HANDLE process, DWORD64 address)
- : sym((sym_type *)::operator new(sizeof(*sym) + max_name_len)) {
+ symbol(HANDLE process, DWORD64 address) :
+ sym((sym_type *)::operator new(sizeof(*sym) + max_name_len)) {
memset(sym, '\0', sizeof(*sym) + max_name_len);
sym->SizeOfStruct = sizeof(*sym);
sym->MaxNameLength = max_name_len;
@@ -85,8 +85,8 @@ class get_mod_info {
HANDLE process;
public:
- get_mod_info(HANDLE h)
- : process(h) {}
+ get_mod_info(HANDLE h) :
+ process(h) {}
module_data operator()(HMODULE module) {
module_data ret;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index fbb02c9d1b..d85e1b061c 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -64,6 +64,10 @@ def get_opts():
return [
('mingw_prefix_32', 'MinGW prefix (Win32)', mingw32),
('mingw_prefix_64', 'MinGW prefix (Win64)', mingw64),
+ # Targeted Windows version: 7 (and later), minimum supported version
+ # 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')),
]
@@ -97,11 +101,6 @@ def configure(env):
env.Append(CPPPATH=['#platform/windows'])
- # Targeted Windows version: 7 (and later), minimum supported version
- # XP support dropped after EOL due to missing API for IPv6 and other issues
- # Vista support dropped after EOL due to GH-10243
- winver = "0x0601"
-
if (os.name == "nt" and os.getenv("VCINSTALLDIR")): # MSVC
env['ENV']['TMP'] = os.environ['TMP']
@@ -175,7 +174,7 @@ def configure(env):
env.Append(CCFLAGS=['/DWASAPI_ENABLED'])
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
env.Append(CCFLAGS=['/DWIN32'])
- env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver])
+ env.Append(CCFLAGS=['/DWINVER=%s' % env['target_win_version'], '/D_WIN32_WINNT=%s' % env['target_win_version']])
if env["bits"] == "64":
env.Append(CCFLAGS=['/D_WIN64'])
@@ -271,7 +270,7 @@ def configure(env):
env.Append(CCFLAGS=['-DOPENGL_ENABLED'])
env.Append(CCFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DWASAPI_ENABLED'])
- env.Append(CCFLAGS=['-DWINVER=%s' % winver, '-D_WIN32_WINNT=%s' % winver])
+ env.Append(CCFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']])
env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser'])
env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 5301aa9e95..1b6a8f4a60 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -28,11 +28,135 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "editor/editor_export.h"
+#include "editor/editor_settings.h"
+#include "os/file_access.h"
+#include "os/os.h"
#include "platform/windows/logo.gen.h"
+class EditorExportPlatformWindows : public EditorExportPlatformPC {
+
+public:
+ virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
+ virtual void get_export_options(List<ExportOption> *r_options);
+};
+
+Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, p_path, p_flags);
+
+ if (err != OK) {
+ return err;
+ }
+
+ String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
+
+ if (rcedit_path == String()) {
+ return OK;
+ }
+
+ if (!FileAccess::exists(rcedit_path)) {
+ ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", aborting.");
+ return ERR_FILE_NOT_FOUND;
+ }
+
+#ifndef WINDOWS_ENABLED
+ // On non-Windows we need WINE to run rcedit
+ 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;
+ }
+
+ if (wine_path == String()) {
+ wine_path = "wine"; // try to run wine from PATH
+ }
+#endif
+
+ String icon_path = p_preset->get("application/icon");
+ String file_verion = p_preset->get("application/file_version");
+ String product_version = p_preset->get("application/product_version");
+ String company_name = p_preset->get("application/company_name");
+ String product_name = p_preset->get("application/product_name");
+ String file_description = p_preset->get("application/file_description");
+ String copyright = p_preset->get("application/copyright");
+ String trademarks = p_preset->get("application/trademarks");
+ String comments = p_preset->get("application/comments");
+
+ List<String> args;
+ args.push_back(p_path);
+ if (icon_path != String()) {
+ args.push_back("--set-icon");
+ args.push_back(icon_path);
+ }
+ if (file_verion != String()) {
+ args.push_back("--set-file-version");
+ args.push_back(file_verion);
+ }
+ if (product_version != String()) {
+ args.push_back("--set-product-version");
+ args.push_back(product_version);
+ }
+ if (company_name != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("CompanyName");
+ args.push_back(company_name);
+ }
+ if (product_name != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("ProductName");
+ args.push_back(product_name);
+ }
+ if (file_description != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("FileDescription");
+ args.push_back(file_description);
+ }
+ if (copyright != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("LegalCopyright");
+ args.push_back(copyright);
+ }
+ if (trademarks != String()) {
+ args.push_back("--set-version-string");
+ args.push_back("LegalTrademarks");
+ args.push_back(trademarks);
+ }
+
+#ifdef WINDOWS_ENABLED
+ OS::get_singleton()->execute(rcedit_path, args, true);
+#else
+ // On non-Windows we need WINE to run rcedit
+ args.push_front(rcedit_path);
+ OS::get_singleton()->execute(wine_path, args, true);
+#endif
+
+ return OK;
+}
+
+void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) {
+ EditorExportPlatformPC::get_export_options(r_options);
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_GLOBAL_FILE, "*.ico"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), String()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), String()));
+}
+
void register_windows_exporter() {
- Ref<EditorExportPlatformPC> platform;
+ EDITOR_DEF("export/windows/rcedit", "");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/rcedit", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
+#ifndef WINDOWS_ENABLED
+ // On non-Windows we need WINE to run rcedit
+ EDITOR_DEF("export/windows/wine", "");
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/wine", PROPERTY_HINT_GLOBAL_FILE));
+#endif
+
+ Ref<EditorExportPlatformWindows> platform;
platform.instance();
Ref<Image> img = memnew(Image(_windows_logo));
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 284dfaf904..41730d33af 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -69,6 +69,19 @@ __attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001;
#define WM_TOUCH 576
#endif
+static String format_error_message(DWORD id) {
+
+ LPWSTR messageBuffer = NULL;
+ size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
+
+ String msg = "Error " + itos(id) + ": " + String(messageBuffer, size);
+
+ LocalFree(messageBuffer);
+
+ return msg;
+}
+
extern HINSTANCE godot_hinstance;
void RedirectIOToConsole() {
@@ -210,7 +223,17 @@ bool OS_Windows::can_draw() const {
#define SIGNATURE_MASK 0xFFFFFF00
#define IsPenEvent(dw) (((dw)&SIGNATURE_MASK) == MI_WP_SIGNATURE)
-void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
+void OS_Windows::_touch_event(bool p_pressed, float p_x, float p_y, int idx) {
+
+ // Defensive
+ if (touch_state.has(idx) == p_pressed)
+ return;
+
+ if (p_pressed) {
+ touch_state.insert(idx, Vector2(p_x, p_y));
+ } else {
+ touch_state.erase(idx);
+ }
Ref<InputEventScreenTouch> event;
event.instance();
@@ -223,7 +246,17 @@ void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
}
};
-void OS_Windows::_drag_event(int p_x, int p_y, int idx) {
+void OS_Windows::_drag_event(float p_x, float p_y, int idx) {
+
+ Map<int, Vector2>::Element *curr = touch_state.find(idx);
+ // Defensive
+ if (!curr)
+ return;
+
+ if (curr->get() == Vector2(p_x, p_y))
+ return;
+
+ curr->get() = Vector2(p_x, p_y);
Ref<InputEventScreenDrag> event;
event.instance();
@@ -253,6 +286,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
ReleaseCapture();
}
+
+ // Release every touch to avoid sticky points
+ for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) {
+ _touch_event(false, E->get().x, E->get().y, E->key());
+ }
+ touch_state.clear();
+
break;
}
case WM_ACTIVATE: // Watch For Window Activate Message
@@ -656,7 +696,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
print_line("input lang change");
} break;
-#if WINVER >= 0x0601 // for windows 7
case WM_TOUCH: {
BOOL bHandled = FALSE;
@@ -669,10 +708,10 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
//do something with each touch input entry
if (ti.dwFlags & TOUCHEVENTF_MOVE) {
- _drag_event(ti.x / 100, ti.y / 100, ti.dwID);
+ _drag_event(ti.x / 100.0f, ti.y / 100.0f, ti.dwID);
} else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) {
- _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN != 0, ti.x / 100, ti.y / 100, ti.dwID);
+ _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN, ti.x / 100.0f, ti.y / 100.0f, ti.dwID);
};
}
bHandled = TRUE;
@@ -690,7 +729,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} break;
-#endif
case WM_DEVICECHANGE: {
joypad->probe_joypads();
@@ -1036,6 +1074,8 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
+
+ gl_context->set_use_vsync(video_mode.use_vsync);
#endif
visual_server = memnew(VisualServerRaster);
@@ -1044,12 +1084,6 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
- if (!is_no_window_mode_enabled()) {
- ShowWindow(hWnd, SW_SHOW); // Show The Window
- SetForegroundWindow(hWnd); // Slightly Higher Priority
- SetFocus(hWnd); // Sets Keyboard Focus To
- }
-
/*
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
@@ -1080,13 +1114,19 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
- //RegisterTouchWindow(hWnd, 0); // Windows 7
+ RegisterTouchWindow(hWnd, 0);
_ensure_user_data_dir();
DragAcceptFiles(hWnd, true);
move_timer_id = 1;
+
+ if (!is_no_window_mode_enabled()) {
+ ShowWindow(hWnd, SW_SHOW); // Show The Window
+ SetForegroundWindow(hWnd); // Slightly Higher Priority
+ SetFocus(hWnd); // Sets Keyboard Focus To
+ }
}
void OS_Windows::set_clipboard(const String &p_text) {
@@ -1188,6 +1228,7 @@ void OS_Windows::finalize() {
memdelete(joypad);
memdelete(input);
+ touch_state.clear();
visual_server->finish();
memdelete(visual_server);
@@ -1588,10 +1629,29 @@ void OS_Windows::_update_window_style(bool repaint) {
}
}
-Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle) {
- p_library_handle = (void *)LoadLibrary(p_path.utf8().get_data());
+Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
+
+ typedef DLL_DIRECTORY_COOKIE(WINAPI * PAddDllDirectory)(PCWSTR);
+ typedef BOOL(WINAPI * PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE);
+
+ PAddDllDirectory add_dll_directory = (PAddDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "AddDllDirectory");
+ PRemoveDllDirectory remove_dll_directory = (PRemoveDllDirectory)GetProcAddress(GetModuleHandle("kernel32.dll"), "RemoveDllDirectory");
+
+ bool has_dll_directory_api = ((add_dll_directory != NULL) && (remove_dll_directory != NULL));
+ DLL_DIRECTORY_COOKIE cookie;
+
+ if (p_also_set_library_path && has_dll_directory_api) {
+ cookie = add_dll_directory(p_path.get_base_dir().c_str());
+ }
+
+ p_library_handle = (void *)LoadLibraryExW(p_path.c_str(), NULL, (p_also_set_library_path && has_dll_directory_api) ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
+
+ if (p_also_set_library_path && has_dll_directory_api) {
+ remove_dll_directory(cookie);
+ }
+
if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + String::num(GetLastError()));
+ ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + format_error_message(GetLastError()));
ERR_FAIL_V(ERR_CANT_OPEN);
}
return OK;
@@ -1954,7 +2014,7 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) {
bool OS_Windows::has_environment(const String &p_var) const {
- return getenv(p_var.utf8().get_data()) != NULL;
+ return _wgetenv(p_var.c_str()) != NULL;
};
String OS_Windows::get_environment(const String &p_var) const {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 4367297262..af1ccd4446 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -117,6 +117,7 @@ class OS_Windows : public OS {
InputDefault *input;
JoypadWindows *joypad;
+ Map<int, Vector2> touch_state;
PowerWindows *power_manager;
@@ -132,8 +133,8 @@ class OS_Windows : public OS {
CrashHandler crash_handler;
- void _drag_event(int p_x, int p_y, int idx);
- void _touch_event(bool p_pressed, int p_x, int p_y, int idx);
+ 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);
@@ -212,7 +213,7 @@ public:
virtual void set_borderless_window(int p_borderless);
virtual bool get_borderless_window();
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
virtual Error close_dynamic_library(void *p_library_handle);
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp
index 8d86f160f1..cc452d774d 100644
--- a/platform/windows/power_windows.cpp
+++ b/platform/windows/power_windows.cpp
@@ -121,8 +121,10 @@ int PowerWindows::get_power_percent_left() {
}
}
-PowerWindows::PowerWindows()
- : nsecs_left(-1), percent_left(-1), power_state(OS::POWERSTATE_UNKNOWN) {
+PowerWindows::PowerWindows() :
+ nsecs_left(-1),
+ percent_left(-1),
+ power_state(OS::POWERSTATE_UNKNOWN) {
}
PowerWindows::~PowerWindows() {
diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp
index a9d9cb9373..8b83215325 100644
--- a/platform/windows/stream_peer_winsock.cpp
+++ b/platform/windows/stream_peer_winsock.cpp
@@ -141,7 +141,7 @@ Error StreamPeerWinsock::write(const uint8_t *p_data, int p_bytes, int &r_sent,
if (WSAGetLastError() != WSAEWOULDBLOCK) {
- perror("shit?");
+ perror("Nothing sent");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;
@@ -197,7 +197,7 @@ Error StreamPeerWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received, b
if (WSAGetLastError() != WSAEWOULDBLOCK) {
- perror("shit?");
+ perror("Nothing read");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;