diff options
Diffstat (limited to 'platform')
| -rw-r--r-- | platform/linuxbsd/x11/display_server_x11.cpp | 26 | ||||
| -rw-r--r-- | platform/linuxbsd/x11/display_server_x11.h | 1 | ||||
| -rw-r--r-- | platform/macos/detect.py | 8 | ||||
| -rw-r--r-- | platform/macos/display_server_macos.h | 1 | ||||
| -rw-r--r-- | platform/macos/display_server_macos.mm | 30 | ||||
| -rw-r--r-- | platform/windows/display_server_windows.cpp | 36 | ||||
| -rw-r--r-- | platform/windows/display_server_windows.h | 5 |
7 files changed, 96 insertions, 11 deletions
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index d1f1115aad..72cd622799 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -128,6 +128,7 @@ bool DisplayServerX11::has_feature(Feature p_feature) const { #endif case FEATURE_CLIPBOARD_PRIMARY: case FEATURE_TEXT_TO_SPEECH: + case FEATURE_SCREEN_CAPTURE: return true; default: { } @@ -1169,6 +1170,29 @@ int DisplayServerX11::screen_get_dpi(int p_screen) const { return 96; } +Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const { + Point2i pos = p_position; + + int number_of_screens = XScreenCount(x11_display); + for (int i = 0; i < number_of_screens; i++) { + Window root = XRootWindow(x11_display, i); + XWindowAttributes root_attrs; + XGetWindowAttributes(x11_display, root, &root_attrs); + if ((pos.x >= root_attrs.x) && (pos.x <= root_attrs.x + root_attrs.width) && (pos.y >= root_attrs.y) && (pos.y <= root_attrs.y + root_attrs.height)) { + XImage *image = XGetImage(x11_display, root, pos.x, pos.y, 1, 1, AllPlanes, XYPixmap); + if (image) { + XColor c; + c.pixel = XGetPixel(image, 0, 0); + XFree(image); + XQueryColor(x11_display, XDefaultColormap(x11_display, i), &c); + return Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0); + } + } + } + + return Color(); +} + float DisplayServerX11::screen_get_refresh_rate(int p_screen) const { _THREAD_SAFE_METHOD_ @@ -2917,7 +2941,7 @@ BitField<MouseButtonMask> DisplayServerX11::_get_mouse_button_state(MouseButton } void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, LocalVector<XEvent> &p_events, uint32_t &p_event_index, bool p_echo) { - WindowData wd = windows[p_window]; + WindowData &wd = windows[p_window]; // X11 functions don't know what const is XKeyEvent *xkeyevent = p_event; diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index dbe8a0ce2b..c98409253e 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -409,6 +409,7 @@ public: virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual Color screen_get_pixel(const Point2i &p_position) const override; #if defined(DBUS_ENABLED) virtual void screen_set_keep_on(bool p_enable) override; diff --git a/platform/macos/detect.py b/platform/macos/detect.py index cd46dab4f3..e3c1f17b8f 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -242,17 +242,17 @@ def configure(env: "Environment"): env.Append(LINKFLAGS=["-lMoltenVK"]) mvk_found = False - mkv_list = [get_mvk_sdk_path(), "/opt/homebrew/lib", "/usr/local/homebrew/lib", "/opt/local/lib"] + mvk_list = [get_mvk_sdk_path(), "/opt/homebrew/lib", "/usr/local/homebrew/lib", "/opt/local/lib"] if env["vulkan_sdk_path"] != "": - mkv_list.insert(0, os.path.expanduser(env["vulkan_sdk_path"])) - mkv_list.insert( + mvk_list.insert(0, os.path.expanduser(env["vulkan_sdk_path"])) + mvk_list.insert( 0, os.path.join( os.path.expanduser(env["vulkan_sdk_path"]), "MoltenVK/MoltenVK.xcframework/macos-arm64_x86_64/" ), ) - for mvk_path in mkv_list: + for mvk_path in mvk_list: if mvk_path and os.path.isfile(os.path.join(mvk_path, "libMoltenVK.a")): mvk_found = True print("MoltenVK found at: " + mvk_path) diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index fb9bcdfe56..f7c5b0b847 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -334,6 +334,7 @@ public: virtual float screen_get_max_scale() const override; virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual Color screen_get_pixel(const Point2i &p_position) const override; virtual void screen_set_keep_on(bool p_enable) override; virtual bool screen_is_kept_on() const override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index e8eb5b419b..eba69f8954 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -765,6 +765,7 @@ bool DisplayServerMacOS::has_feature(Feature p_feature) const { case FEATURE_SWAP_BUFFERS: case FEATURE_TEXT_TO_SPEECH: case FEATURE_EXTEND_TO_TITLE: + case FEATURE_SCREEN_CAPTURE: return true; default: { } @@ -2249,6 +2250,35 @@ Rect2i DisplayServerMacOS::screen_get_usable_rect(int p_screen) const { return Rect2i(); } +Color DisplayServerMacOS::screen_get_pixel(const Point2i &p_position) const { + Point2i position = p_position; + // OS X native y-coordinate relative to _get_screens_origin() is negative, + // Godot passes a positive value. + position.y *= -1; + position += _get_screens_origin(); + position /= screen_get_max_scale(); + + for (NSScreen *screen in [NSScreen screens]) { + NSRect frame = [screen frame]; + if (NSMouseInRect(NSMakePoint(position.x, position.y), frame, NO)) { + NSDictionary *screenDescription = [screen deviceDescription]; + CGDirectDisplayID display_id = [[screenDescription objectForKey:@"NSScreenNumber"] unsignedIntValue]; + CGImageRef image = CGDisplayCreateImageForRect(display_id, CGRectMake(position.x - frame.origin.x, frame.size.height - (position.y - frame.origin.y), 1, 1)); + if (image) { + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:image]; + CGImageRelease(image); + NSColor *color = [bitmap colorAtX:0 y:0]; + if (color) { + CGFloat components[4]; + [color getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]]; + return Color(components[0], components[1], components[2], components[3]); + } + } + } + } + return Color(); +} + float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const { _THREAD_SAFE_METHOD_ diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 360e446de7..199386f9bf 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -90,6 +90,7 @@ bool DisplayServerWindows::has_feature(Feature p_feature) const { case FEATURE_SWAP_BUFFERS: case FEATURE_KEEP_SCREEN_ON: case FEATURE_TEXT_TO_SPEECH: + case FEATURE_SCREEN_CAPTURE: return true; default: return false; @@ -264,15 +265,15 @@ BitField<MouseButtonMask> DisplayServerWindows::mouse_get_button_state() const { void DisplayServerWindows::clipboard_set(const String &p_text) { _THREAD_SAFE_METHOD_ - if (!windows.has(last_focused_window)) { - return; // No focused window? + if (!windows.has(MAIN_WINDOW_ID)) { + return; } // 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("\r\n", "\n").replace("\n", "\r\n"); // Avoid \r\r\n. - if (!OpenClipboard(windows[last_focused_window].hWnd)) { + if (!OpenClipboard(windows[MAIN_WINDOW_ID].hWnd)) { ERR_FAIL_MSG("Unable to open clipboard."); } EmptyClipboard(); @@ -305,12 +306,12 @@ void DisplayServerWindows::clipboard_set(const String &p_text) { String DisplayServerWindows::clipboard_get() const { _THREAD_SAFE_METHOD_ - if (!windows.has(last_focused_window)) { - return String(); // No focused window? + if (!windows.has(MAIN_WINDOW_ID)) { + return String(); } String ret; - if (!OpenClipboard(windows[last_focused_window].hWnd)) { + if (!OpenClipboard(windows[MAIN_WINDOW_ID].hWnd)) { ERR_FAIL_V_MSG("", "Unable to open clipboard."); } @@ -631,6 +632,26 @@ int DisplayServerWindows::screen_get_dpi(int p_screen) const { EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcDpi, (LPARAM)&data); return data.dpi; } + +Color DisplayServerWindows::screen_get_pixel(const Point2i &p_position) const { + Point2i pos = p_position + _get_screens_origin(); + + POINT p; + p.x = pos.x; + p.y = pos.y; + if (win81p_LogicalToPhysicalPointForPerMonitorDPI) { + win81p_LogicalToPhysicalPointForPerMonitorDPI(0, &p); + } + HDC dc = GetDC(0); + COLORREF col = GetPixel(dc, p.x, p.y); + if (col != CLR_INVALID) { + return Color(float(col & 0x000000FF) / 256.0, float((col & 0x0000FF00) >> 8) / 256.0, float((col & 0x00FF0000) >> 16) / 256.0, 1.0); + } + ReleaseDC(NULL, dc); + + return Color(); +} + float DisplayServerWindows::screen_get_refresh_rate(int p_screen) const { _THREAD_SAFE_METHOD_ @@ -4023,6 +4044,7 @@ GetImmersiveUserColorSetPreferencePtr DisplayServerWindows::GetImmersiveUserColo bool DisplayServerWindows::winink_available = false; GetPointerTypePtr DisplayServerWindows::win8p_GetPointerType = nullptr; GetPointerPenInfoPtr DisplayServerWindows::win8p_GetPointerPenInfo = nullptr; +LogicalToPhysicalPointForPerMonitorDPIPtr DisplayServerWindows::win81p_LogicalToPhysicalPointForPerMonitorDPI = nullptr; typedef enum _SHC_PROCESS_DPI_AWARENESS { SHC_PROCESS_DPI_UNAWARE = 0, @@ -4151,10 +4173,12 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } // Note: Windows Ink API for pen input, available on Windows 8+ only. + // Note: DPI conversion API, available on Windows 8.1+ only. HMODULE user32_lib = LoadLibraryW(L"user32.dll"); if (user32_lib) { win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType"); win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo"); + win81p_LogicalToPhysicalPointForPerMonitorDPI = (LogicalToPhysicalPointForPerMonitorDPIPtr)GetProcAddress(user32_lib, "LogicalToPhysicalPointForPerMonitorDPI"); winink_available = win8p_GetPointerType && win8p_GetPointerPenInfo; } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 0d2137d048..1b36b0951e 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -259,6 +259,7 @@ typedef struct tagPOINTER_PEN_INFO { typedef BOOL(WINAPI *GetPointerTypePtr)(uint32_t p_id, POINTER_INPUT_TYPE *p_type); typedef BOOL(WINAPI *GetPointerPenInfoPtr)(uint32_t p_id, POINTER_PEN_INFO *p_pen_info); +typedef BOOL(WINAPI *LogicalToPhysicalPointForPerMonitorDPIPtr)(HWND hwnd, LPPOINT lpPoint); typedef struct { BYTE bWidth; // Width, in pixels, of the image @@ -305,6 +306,9 @@ class DisplayServerWindows : public DisplayServer { static GetPointerTypePtr win8p_GetPointerType; static GetPointerPenInfoPtr win8p_GetPointerPenInfo; + // DPI conversion API + static LogicalToPhysicalPointForPerMonitorDPIPtr win81p_LogicalToPhysicalPointForPerMonitorDPI; + void _update_tablet_ctx(const String &p_old_driver, const String &p_new_driver); String tablet_driver; Vector<String> tablet_drivers; @@ -524,6 +528,7 @@ public: virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override; + virtual Color screen_get_pixel(const Point2i &p_position) const override; virtual void screen_set_keep_on(bool p_enable) override; //disable screensaver virtual bool screen_is_kept_on() const override; |
