From 2f6ee56eac907b719befdb2e15b58bf5b06db95a Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 23 Nov 2022 11:00:20 +0900 Subject: [PATCH] Add external output support (#3) The eom API only supports elm_win. So TizenWindowElementary supports this. Currently, only HDMI type is available. It can be extended according to the requirements. https://docs.tizen.org/application/native/guides/device/ext-output/ +) How to map input device.(in sdb shell) 1. Check to input event node. $) winfo -input_devices 2. Set to input and output event node $) winfo -input_output_set [input(ex./dev/input/eventX)] [output(ex.HDMIA-1)] related pr : flutter-tizen/flutter-tizen#465 Co-authored-by: Swift Kim --- flutter/shell/platform/tizen/BUILD.gn | 2 + flutter/shell/platform/tizen/flutter_tizen.cc | 3 +- .../platform/tizen/public/flutter_tizen.h | 9 ++ .../platform/tizen/tizen_window_elementary.cc | 95 +++++++++++++++++-- .../platform/tizen/tizen_window_elementary.h | 14 ++- tools/generate_sysroot.py | 2 + 6 files changed, 113 insertions(+), 12 deletions(-) diff --git a/flutter/shell/platform/tizen/BUILD.gn b/flutter/shell/platform/tizen/BUILD.gn index 5b88b26..c6000a6 100644 --- a/flutter/shell/platform/tizen/BUILD.gn +++ b/flutter/shell/platform/tizen/BUILD.gn @@ -38,6 +38,7 @@ config("flutter_tizen_config") { "${sysroot_path}/usr/include/elementary-1", "${sysroot_path}/usr/include/emile-1", "${sysroot_path}/usr/include/eo-1", + "${sysroot_path}/usr/include/eom", "${sysroot_path}/usr/include/ethumb-1", "${sysroot_path}/usr/include/ethumb-client-1", "${sysroot_path}/usr/include/evas-1", @@ -127,6 +128,7 @@ template("embedder") { "efl-extension", "eina", "elementary", + "eom", "evas", "feedback", "flutter_engine", diff --git a/flutter/shell/platform/tizen/flutter_tizen.cc b/flutter/shell/platform/tizen/flutter_tizen.cc index 6588925..9069b29 100644 --- a/flutter/shell/platform/tizen/flutter_tizen.cc +++ b/flutter/shell/platform/tizen/flutter_tizen.cc @@ -204,7 +204,8 @@ FlutterDesktopViewRef FlutterDesktopViewCreateFromNewWindow( if (window_properties.renderer_type == FlutterDesktopRendererType::kEvasGL) { window = std::make_unique( window_geometry, window_properties.transparent, - window_properties.focusable, window_properties.top_level); + window_properties.focusable, window_properties.top_level, + window_properties.external_output_type); } else { #ifndef WEARABLE_PROFILE window = std::make_unique( diff --git a/flutter/shell/platform/tizen/public/flutter_tizen.h b/flutter/shell/platform/tizen/public/flutter_tizen.h index c1132d6..30d1b2a 100644 --- a/flutter/shell/platform/tizen/public/flutter_tizen.h +++ b/flutter/shell/platform/tizen/public/flutter_tizen.h @@ -38,6 +38,13 @@ typedef enum { kMouseMove, } FlutterDesktopPointerEventType; +typedef enum { + // No external output. + kNone, + // Display to the HDMI external output. + kHDMI, +} FlutterDesktopExternalOutputType; + // Properties for configuring the initial settings of a Flutter window. typedef struct { // The x-coordinate of the top left corner of the window. @@ -56,6 +63,8 @@ typedef struct { bool top_level; // The renderer type of the engine. FlutterDesktopRendererType renderer_type; + // The external output type of the window. + FlutterDesktopExternalOutputType external_output_type; } FlutterDesktopWindowProperties; // Properties for configuring the initial settings of a Flutter view. diff --git a/flutter/shell/platform/tizen/tizen_window_elementary.cc b/flutter/shell/platform/tizen/tizen_window_elementary.cc index 77157bf..ea993b8 100644 --- a/flutter/shell/platform/tizen/tizen_window_elementary.cc +++ b/flutter/shell/platform/tizen/tizen_window_elementary.cc @@ -5,6 +5,7 @@ #include "tizen_window_elementary.h" #include +#include #include #include "flutter/shell/platform/tizen/logger.h" @@ -34,11 +35,20 @@ uint32_t EvasModifierToEcoreEventModifiers(const Evas_Modifier* evas_modifier) { } // namespace -TizenWindowElementary::TizenWindowElementary(TizenGeometry geometry, - bool transparent, - bool focusable, - bool top_level) - : TizenWindow(geometry, transparent, focusable, top_level) { +TizenWindowElementary::TizenWindowElementary( + TizenGeometry geometry, + bool transparent, + bool focusable, + bool top_level, + FlutterDesktopExternalOutputType external_output_type) + : TizenWindow(geometry, transparent, focusable, top_level), + external_output_type_(external_output_type) { + if (external_output_type_ != FlutterDesktopExternalOutputType::kNone && + !InitializeExternalOutputManager()) { + FT_LOG(Error) << "Failed to initialize the External Output Manager."; + return; + } + if (!CreateWindow()) { FT_LOG(Error) << "Failed to create a platform window."; return; @@ -51,6 +61,9 @@ TizenWindowElementary::TizenWindowElementary(TizenGeometry geometry, } TizenWindowElementary::~TizenWindowElementary() { + if (external_output_type_ != FlutterDesktopExternalOutputType::kNone) { + DestroyExternalOutputManager(); + } UnregisterEventHandlers(); DestroyWindow(); } @@ -69,11 +82,15 @@ bool TizenWindowElementary::CreateWindow() { elm_win_aux_hint_add(elm_win_, "wm.policy.win.user.geometry", "1"); #endif - Ecore_Evas* ecore_evas = - ecore_evas_ecore_evas_get(evas_object_evas_get(elm_win_)); - - int32_t width, height; - ecore_evas_screen_geometry_get(ecore_evas, nullptr, nullptr, &width, &height); + int32_t width = 0, height = 0; + if (external_output_type_ != FlutterDesktopExternalOutputType::kNone) { + eom_get_output_resolution(external_output_id_, &width, &height); + } else { + Ecore_Evas* ecore_evas = + ecore_evas_ecore_evas_get(evas_object_evas_get(elm_win_)); + ecore_evas_screen_geometry_get(ecore_evas, nullptr, nullptr, &width, + &height); + } if (width == 0 || height == 0) { FT_LOG(Error) << "Invalid screen size: " << width << " x " << height; return false; @@ -99,6 +116,14 @@ bool TizenWindowElementary::CreateWindow() { evas_object_image_alpha_set(image_, EINA_TRUE); elm_win_resize_object_add(elm_win_, image_); + if (external_output_type_ != FlutterDesktopExternalOutputType::kNone) { + if (eom_set_output_window(external_output_id_, elm_win_) != + EOM_ERROR_NONE) { + FT_LOG(Error) << "eom_set_output_window() failed."; + return false; + } + } + return elm_win_ && image_; } @@ -403,4 +428,54 @@ void TizenWindowElementary::PrepareInputMethod() { [this](std::string str) { view_delegate_->OnCommit(str); }); } +int32_t TizenWindowElementary::GetExternalOutputId() { + int32_t num_ids = 0; + eom_output_id* output_ids = eom_get_eom_output_ids(&num_ids); + if (!output_ids || num_ids == 0) { + FT_LOG(Error) << "No external output found."; + return 0; + } + + eom_output_id output_id = 0; + for (int32_t i = 0; i < num_ids; i++) { + eom_output_type_e output_type = EOM_OUTPUT_TYPE_UNKNOWN; + eom_get_output_type(output_ids[i], &output_type); + + if (external_output_type_ == FlutterDesktopExternalOutputType::kHDMI && + (output_type == EOM_OUTPUT_TYPE_HDMIA || + output_type == EOM_OUTPUT_TYPE_HDMIB)) { + output_id = output_ids[i]; + break; + } + } + free(output_ids); + return output_id; +} + +bool TizenWindowElementary::InitializeExternalOutputManager() { + if (eom_init()) { + FT_LOG(Error) << "eom_init() failed."; + return false; + } + + external_output_id_ = GetExternalOutputId(); + if (external_output_id_ == 0) { + FT_LOG(Error) << "Invalid external output ID."; + return false; + } + + int ret = eom_set_output_attribute(external_output_id_, + EOM_OUTPUT_ATTRIBUTE_NORMAL); + if (ret != EOM_ERROR_NONE) { + FT_LOG(Error) + << "eom_set_output_attribute() failed. Cannot use external output."; + return false; + } + return true; +} + +void TizenWindowElementary::DestroyExternalOutputManager() { + eom_deinit(); +} + } // namespace flutter diff --git a/flutter/shell/platform/tizen/tizen_window_elementary.h b/flutter/shell/platform/tizen/tizen_window_elementary.h index 5bff6a0..ea8aac7 100644 --- a/flutter/shell/platform/tizen/tizen_window_elementary.h +++ b/flutter/shell/platform/tizen/tizen_window_elementary.h @@ -12,6 +12,7 @@ #include #include +#include "flutter/shell/platform/tizen/public/flutter_tizen.h" #include "flutter/shell/platform/tizen/tizen_window.h" namespace flutter { @@ -21,7 +22,8 @@ class TizenWindowElementary : public TizenWindow { TizenWindowElementary(TizenGeometry geometry, bool transparent, bool focusable, - bool top_level); + bool top_level, + FlutterDesktopExternalOutputType external_output_type); ~TizenWindowElementary(); @@ -50,6 +52,12 @@ class TizenWindowElementary : public TizenWindow { void Show() override; private: + bool InitializeExternalOutputManager(); + + void DestroyExternalOutputManager(); + + int GetExternalOutputId(); + bool CreateWindow(); void DestroyWindow(); @@ -68,6 +76,10 @@ class TizenWindowElementary : public TizenWindow { Evas_Smart_Cb rotation_changed_callback_ = nullptr; std::unordered_map evas_object_callbacks_; + + int32_t external_output_id_; + FlutterDesktopExternalOutputType external_output_type_ = + FlutterDesktopExternalOutputType::kNone; }; } // namespace flutter diff --git a/tools/generate_sysroot.py b/tools/generate_sysroot.py index dd5b32d..9e9be17 100755 --- a/tools/generate_sysroot.py +++ b/tools/generate_sysroot.py @@ -85,6 +85,8 @@ 'jsoncpp-devel', 'libatk', 'libatk-bridge-2_0-0', + 'libeom', + 'libeom-devel', 'libfeedback', 'libfeedback-devel', 'libdlog',