/*************************************************************************/ /* os_haiku.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2020 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 "os_haiku.h" #include "drivers/gles2/rasterizer_gles2.h" #include "main/main.h" #include "servers/physics_3d/physics_server_3d_sw.h" #include "servers/rendering/rendering_server_raster.h" #include "servers/rendering/rendering_server_wrap_mt.h" #include OS_Haiku::OS_Haiku() { #ifdef MEDIA_KIT_ENABLED AudioDriverManager::add_driver(&driver_media_kit); #endif }; void OS_Haiku::run() { if (!main_loop) { return; } main_loop->init(); context_gl->release_current(); // TODO: clean up BMessenger *bms = new BMessenger(window); BMessage *msg = new BMessage(); bms->SendMessage(LOCKGL_MSG, msg); window->StartMessageRunner(); app->Run(); window->StopMessageRunner(); delete app; delete bms; delete msg; main_loop->finish(); } String OS_Haiku::get_name() const { return "Haiku"; } int OS_Haiku::get_video_driver_count() const { return 1; } const char *OS_Haiku::get_video_driver_name(int p_driver) const { return "GLES2"; } int OS_Haiku::get_current_video_driver() const { return video_driver_index; } Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; current_video_mode = p_desired; app = new HaikuApplication(); BRect frame; frame.Set(50, 50, 50 + current_video_mode.width - 1, 50 + current_video_mode.height - 1); window = new HaikuDirectWindow(frame); window->SetVideoMode(¤t_video_mode); if (current_video_mode.fullscreen) { window->SetFullScreen(true); } if (!current_video_mode.resizable) { uint32 flags = window->Flags(); flags |= B_NOT_RESIZABLE; window->SetFlags(flags); } #if defined(OPENGL_ENABLED) context_gl = memnew(ContextGL_Haiku(window)); context_gl->initialize(); context_gl->make_current(); context_gl->set_use_vsync(current_video_mode.use_vsync); // FIXME: That's not how the rasterizer setup should happen. RasterizerGLES2::register_config(); RasterizerGLES2::make_current(); #endif rendering_server = memnew(RenderingServerRaster); // FIXME: Reimplement threaded rendering if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { rendering_server = memnew(RenderingServerWrapMT(rendering_server, false)); } ERR_FAIL_COND_V(!rendering_server, ERR_UNAVAILABLE); video_driver_index = p_video_driver; input = memnew(InputDefault); window->SetInput(input); window->Show(); rendering_server->init(); AudioDriverManager::initialize(p_audio_driver); return OK; } void OS_Haiku::finalize() { if (main_loop) { memdelete(main_loop); } main_loop = NULL; rendering_server->finish(); memdelete(rendering_server); memdelete(input); #if defined(OPENGL_ENABLED) memdelete(context_gl); #endif } void OS_Haiku::set_main_loop(MainLoop *p_main_loop) { main_loop = p_main_loop; input->set_main_loop(p_main_loop); window->SetMainLoop(p_main_loop); } MainLoop *OS_Haiku::get_main_loop() const { return main_loop; } void OS_Haiku::delete_main_loop() { if (main_loop) { memdelete(main_loop); } main_loop = NULL; window->SetMainLoop(NULL); } void OS_Haiku::release_rendering_thread() { context_gl->release_current(); } void OS_Haiku::make_rendering_thread() { context_gl->make_current(); } bool OS_Haiku::can_draw() const { // TODO: implement return true; } void OS_Haiku::swap_buffers() { context_gl->swap_buffers(); } Point2 OS_Haiku::get_mouse_position() const { return window->GetLastMousePosition(); } int OS_Haiku::get_mouse_button_state() const { return window->GetLastButtonMask(); } void OS_Haiku::set_cursor_shape(CursorShape p_shape) { //ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED"); } OS::CursorShape OS_Haiku::get_cursor_shape() const { // TODO: implement get_cursor_shape } void OS_Haiku::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { // TODO } int OS_Haiku::get_screen_count() const { // TODO: implement get_screen_count() return 1; } int OS_Haiku::get_current_screen() const { // TODO: implement get_current_screen() return 0; } void OS_Haiku::set_current_screen(int p_screen) { // TODO: implement set_current_screen() } Point2 OS_Haiku::get_screen_position(int p_screen) const { // TODO: make this work with the p_screen parameter BScreen *screen = new BScreen(window); BRect frame = screen->Frame(); delete screen; return Point2i(frame.left, frame.top); } Size2 OS_Haiku::get_screen_size(int p_screen) const { // TODO: make this work with the p_screen parameter BScreen *screen = new BScreen(window); BRect frame = screen->Frame(); delete screen; return Size2i(frame.IntegerWidth() + 1, frame.IntegerHeight() + 1); } void OS_Haiku::set_window_title(const String &p_title) { window->SetTitle(p_title.utf8().get_data()); } Size2 OS_Haiku::get_window_size() const { BSize size = window->Size(); return Size2i(size.IntegerWidth() + 1, size.IntegerHeight() + 1); } void OS_Haiku::set_window_size(const Size2 p_size) { // TODO: why does it stop redrawing after this is called? window->ResizeTo(p_size.x, p_size.y); } Point2 OS_Haiku::get_window_position() const { BPoint point(0, 0); window->ConvertToScreen(&point); return Point2i(point.x, point.y); } void OS_Haiku::set_window_position(const Point2 &p_position) { window->MoveTo(p_position.x, p_position.y); } void OS_Haiku::set_window_fullscreen(bool p_enabled) { window->SetFullScreen(p_enabled); current_video_mode.fullscreen = p_enabled; rendering_server->init(); } bool OS_Haiku::is_window_fullscreen() const { return current_video_mode.fullscreen; } void OS_Haiku::set_window_resizable(bool p_enabled) { uint32 flags = window->Flags(); if (p_enabled) { flags &= ~(B_NOT_RESIZABLE); } else { flags |= B_NOT_RESIZABLE; } window->SetFlags(flags); current_video_mode.resizable = p_enabled; } bool OS_Haiku::is_window_resizable() const { return current_video_mode.resizable; } void OS_Haiku::set_window_minimized(bool p_enabled) { window->Minimize(p_enabled); } bool OS_Haiku::is_window_minimized() const { return window->IsMinimized(); } void OS_Haiku::set_window_maximized(bool p_enabled) { window->Minimize(!p_enabled); } bool OS_Haiku::is_window_maximized() const { return !window->IsMinimized(); } void OS_Haiku::set_video_mode(const VideoMode &p_video_mode, int p_screen) { ERR_PRINT("set_video_mode() NOT IMPLEMENTED"); } OS::VideoMode OS_Haiku::get_video_mode(int p_screen) const { return current_video_mode; } void OS_Haiku::get_fullscreen_mode_list(List *p_list, int p_screen) const { ERR_PRINT("get_fullscreen_mode_list() NOT IMPLEMENTED"); } String OS_Haiku::get_executable_path() const { return OS::get_executable_path(); } bool OS_Haiku::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc"; } String OS_Haiku::get_config_path() const { if (has_environment("XDG_CONFIG_HOME")) { return get_environment("XDG_CONFIG_HOME"); } else if (has_environment("HOME")) { return get_environment("HOME").plus_file("config/settings"); } else { return "."; } } String OS_Haiku::get_data_path() const { if (has_environment("XDG_DATA_HOME")) { return get_environment("XDG_DATA_HOME"); } else if (has_environment("HOME")) { return get_environment("HOME").plus_file("config/data"); } else { return get_config_path(); } } String OS_Haiku::get_cache_path() const { if (has_environment("XDG_CACHE_HOME")) { return get_environment("XDG_CACHE_HOME"); } else if (has_environment("HOME")) { return get_environment("HOME").plus_file("config/cache"); } else { return get_config_path(); } }