Browse Source

Merge pull request #42531 from BastiaanOlij/add_get_native_handle

Add get native handle
Rémi Verschelde 4 years ago
parent
commit
04fb41a0f3

+ 13 - 0
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);

+ 11 - 0
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 {
 

+ 16 - 0
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.
 	//

+ 38 - 0
doc/classes/OS.xml

@@ -292,6 +292,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].
 			</description>
 		</method>
+		<method name="get_native_handle">
+			<return type="int">
+			</return>
+			<argument index="0" name="handle_type" type="int" enum="OS.HandleType">
+			</argument>
+			<description>
+				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).
+			</description>
+		</method>
 		<method name="get_power_percent_left">
 			<return type="int">
 			</return>
@@ -1163,6 +1173,34 @@
 		<constant name="MONTH_DECEMBER" value="12" enum="Month">
 			December.
 		</constant>
+		<constant name="APPLICATION_HANDLE" value="0" enum="HandleType">
+			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)
+		</constant>
+		<constant name="DISPLAY_HANDLE" value="1" enum="HandleType">
+			Display handle:
+			- Linux: [code]X11::Display*[/code] for the display
+		</constant>
+		<constant name="WINDOW_HANDLE" value="2" enum="HandleType">
+			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)
+		</constant>
+		<constant name="WINDOW_VIEW" value="3" enum="HandleType">
+			Window view:
+			- Windows: [code]HDC[/code] of the main window drawing context
+			- MacOS: [code]NSView*[/code] of the main windows view (not yet implemented)
+		</constant>
+		<constant name="OPENGL_CONTEXT" value="4" enum="HandleType">
+			OpenGL Context:
+			- Windows: [code]HGLRC[/code]
+			- Linux: [code]X11::GLXContext[/code]
+			- MacOS: [code]NSOpenGLContext*[/code] (not yet implemented)
+		</constant>
 		<constant name="SCREEN_ORIENTATION_LANDSCAPE" value="0" enum="ScreenOrientation">
 			Landscape screen orientation.
 		</constant>

+ 8 - 0
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;

+ 3 - 0
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();

+ 11 - 0
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";

+ 1 - 0
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();

+ 8 - 0
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;

+ 1 - 0
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();
 

+ 11 - 0
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<InputEventWithModifiers> state) {
 
 	state->set_shift((p_x11_state & ShiftMask));

+ 1 - 0
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();