From 1ea7358405d9d98dac2e2a9c0acd563be4d68e17 Mon Sep 17 00:00:00 2001 From: Bastiaan Olij Date: Sat, 3 Oct 2020 22:13:39 +1000 Subject: [PATCH] Add get_native_handle to OS --- core/bind/core_bind.cpp | 13 +++++++++ core/bind/core_bind.h | 11 +++++++ core/os/os.h | 16 +++++++++++ doc/classes/OS.xml | 38 +++++++++++++++++++++++++ platform/windows/context_gl_windows.cpp | 8 ++++++ platform/windows/context_gl_windows.h | 3 ++ platform/windows/os_windows.cpp | 11 +++++++ platform/windows/os_windows.h | 1 + platform/x11/context_gl_x11.cpp | 8 ++++++ platform/x11/context_gl_x11.h | 1 + platform/x11/os_x11.cpp | 11 +++++++ platform/x11/os_x11.h | 1 + 12 files changed, 122 insertions(+) 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();