From 89f37d410557c9062b45f090f08d006453bc4fc9 Mon Sep 17 00:00:00 2001
From: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date: Fri, 14 Jan 2022 12:41:04 +0200
Subject: [PATCH] Add support for getting native display, window, and view
handles.
---
doc/classes/DisplayServer.xml | 26 +++++++++++++++++++++
platform/android/display_server_android.cpp | 18 ++++++++++++++
platform/android/display_server_android.h | 3 +++
platform/iphone/display_server_iphone.h | 2 ++
platform/iphone/display_server_iphone.mm | 18 ++++++++++++++
platform/linuxbsd/display_server_x11.cpp | 18 ++++++++++++++
platform/linuxbsd/display_server_x11.h | 2 ++
platform/osx/display_server_osx.h | 2 ++
platform/osx/display_server_osx.mm | 18 ++++++++++++++
platform/windows/display_server_windows.cpp | 18 ++++++++++++++
platform/windows/display_server_windows.h | 2 ++
servers/display_server.cpp | 11 +++++++++
servers/display_server.h | 9 +++++++
13 files changed, 147 insertions(+)
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index a41875385c4..ddcef437a5e 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -579,6 +579,15 @@
Returns the mode of the given window.
+
+
+
+
+
+ Returns internal structure pointers for use in plugins.
+ [b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows.
+
+
@@ -942,5 +951,22 @@
Displays the most recent image in the queue on vertical blanking intervals, while rendering to the other images (no tearing is visible).
Although not guaranteed, the images can be rendered as fast as possible, which may reduce input lag.
+
+ Display handle:
+ - Linux: [code]X11::Display*[/code] for the display.
+
+
+ Window handle:
+ - Windows: [code]HWND[/code] for the window.
+ - Linux: [code]X11::Window*[/code] for the window.
+ - MacOS: [code]NSWindow*[/code] for the window.
+ - iOS: [code]UIViewController*[/code] for the view controller.
+ - Android: [code]jObject[/code] for the activity.
+
+
+ Window view:
+ - MacOS: [code]NSView*[/code] for the window main view.
+ - iOS: [code]UIView*[/code] for the window main view.
+
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 5b9ca441803..e31e1d8c035 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -243,6 +243,24 @@ DisplayServer::WindowID DisplayServerAndroid::get_window_at_screen_position(cons
return MAIN_WINDOW_ID;
}
+int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)((OS_Android *)OS::get_singleton())->get_godot_java()->get_activity();
+ }
+ case WINDOW_VIEW: {
+ return 0; // Not supported.
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerAndroid::window_attach_instance_id(ObjectID p_instance, DisplayServer::WindowID p_window) {
window_attached_instance_id = p_instance;
}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index 8538b6e660a..aa5c511de85 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -123,6 +123,9 @@ public:
virtual Vector get_window_list() const override;
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
+
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h
index de04bc88e3a..64344836413 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/iphone/display_server_iphone.h
@@ -135,6 +135,8 @@ public:
virtual WindowID
get_window_at_screen_position(const Point2i &p_position) const override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index 3047d91a4d2..d8e0d7f9168 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -408,6 +408,24 @@ DisplayServer::WindowID DisplayServerIPhone::get_window_at_screen_position(const
return MAIN_WINDOW_ID;
}
+int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)AppDelegate.viewController;
+ }
+ case WINDOW_VIEW: {
+ return (int64_t)AppDelegate.viewController.godotView;
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerIPhone::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
window_attached_instance_id = p_instance;
}
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index c4f7a3a6463..da07eb11e3f 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -1170,6 +1170,24 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
windows.erase(p_id);
}
+int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return (int64_t)x11_display;
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)windows[p_window].x11_window;
+ }
+ case WINDOW_VIEW: {
+ return 0; // Not supported.
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerX11::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 1dcedabb1af..8e732430b1b 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -317,6 +317,8 @@ public:
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 4b558d973df..430c8852180 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -281,6 +281,8 @@ public:
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void gl_window_make_current(DisplayServer::WindowID p_window_id) override;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 27d302a984c..635fedb2fc7 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -3519,6 +3519,24 @@ DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Po
return INVALID_WINDOW_ID;
}
+int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)windows[p_window].window_object;
+ }
+ case WINDOW_VIEW: {
+ return (int64_t)windows[p_window].window_view;
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerOSX::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
_THREAD_SAFE_METHOD_
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 091bed36eaa..9f1b1b761da 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -571,6 +571,24 @@ void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_wind
#endif
}
+int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)windows[p_window].hWnd;
+ }
+ case WINDOW_VIEW: {
+ return 0; // Not supported.
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerWindows::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
_THREAD_SAFE_METHOD_
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 409335b41c6..e51bc1e854c 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -473,6 +473,8 @@ public:
virtual void show_window(WindowID p_window) override;
virtual void delete_sub_window(WindowID p_window) override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 01f58e37ebe..c8f48ba20b6 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -324,6 +324,11 @@ void DisplayServer::set_icon(const Ref &p_icon) {
WARN_PRINT("Icon not supported by this display server.");
}
+int64_t DisplayServer::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ WARN_PRINT("Native handle not supported by this display server.");
+ return 0;
+}
+
void DisplayServer::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
WARN_PRINT("Changing the VSync mode is not supported by this display server.");
}
@@ -396,6 +401,8 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "vsync_mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i()));
ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window);
+ ClassDB::bind_method(D_METHOD("window_get_native_handle", "handle_type", "window_id"), &DisplayServer::window_get_native_handle, DEFVAL(MAIN_WINDOW_ID));
+
ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_set_mouse_passthrough", "region", "window_id"), &DisplayServer::window_set_mouse_passthrough, DEFVAL(MAIN_WINDOW_ID));
@@ -564,6 +571,10 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(VSYNC_ENABLED);
BIND_ENUM_CONSTANT(VSYNC_ADAPTIVE);
BIND_ENUM_CONSTANT(VSYNC_MAILBOX);
+
+ BIND_ENUM_CONSTANT(DISPLAY_HANDLE);
+ BIND_ENUM_CONSTANT(WINDOW_HANDLE);
+ BIND_ENUM_CONSTANT(WINDOW_VIEW);
}
void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers) {
diff --git a/servers/display_server.h b/servers/display_server.h
index a84290be777..28addea463a 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -65,6 +65,12 @@ public:
VSYNC_MAILBOX
};
+ enum HandleType {
+ DISPLAY_HANDLE,
+ WINDOW_HANDLE,
+ WINDOW_VIEW,
+ };
+
typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Size2i &, Error &r_error);
typedef Vector (*GetRenderingDriversFunction)();
@@ -233,6 +239,8 @@ public:
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const;
+
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) = 0;
@@ -391,6 +399,7 @@ VARIANT_ENUM_CAST(DisplayServer::MouseMode)
VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation)
VARIANT_ENUM_CAST(DisplayServer::WindowMode)
VARIANT_ENUM_CAST(DisplayServer::WindowFlags)
+VARIANT_ENUM_CAST(DisplayServer::HandleType)
VARIANT_ENUM_CAST(DisplayServer::CursorShape)
VARIANT_ENUM_CAST(DisplayServer::VSyncMode)