diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 6325a08187d..5ed422aa4d8 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -1144,6 +1144,11 @@ void _OS::move_window_to_foreground() {
OS::get_singleton()->move_window_to_foreground();
}
+int64_t _OS::get_native_handle(HandleType p_handle_type) {
+
+ return (int64_t)OS::get_singleton()->get_native_handle(p_handle_type);
+}
+
bool _OS::is_debug_build() const {
#ifdef DEBUG_ENABLED
@@ -1292,6 +1297,8 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("center_window"), &_OS::center_window);
ClassDB::bind_method(D_METHOD("move_window_to_foreground"), &_OS::move_window_to_foreground);
+ ClassDB::bind_method(D_METHOD("get_native_handle", "handle_type"), &_OS::get_native_handle);
+
ClassDB::bind_method(D_METHOD("set_borderless_window", "borderless"), &_OS::set_borderless_window);
ClassDB::bind_method(D_METHOD("get_borderless_window"), &_OS::get_borderless_window);
@@ -1503,6 +1510,12 @@ void _OS::_bind_methods() {
BIND_ENUM_CONSTANT(MONTH_NOVEMBER);
BIND_ENUM_CONSTANT(MONTH_DECEMBER);
+ BIND_ENUM_CONSTANT(APPLICATION_HANDLE);
+ BIND_ENUM_CONSTANT(DISPLAY_HANDLE);
+ BIND_ENUM_CONSTANT(WINDOW_HANDLE);
+ BIND_ENUM_CONSTANT(WINDOW_VIEW);
+ BIND_ENUM_CONSTANT(OPENGL_CONTEXT);
+
BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_LANDSCAPE);
BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_PORTRAIT);
BIND_ENUM_CONSTANT(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 9d00e27a43f..e5d88f45977 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -143,6 +143,14 @@ public:
MONTH_DECEMBER
};
+ enum HandleType {
+ APPLICATION_HANDLE, // HINSTANCE, NSApplication*, UIApplication*, JNIEnv* ...
+ DISPLAY_HANDLE, // X11::Display* ...
+ WINDOW_HANDLE, // HWND, X11::Window*, NSWindow*, UIWindow*, Android activity ...
+ WINDOW_VIEW, // HDC, NSView*, UIView*, Android surface ...
+ OPENGL_CONTEXT, // HGLRC, X11::GLXContext, NSOpenGLContext*, EGLContext* ...
+ };
+
void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta);
void global_menu_add_separator(const String &p_menu);
void global_menu_remove_item(const String &p_menu, int p_idx);
@@ -206,6 +214,8 @@ public:
virtual void center_window();
virtual void move_window_to_foreground();
+ virtual int64_t get_native_handle(HandleType p_handle_type);
+
virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window() const;
@@ -383,6 +393,7 @@ VARIANT_ENUM_CAST(_OS::Weekday);
VARIANT_ENUM_CAST(_OS::Month);
VARIANT_ENUM_CAST(_OS::SystemDir);
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
+VARIANT_ENUM_CAST(_OS::HandleType);
class _Geometry : public Object {
diff --git a/core/os/os.h b/core/os/os.h
index f97d89e7116..6eb1e073679 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -238,6 +238,22 @@ public:
virtual void request_attention() {}
virtual void center_window();
+ // Returns internal pointers and handles.
+ // While exposed to GDScript this is mostly to give GDNative plugins access to this information.
+ // Note that whether a valid handle is returned depends on whether it applies to the given
+ // platform and often to the chosen render driver.
+ // NULL will be returned if a handle is not available.
+
+ enum HandleType {
+ APPLICATION_HANDLE, // HINSTANCE, NSApplication*, UIApplication*, JNIEnv* ...
+ DISPLAY_HANDLE, // X11::Display* ...
+ WINDOW_HANDLE, // HWND, X11::Window*, NSWindow*, UIWindow*, Android activity ...
+ WINDOW_VIEW, // HDC, NSView*, UIView*, Android surface ...
+ OPENGL_CONTEXT, // HGLRC, X11::GLXContext, NSOpenGLContext*, EGLContext* ...
+ };
+
+ virtual void *get_native_handle(int p_handle_type) { return NULL; };
+
// Returns window area free of hardware controls and other obstacles.
// The application should use this to determine where to place UI elements.
//
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 50f5707e750..dab44eb05e3 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -291,6 +291,16 @@
Returns the name of the host OS. Possible values are: [code]"Android"[/code], [code]"iOS"[/code], [code]"HTML5"[/code], [code]"OSX"[/code], [code]"Server"[/code], [code]"Windows"[/code], [code]"UWP"[/code], [code]"X11"[/code].
+
+
+
+
+
+
+ Returns internal structure pointers for use in GDNative plugins.
+ [b]Note:[/b] This method is implemented on Linux and Windows (other OSs will soon be supported).
+
+
@@ -1162,6 +1172,34 @@
December.
+
+ Application handle:
+ - Windows: [code]HINSTANCE[/code] of the application
+ - MacOS: [code]NSApplication*[/code] of the application (not yet implemented)
+ - Android: [code]JNIEnv*[/code] of the application (not yet implemented)
+
+
+ Display handle:
+ - Linux: [code]X11::Display*[/code] for the display
+
+
+ Window handle:
+ - Windows: [code]HWND[/code] of the main window
+ - Linux: [code]X11::Window*[/code] of the main window
+ - MacOS: [code]NSWindow*[/code] of the main window (not yet implemented)
+ - Android: [code]jObject[/code] the main android activity (not yet implemented)
+
+
+ Window view:
+ - Windows: [code]HDC[/code] of the main window drawing context
+ - MacOS: [code]NSView*[/code] of the main windows view (not yet implemented)
+
+
+ OpenGL Context:
+ - Windows: [code]HGLRC[/code]
+ - Linux: [code]X11::GLXContext[/code]
+ - MacOS: [code]NSOpenGLContext*[/code] (not yet implemented)
+
Landscape screen orientation.
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index ad62e3a3067..a397b855fa1 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -60,6 +60,14 @@ void ContextGL_Windows::make_current() {
wglMakeCurrent(hDC, hRC);
}
+HDC ContextGL_Windows::get_hdc() {
+ return hDC;
+}
+
+HGLRC ContextGL_Windows::get_hglrc() {
+ return hRC;
+}
+
int ContextGL_Windows::get_window_width() {
return OS::get_singleton()->get_video_mode().width;
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index 280c5a1e3c2..0b1a20706ba 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -63,6 +63,9 @@ public:
void make_current();
+ HDC get_hdc();
+ HGLRC get_hglrc();
+
int get_window_width();
int get_window_height();
void swap_buffers();
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 0007155e0ee..02ac7014651 100755
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -2463,6 +2463,17 @@ void OS_Windows::request_attention() {
FlashWindowEx(&info);
}
+void *OS_Windows::get_native_handle(int p_handle_type) {
+ switch (p_handle_type) {
+ case APPLICATION_HANDLE: return hInstance;
+ case DISPLAY_HANDLE: return NULL; // Do we have a value to return here?
+ case WINDOW_HANDLE: return hWnd;
+ case WINDOW_VIEW: return gl_context->get_hdc();
+ case OPENGL_CONTEXT: return gl_context->get_hglrc();
+ default: return NULL;
+ }
+}
+
String OS_Windows::get_name() const {
return "Windows";
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 6ddb3c3ac6d..a073bcc431d 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -466,6 +466,7 @@ public:
virtual void set_console_visible(bool p_enabled);
virtual bool is_console_visible() const;
virtual void request_attention();
+ virtual void *get_native_handle(int p_handle_type);
virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window();
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp
index 3b88af28e42..1b3e2547fb0 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/x11/context_gl_x11.cpp
@@ -224,6 +224,14 @@ int ContextGL_X11::get_window_height() {
return xwa.height;
}
+void *ContextGL_X11::get_glx_context() {
+ if (p != NULL) {
+ return p->glx_context;
+ } else {
+ return NULL;
+ }
+}
+
void ContextGL_X11::set_use_vsync(bool p_use) {
static bool setup = false;
static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = NULL;
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index 5e5ccc5c86e..01cb5447ede 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -68,6 +68,7 @@ public:
void swap_buffers();
int get_window_width();
int get_window_height();
+ void *get_glx_context();
Error initialize();
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 104bb6f12b8..87032516972 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1756,6 +1756,17 @@ void OS_X11::request_attention() {
XFlush(x11_display);
}
+void *OS_X11::get_native_handle(int p_handle_type) {
+ switch (p_handle_type) {
+ case APPLICATION_HANDLE: return NULL; // Do we have a value to return here?
+ case DISPLAY_HANDLE: return (void *)x11_display;
+ case WINDOW_HANDLE: return (void *)x11_window;
+ case WINDOW_VIEW: return NULL; // Do we have a value to return here?
+ case OPENGL_CONTEXT: return context_gl->get_glx_context();
+ default: return NULL;
+ }
+}
+
void OS_X11::get_key_modifier_state(unsigned int p_x11_state, Ref state) {
state->set_shift((p_x11_state & ShiftMask));
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index a37578d75bc..fe9c9feae31 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -308,6 +308,7 @@ public:
virtual bool is_window_always_on_top() const;
virtual bool is_window_focused() const;
virtual void request_attention();
+ virtual void *get_native_handle(int p_handle_type);
virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window();