summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp26
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h1
-rw-r--r--platform/macos/detect.py8
-rw-r--r--platform/macos/display_server_macos.h1
-rw-r--r--platform/macos/display_server_macos.mm30
-rw-r--r--platform/windows/display_server_windows.cpp36
-rw-r--r--platform/windows/display_server_windows.h5
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;