<commit_before>/*************************************************************************/
/*  display_server_iphone.mm                                             */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2022 <NAME>, <NAME>.                 */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "display_server_iphone.h"

#import "app_delegate.h"
#include "core/config/project_settings.h"
#include "core/io/file_access_pack.h"
#import "device_metrics.h"
#import "godot_view.h"
#include "ios.h"
#import "keyboard_input_view.h"
#include "os_iphone.h"
#include "tts_ios.h"
#import "view_controller.h"

#import <Foundation/Foundation.h>
#import <sys/utsname.h>

static const float kDisplayServerIPhoneAcceleration = 1;

DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
	return (DisplayServerIPhone *)DisplayServer::get_singleton();
}

DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
	rendering_driver = p_rendering_driver;

	// Init TTS
	tts = [[TTS_IOS alloc] init];

#if defined(GLES3_ENABLED)
	// FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented
	// again,
	// Note that we should be checking "opengl3" as the driver, might never enable this seeing OpenGL is deprecated on iOS
	// We are hardcoding the rendering_driver to "vulkan" down below

	if (rendering_driver == "opengl_es") {
		bool gl_initialization_error = false;

		// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?

		if (RasterizerGLES3::is_viable() == OK) {
			RasterizerGLES3::register_config();
			RasterizerGLES3::make_current();
		} else {
			gl_initialization_error = true;
		}

		if (gl_initialization_error) {
			OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.", "Unable to initialize video driver");
			//        return ERR_UNAVAILABLE;
		}

		//    rendering_server = memnew(RenderingServerDefault);
		//    // FIXME: Reimplement threaded rendering
		//    if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
		//        rendering_server = memnew(RenderingServerWrapMT(rendering_server,
		//        false));
		//    }
		//    rendering_server->init();
		// rendering_server->cursor_set_visible(false, 0);

		// reset this to what it should be, it will have been set to 0 after
		// rendering_server->init() is called
		//    RasterizerStorageGLES3system_fbo = gl_view_base_fb;
	}
#endif

#if defined(VULKAN_ENABLED)
	rendering_driver = "vulkan";

	context_vulkan = nullptr;
	rendering_device_vulkan = nullptr;

	if (rendering_driver == "vulkan") {
		context_vulkan = memnew(VulkanContextIPhone);
		if (context_vulkan->initialize() != OK) {
			memdelete(context_vulkan);
			context_vulkan = nullptr;
			ERR_FAIL_MSG("Failed to initialize Vulkan context");
		}

		CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];

		if (!layer) {
			ERR_FAIL_MSG("Failed to create iOS rendering layer.");
		}

		Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
		if (context_vulkan->window_create(MAIN_WINDOW_ID, p_vsync_mode, layer, size.width, size.height) != OK) {
			memdelete(context_vulkan);
			context_vulkan = nullptr;
			ERR_FAIL_MSG("Failed to create Vulkan window.");
		}

		rendering_device_vulkan = memnew(RenderingDeviceVulkan);
		rendering_device_vulkan->initialize(context_vulkan);

		RendererCompositorRD::make_current();
	}
#endif

	bool keep_screen_on = bool(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true));
	screen_set_keep_on(keep_screen_on);

	Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);

	r_error = OK;
}

DisplayServerIPhone::~DisplayServerIPhone() {
#if defined(VULKAN_ENABLED)
	if (rendering_device_vulkan) {
		rendering_device_vulkan->finalize();
		memdelete(rendering_device_vulkan);
		rendering_device_vulkan = nullptr;
	}

	if (context_vulkan) {
		context_vulkan->window_destroy(MAIN_WINDOW_ID);
		memdelete(context_vulkan);
		context_vulkan = nullptr;
	}
#endif
}

DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
	return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
}

Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
	Vector<String> drivers;

#if defined(VULKAN_ENABLED)
	drivers.push_back("vulkan");
#endif
#if defined(GLES3_ENABLED)
	drivers.push_back("opengl_es");
#endif

	return drivers;
}

void DisplayServerIPhone::register_iphone_driver() {
	register_create_function("iphone", create_func, get_rendering_drivers_func);
}

// MARK: Events

void DisplayServerIPhone::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
	window_resize_callback = p_callable;
}

void DisplayServerIPhone::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
	window_event_callback = p_callable;
}
void DisplayServerIPhone::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
	input_event_callback = p_callable;
}

void DisplayServerIPhone::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
	input_text_callback = p_callable;
}

void DisplayServerIPhone::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
	// Probably not supported for iOS
}

void DisplayServerIPhone::process_events() {
}

void DisplayServerIPhone::_dispatch_input_events(const Ref<InputEvent> &p_event) {
	DisplayServerIPhone::get_singleton()->send_input_event(p_event);
}

void DisplayServerIPhone::send_input_event(const Ref<InputEvent> &p_event) const {
	_window_callback(input_event_callback, p_event);
}<commit_msg>Flush accumulated input events on iOS<commit_after>/*************************************************************************/
/*  display_server_iphone.mm                                             */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2022 <NAME>, <NAME>.                 */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "display_server_iphone.h"

#import "app_delegate.h"
#include "core/config/project_settings.h"
#include "core/io/file_access_pack.h"
#import "device_metrics.h"
#import "godot_view.h"
#include "ios.h"
#import "keyboard_input_view.h"
#include "os_iphone.h"
#include "tts_ios.h"
#import "view_controller.h"

#import <Foundation/Foundation.h>
#import <sys/utsname.h>

static const float kDisplayServerIPhoneAcceleration = 1;

DisplayServerIPhone *DisplayServerIPhone::get_singleton() {
	return (DisplayServerIPhone *)DisplayServer::get_singleton();
}

DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
	rendering_driver = p_rendering_driver;

	// Init TTS
	tts = [[TTS_IOS alloc] init];

#if defined(GLES3_ENABLED)
	// FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented
	// again,
	// Note that we should be checking "opengl3" as the driver, might never enable this seeing OpenGL is deprecated on iOS
	// We are hardcoding the rendering_driver to "vulkan" down below

	if (rendering_driver == "opengl_es") {
		bool gl_initialization_error = false;

		// FIXME: Add Vulkan support via MoltenVK. Add fallback code back?

		if (RasterizerGLES3::is_viable() == OK) {
			RasterizerGLES3::register_config();
			RasterizerGLES3::make_current();
		} else {
			gl_initialization_error = true;
		}

		if (gl_initialization_error) {
			OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.", "Unable to initialize video driver");
			//        return ERR_UNAVAILABLE;
		}

		//    rendering_server = memnew(RenderingServerDefault);
		//    // FIXME: Reimplement threaded rendering
		//    if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
		//        rendering_server = memnew(RenderingServerWrapMT(rendering_server,
		//        false));
		//    }
		//    rendering_server->init();
		// rendering_server->cursor_set_visible(false, 0);

		// reset this to what it should be, it will have been set to 0 after
		// rendering_server->init() is called
		//    RasterizerStorageGLES3system_fbo = gl_view_base_fb;
	}
#endif

#if defined(VULKAN_ENABLED)
	rendering_driver = "vulkan";

	context_vulkan = nullptr;
	rendering_device_vulkan = nullptr;

	if (rendering_driver == "vulkan") {
		context_vulkan = memnew(VulkanContextIPhone);
		if (context_vulkan->initialize() != OK) {
			memdelete(context_vulkan);
			context_vulkan = nullptr;
			ERR_FAIL_MSG("Failed to initialize Vulkan context");
		}

		CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];

		if (!layer) {
			ERR_FAIL_MSG("Failed to create iOS rendering layer.");
		}

		Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
		if (context_vulkan->window_create(MAIN_WINDOW_ID, p_vsync_mode, layer, size.width, size.height) != OK) {
			memdelete(context_vulkan);
			context_vulkan = nullptr;
			ERR_FAIL_MSG("Failed to create Vulkan window.");
		}

		rendering_device_vulkan = memnew(RenderingDeviceVulkan);
		rendering_device_vulkan->initialize(context_vulkan);

		RendererCompositorRD::make_current();
	}
#endif

	bool keep_screen_on = bool(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true));
	screen_set_keep_on(keep_screen_on);

	Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);

	r_error = OK;
}

DisplayServerIPhone::~DisplayServerIPhone() {
#if defined(VULKAN_ENABLED)
	if (rendering_device_vulkan) {
		rendering_device_vulkan->finalize();
		memdelete(rendering_device_vulkan);
		rendering_device_vulkan = nullptr;
	}

	if (context_vulkan) {
		context_vulkan->window_destroy(MAIN_WINDOW_ID);
		memdelete(context_vulkan);
		context_vulkan = nullptr;
	}
#endif
}

DisplayServer *DisplayServerIPhone::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
	return memnew(DisplayServerIPhone(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error));
}

Vector<String> DisplayServerIPhone::get_rendering_drivers_func() {
	Vector<String> drivers;

#if defined(VULKAN_ENABLED)
	drivers.push_back("vulkan");
#endif
#if defined(GLES3_ENABLED)
	drivers.push_back("opengl_es");
#endif

	return drivers;
}

void DisplayServerIPhone::register_iphone_driver() {
	register_create_function("iphone", create_func, get_rendering_drivers_func);
}

// MARK: Events

void DisplayServerIPhone::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
	window_resize_callback = p_callable;
}

void DisplayServerIPhone::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
	window_event_callback = p_callable;
}
void DisplayServerIPhone::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
	input_event_callback = p_callable;
}

void DisplayServerIPhone::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
	input_text_callback = p_callable;
}

void DisplayServerIPhone::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
	// Probably not supported for iOS
}

void DisplayServerIPhone::process_events() {
	Input::get_singleton()->flush_buffered_events();
}

void DisplayServerIPhone::_dispatch_input_events(const Ref<InputEvent> &p_event) {
	DisplayServerIPhone::get_singleton()->send_input_event(p_event);
}

void DisplayServerIPhone::send_input_event(const Ref<InputEvent> &p_event) const {
	_window_callback(input_event_callback, p_event);
}
{'fraction_non_alphanumeric': 0.1334979111279909, 'fraction_numerical': 0.004304342321812888, 'mean_word_length': 3.874730021598272, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 42, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1547055', 'n_tokens_mistral': 4976, 'n_tokens_neox': 4674, 'n_words': 1110}