summaryrefslogtreecommitdiff
path: root/platform/windows/os_windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows/os_windows.cpp')
-rw-r--r--platform/windows/os_windows.cpp424
1 files changed, 288 insertions, 136 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index bd76db8796..55d2bb2153 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -28,27 +28,27 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+// Must include Winsock before windows.h (included by os_windows.h)
+#include "drivers/unix/net_socket_posix.h"
+
#include "os_windows.h"
+#include "core/io/marshalls.h"
+#include "core/version_generated.gen.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles3/rasterizer_gles3.h"
#include "drivers/windows/dir_access_windows.h"
#include "drivers/windows/file_access_windows.h"
#include "drivers/windows/mutex_windows.h"
-#include "drivers/windows/packet_peer_udp_winsock.h"
#include "drivers/windows/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
-#include "drivers/windows/stream_peer_tcp_winsock.h"
-#include "drivers/windows/tcp_server_winsock.h"
#include "drivers/windows/thread_windows.h"
-#include "io/marshalls.h"
#include "joypad.h"
#include "lang_table.h"
#include "main/main.h"
#include "servers/audio_server.h"
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
-#include "version_generated.gen.h"
#include "windows_terminal_logger.h"
#include <process.h>
@@ -58,11 +58,8 @@
static const WORD MAX_CONSOLE_LINES = 1500;
extern "C" {
-#ifdef _MSC_VER
-_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
-#else
-__attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001;
-#endif
+__declspec(dllexport) DWORD NvOptimusEnablement = 1;
+__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
// Workaround mingw-w64 < 4.0 bug
@@ -219,9 +216,7 @@ void OS_Windows::initialize_core() {
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA);
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
- TCPServerWinsock::make_default();
- StreamPeerTCPWinsock::make_default();
- PacketPeerUDPWinsock::make_default();
+ NetSocketPosix::make_default();
// We need to know how often the clock is updated
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
@@ -249,7 +244,11 @@ bool OS_Windows::can_draw() const {
#define MI_WP_SIGNATURE 0xFF515700
#define SIGNATURE_MASK 0xFFFFFF00
+// Keeping the name suggested by Microsoft, but this macro really answers:
+// Is this mouse event emulated from touch or pen input?
#define IsPenEvent(dw) (((dw)&SIGNATURE_MASK) == MI_WP_SIGNATURE)
+// This one tells whether the event comes from touchscreen (and not from pen)
+#define IsTouchEvent(dw) (IsPenEvent(dw) && ((dw)&0x80))
void OS_Windows::_touch_event(bool p_pressed, float p_x, float p_y, int idx) {
@@ -301,19 +300,17 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
case WM_SETFOCUS: {
window_has_focus = true;
- // Re-capture cursor if we're in one of the capture modes
- if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
- SetCapture(hWnd);
- }
+
+ // Restore mouse mode
+ _set_mouse_mode_impl(mouse_mode);
+
break;
}
case WM_KILLFOCUS: {
window_has_focus = false;
- // Release capture if we're in one of the capture modes
- if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
- ReleaseCapture();
- }
+ // Release capture unconditionally because it can be set due to dragging, in addition to captured mode
+ ReleaseCapture();
// Release every touch to avoid sticky points
for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) {
@@ -335,15 +332,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
alt_mem = false;
control_mem = false;
shift_mem = false;
- if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
- RECT clipRect;
- GetClientRect(hWnd, &clipRect);
- ClientToScreen(hWnd, (POINT *)&clipRect.left);
- ClientToScreen(hWnd, (POINT *)&clipRect.right);
- ClipCursor(&clipRect);
- SetCapture(hWnd);
- }
- } else {
+ } else { // WM_INACTIVE
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
alt_mem = false;
};
@@ -387,12 +376,89 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
input->set_mouse_in_window(false);
} break;
+ case WM_INPUT: {
+ if (mouse_mode != MOUSE_MODE_CAPTURED || !use_raw_input) {
+ break;
+ }
+
+ UINT dwSize;
+
+ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
+ LPBYTE lpb = new BYTE[dwSize];
+ if (lpb == NULL) {
+ return 0;
+ }
+
+ if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize)
+ OutputDebugString(TEXT("GetRawInputData does not return correct size !\n"));
+
+ RAWINPUT *raw = (RAWINPUT *)lpb;
+
+ if (raw->header.dwType == RIM_TYPEMOUSE) {
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ mm->set_control(control_mem);
+ mm->set_shift(shift_mem);
+ mm->set_alt(alt_mem);
+
+ mm->set_button_mask(last_button_state);
+
+ Point2i c(video_mode.width / 2, video_mode.height / 2);
+
+ // centering just so it works as before
+ POINT pos = { (int)c.x, (int)c.y };
+ ClientToScreen(hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+
+ mm->set_position(c);
+ mm->set_global_position(c);
+ input->set_mouse_position(c);
+ mm->set_speed(Vector2(0, 0));
+
+ if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) {
+ mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY));
+
+ } else if (raw->data.mouse.usFlags == MOUSE_MOVE_ABSOLUTE) {
+
+ int nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ int nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ int nScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ int nScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ Vector2 abs_pos(
+ (double(raw->data.mouse.lLastX) - 65536.0 / (nScreenWidth)) * nScreenWidth / 65536.0 + nScreenLeft,
+ (double(raw->data.mouse.lLastY) - 65536.0 / (nScreenHeight)) * nScreenHeight / 65536.0 + nScreenTop);
+
+ POINT coords; //client coords
+ coords.x = abs_pos.x;
+ coords.y = abs_pos.y;
+
+ ScreenToClient(hWnd, &coords);
+
+ mm->set_relative(Vector2(coords.x - old_x, coords.y - old_y));
+ old_x = coords.x;
+ old_y = coords.y;
+
+ /*Input.mi.dx = (int)((((double)(pos.x)-nScreenLeft) * 65536) / nScreenWidth + 65536 / (nScreenWidth));
+ Input.mi.dy = (int)((((double)(pos.y)-nScreenTop) * 65536) / nScreenHeight + 65536 / (nScreenHeight));
+ */
+ }
+
+ if (window_has_focus && main_loop && mm->get_relative() != Vector2())
+ input->parse_input_event(mm);
+ }
+ delete[] lpb;
+ } break;
case WM_MOUSEMOVE: {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
+ break;
+ }
if (input->is_emulating_mouse_from_touch()) {
// Universal translation enabled; ignore OS translation
LPARAM extra = GetMessageExtraInfo();
- if (IsPenEvent(extra)) {
+ if (IsTouchEvent(extra)) {
break;
}
}
@@ -483,7 +549,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (input->is_emulating_mouse_from_touch()) {
// Universal translation enabled; ignore OS translations for left button
LPARAM extra = GetMessageExtraInfo();
- if (IsPenEvent(extra)) {
+ if (IsTouchEvent(extra)) {
break;
}
}
@@ -618,7 +684,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
last_button_state = mb->get_button_mask();
mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
- if (mouse_mode == MOUSE_MODE_CAPTURED) {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && !use_raw_input) {
mb->set_position(Vector2(old_x, old_y));
}
@@ -626,12 +692,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) {
if (mb->is_pressed()) {
- if (++pressrc > 0)
+ if (++pressrc > 0 && mouse_mode != MOUSE_MODE_CAPTURED)
SetCapture(hWnd);
} else {
if (--pressrc <= 0) {
- ReleaseCapture();
+ if (mouse_mode != MOUSE_MODE_CAPTURED) {
+ ReleaseCapture();
+ }
pressrc = 0;
}
}
@@ -659,16 +727,28 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
} break;
+ case WM_MOVE: {
+ if (!IsIconic(hWnd)) {
+ int x = LOWORD(lParam);
+ int y = HIWORD(lParam);
+ last_pos = Point2(x, y);
+ }
+ } break;
+
case WM_SIZE: {
- int window_w = LOWORD(lParam);
- int window_h = HIWORD(lParam);
- 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));
+ // Ignore size when a SIZE_MINIMIZED event is triggered
+ if (wParam != SIZE_MINIMIZED) {
+ int window_w = LOWORD(lParam);
+ int window_h = HIWORD(lParam);
+ 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;
minimized = false;
@@ -684,7 +764,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
RECT r;
GetWindowRect(hWnd, &r);
- dib_size = Size2(r.right - r.left, r.bottom - r.top);
+ dib_size = Size2i(r.right - r.left, r.bottom - r.top);
BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
@@ -694,7 +774,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = dib_size.x, dib_size.y * 4;
+ bmi.bmiHeader.biSizeImage = dib_size.x * dib_size.y * 4;
hBitmap = CreateDIBSection(hDC_dib, &bmi, DIB_RGB_COLORS, (void **)&dib_data, NULL, 0x0);
SelectObject(hDC_dib, hBitmap);
@@ -754,14 +834,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (ke.uMsg == WM_SYSKEYUP)
ke.uMsg = WM_KEYUP;
- /*if (ke.uMsg==WM_KEYDOWN && alt_mem && uMsg!=WM_SYSKEYDOWN) {
- //altgr hack for intl keyboards, not sure how good it is
- //windows is weeeeird
- ke.mod_state.alt=false;
- ke.mod_state.control=false;
- print_line("")
- }*/
-
ke.wParam = wParam;
ke.lParam = lParam;
key_event_buffer[key_event_pos++] = ke;
@@ -769,7 +841,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} break;
case WM_INPUTLANGCHANGEREQUEST: {
- print_line("input lang change");
+ // FIXME: Do something?
} break;
case WM_TOUCH: {
@@ -979,7 +1051,6 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau
UINT x = 0, y = 0;
HRESULT hr = E_FAIL;
- bool bSet = false;
if (hmon && (Shcore != (HMODULE)INVALID_HANDLE_VALUE)) {
hr = getDPIForMonitor(hmon, dpiType /*MDT_Effective_DPI*/, &x, &y);
if (SUCCEEDED(hr) && (x > 0) && (y > 0)) {
@@ -1024,7 +1095,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
WNDCLASSEXW wc;
if (is_hidpi_allowed()) {
- print_line("hidpi aware?");
HMODULE Shcore = LoadLibraryW(L"Shcore.dll");
if (Shcore != NULL) {
@@ -1066,6 +1136,20 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
return ERR_UNAVAILABLE;
}
+ use_raw_input = true;
+
+ RAWINPUTDEVICE Rid[1];
+
+ Rid[0].usUsagePage = 0x01;
+ Rid[0].usUsage = 0x02;
+ Rid[0].dwFlags = 0;
+ Rid[0].hwndTarget = 0;
+
+ if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) {
+ //registration failed.
+ use_raw_input = false;
+ }
+
pre_fs_valid = true;
if (video_mode.fullscreen) {
@@ -1085,8 +1169,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
WindowRect.right = data.size.width;
WindowRect.bottom = data.size.height;
- print_line("wr right " + itos(WindowRect.right) + ", " + itos(WindowRect.bottom));
-
/* DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
@@ -1122,7 +1204,14 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
- char *windowid = getenv("GODOT_WINDOWID");
+ char *windowid;
+#ifdef MINGW_ENABLED
+ windowid = getenv("GODOT_WINDOWID");
+#else
+ size_t len;
+ _dupenv_s(&windowid, &len, "GODOT_WINDOWID");
+#endif
+
if (windowid) {
// strtoull on mingw
@@ -1131,6 +1220,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
#else
hWnd = (HWND)_strtoui64(windowid, NULL, 0);
#endif
+ free(windowid);
SetLastError(0);
user_proc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)(WNDPROC)::WndProc);
@@ -1139,7 +1229,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
printf("Error setting WNDPROC: %li\n", le);
};
- LONG_PTR proc = GetWindowLongPtr(hWnd, GWLP_WNDPROC);
+ GetWindowLongPtr(hWnd, GWLP_WNDPROC);
RECT rect;
if (!GetClientRect(hWnd, &rect)) {
@@ -1171,45 +1261,83 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
}
#if defined(OPENGL_ENABLED)
+
+ bool gles3_context = true;
if (p_video_driver == VIDEO_DRIVER_GLES2) {
- gl_context = memnew(ContextGL_Win(hWnd, false));
- gl_context->initialize();
+ gles3_context = false;
+ }
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- gl_context = memnew(ContextGL_Win(hWnd, true));
- gl_context->initialize();
+ bool editor = Engine::get_singleton()->is_editor_hint();
+ bool gl_initialization_error = false;
+
+ gl_context = NULL;
+ while (!gl_context) {
+ gl_context = memnew(ContextGL_Win(hWnd, gles3_context));
+
+ if (gl_context->initialize() != OK) {
+ memdelete(gl_context);
+ gl_context = NULL;
+
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ gl_initialization_error = true;
+ break;
+ }
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ gles3_context = false;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
+
+ while (true) {
+ if (gles3_context) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best" || editor) {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ gles3_context = false;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ } else {
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
}
- video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
+ "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
+ "Unable to initialize Video driver");
+ return ERR_UNAVAILABLE;
+ }
+
+ video_driver_index = p_video_driver;
gl_context->set_use_vsync(video_mode.use_vsync);
#endif
visual_server = memnew(VisualServerRaster);
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
-
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
- /*
- DEVMODE dmScreenSettings; // Device Mode
- memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
- dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
- dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
- dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
- dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
- dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
- if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
-
-
-
-
- */
visual_server->init();
input = memnew(InputDefault);
@@ -1219,10 +1347,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
AudioDriverManager::initialize(p_audio_driver);
-#ifdef WINMIDI_ENABLED
- driver_midi.open();
-#endif
-
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
@@ -1374,12 +1498,6 @@ void OS_Windows::finalize() {
if (user_proc) {
SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc);
};
-
- /*
- if (debugger_connection_console) {
- memdelete(debugger_connection_console);
- }
- */
}
void OS_Windows::finalize_core() {
@@ -1387,9 +1505,7 @@ void OS_Windows::finalize_core() {
timeEndPeriod(1);
memdelete(process_map);
-
- TCPServerWinsock::cleanup();
- StreamPeerTCPWinsock::cleanup();
+ NetSocketPosix::cleanup();
}
void OS_Windows::alert(const String &p_alert, const String &p_title) {
@@ -1404,18 +1520,27 @@ void OS_Windows::set_mouse_mode(MouseMode p_mode) {
if (mouse_mode == p_mode)
return;
+
+ _set_mouse_mode_impl(p_mode);
+
mouse_mode = p_mode;
- if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
+}
+
+void OS_Windows::_set_mouse_mode_impl(MouseMode p_mode) {
+
+ if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED) {
RECT clipRect;
GetClientRect(hWnd, &clipRect);
ClientToScreen(hWnd, (POINT *)&clipRect.left);
ClientToScreen(hWnd, (POINT *)&clipRect.right);
ClipCursor(&clipRect);
- center = Point2i(video_mode.width / 2, video_mode.height / 2);
- POINT pos = { (int)center.x, (int)center.y };
- ClientToScreen(hWnd, &pos);
- if (mouse_mode == MOUSE_MODE_CAPTURED)
+ if (p_mode == MOUSE_MODE_CAPTURED) {
+ center = Point2i(video_mode.width / 2, video_mode.height / 2);
+ POINT pos = { (int)center.x, (int)center.y };
+ ClientToScreen(hWnd, &pos);
SetCursorPos(pos.x, pos.y);
+ SetCapture(hWnd);
+ }
} else {
ReleaseCapture();
ClipCursor(NULL);
@@ -1429,7 +1554,6 @@ void OS_Windows::set_mouse_mode(MouseMode p_mode) {
set_cursor_shape(c);
}
}
-
OS_Windows::MouseMode OS_Windows::get_mouse_mode() const {
return mouse_mode;
@@ -1573,6 +1697,10 @@ int OS_Windows::get_screen_dpi(int p_screen) const {
Point2 OS_Windows::get_window_position() const {
+ if (minimized) {
+ return last_pos;
+ }
+
RECT r;
GetWindowRect(hWnd, &r);
return Point2(r.left, r.top);
@@ -1584,18 +1712,37 @@ void OS_Windows::set_window_position(const Point2 &p_position) {
RECT r;
GetWindowRect(hWnd, &r);
MoveWindow(hWnd, p_position.x, p_position.y, r.right - r.left, r.bottom - r.top, TRUE);
+
+ // Don't let the mouse leave the window when moved
+ if (mouse_mode == MOUSE_MODE_CONFINED) {
+ RECT rect;
+ GetClientRect(hWnd, &rect);
+ ClientToScreen(hWnd, (POINT *)&rect.left);
+ ClientToScreen(hWnd, (POINT *)&rect.right);
+ ClipCursor(&rect);
+ }
+
+ last_pos = p_position;
}
Size2 OS_Windows::get_window_size() const {
+ if (minimized) {
+ return Size2(video_mode.width, video_mode.height);
+ }
+
RECT r;
- GetClientRect(hWnd, &r);
- return Vector2(r.right - r.left, r.bottom - r.top);
+ if (GetClientRect(hWnd, &r)) { // Only area inside of window border
+ return Size2(r.right - r.left, r.bottom - r.top);
+ }
+ return Size2();
}
Size2 OS_Windows::get_real_window_size() const {
RECT r;
- GetWindowRect(hWnd, &r);
- return Vector2(r.right - r.left, r.bottom - r.top);
+ if (GetWindowRect(hWnd, &r)) { // Includes area of the window border
+ return Size2(r.right - r.left, r.bottom - r.top);
+ }
+ return Size2();
}
void OS_Windows::set_window_size(const Size2 p_size) {
@@ -1612,7 +1759,7 @@ void OS_Windows::set_window_size(const Size2 p_size) {
RECT rect;
GetWindowRect(hWnd, &rect);
- if (video_mode.borderless_window == false) {
+ if (!video_mode.borderless_window) {
RECT crect;
GetClientRect(hWnd, &crect);
@@ -1643,9 +1790,6 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) {
if (pre_fs_valid) {
GetWindowRect(hWnd, &pre_fs_rect);
- //print_line("A: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top));
- //MapWindowPoints(hWnd, GetParent(hWnd), (LPPOINT) &pre_fs_rect, 2);
- //print_line("B: "+itos(pre_fs_rect.left)+","+itos(pre_fs_rect.top)+","+itos(pre_fs_rect.right-pre_fs_rect.left)+","+itos(pre_fs_rect.bottom-pre_fs_rect.top));
}
int cs = get_current_screen();
@@ -2128,14 +2272,15 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
}
ERR_FAIL_COND(!texture.is_valid());
+ ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
+ ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
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 *)memalloc(sizeof(COLORREF) * image_size);
@@ -2180,8 +2325,10 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
cursors[p_shape] = CreateIconIndirect(&iconinfo);
- if (p_shape == CURSOR_ARROW) {
- SetCursor(cursors[p_shape]);
+ if (p_shape == cursor_shape) {
+ if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) {
+ SetCursor(cursors[p_shape]);
+ }
}
if (hAndMask != NULL) {
@@ -2197,8 +2344,10 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
} else {
// Reset to default system cursor
cursors[p_shape] = NULL;
+
+ CursorShape c = cursor_shape;
cursor_shape = CURSOR_MAX;
- set_cursor_shape(p_shape);
+ set_cursor_shape(c);
}
}
@@ -2309,6 +2458,8 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
if (r_exitcode)
*r_exitcode = ret;
+ CloseHandle(pi.pi.hProcess);
+ CloseHandle(pi.pi.hThread);
} else {
ProcessID pid = pi.pi.dwProcessId;
@@ -2322,17 +2473,15 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
Error OS_Windows::kill(const ProcessID &p_pid) {
- HANDLE h;
+ ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED);
- if (process_map->has(p_pid)) {
- h = (*process_map)[p_pid].pi.hProcess;
- process_map->erase(p_pid);
- } else {
+ const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi;
+ process_map->erase(p_pid);
- ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED);
- };
+ const int ret = TerminateProcess(pi.hProcess, 0);
- int ret = TerminateProcess(h, 0);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
return ret != 0 ? OK : FAILED;
};
@@ -2411,7 +2560,16 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) {
bool OS_Windows::has_environment(const String &p_var) const {
+#ifdef MINGW_ENABLED
return _wgetenv(p_var.c_str()) != NULL;
+#else
+ wchar_t *env;
+ size_t len;
+ _wdupenv_s(&env, &len, p_var.c_str());
+ const bool has_env = env != NULL;
+ free(env);
+ return has_env;
+#endif
};
String OS_Windows::get_environment(const String &p_var) const {
@@ -2594,15 +2752,10 @@ void OS_Windows::run() {
main_loop->init();
- uint64_t last_ticks = get_ticks_usec();
-
- int frames = 0;
- uint64_t frame = 0;
-
while (!force_quit) {
process_events(); // get rid of pending events
- if (Main::iteration() == true)
+ if (Main::iteration())
break;
};
@@ -2777,7 +2930,7 @@ int OS_Windows::get_power_percent_left() {
bool OS_Windows::_check_internal_feature_support(const String &p_feature) {
- return p_feature == "pc" || p_feature == "s3tc";
+ return p_feature == "pc" || p_feature == "s3tc" || p_feature == "bptc";
}
void OS_Windows::disable_crash_handler() {
@@ -2789,10 +2942,9 @@ bool OS_Windows::is_disable_crash_handler() const {
}
Error OS_Windows::move_to_trash(const String &p_path) {
- SHFILEOPSTRUCTA sf;
- TCHAR *from = new TCHAR[p_path.length() + 2];
- strcpy(from, p_path.utf8().get_data());
- from[p_path.length()] = 0;
+ SHFILEOPSTRUCTW sf;
+ WCHAR *from = new WCHAR[p_path.length() + 2];
+ wcscpy_s(from, p_path.length() + 1, p_path.c_str());
from[p_path.length() + 1] = 0;
sf.hwnd = hWnd;
@@ -2804,7 +2956,7 @@ Error OS_Windows::move_to_trash(const String &p_path) {
sf.hNameMappings = NULL;
sf.lpszProgressTitle = NULL;
- int ret = SHFileOperation(&sf);
+ int ret = SHFileOperationW(&sf);
delete[] from;
if (ret) {