aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2018-10-24 11:27:39 +0000
committerGerrit Code Review <gerrit@automotivelinux.org>2018-10-24 11:27:39 +0000
commitb1f7a756ff0fce7ff38d24b256476902f748be0b (patch)
tree83d575e2d37161bdeeaeae12effde1904ae4da8b /src
parent5a2494b3b0f2b3f2bc885ab6d4b55f1d5d5822c9 (diff)
parent6819f403a6b8a1ab5e8cdffd9fd1460d49045059 (diff)
Merge "Refactor : Hide wayland operations from Window Manager"
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt17
-rw-r--r--src/controller_hooks.hpp41
-rw-r--r--src/json_helper.cpp65
-rw-r--r--src/json_helper.hpp3
-rw-r--r--src/layout.cpp17
-rw-r--r--src/layout.hpp41
-rw-r--r--src/main.cpp128
-rw-r--r--src/util.hpp25
-rw-r--r--src/wayland_ivi_wm.cpp721
-rw-r--r--src/wayland_ivi_wm.hpp326
-rw-r--r--src/window_manager.cpp702
-rw-r--r--src/window_manager.hpp114
-rw-r--r--src/wm_layer.cpp334
-rw-r--r--src/wm_layer.hpp145
-rw-r--r--src/wm_layer_control.cpp594
-rw-r--r--src/wm_layer_control.hpp105
16 files changed, 946 insertions, 2432 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 223dd33..d8f1143 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,10 +14,9 @@
# limitations under the License.
#
-wlproto(IVI_CON ivi-wm)
-
include(FindPkgConfig)
pkg_check_modules(AFB REQUIRED afb-daemon)
+pkg_check_modules(ILM REQUIRED ilmControl ilmCommon)
pkg_check_modules(SD REQUIRED libsystemd>=222)
# We do not want a prefix for our module
@@ -27,23 +26,22 @@ set(TARGETS_WM windowmanager-service)
add_library(${TARGETS_WM} MODULE
main.cpp
- wayland_ivi_wm.cpp
util.cpp
- layout.cpp
- ${IVI_CON_PROTO}
json_helper.cpp
+ applist.cpp
+ request.cpp
+ pm_wrapper.cpp
window_manager.cpp
- wm_layer.cpp
wm_client.cpp
wm_error.cpp
- applist.cpp
- request.cpp
- pm_wrapper.cpp)
+ wm_layer.cpp
+ wm_layer_control.cpp)
target_include_directories(${TARGETS_WM}
PRIVATE
${AFB_INCLUDE_DIRS}
${SD_INCLUDE_DIRS}
+ ${ILM_INCLUDE_DIRS}
../include
../src
../${PLUGIN_PM})
@@ -52,6 +50,7 @@ target_link_libraries(${TARGETS_WM}
PRIVATE
${AFB_LIBRARIES}
${WLC_LIBRARIES}
+ ${ILM_LIBRARIES}
${SD_LIBRARIES}
${PLUGIN_PM})
diff --git a/src/controller_hooks.hpp b/src/controller_hooks.hpp
deleted file mode 100644
index dd0a3aa..0000000
--- a/src/controller_hooks.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef TMCAGLWM_CONTROLLER_HOOKS_HPP
-#define TMCAGLWM_CONTROLLER_HOOKS_HPP
-
-#include <cstdint>
-
-#include <functional>
-
-namespace wm
-{
-
-class WindowManager;
-
-struct controller_hooks
-{
- WindowManager *wmgr;
-
- void surface_created(uint32_t surface_id);
- void surface_removed(uint32_t surface_id);
- void surface_visibility(uint32_t surface_id, uint32_t v);
- void surface_destination_rectangle(uint32_t surface_id, uint32_t x, uint32_t y, uint32_t w, uint32_t h);
-};
-
-} // namespace wm
-
-#endif // TMCAGLWM_CONTROLLER_HOOKS_HPP
diff --git a/src/json_helper.cpp b/src/json_helper.cpp
index cf13363..72ae36a 100644
--- a/src/json_helper.cpp
+++ b/src/json_helper.cpp
@@ -17,66 +17,6 @@
#include "json_helper.hpp"
#include "util.hpp"
-json_object *to_json(compositor::surface_properties const &s)
-{
- // auto j = json::object({
- auto j = json_object_new_object();
-
- // {"id", s.id},
- json_object_object_add(j, "id", json_object_new_int(s.id));
-
- // {"size", {{"width", s.size.w}, {"height", s.size.h}}},
- auto jsize = json_object_new_object();
- json_object_object_add(jsize, "width", json_object_new_int(s.size.w));
- json_object_object_add(jsize, "height", json_object_new_int(s.size.h));
- json_object_object_add(j, "size", jsize);
-
- // {"dst",
- // {{"width", s.dst_rect.w},
- // {"height", s.dst_rect.h},
- // {"x", s.dst_rect.x},
- // {"y", s.dst_rect.y}}},
- auto jdst = json_object_new_object();
- json_object_object_add(jdst, "width", json_object_new_int(s.dst_rect.w));
- json_object_object_add(jdst, "height", json_object_new_int(s.dst_rect.h));
- json_object_object_add(jdst, "x", json_object_new_int(s.dst_rect.x));
- json_object_object_add(jdst, "y", json_object_new_int(s.dst_rect.y));
- json_object_object_add(j, "dst", jdst);
-
- // {"src",
- // {{"width", s.src_rect.w},
- // {"height", s.src_rect.h},
- // {"x", s.src_rect.x},
- // {"y", s.src_rect.y}}},
- auto jsrc = json_object_new_object();
- json_object_object_add(jsrc, "width", json_object_new_int(s.src_rect.w));
- json_object_object_add(jsrc, "height", json_object_new_int(s.src_rect.h));
- json_object_object_add(jsrc, "x", json_object_new_int(s.src_rect.x));
- json_object_object_add(jsrc, "y", json_object_new_int(s.src_rect.y));
- json_object_object_add(j, "src", jsrc);
-
- // {"visibility", s.visibility},
- json_object_object_add(
- j, "visibility",
- json_object_new_boolean(static_cast<json_bool>(s.visibility == 1)));
-
- // {"opacity", s.opacity},
- json_object_object_add(j, "opacity", json_object_new_double(s.opacity));
-
- // {"orientation", s.orientation},
- json_object_object_add(j, "orientation", json_object_new_int(s.orientation));
-
- // });
- return j;
-}
-
-json_object *to_json(compositor::screen const *s)
-{
- auto o = json_object_new_object();
- json_object_object_add(o, "id", json_object_new_int(s->id));
- return o;
-}
-
template <typename T>
json_object *to_json_(T const &s)
{
@@ -93,11 +33,6 @@ json_object *to_json_(T const &s)
return a;
}
-json_object *to_json(compositor::controller::props_map const &s)
-{
- return to_json_(s);
-}
-
json_object *to_json(std::vector<uint32_t> const &v)
{
auto a = json_object_new_array();
diff --git a/src/json_helper.hpp b/src/json_helper.hpp
index 2321f8b..6ccbcc1 100644
--- a/src/json_helper.hpp
+++ b/src/json_helper.hpp
@@ -19,12 +19,9 @@
#include <json-c/json.h>
#include <vector>
-#include "wayland_ivi_wm.hpp"
struct json_object;
-json_object *to_json(compositor::screen const *s);
-json_object *to_json(compositor::controller::props_map const &s);
json_object *to_json(std::vector<uint32_t> const &v);
namespace jh {
diff --git a/src/layout.cpp b/src/layout.cpp
deleted file mode 100644
index fbf2baa..0000000
--- a/src/layout.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "layout.hpp"
diff --git a/src/layout.hpp b/src/layout.hpp
deleted file mode 100644
index 3430ef3..0000000
--- a/src/layout.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef TMCAGLWM_LAYOUT_HPP
-#define TMCAGLWM_LAYOUT_HPP
-
-namespace wm
-{
-
-struct LayoutState
-{
- int main{-1};
- int sub{-1};
-
- bool operator==(const LayoutState &b) const
- {
- return main == b.main && sub == b.sub;
- }
-
- bool operator!=(const LayoutState &b) const
- {
- return !(*this == b);
- }
-};
-
-} // namespace wm
-
-#endif // TMCAGLWM_LAYOUT_HPP
diff --git a/src/main.cpp b/src/main.cpp
index d9f0302..36577fe 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,7 +20,6 @@
#include <json.h>
#include "window_manager.hpp"
#include "json_helper.hpp"
-#include "wayland_ivi_wm.hpp"
extern "C"
{
@@ -41,10 +40,10 @@ typedef struct WMClientCtxt
struct afb_instance
{
- std::unique_ptr<wl::display> display;
wm::WindowManager wmgr;
- afb_instance() : display{new wl::display}, wmgr{this->display.get()} {}
+ afb_instance() : wmgr() {}
+ ~afb_instance() = default;
int init();
};
@@ -57,78 +56,11 @@ int afb_instance::init()
return this->wmgr.init();
}
-int display_event_callback(sd_event_source *evs, int /*fd*/, uint32_t events,
- void * /*data*/)
-{
- if ((events & EPOLLHUP) != 0)
- {
- HMI_ERROR("The compositor hung up, dying now.");
- delete g_afb_instance;
- g_afb_instance = nullptr;
- goto error;
- }
-
- if ((events & EPOLLIN) != 0u)
- {
- {
- g_afb_instance->wmgr.display->read_events();
- g_afb_instance->wmgr.set_pending_events();
- }
- {
- // We want do dispatch pending wayland events from within
- // the API context
- afb_service_call("windowmanager", "ping", json_object_new_object(),
- [](void *c, int st, json_object *j) {
- },
- nullptr);
- }
- }
-
- return 0;
-
-error:
- sd_event_source_unref(evs);
- if (getenv("WINMAN_EXIT_ON_HANGUP") != nullptr)
- {
- exit(1);
- }
- return -1;
-}
-
int _binding_init()
{
HMI_NOTICE("WinMan ver. %s", WINMAN_VERSION_STRING);
- if (g_afb_instance != nullptr)
- {
- HMI_ERROR("Wayland context already initialized?");
- return 0;
- }
-
- if (getenv("XDG_RUNTIME_DIR") == nullptr)
- {
- HMI_ERROR("Environment variable XDG_RUNTIME_DIR not set");
- goto error;
- }
-
- {
- // wait until wayland compositor starts up.
- int cnt = 0;
- g_afb_instance = new afb_instance;
- while (!g_afb_instance->display->ok())
- {
- cnt++;
- if (20 <= cnt)
- {
- HMI_ERROR("Could not connect to compositor");
- goto error;
- }
- HMI_ERROR("Wait to start weston ...");
- sleep(1);
- delete g_afb_instance;
- g_afb_instance = new afb_instance;
- }
- }
+ g_afb_instance = new afb_instance;
if (g_afb_instance->init() == -1)
{
@@ -136,17 +68,6 @@ int _binding_init()
goto error;
}
- {
- int ret = sd_event_add_io(afb_daemon_get_event_loop(), nullptr,
- g_afb_instance->display->get_fd(), EPOLLIN,
- display_event_callback, g_afb_instance);
- if (ret < 0)
- {
- HMI_ERROR("Could not initialize afb_instance event handler: %d", -ret);
- goto error;
- }
- }
-
atexit([] { delete g_afb_instance; });
return 0;
@@ -511,10 +432,9 @@ void windowmanager_wm_subscribe(afb_req req) noexcept
afb_req_fail(req, "failed", "Need char const* argument event");
return;
}
- int event_type = json_object_get_int(j);
- const char *event_name = g_afb_instance->wmgr.kListEventName[event_type];
- struct afb_event event = g_afb_instance->wmgr.map_afb_event[event_name];
- int ret = afb_req_subscribe(req, event);
+ int event_id = json_object_get_int(j);
+ int ret = g_afb_instance->wmgr.api_subscribe(req, event_id);
+
if (ret)
{
afb_req_fail(req, "failed", "Error: afb_req_subscribe()");
@@ -531,7 +451,8 @@ void windowmanager_wm_subscribe(afb_req req) noexcept
void windowmanager_list_drawing_names(afb_req req) noexcept
{
- std::lock_guard<std::mutex> guard(binding_m);
+ /* std::lock_guard<std::mutex> guard(binding_m);
+
if (g_afb_instance == nullptr)
{
afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
@@ -555,36 +476,30 @@ void windowmanager_list_drawing_names(afb_req req) noexcept
{
afb_req_fail_f(req, "failed", "Uncaught exception while calling list_drawing_names: %s", e.what());
return;
- }
+ } */
+ afb_req_success(req, NULL, "not-implemented");
}
void windowmanager_ping(afb_req req) noexcept
{
std::lock_guard<std::mutex> guard(binding_m);
+
if (g_afb_instance == nullptr)
{
afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
return;
}
-
- try
+ else
{
-
- g_afb_instance->wmgr.api_ping();
-
afb_req_success(req, NULL, "success");
}
- catch (std::exception &e)
- {
- afb_req_fail_f(req, "failed", "Uncaught exception while calling ping: %s", e.what());
- return;
- }
}
void windowmanager_debug_status(afb_req req) noexcept
{
std::lock_guard<std::mutex> guard(binding_m);
- if (g_afb_instance == nullptr)
+
+ /* if (g_afb_instance == nullptr)
{
afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
return;
@@ -604,12 +519,14 @@ void windowmanager_debug_status(afb_req req) noexcept
{
afb_req_fail_f(req, "failed", "Uncaught exception while calling debug_status: %s", e.what());
return;
- }
+ } */
+ afb_req_fail(req, NULL, "not-implemented");
}
void windowmanager_debug_layers(afb_req req) noexcept
{
- std::lock_guard<std::mutex> guard(binding_m);
+ /* std::lock_guard<std::mutex> guard(binding_m);
+
if (g_afb_instance == nullptr)
{
afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
@@ -626,12 +543,14 @@ void windowmanager_debug_layers(afb_req req) noexcept
{
afb_req_fail_f(req, "failed", "Uncaught exception while calling debug_layers: %s", e.what());
return;
- }
+ } */
+ afb_req_fail(req, NULL, "not-implemented");
}
void windowmanager_debug_surfaces(afb_req req) noexcept
{
- std::lock_guard<std::mutex> guard(binding_m);
+ /* std::lock_guard<std::mutex> guard(binding_m);
+
if (g_afb_instance == nullptr)
{
afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
@@ -654,7 +573,8 @@ void windowmanager_debug_surfaces(afb_req req) noexcept
{
afb_req_fail_f(req, "failed", "Uncaught exception while calling debug_surfaces: %s", e.what());
return;
- }
+ } */
+ afb_req_fail(req, NULL, "not-implemented");
}
void windowmanager_debug_terminate(afb_req req) noexcept
diff --git a/src/util.hpp b/src/util.hpp
index 812a130..077f212 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -52,24 +52,15 @@ void _HMI_LOG(enum LOG_LEVEL level, const char* file, const char* func, const in
void _HMI_SEQ_LOG(enum LOG_LEVEL level, const char* file, const char* func, const int line, unsigned seq_num, const char* log, ...);
void _DUMP(enum LOG_LEVEL level, const char *log, ...);
-/**
- * @struct unique_fd
- */
-struct unique_fd
+struct rect
{
- int fd{-1};
- unique_fd() = default;
- explicit unique_fd(int f) : fd{f} {}
- operator int() const { return fd; }
- ~unique_fd();
- unique_fd(unique_fd const &) = delete;
- unique_fd &operator=(unique_fd const &) = delete;
- unique_fd(unique_fd &&o) : fd(o.fd) { o.fd = -1; }
- unique_fd &operator=(unique_fd &&o)
- {
- std::swap(this->fd, o.fd);
- return *this;
- }
+ int32_t w, h;
+ int32_t x, y;
+};
+
+struct size
+{
+ uint32_t w, h;
};
class rectangle
diff --git a/src/wayland_ivi_wm.cpp b/src/wayland_ivi_wm.cpp
deleted file mode 100644
index bbf745b..0000000
--- a/src/wayland_ivi_wm.cpp
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "wayland_ivi_wm.hpp"
-
-/**
- * namespace wl
- */
-namespace wl
-{
-
-/**
- * display
- */
-display::display()
- : d(std::unique_ptr<struct wl_display, void (*)(struct wl_display *)>(
- wl_display_connect(nullptr), &wl_display_disconnect)),
- r(d.get()) {}
-
-bool display::ok() const { return d && wl_display_get_error(d.get()) == 0; }
-
-void display::roundtrip() { wl_display_roundtrip(this->d.get()); }
-
-int display::dispatch() { return wl_display_dispatch(this->d.get()); }
-
-int display::dispatch_pending() { return wl_display_dispatch_pending(this->d.get()); }
-
-int display::read_events()
-{
- while (wl_display_prepare_read(this->d.get()) == -1)
- {
- if (wl_display_dispatch_pending(this->d.get()) == -1)
- {
- return -1;
- }
- }
-
- if (wl_display_flush(this->d.get()) == -1)
- {
- return -1;
- }
-
- if (wl_display_read_events(this->d.get()) == -1)
- {
- wl_display_cancel_read(this->d.get());
- }
-
- return 0;
-}
-
-void display::flush() { wl_display_flush(this->d.get()); }
-
-int display::get_fd() const { return wl_display_get_fd(this->d.get()); }
-
-int display::get_error() { return wl_display_get_error(this->d.get()); }
-
-/**
- * registry
- */
-namespace
-{
-void registry_global_created(void *data, struct wl_registry * /*r*/, uint32_t name,
- char const *iface, uint32_t v)
-{
- static_cast<struct registry *>(data)->global_created(name, iface, v);
-}
-
-void registry_global_removed(void *data, struct wl_registry * /*r*/,
- uint32_t name)
-{
- static_cast<struct registry *>(data)->global_removed(name);
-}
-
-constexpr struct wl_registry_listener registry_listener = {
- registry_global_created, registry_global_removed};
-} // namespace
-
-registry::registry(struct wl_display *d)
- : wayland_proxy(d == nullptr ? nullptr : wl_display_get_registry(d))
-{
- if (this->proxy != nullptr)
- {
- wl_registry_add_listener(this->proxy.get(), &registry_listener, this);
- }
-}
-
-void registry::add_global_handler(char const *iface, binder bind)
-{
- this->bindings[iface] = std::move(bind);
-}
-
-void registry::global_created(uint32_t name, char const *iface, uint32_t v)
-{
- auto b = this->bindings.find(iface);
- if (b != this->bindings.end())
- {
- b->second(this->proxy.get(), name, v);
- }
- HMI_DEBUG("wl::registry @ %p global n %u i %s v %u", this->proxy.get(), name,
- iface, v);
-}
-
-void registry::global_removed(uint32_t /*name*/) {}
-
-/**
- * output
- */
-namespace
-{
-void output_geometry(void *data, struct wl_output * /*wl_output*/, int32_t x,
- int32_t y, int32_t physical_width, int32_t physical_height,
- int32_t subpixel, const char *make, const char *model,
- int32_t transform)
-{
- static_cast<struct output *>(data)->geometry(
- x, y, physical_width, physical_height, subpixel, make, model, transform);
-}
-
-void output_mode(void *data, struct wl_output * /*wl_output*/, uint32_t flags,
- int32_t width, int32_t height, int32_t refresh)
-{
- static_cast<struct output *>(data)->mode(flags, width, height, refresh);
-}
-
-void output_done(void *data, struct wl_output * /*wl_output*/)
-{
- static_cast<struct output *>(data)->done();
-}
-
-void output_scale(void *data, struct wl_output * /*wl_output*/,
- int32_t factor)
-{
- static_cast<struct output *>(data)->scale(factor);
-}
-
-constexpr struct wl_output_listener output_listener = {
- output_geometry, output_mode, output_done, output_scale};
-} // namespace
-
-output::output(struct wl_registry *r, uint32_t name, uint32_t v)
- : wayland_proxy(wl_registry_bind(r, name, &wl_output_interface, v))
-{
- wl_output_add_listener(this->proxy.get(), &output_listener, this);
-}
-
-void output::geometry(int32_t x, int32_t y, int32_t pw, int32_t ph,
- int32_t subpel, char const *make, char const *model,
- int32_t tx)
-{
- HMI_DEBUG("wl::output %s @ %p x %i y %i w %i h %i spel %x make %s model %s tx %i",
- __func__, this->proxy.get(), x, y, pw, ph, subpel, make, model, tx);
- this->physical_width = pw;
- this->physical_height = ph;
- this->transform = tx;
-}
-
-void output::mode(uint32_t flags, int32_t w, int32_t h, int32_t r)
-{
- HMI_DEBUG("wl::output %s @ %p f %x w %i h %i r %i", __func__,
- this->proxy.get(), flags, w, h, r);
- if ((flags & WL_OUTPUT_MODE_CURRENT) != 0u)
- {
- this->width = w;
- this->height = h;
- this->refresh = r;
- }
-}
-
-void output::done()
-{
- HMI_DEBUG("wl::output %s @ %p done", __func__, this->proxy.get());
- // Pivot and flipped
- if (this->transform == WL_OUTPUT_TRANSFORM_90 ||
- this->transform == WL_OUTPUT_TRANSFORM_270 ||
- this->transform == WL_OUTPUT_TRANSFORM_FLIPPED_90 ||
- this->transform == WL_OUTPUT_TRANSFORM_FLIPPED_270)
- {
- std::swap(this->width, this->height);
- std::swap(this->physical_width, this->physical_height);
- }
-}
-
-void output::scale(int32_t factor)
-{
- HMI_DEBUG("wl::output %s @ %p f %i", __func__, this->proxy.get(), factor);
-}
-} // namespace wl
-
-/**
- * namespace compositor
- */
-namespace compositor
-{
-
-namespace
-{
-
-void surface_visibility_changed(
- void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t surface_id, int32_t visibility)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_visibility_changed(surface_id, visibility);
-}
-
-void surface_opacity_changed(void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t surface_id, wl_fixed_t opacity)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_opacity_changed(surface_id, float(wl_fixed_to_double(opacity)));
-}
-
-void surface_source_rectangle_changed(
- void *data, struct ivi_wm * /*ivi_wm*/, uint32_t surface_id,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_source_rectangle_changed(surface_id, x, y, width, height);
-}
-
-void surface_destination_rectangle_changed(
- void *data, struct ivi_wm * /*ivi_wm*/, uint32_t surface_id,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_destination_rectangle_changed(surface_id, x, y, width, height);
-}
-
-void surface_created(void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t id_surface)
-{
- static_cast<struct controller *>(data)->surface_created(id_surface);
-}
-
-void surface_destroyed(
- void *data, struct ivi_wm * /*ivi_wm*/, uint32_t surface_id)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_destroyed(surface_id);
-}
-
-void surface_error_detected(void *data, struct ivi_wm * /*ivi_wm*/, uint32_t object_id,
- uint32_t error_code, const char *error_text)
-{
- static_cast<struct controller *>(data)->surface_error_detected(
- object_id, error_code, error_text);
-}
-
-void surface_size_changed(
- void *data, struct ivi_wm * /*ivi_wm*/, uint32_t surface_id,
- int32_t width, int32_t height)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_size_changed(surface_id, width, height);
-}
-
-void surface_stats_received(void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t surface_id, uint32_t frame_count, uint32_t pid)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_stats_received(surface_id, frame_count, pid);
-}
-
-void surface_added_to_layer(void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t layer_id, uint32_t surface_id)
-{
- auto c = static_cast<struct controller *>(data);
- c->surface_added_to_layer(layer_id, surface_id);
-}
-
-void layer_visibility_changed(void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t layer_id, int32_t visibility)
-{
- auto c = static_cast<struct controller *>(data);
- c->layer_visibility_changed(layer_id, visibility);
-}
-
-void layer_opacity_changed(void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t layer_id, wl_fixed_t opacity)
-{
- auto c = static_cast<struct controller *>(data);
- c->layer_opacity_changed(layer_id, float(wl_fixed_to_double(opacity)));
-}
-
-void layer_source_rectangle_changed(
- void *data, struct ivi_wm * /*ivi_wm*/, uint32_t layer_id,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- auto c = static_cast<struct controller *>(data);
- c->layer_source_rectangle_changed(layer_id, x, y, width, height);
-}
-
-void layer_destination_rectangle_changed(
- void *data, struct ivi_wm * /*ivi_wm*/, uint32_t layer_id,
- int32_t x, int32_t y, int32_t width, int32_t height)
-{
- auto c = static_cast<struct controller *>(data);
- c->layer_destination_rectangle_changed(layer_id, x, y, width, height);
-}
-
-void layer_created(void *data, struct ivi_wm * /*ivi_wm*/,
- uint32_t id_layer)
-{
- static_cast<struct controller *>(data)->layer_created(id_layer);
-}
-
-void layer_destroyed(void *data, struct ivi_wm * /*ivi_wm*/, uint32_t layer_id)
-{
- auto c = static_cast<struct controller *>(data);
- c->layer_destroyed(layer_id);
-}
-
-void layer_error_detected(void *data, struct ivi_wm * /*ivi_wm*/, uint32_t object_id,
- uint32_t error_code, const char *error_text)
-{
- static_cast<struct controller *>(data)->layer_error_detected(
- object_id, error_code, error_text);
-}
-
-constexpr struct ivi_wm_listener listener = {
- surface_visibility_changed,
- layer_visibility_changed,
- surface_opacity_changed,
- layer_opacity_changed,
- surface_source_rectangle_changed,
- layer_source_rectangle_changed,
- surface_destination_rectangle_changed,
- layer_destination_rectangle_changed,
- surface_created,
- layer_created,
- surface_destroyed,
- layer_destroyed,
- surface_error_detected,
- layer_error_detected,
- surface_size_changed,
- surface_stats_received,
- surface_added_to_layer,
-};
-
-void screen_created(void *data, struct ivi_wm_screen *ivi_wm_screen, uint32_t id)
-{
- static_cast<struct screen *>(data)->screen_created((struct screen *)data, id);
-}
-
-void layer_added(void *data,
- struct ivi_wm_screen *ivi_wm_screen,
- uint32_t layer_id)
-{
- HMI_DEBUG("added layer_id:%d", layer_id);
-}
-
-void connector_name(void *data,
- struct ivi_wm_screen *ivi_wm_screen,
- const char *process_name)
-{
- HMI_DEBUG("process_name:%s", process_name);
-}
-
-void screen_error(void *data,
- struct ivi_wm_screen *ivi_wm_screen,
- uint32_t error,
- const char *message)
-{
- HMI_DEBUG("screen error:%d message:%s", error, message);
-}
-
-constexpr struct ivi_wm_screen_listener screen_listener = {
- screen_created,
- layer_added,
- connector_name,
- screen_error,
-};
-} // namespace
-
-/**
- * surface
- */
-surface::surface(uint32_t i, struct controller *c)
- : controller_child(c, i)
-{
- this->parent->add_proxy_to_sid_mapping(this->parent->proxy.get(), i);
-}
-
-void surface::set_visibility(uint32_t visibility)
-{
- HMI_DEBUG("compositor::surface id:%d v:%d", this->id, visibility);
- ivi_wm_set_surface_visibility(this->parent->proxy.get(), this->id, visibility);
-}
-
-void surface::set_source_rectangle(int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- ivi_wm_set_surface_source_rectangle(this->parent->proxy.get(), this->id,
- x, y, width, height);
-}
-
-void surface::set_destination_rectangle(int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- ivi_wm_set_surface_destination_rectangle(this->parent->proxy.get(), this->id,
- x, y, width, height);
-}
-
-/**
- * layer
- */
-layer::layer(uint32_t i, struct controller *c) : layer(i, 0, 0, c) {}
-
-layer::layer(uint32_t i, int32_t w, int32_t h, struct controller *c)
- : controller_child(c, i)
-{
- this->parent->add_proxy_to_lid_mapping(this->parent->proxy.get(), i);
- ivi_wm_create_layout_layer(c->proxy.get(), i, w, h);
-}
-
-void layer::set_visibility(uint32_t visibility)
-{
- ivi_wm_set_layer_visibility(this->parent->proxy.get(), this->id, visibility);
-}
-
-void layer::set_destination_rectangle(int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- ivi_wm_set_layer_destination_rectangle(this->parent->proxy.get(), this->id,
- x, y, width, height);
-}
-
-void layer::add_surface(uint32_t surface_id)
-{
- ivi_wm_layer_add_surface(this->parent->proxy.get(), this->id, surface_id);
-}
-
-void layer::remove_surface(uint32_t surface_id)
-{
- ivi_wm_layer_remove_surface(this->parent->proxy.get(), this->id, surface_id);
-}
-
-/**
- * screen
- */
-screen::screen(uint32_t i, struct controller *c, struct wl_output *o)
- : wayland_proxy(ivi_wm_create_screen(c->proxy.get(), o)),
- controller_child(c, i)
-{
- HMI_DEBUG("compositor::screen @ %p id %u o %p", this->proxy.get(), i, o);
-
- // Add listener for screen
- ivi_wm_screen_add_listener(this->proxy.get(), &screen_listener, this);
-}
-
-void screen::clear() { ivi_wm_screen_clear(this->proxy.get()); }
-
-void screen::screen_created(struct screen *screen, uint32_t id)
-{
- HMI_DEBUG("compositor::screen @ %p screen %u (%x) @ %p", this->proxy.get(),
- id, id, screen);
- this->id = id;
- this->parent->screens[id] = screen;
-}
-
-void screen::set_render_order(std::vector<uint32_t> const &ro)
-{
- std::size_t i;
-
- // Remove all layers from the screen render order
- ivi_wm_screen_clear(this->proxy.get());
-
- for (i = 0; i < ro.size(); i++)
- {
- HMI_DEBUG("compositor::screen @ %p add layer %u", this->proxy.get(), ro[i]);
- // Add the layer to screen render order at nearest z-position
- ivi_wm_screen_add_layer(this->proxy.get(), ro[i]);
- }
-}
-
-/**
- * controller
- */
-controller::controller(struct wl_registry *r, uint32_t name, uint32_t version)
- : wayland_proxy(
- wl_registry_bind(r, name, &ivi_wm_interface, version)),
- output_size{}
-{
- ivi_wm_add_listener(this->proxy.get(), &listener, this);
-}
-
-void controller::layer_create(uint32_t id, int32_t w, int32_t h)
-{
- this->layers[id] = std::make_unique<struct layer>(id, w, h, this);
-}
-
-void controller::surface_create(uint32_t id)
-{
- this->surfaces[id] = std::make_unique<struct surface>(id, this);
-
- // TODO: If Clipping is necessary, this process should be modified.
- {
- // Set surface type:IVI_WM_SURFACE_TYPE_DESKTOP)
- // for resizing wayland surface when switching from split to full surface.
- ivi_wm_set_surface_type(this->proxy.get(), id, IVI_WM_SURFACE_TYPE_DESKTOP);
-
- // Set source reactangle even if we should not need to set it
- // for enable setting for destination region.
- this->surfaces[id]->set_source_rectangle(0, 0, this->output_size.w, this->output_size.h);
-
- // Flush display
- this->display->flush();
- }
-}
-
-void controller::create_screen(struct wl_output *output)
-{
- // TODO: screen id is 0 (WM manages one screen for now)
- this->screen = std::make_unique<struct screen>(0, this, output);
-}
-
-void controller::get_surface_properties(uint32_t surface_id, int param)
-{
- ivi_wm_surface_get(this->proxy.get(), surface_id, param);
-}
-
-void controller::layer_created(uint32_t id)
-{
- HMI_DEBUG("compositor::controller @ %p layer %u (%x)", this->proxy.get(), id, id);
- if (this->layers.find(id) != this->layers.end())
- {
- HMI_DEBUG("WindowManager has created layer %u (%x) already", id, id);
- }
- else
- {
- this->layers[id] = std::make_unique<struct layer>(id, this);
- }
-}
-
-void controller::layer_error_detected(uint32_t object_id,
- uint32_t error_code, const char *error_text)
-{
- HMI_DEBUG("compositor::controller @ %p error o %d c %d text %s",
- this->proxy.get(), object_id, error_code, error_text);
-}
-
-void controller::surface_visibility_changed(uint32_t id, int32_t visibility)
-{
- HMI_DEBUG("compositor::surface %s @ %d v %i", __func__, id,
- visibility);
- this->sprops[id].visibility = visibility;
- this->chooks->surface_visibility(id, visibility);
-}
-
-void controller::surface_opacity_changed(uint32_t id, float opacity)
-{
- HMI_DEBUG("compositor::surface %s @ %d o %f",
- __func__, id, opacity);
- this->sprops[id].opacity = opacity;
-}
-
-void controller::surface_source_rectangle_changed(uint32_t id, int32_t x,
- int32_t y, int32_t width,
- int32_t height)
-{
- HMI_DEBUG("compositor::surface %s @ %d x %i y %i w %i h %i", __func__,
- id, x, y, width, height);
- this->sprops[id].src_rect = rect{width, height, x, y};
-}
-
-void controller::surface_destination_rectangle_changed(uint32_t id, int32_t x,
- int32_t y, int32_t width,
- int32_t height)
-{
- HMI_DEBUG("compositor::surface %s @ %d x %i y %i w %i h %i", __func__,
- id, x, y, width, height);
- this->sprops[id].dst_rect = rect{width, height, x, y};
- this->chooks->surface_destination_rectangle(id, x, y, width, height);
-}
-
-void controller::surface_size_changed(uint32_t id, int32_t width,
- int32_t height)
-{
- HMI_DEBUG("compositor::surface %s @ %d w %i h %i", __func__, id,
- width, height);
- this->sprops[id].size = size{uint32_t(width), uint32_t(height)};
- this->surfaces[id]->set_source_rectangle(0, 0, width, height);
-}
-
-void controller::surface_added_to_layer(uint32_t layer_id, uint32_t surface_id)
-{
- HMI_DEBUG("compositor::surface %s @ %d l %u",
- __func__, layer_id, surface_id);
-}
-
-void controller::surface_stats_received(uint32_t surface_id,
- uint32_t frame_count, uint32_t pid)
-{
- HMI_DEBUG("compositor::surface %s @ %d f %u pid %u",
- __func__, surface_id, frame_count, pid);
-}
-
-void controller::surface_created(uint32_t id)
-{
- HMI_DEBUG("compositor::controller @ %p surface %u (%x)", this->proxy.get(), id,
- id);
- if (this->surfaces.find(id) == this->surfaces.end())
- {
- this->surfaces[id] = std::make_unique<struct surface>(id, this);
- this->chooks->surface_created(id);
-
- // Set surface type:IVI_WM_SURFACE_TYPE_DESKTOP)
- // for resizing wayland surface when switching from split to full surface.
- ivi_wm_set_surface_type(this->proxy.get(), id, IVI_WM_SURFACE_TYPE_DESKTOP);
-
- // Flush display
- this->display->flush();
- }
-}
-
-void controller::surface_destroyed(uint32_t surface_id)
-{
- HMI_DEBUG("compositor::surface %s @ %d", __func__, surface_id);
- this->chooks->surface_removed(surface_id);
- this->sprops.erase(surface_id);
- this->surfaces.erase(surface_id);
-}
-
-void controller::surface_error_detected(uint32_t object_id,
- uint32_t error_code, const char *error_text)
-{
- HMI_DEBUG("compositor::controller @ %p error o %d c %d text %s",
- this->proxy.get(), object_id, error_code, error_text);
-}
-
-void controller::layer_visibility_changed(uint32_t layer_id, int32_t visibility)
-{
- HMI_DEBUG("compositor::layer %s @ %d v %i", __func__, layer_id, visibility);
- this->lprops[layer_id].visibility = visibility;
-}
-
-void controller::layer_opacity_changed(uint32_t layer_id, float opacity)
-{
- HMI_DEBUG("compositor::layer %s @ %d o %f", __func__, layer_id, opacity);
- this->lprops[layer_id].opacity = opacity;
-}
-
-void controller::layer_source_rectangle_changed(uint32_t layer_id,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- HMI_DEBUG("compositor::layer %s @ %d x %i y %i w %i h %i",
- __func__, layer_id, x, y, width, height);
- this->lprops[layer_id].src_rect = rect{width, height, x, y};
-}
-
-void controller::layer_destination_rectangle_changed(uint32_t layer_id,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- HMI_DEBUG("compositor::layer %s @ %d x %i y %i w %i h %i",
- __func__, layer_id, x, y, width, height);
- this->lprops[layer_id].dst_rect = rect{width, height, x, y};
-}
-
-void controller::layer_destroyed(uint32_t layer_id)
-{
- HMI_DEBUG("compositor::layer %s @ %d", __func__, layer_id);
- this->lprops.erase(layer_id);
- this->layers.erase(layer_id);
-}
-
-void controller::add_proxy_to_sid_mapping(struct ivi_wm *p,
- uint32_t id)
-{
- HMI_DEBUG("Add surface proxy mapping for %p (%u)", p, id);
- this->surface_proxy_to_id[uintptr_t(p)] = id;
- this->sprops[id].id = id;
-}
-
-void controller::remove_proxy_to_sid_mapping(struct ivi_wm *p)
-{
- HMI_DEBUG("Remove surface proxy mapping for %p", p);
- this->surface_proxy_to_id.erase(uintptr_t(p));
-}
-
-void controller::add_proxy_to_lid_mapping(struct ivi_wm *p,
- uint32_t id)
-{
- HMI_DEBUG("Add layer proxy mapping for %p (%u)", p, id);
- this->layer_proxy_to_id[uintptr_t(p)] = id;
- this->lprops[id].id = id;
-}
-
-void controller::remove_proxy_to_lid_mapping(struct ivi_wm *p)
-{
- HMI_DEBUG("Remove layer proxy mapping for %p", p);
- this->layer_proxy_to_id.erase(uintptr_t(p));
-}
-
-void controller::add_proxy_to_id_mapping(struct wl_output *p, uint32_t id)
-{
- HMI_DEBUG("Add screen proxy mapping for %p (%u)", p, id);
- this->screen_proxy_to_id[uintptr_t(p)] = id;
-}
-
-void controller::remove_proxy_to_id_mapping(struct wl_output *p)
-{
- HMI_DEBUG("Remove screen proxy mapping for %p", p);
- this->screen_proxy_to_id.erase(uintptr_t(p));
-}
-
-} // namespace compositor
diff --git a/src/wayland_ivi_wm.hpp b/src/wayland_ivi_wm.hpp
deleted file mode 100644
index b515a06..0000000
--- a/src/wayland_ivi_wm.hpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef WM_WAYLAND_HPP
-#define WM_WAYLAND_HPP
-
-#include "controller_hooks.hpp"
-#include "ivi-wm-client-protocol.h"
-#include "util.hpp"
-
-#include <functional>
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-/**
- * @struct wayland_proxy
- */
-template <typename ProxyT>
-struct wayland_proxy
-{
- std::unique_ptr<ProxyT, std::function<void(ProxyT *)>> proxy;
- wayland_proxy(wayland_proxy const &) = delete;
- wayland_proxy &operator=(wayland_proxy const &) = delete;
- wayland_proxy(void *p)
- : wayland_proxy(p,
- reinterpret_cast<void (*)(ProxyT *)>(wl_proxy_destroy)) {}
- wayland_proxy(void *p, std::function<void(ProxyT *)> &&p_del)
- : proxy(std::unique_ptr<ProxyT, std::function<void(ProxyT *)>>(
- static_cast<ProxyT *>(p), p_del)) {}
-};
-
-/**
- * namespace wl
- */
-namespace wl
-{
-
-/**
- * @struct registry
- */
-struct registry : public wayland_proxy<struct wl_registry>
-{
- typedef std::function<void(struct wl_registry *, uint32_t, uint32_t)> binder;
- std::unordered_map<std::string, binder> bindings;
-
- registry(registry const &) = delete;
- registry &operator=(registry const &) = delete;
- registry(struct wl_display *d);
-
- void add_global_handler(char const *iface, binder bind);
-
- // Events
- void global_created(uint32_t name, char const *iface, uint32_t v);
- void global_removed(uint32_t name);
-};
-
-/**
- * @struct display
- */
-struct display
-{
- std::unique_ptr<struct wl_display, void (*)(struct wl_display *)> d;
- struct registry r;
-
- display(display const &) = delete;
- display &operator=(display const &) = delete;
- display();
- bool ok() const;
- void roundtrip();
- int dispatch();
- int dispatch_pending();
- int read_events();
- void flush();
- int get_fd() const;
- int get_error();
-
- // Lets just proxy this for the registry
- inline void add_global_handler(char const *iface, registry::binder bind)
- {
- this->r.add_global_handler(iface, bind);
- }
-};
-
-/**
- * @struct output
- */
-struct output : public wayland_proxy<struct wl_output>
-{
- int width{};
- int height{};
- int physical_width{};
- int physical_height{};
- int refresh{};
- int transform{};
-
- output(output const &) = delete;
- output &operator=(output const &) = delete;
- output(struct wl_registry *r, uint32_t name, uint32_t v);
-
- // Events
- void geometry(int32_t x, int32_t y, int32_t pw, int32_t ph, int32_t subpel,
- char const *make, char const *model, int32_t tx);
- void mode(uint32_t flags, int32_t w, int32_t h, int32_t r);
- void done();
- void scale(int32_t factor);
-};
-} // namespace wl
-
-/**
- * namespace compositor
- */
-namespace compositor
-{
-
-struct size
-{
- uint32_t w, h;
-};
-
-struct rect
-{
- int32_t w, h;
- int32_t x, y;
-};
-
-static const constexpr rect full_rect = rect{-1, -1, 0, 0};
-
-inline bool operator==(struct rect a, struct rect b)
-{
- return a.w == b.w && a.h == b.h && a.x == b.x && a.y == b.y;
-}
-
-struct controller;
-
-struct controller_child
-{
- struct controller *parent;
- uint32_t id;
-
- controller_child(controller_child const &) = delete;
- controller_child &operator=(controller_child const &) = delete;
- controller_child(struct controller *c, uint32_t i) : parent(c), id(i) {}
- virtual ~controller_child() {}
-};
-
-struct surface_properties
-{
- uint32_t id; // let's just save an ID here too
- struct rect dst_rect;
- struct rect src_rect;
- struct size size;
- int32_t orientation;
- int32_t visibility;
- float opacity;
-};
-
-/**
- * @struct surface
- */
-struct surface : public controller_child
-{
- surface(surface const &) = delete;
- surface &operator=(surface const &) = delete;
- surface(uint32_t i, struct controller *c);
-
- // Requests
- void set_visibility(uint32_t visibility);
- void set_source_rectangle(int32_t x, int32_t y,
- int32_t width, int32_t height);
- void set_destination_rectangle(int32_t x, int32_t y,
- int32_t width, int32_t height);
-};
-
-/**
- * @struct layer
- */
-struct layer : public controller_child
-{
- layer(layer const &) = delete;
- layer &operator=(layer const &) = delete;
- layer(uint32_t i, struct controller *c);
- layer(uint32_t i, int32_t w, int32_t h, struct controller *c);
-
- // Requests
- void set_visibility(uint32_t visibility);
- void set_destination_rectangle(int32_t x, int32_t y,
- int32_t width, int32_t height);
- void add_surface(uint32_t surface_id);
- void remove_surface(uint32_t surface_id);
-};
-
-/**
- * @struct screen
- */
-struct screen : public wayland_proxy<struct ivi_wm_screen>,
- public controller_child
-{
- screen(screen const &) = delete;
- screen &operator=(screen const &) = delete;
- screen(uint32_t i, struct controller *c, struct wl_output *o);
-
- void clear();
- void screen_created(struct screen *screen, uint32_t id);
- void set_render_order(std::vector<uint32_t> const &ro);
-};
-
-/**
- * @struct controller
- */
-struct controller : public wayland_proxy<struct ivi_wm>
-{
- // This controller is still missing ivi-input
-
- typedef std::unordered_map<uintptr_t, uint32_t> proxy_to_id_map_type;
- typedef std::unordered_map<uint32_t, std::unique_ptr<struct surface>>
- surface_map_type;
- typedef std::unordered_map<uint32_t, std::unique_ptr<struct layer>>
- layer_map_type;
- typedef std::unordered_map<uint32_t, struct screen *> screen_map_type;
- typedef std::unordered_map<uint32_t, struct surface_properties> props_map;
-
- // HACK:
- // The order of these member is mandatory, as when objects are destroyed
- // they will call their parent (that's us right here!) and remove their
- // proxy-to-id mapping. I.e. the *_proxy_to_id members need to be valid
- // when the surfaces/layers/screens maps are destroyed. This sucks, but
- // I cannot see a better solution w/o globals or some other horrible
- // call-our-parent construct.
- proxy_to_id_map_type surface_proxy_to_id;
- proxy_to_id_map_type layer_proxy_to_id;
- proxy_to_id_map_type screen_proxy_to_id;
-
- props_map sprops;
- props_map lprops;
-
- surface_map_type surfaces;
- layer_map_type layers;
- screen_map_type screens;
-
- std::unique_ptr<struct screen> screen;
-
- size output_size; // Display size[pixel]
- size physical_size; // Display size[mm]
-
- // Scale for conversion CSS PX -> DP(Device Pixel)
- double scale;
-
- wm::controller_hooks *chooks;
-
- struct wl::display *display;
-
- void add_proxy_to_sid_mapping(struct ivi_wm *p, uint32_t id);
- void remove_proxy_to_sid_mapping(struct ivi_wm *p);
-
- void add_proxy_to_lid_mapping(struct ivi_wm *p, uint32_t id);
- void remove_proxy_to_lid_mapping(struct ivi_wm *p);
-
- void add_proxy_to_id_mapping(struct wl_output *p, uint32_t id);
- void remove_proxy_to_id_mapping(struct wl_output *p);
-
- bool surface_exists(uint32_t id) const
- {
- return this->surfaces.find(id) != this->surfaces.end();
- }
-
- bool layer_exists(uint32_t id) const
- {
- return this->layers.find(id) != this->layers.end();
- }
-
- controller(struct wl_registry *r, uint32_t name, uint32_t version);
-
- // Requests
- void commit_changes() const
- {
- ivi_wm_commit_changes(this->proxy.get());
- }
- void layer_create(uint32_t id, int32_t w, int32_t h);
- void surface_create(uint32_t id);
- void create_screen(struct wl_output *output);
- void get_surface_properties(uint32_t surface_id, int param = 0);
-
- // Events
- void surface_visibility_changed(uint32_t id, int32_t visibility);
- void surface_opacity_changed(uint32_t id, float opacity);
- void surface_source_rectangle_changed(uint32_t id, int32_t x, int32_t y,
- int32_t width, int32_t height);
- void surface_destination_rectangle_changed(uint32_t id, int32_t x, int32_t y,
- int32_t width, int32_t height);
- void surface_created(uint32_t id);
- void surface_destroyed(uint32_t surface_id);
- void surface_error_detected(uint32_t object_id,
- uint32_t error_code, char const *error_text);
- void surface_size_changed(uint32_t id, int32_t width, int32_t height);
- void surface_stats_received(uint32_t surface_id,
- uint32_t frame_count, uint32_t pid);
- void surface_added_to_layer(uint32_t layer_id, uint32_t surface_id);
-
- void layer_visibility_changed(uint32_t layer_id, int32_t visibility);
- void layer_opacity_changed(uint32_t layer_id, float opacity);
- void layer_source_rectangle_changed(uint32_t layer_id, int32_t x, int32_t y,
- int32_t width, int32_t height);
- void layer_destination_rectangle_changed(uint32_t layer_id, int32_t x, int32_t y,
- int32_t width, int32_t height);
- void layer_created(uint32_t id);
- void layer_destroyed(uint32_t layer_id);
- void layer_error_detected(uint32_t object_id,
- uint32_t error_code, char const *error_text);
-};
-} // namespace compositor
-
-#endif // !WM_WAYLAND_HPP
diff --git a/src/window_manager.cpp b/src/window_manager.cpp
index 3e1a8bc..c69c839 100644
--- a/src/window_manager.cpp
+++ b/src/window_manager.cpp
@@ -56,6 +56,16 @@ const char kKeyHeightMm[] = "height_mm";
const char kKeyScale[] = "scale";
const char kKeyIds[] = "ids";
+static const vector<string> kListEventName{
+ "active",
+ "inactive",
+ "visible",
+ "invisible",
+ "syncDraw",
+ "flushDraw",
+ "screenUpdated",
+ "error"};
+
static sd_event_source *g_timer_ev_src = nullptr;
static AppList g_app_list;
static WindowManager *g_context;
@@ -63,39 +73,6 @@ static WindowManager *g_context;
namespace
{
-using nlohmann::json;
-
-result<json> file_to_json(char const *filename)
-{
- json j;
- std::ifstream i(filename);
- if (i.fail())
- {
- HMI_DEBUG("Could not open config file, so use default layer information");
- j = default_layers_json;
- }
- else
- {
- i >> j;
- }
-
- return Ok(j);
-}
-
-struct result<layer_map> load_layer_map(char const *filename)
-{
- HMI_DEBUG("loading IDs from %s", filename);
-
- auto j = file_to_json(filename);
- if (j.is_err())
- {
- return Err<layer_map>(j.unwrap_err());
- }
- json jids = j.unwrap();
-
- return to_layer_map(jids);
-}
-
static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata)
{
HMI_NOTICE("Time out occurs because the client replys endDraw slow, so revert the request");
@@ -117,57 +94,33 @@ static void onError()
/**
* WindowManager Impl
*/
-WindowManager::WindowManager(wl::display *d)
- : chooks{this},
- display{d},
- controller{},
- outputs(),
- layers(),
- id_alloc{},
- pending_events(false)
+WindowManager::WindowManager()
+ : id_alloc{}
{
- char const *path_layers_json = getenv("AFM_APP_INSTALL_DIR");
- string path;
- if (!path_layers_json)
+ const char *path = getenv("AFM_APP_INSTALL_DIR");
+ if (!path)
{
HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
- path = string(path_layers_json);
- }
- else
- {
- path = string(path_layers_json) + string("/etc/layers.json");
}
+ string root = path;
- try
- {
- {
- auto l = load_layer_map(path.c_str());
- if (l.is_ok())
- {
- this->layers = l.unwrap();
- }
- else
- {
- HMI_ERROR("%s", l.err().value());
- }
- }
- }
- catch (std::exception &e)
- {
- HMI_ERROR("Loading of configuration failed: %s", e.what());
- }
+ this->lc = std::make_shared<LayerControl>(root);
+
+ HMI_DEBUG("Layer Controller initialized");
}
int WindowManager::init()
{
- if (!this->display->ok())
- {
- return -1;
- }
+ LayerControlCallbacks lmcb;
+ lmcb.surfaceCreated = [&](unsigned pid, unsigned surface){
+ this->surface_created(surface);
+ };
+ lmcb.surfaceDestroyed = [&](unsigned surface){
+ this->surface_removed(surface);
+ };
- if (this->layers.mapping.empty())
+ if(this->lc->init(lmcb) != WMError::SUCCESS)
{
- HMI_ERROR("No surface -> layer mapping loaded");
return -1;
}
@@ -188,58 +141,25 @@ int WindowManager::init()
// Make afb event
for (int i = Event_Val_Min; i <= Event_Val_Max; i++)
{
- map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i]);
+ map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i].c_str());
}
- this->display->add_global_handler(
- "wl_output", [this](wl_registry *r, uint32_t name, uint32_t v) {
- this->outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
- });
-
- this->display->add_global_handler(
- "ivi_wm", [this](wl_registry *r, uint32_t name, uint32_t v) {
- this->controller =
- std::make_unique<struct compositor::controller>(r, name, v);
-
- // Init controller hooks
- this->controller->chooks = &this->chooks;
+ const struct rect css_bg = this->lc->getAreaSize("fullscreen");
+ Screen screen = this->lc->getScreenInfo();
+ rectangle dp_bg(screen.width(), screen.height());
- // This protocol needs the output, so lets just add our mapping here...
- this->controller->add_proxy_to_id_mapping(
- this->outputs.front()->proxy.get(),
- wl_proxy_get_id(reinterpret_cast<struct wl_proxy *>(
- this->outputs.front()->proxy.get())));
-
- // Create screen
- this->controller->create_screen(this->outputs.front()->proxy.get());
-
- // Set display to controller
- this->controller->display = this->display;
- });
-
- // First level objects
- this->display->roundtrip();
- // Second level objects
- this->display->roundtrip();
- // Third level objects
- this->display->roundtrip();
+ dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
+ dp_bg.fit(screen.width(), screen.height());
+ dp_bg.center(screen.width(), screen.height());
+ HMI_DEBUG("SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
+ css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
- return init_layers();
-}
+ double scale = static_cast<double>(dp_bg.height()) / css_bg.h;
+ this->lc->setupArea(dp_bg, scale);
-int WindowManager::dispatch_pending_events()
-{
- if (this->pop_pending_events())
- {
- this->display->dispatch_pending();
- return 0;
- }
- return -1;
-}
+ this->lc->createLayers();
-void WindowManager::set_pending_events()
-{
- this->pending_events.store(true, std::memory_order_release);
+ return 0;
}
result<int> WindowManager::api_request_surface(char const *appid, char const *drawing_name)
@@ -248,38 +168,33 @@ result<int> WindowManager::api_request_surface(char const *appid, char const *dr
// so convert role old to new
const char *role = this->convertRoleOldToNew(drawing_name);
- auto lid = this->layers.get_layer_id(string(role));
- if (!lid)
+ // auto lid = this->layers.get_layer_id(string(role));
+ unsigned lid = this->lc->getLayerID(string(role));
+ if (lid == 0)
{
/**
* register drawing_name as fallback and make it displayed.
*/
- lid = this->layers.get_layer_id(string("fallback"));
+ // lid = this->layers.get_layer_id(string("fallback"));
+ lid = this->lc->getLayerID(string("fallback"));
HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
- if (!lid)
+ if (lid == 0)
{
return Err<int>("Drawing name does not match any role, fallback is disabled");
}
}
- auto rname = this->lookup_id(role);
+ auto rname = this->id_alloc.lookup(role);
if (!rname)
{
// name does not exist yet, allocate surface id...
auto id = int(this->id_alloc.generate_id(role));
- this->layers.add_surface(id, *lid);
-
- // set the main_surface[_name] here and now
- if (!this->layers.main_surface_name.empty() &&
- this->layers.main_surface_name == drawing_name)
- {
- this->layers.main_surface = id;
- HMI_DEBUG("Set main_surface id to %u", id);
- }
+ // this->layers.add_surface(id, *lid);
+ this->tmp_surface2app[id] = {string(appid), lid};
// add client into the db
string appid_str(appid);
- g_app_list.addClient(appid_str, *lid, id, string(role));
+ g_app_list.addClient(appid_str, lid, id, string(role));
// Set role map of (new, old)
this->rolenew2old[role] = string(drawing_name);
@@ -298,23 +213,31 @@ char const *WindowManager::api_request_surface(char const *appid, char const *dr
// so convert role old to new
const char *role = this->convertRoleOldToNew(drawing_name);
- auto lid = this->layers.get_layer_id(string(role));
unsigned sid = std::stol(ivi_id);
+ WMError ret = this->lc->setXDGSurfaceOriginSize(sid);
+ if(ret != SUCCESS)
+ {
+ HMI_ERROR("%s", errorDescription(ret));
+ HMI_WARNING("The main user of this API is runXDG");
+ return "fail";
+ }
- if (!lid)
+ // auto lid = this->layers.get_layer_id(string(role));
+ auto lid = this->lc->getLayerID(string(role));
+ if (lid == 0)
{
/**
* register drawing_name as fallback and make it displayed.
*/
- lid = this->layers.get_layer_id(string("fallback"));
+ lid = this->lc->getLayerID(string("fallback"));
HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
- if (!lid)
+ if (lid == 0)
{
return "Drawing name does not match any role, fallback is disabled";
}
}
- auto rname = this->lookup_id(role);
+ auto rname = this->id_alloc.lookup(role);
if (rname)
{
@@ -323,17 +246,13 @@ char const *WindowManager::api_request_surface(char const *appid, char const *dr
// register pair drawing_name and ivi_id
this->id_alloc.register_name_id(role, sid);
- this->layers.add_surface(sid, *lid);
-
- // this surface is already created
- HMI_DEBUG("surface_id is %u, layer_id is %u", sid, *lid);
+ this->lc->addSurface(sid, lid);
- this->controller->layers[*lid]->add_surface(sid);
- this->layout_commit();
+ HMI_DEBUG("surface_id is %u, layer_id is %u", sid, lid);
- // add client into the db
+ // add client into the list
string appid_str(appid);
- g_app_list.addClient(appid_str, *lid, sid, string(role));
+ g_app_list.addClient(appid_str, lid, sid, string(role));
// Set role map of (new, old)
this->rolenew2old[role] = string(drawing_name);
@@ -351,6 +270,14 @@ void WindowManager::api_activate_surface(char const *appid, char const *drawing_
string id = appid;
string role = c_role;
string area = drawing_area;
+
+ if(!g_app_list.contains(id))
+ {
+ reply("app doesn't request 'requestSurface' or 'setRole' yet");
+ return;
+ }
+
+ auto client = g_app_list.lookUpClient(id);
Task task = Task::TASK_ALLOCATE;
unsigned req_num = 0;
WMError ret = WMError::UNKNOWN;
@@ -375,7 +302,7 @@ void WindowManager::api_activate_surface(char const *appid, char const *drawing_
/*
* Do allocate tasks
*/
- ret = this->doTransition(req_num);
+ ret = this->checkPolicy(req_num);
if (ret != WMError::SUCCESS)
{
@@ -423,7 +350,7 @@ void WindowManager::api_deactivate_surface(char const *appid, char const *drawin
/*
* Do allocate tasks
*/
- ret = this->doTransition(req_num);
+ ret = this->checkPolicy(req_num);
if (ret != WMError::SUCCESS)
{
@@ -478,23 +405,23 @@ void WindowManager::api_enddraw(char const *appid, char const *drawing_name)
}
}
-result<json_object *> WindowManager::api_get_display_info()
+int WindowManager::api_subscribe(afb_req req, int event_id)
{
- if (!this->display->ok())
- {
- return Err<json_object *>("Wayland compositor is not available");
- }
+ struct afb_event event = this->map_afb_event[kListEventName[event_id]];
+ return afb_req_subscribe(req, event);
+}
- // Set display info
- compositor::size o_size = this->controller->output_size;
- compositor::size p_size = this->controller->physical_size;
+result<json_object *> WindowManager::api_get_display_info()
+{
+ Screen screen = this->lc->getScreenInfo();
json_object *object = json_object_new_object();
- json_object_object_add(object, kKeyWidthPixel, json_object_new_int(o_size.w));
- json_object_object_add(object, kKeyHeightPixel, json_object_new_int(o_size.h));
- json_object_object_add(object, kKeyWidthMm, json_object_new_int(p_size.w));
- json_object_object_add(object, kKeyHeightMm, json_object_new_int(p_size.h));
- json_object_object_add(object, kKeyScale, json_object_new_double(this->controller->scale));
+ json_object_object_add(object, kKeyWidthPixel, json_object_new_int(screen.width()));
+ json_object_object_add(object, kKeyHeightPixel, json_object_new_int(screen.height()));
+ // TODO: set size
+ json_object_object_add(object, kKeyWidthMm, json_object_new_int(0));
+ json_object_object_add(object, kKeyHeightMm, json_object_new_int(0));
+ json_object_object_add(object, kKeyScale, json_object_new_double(this->lc->scale()));
return Ok<json_object *>(object);
}
@@ -508,25 +435,14 @@ result<json_object *> WindowManager::api_get_area_info(char const *drawing_name)
const char *role = this->convertRoleOldToNew(drawing_name);
// Check drawing name, surface/layer id
- auto const &surface_id = this->lookup_id(role);
+ auto const &surface_id = this->id_alloc.lookup(role);
if (!surface_id)
{
return Err<json_object *>("Surface does not exist");
}
- if (!this->controller->surface_exists(*surface_id))
- {
- return Err<json_object *>("Surface does not exist in controller!");
- }
-
- auto layer_id = this->layers.get_layer_id(*surface_id);
- if (!layer_id)
- {
- return Err<json_object *>("Surface is not on any layer!");
- }
-
// Set area rectangle
- compositor::rect area_info = this->area_info[*surface_id];
+ struct rect area_info = this->area_info[*surface_id];
json_object *object = json_object_new_object();
json_object_object_add(object, kKeyX, json_object_new_int(area_info.x));
json_object_object_add(object, kKeyY, json_object_new_int(area_info.y));
@@ -536,14 +452,10 @@ result<json_object *> WindowManager::api_get_area_info(char const *drawing_name)
return Ok<json_object *>(object);
}
-void WindowManager::api_ping() { this->dispatch_pending_events(); }
-
-void WindowManager::send_event(char const *evname, char const *label)
+void WindowManager::send_event(const string& evname, const string& role)
{
- HMI_DEBUG("%s: %s(%s)", __func__, evname, label);
-
json_object *j = json_object_new_object();
- json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
+ json_object_object_add(j, kKeyDrawingName, json_object_new_string(role.c_str()));
int ret = afb_event_push(this->map_afb_event[evname], j);
if (ret != 0)
@@ -552,12 +464,9 @@ void WindowManager::send_event(char const *evname, char const *label)
}
}
-void WindowManager::send_event(char const *evname, char const *label, char const *area,
+void WindowManager::send_event(const string& evname, const string& role, const string& area,
int x, int y, int w, int h)
{
- HMI_DEBUG("%s: %s(%s, %s) x:%d y:%d w:%d h:%d",
- __func__, evname, label, area, x, y, w, h);
-
json_object *j_rect = json_object_new_object();
json_object_object_add(j_rect, kKeyX, json_object_new_int(x));
json_object_object_add(j_rect, kKeyY, json_object_new_int(y));
@@ -565,8 +474,8 @@ void WindowManager::send_event(char const *evname, char const *label, char const
json_object_object_add(j_rect, kKeyHeight, json_object_new_int(h));
json_object *j = json_object_new_object();
- json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
- json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area));
+ json_object_object_add(j, kKeyDrawingName, json_object_new_string(role.c_str()));
+ json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area.c_str()));
json_object_object_add(j, kKeyDrawingRect, j_rect);
int ret = afb_event_push(this->map_afb_event[evname], j);
@@ -579,29 +488,22 @@ void WindowManager::send_event(char const *evname, char const *label, char const
/**
* proxied events
*/
-void WindowManager::surface_created(uint32_t surface_id)
+void WindowManager::surface_created(unsigned surface_id)
{
- this->controller->get_surface_properties(surface_id, IVI_WM_PARAM_SIZE);
-
- auto layer_id = this->layers.get_layer_id(surface_id);
- if (!layer_id)
+ // requestSurface
+ if(this->tmp_surface2app.count(surface_id) != 0)
{
- HMI_DEBUG("Newly created surfce %d is not associated with any layer!",
- surface_id);
- return;
+ unsigned layer_id = this->tmp_surface2app[surface_id].layer;
+ this->lc->addSurface(surface_id, layer_id);
+ this->tmp_surface2app.erase(surface_id);
+ HMI_DEBUG("surface_id is %u, layer_id is %u", surface_id, layer_id);
}
-
- HMI_DEBUG("surface_id is %u, layer_id is %u", surface_id, *layer_id);
-
- this->controller->layers[*layer_id]->add_surface(surface_id);
- this->layout_commit();
}
-void WindowManager::surface_removed(uint32_t surface_id)
+void WindowManager::surface_removed(unsigned surface_id)
{
HMI_DEBUG("Delete surface_id %u", surface_id);
this->id_alloc.remove_id(surface_id);
- this->layers.remove_surface(surface_id);
g_app_list.removeSurface(surface_id);
}
@@ -653,7 +555,7 @@ void WindowManager::startTransitionWrapper(vector<WMAction> &actions)
if ("" != act.role)
{
bool found;
- auto const &surface_id = this->lookup_id(act.role.c_str());
+ auto const &surface_id = this->id_alloc.lookup(act.role.c_str());
if(surface_id == nullopt)
{
goto proc_remove_request;
@@ -727,281 +629,44 @@ void WindowManager::processError(WMError error)
******* Private Functions *******
*/
-bool WindowManager::pop_pending_events()
+void WindowManager::emit_activated(const string& role)
{
- bool x{true};
- return this->pending_events.compare_exchange_strong(
- x, false, std::memory_order_consume);
+ this->send_event(kListEventName[Event_Active], role);
}
-optional<int> WindowManager::lookup_id(char const *name)
-{
- return this->id_alloc.lookup(string(name));
-}
-optional<string> WindowManager::lookup_name(int id)
+void WindowManager::emit_deactivated(const string& role)
{
- return this->id_alloc.lookup(id);
+ this->send_event(kListEventName[Event_Inactive], role);
}
-/**
- * init_layers()
- */
-int WindowManager::init_layers()
+void WindowManager::emit_syncdraw(const string& role, char const *area, int x, int y, int w, int h)
{
- if (!this->controller)
- {
- HMI_ERROR("ivi_controller global not available");
- return -1;
- }
-
- if (this->outputs.empty())
- {
- HMI_ERROR("no output was set up!");
- return -1;
- }
-
- auto &c = this->controller;
-
- auto &o = this->outputs.front();
- auto &s = c->screens.begin()->second;
- auto &layers = c->layers;
-
- // Write output dimensions to ivi controller...
- c->output_size = compositor::size{uint32_t(o->width), uint32_t(o->height)};
- c->physical_size = compositor::size{uint32_t(o->physical_width),
- uint32_t(o->physical_height)};
-
-
- HMI_DEBUG("SCALING: screen (%dx%d), physical (%dx%d)",
- o->width, o->height, o->physical_width, o->physical_height);
-
- this->layers.loadAreaDb();
-
- const compositor::rect css_bg = this->layers.getAreaSize("fullscreen");
- rectangle dp_bg(o->width, o->height);
-
- dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
- dp_bg.fit(o->width, o->height);
- dp_bg.center(o->width, o->height);
- HMI_DEBUG("SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
- css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
-
- // Clear scene
- layers.clear();
-
- // Clear screen
- s->clear();
-
- // Quick and dirty setup of layers
- for (auto const &i : this->layers.mapping)
- {
- c->layer_create(i.second.layer_id, dp_bg.width(), dp_bg.height());
- auto &l = layers[i.second.layer_id];
- l->set_destination_rectangle(dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
- l->set_visibility(1);
- HMI_DEBUG("Setting up layer %s (%d) for surface role match \"%s\"",
- i.second.name.c_str(), i.second.layer_id, i.second.role.c_str());
- }
-
- // Add layers to screen
- s->set_render_order(this->layers.layers);
-
- this->layout_commit();
-
- c->scale = static_cast<double>(dp_bg.height()) / css_bg.h;
- this->layers.setupArea(c->scale);
-
- return 0;
-}
-
-void WindowManager::surface_set_layout(int surface_id, const string& area)
-{
- if (!this->controller->surface_exists(surface_id))
- {
- HMI_ERROR("Surface %d does not exist", surface_id);
- return;
- }
-
- auto o_layer_id = this->layers.get_layer_id(surface_id);
-
- if (!o_layer_id)
- {
- HMI_ERROR("Surface %d is not associated with any layer!", surface_id);
- return;
- }
-
- uint32_t layer_id = *o_layer_id;
-
- auto const &layer = this->layers.get_layer(layer_id);
- auto rect = this->layers.getAreaSize(area);
- HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "%s : x:%d y:%d w:%d h:%d", area.c_str(),
- rect.x, rect.y, rect.w, rect.h);
- auto &s = this->controller->surfaces[surface_id];
-
- int x = rect.x;
- int y = rect.y;
- int w = rect.w;
- int h = rect.h;
-
- HMI_DEBUG("surface_set_layout for surface %u on layer %u", surface_id,
- layer_id);
-
- // set destination to the display rectangle
- s->set_destination_rectangle(x, y, w, h);
-
- // update area information
- this->area_info[surface_id].x = x;
- this->area_info[surface_id].y = y;
- this->area_info[surface_id].w = w;
- this->area_info[surface_id].h = h;
-
- HMI_DEBUG("Surface %u now on layer %u with rect { %d, %d, %d, %d }",
- surface_id, layer_id, x, y, w, h);
-}
-
-void WindowManager::layout_commit()
-{
- this->controller->commit_changes();
- this->display->flush();
-}
-
-void WindowManager::emit_activated(char const *label)
-{
- this->send_event(kListEventName[Event_Active], label);
-}
-
-void WindowManager::emit_deactivated(char const *label)
-{
- this->send_event(kListEventName[Event_Inactive], label);
-}
-
-void WindowManager::emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h)
-{
- this->send_event(kListEventName[Event_SyncDraw], label, area, x, y, w, h);
+ this->send_event(kListEventName[Event_SyncDraw], role, area, x, y, w, h);
}
void WindowManager::emit_syncdraw(const string &role, const string &area)
{
- compositor::rect rect = this->layers.getAreaSize(area);
+ struct rect rect = this->lc->getAreaSize(area);
this->send_event(kListEventName[Event_SyncDraw],
role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h);
}
-void WindowManager::emit_flushdraw(char const *label)
+void WindowManager::emit_flushdraw(const string& role)
{
- this->send_event(kListEventName[Event_FlushDraw], label);
+ this->send_event(kListEventName[Event_FlushDraw], role);
}
-void WindowManager::emit_visible(char const *label, bool is_visible)
+void WindowManager::emit_visible(const string& role, bool is_visible)
{
- this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label);
+ this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], role);
}
-void WindowManager::emit_invisible(char const *label)
+void WindowManager::emit_invisible(const string& role)
{
- return emit_visible(label, false);
+ return emit_visible(role, false);
}
-void WindowManager::emit_visible(char const *label) { return emit_visible(label, true); }
-
-void WindowManager::activate(int id)
-{
- auto ip = this->controller->sprops.find(id);
- if (ip != this->controller->sprops.end())
- {
- this->controller->surfaces[id]->set_visibility(1);
- char const *label =
- this->lookup_name(id).value_or("unknown-name").c_str();
-
- // FOR CES DEMO >>>
- if ((0 == strcmp(label, "radio")) ||
- (0 == strcmp(label, "music")) ||
- (0 == strcmp(label, "video")) ||
- (0 == strcmp(label, "map")))
- {
- for (auto i = surface_bg.begin(); i != surface_bg.end(); ++i)
- {
- if (id == *i)
- {
- // Remove id
- this->surface_bg.erase(i);
-
- // Remove from BG layer (999)
- HMI_DEBUG("Remove %s(%d) from BG layer", label, id);
- this->controller->layers[999]->remove_surface(id);
-
- // Add to FG layer (1001)
- HMI_DEBUG("Add %s(%d) to FG layer", label, id);
- this->controller->layers[1001]->add_surface(id);
-
- for (int j : this->surface_bg)
- {
- HMI_DEBUG("Stored id:%d", j);
- }
- break;
- }
- }
- }
- // <<< FOR CES DEMO
-
- this->layout_commit();
-
- // TODO: application requests by old role,
- // so convert role new to old for emitting event
- const char* old_role = this->rolenew2old[label].c_str();
-
- this->emit_visible(old_role);
- this->emit_activated(old_role);
- }
-}
-
-void WindowManager::deactivate(int id)
-{
- auto ip = this->controller->sprops.find(id);
- if (ip != this->controller->sprops.end())
- {
- char const *label =
- this->lookup_name(id).value_or("unknown-name").c_str();
-
- // FOR CES DEMO >>>
- if ((0 == strcmp(label, "radio")) ||
- (0 == strcmp(label, "music")) ||
- (0 == strcmp(label, "video")) ||
- (0 == strcmp(label, "map")))
- {
-
- // Store id
- this->surface_bg.push_back(id);
-
- // Remove from FG layer (1001)
- HMI_DEBUG("Remove %s(%d) from FG layer", label, id);
- this->controller->layers[1001]->remove_surface(id);
-
- // Add to BG layer (999)
- HMI_DEBUG("Add %s(%d) to BG layer", label, id);
- this->controller->layers[999]->add_surface(id);
-
- for (int j : surface_bg)
- {
- HMI_DEBUG("Stored id:%d", j);
- }
- }
- else
- {
- this->controller->surfaces[id]->set_visibility(0);
- }
- // <<< FOR CES DEMO
-
- this->layout_commit();
-
- // TODO: application requests by old role,
- // so convert role new to old for emitting event
- const char* old_role = this->rolenew2old[label].c_str();
-
- this->emit_deactivated(old_role);
- this->emit_invisible(old_role);
- }
-}
+void WindowManager::emit_visible(const string& role) { return emit_visible(role, true); }
WMError WindowManager::setRequest(const string& appid, const string &role, const string &area,
Task task, unsigned* req_num)
@@ -1035,13 +700,6 @@ WMError WindowManager::setRequest(const string& appid, const string &role, const
return WMError::SUCCESS;
}
-WMError WindowManager::doTransition(unsigned req_num)
-{
- HMI_SEQ_DEBUG(req_num, "check policy");
- WMError ret = this->checkPolicy(req_num);
- return ret;
-}
-
WMError WindowManager::checkPolicy(unsigned req_num)
{
/*
@@ -1131,11 +789,14 @@ WMError WindowManager::startTransition(unsigned req_num)
// Make it deactivate here
for (const auto &x : actions)
{
- if (g_app_list.contains(x.client->appID()))
+ this->lc->visibilityChange(x);
+ string old_role = this->rolenew2old[x.role];
+ emit_deactivated(old_role.c_str());
+ /* if (g_app_list.contains(x.client->appID()))
{
auto client = g_app_list.lookUpClient(x.client->appID());
this->deactivate(client->surfaceID(x.role));
- }
+ } */
}
ret = WMError::NO_LAYOUT_CHANGE;
}
@@ -1162,17 +823,26 @@ WMError WindowManager::doEndDraw(unsigned req_num)
if(act.visible != TaskVisible::NO_CHANGE)
{
// layout change
- if(!g_app_list.contains(act.client->appID())){
- ret = WMError::NOT_REGISTERED;
- }
- ret = this->layoutChange(act);
+ ret = this->lc->layoutChange(act);
if(ret != WMError::SUCCESS)
{
HMI_SEQ_WARNING(req_num,
"Failed to manipulate surfaces while state change : %s", errorDescription(ret));
return ret;
}
- ret = this->visibilityChange(act);
+ ret = this->lc->visibilityChange(act);
+
+ // Emit active/deactive event
+ string old_role = this->rolenew2old[act.role];
+ if(act.visible == VISIBLE)
+ {
+ emit_activated(old_role.c_str());
+ }
+ else
+ {
+ emit_deactivated(old_role.c_str());
+ }
+
if (ret != WMError::SUCCESS)
{
HMI_SEQ_WARNING(req_num,
@@ -1180,10 +850,8 @@ WMError WindowManager::doEndDraw(unsigned req_num)
return ret;
}
HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str());
- //this->lm_enddraw(act.role.c_str());
}
}
- this->layout_commit();
HMI_SEQ_INFO(req_num, "emit flushDraw");
@@ -1202,60 +870,6 @@ WMError WindowManager::doEndDraw(unsigned req_num)
return ret;
}
-WMError WindowManager::layoutChange(const WMAction &action)
-{
- if (action.visible == TaskVisible::INVISIBLE)
- {
- // Visibility is not change -> no redraw is required
- return WMError::SUCCESS;
- }
- auto client = g_app_list.lookUpClient(action.client->appID());
- unsigned surface = client->surfaceID(action.role);
- if (surface == 0)
- {
- HMI_SEQ_ERROR(g_app_list.currentRequestNumber(),
- "client doesn't have surface with role(%s)", action.role.c_str());
- return WMError::NOT_REGISTERED;
- }
- // Layout Manager
- WMError ret = this->setSurfaceSize(surface, action.area);
- return ret;
-}
-
-WMError WindowManager::visibilityChange(const WMAction &action)
-{
- HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Change visibility");
- if(!g_app_list.contains(action.client->appID()))
- {
- return WMError::NOT_REGISTERED;
- }
- auto client = g_app_list.lookUpClient(action.client->appID());
- unsigned surface = client->surfaceID(action.role);
- if(surface == 0)
- {
- HMI_SEQ_ERROR(g_app_list.currentRequestNumber(),
- "client doesn't have surface with role(%s)", action.role.c_str());
- return WMError::NOT_REGISTERED;
- }
-
- if (action.visible != TaskVisible::INVISIBLE)
- {
- this->activate(surface); // Layout Manager task
- }
- else
- {
- this->deactivate(surface); // Layout Manager task
- }
- return WMError::SUCCESS;
-}
-
-WMError WindowManager::setSurfaceSize(unsigned surface, const string &area)
-{
- this->surface_set_layout(surface, area);
-
- return WMError::SUCCESS;
-}
-
void WindowManager::emitScreenUpdated(unsigned req_num)
{
// Get visible apps
@@ -1331,7 +945,7 @@ void WindowManager::processNextRequest()
if (g_app_list.haveRequest())
{
HMI_SEQ_DEBUG(req_num, "Process next request");
- WMError rc = doTransition(req_num);
+ WMError rc = checkPolicy(req_num);
if (rc != WMError::SUCCESS)
{
HMI_SEQ_ERROR(req_num, errorDescription(rc));
@@ -1444,25 +1058,11 @@ int WindowManager::loadOldRoleDb()
const char *WindowManager::check_surface_exist(const char *drawing_name)
{
- auto const &surface_id = this->lookup_id(drawing_name);
+ auto const &surface_id = this->id_alloc.lookup(drawing_name);
if (!surface_id)
{
return "Surface does not exist";
}
-
- if (!this->controller->surface_exists(*surface_id))
- {
- return "Surface does not exist in controller!";
- }
-
- auto layer_id = this->layers.get_layer_id(*surface_id);
-
- if (!layer_id)
- {
- return "Surface is not on any layer!";
- }
-
- HMI_DEBUG("surface %d is detected", *surface_id);
return nullptr;
}
@@ -1535,26 +1135,4 @@ const char* WindowManager::kDefaultOldRoleDb = "{ \
] \
}";
-/**
- * controller_hooks
- */
-void controller_hooks::surface_created(uint32_t surface_id)
-{
- this->wmgr->surface_created(surface_id);
-}
-
-void controller_hooks::surface_removed(uint32_t surface_id)
-{
- this->wmgr->surface_removed(surface_id);
-}
-
-void controller_hooks::surface_visibility(uint32_t /*surface_id*/,
- uint32_t /*v*/) {}
-
-void controller_hooks::surface_destination_rectangle(uint32_t /*surface_id*/,
- uint32_t /*x*/,
- uint32_t /*y*/,
- uint32_t /*w*/,
- uint32_t /*h*/) {}
-
} // namespace wm
diff --git a/src/window_manager.hpp b/src/window_manager.hpp
index b591149..6416e67 100644
--- a/src/window_manager.hpp
+++ b/src/window_manager.hpp
@@ -21,14 +21,12 @@
#include <memory>
#include <unordered_map>
#include <experimental/optional>
-#include "util.hpp"
-#include "controller_hooks.hpp"
-#include "wm_layer.hpp"
-#include "layout.hpp"
-#include "wayland_ivi_wm.hpp"
+#include "result.hpp"
#include "pm_wrapper.hpp"
+#include "util.hpp"
#include "request.hpp"
#include "wm_error.hpp"
+#include "wm_layer_control.hpp"
extern "C"
{
#include <afb/afb-binding.h>
@@ -36,16 +34,6 @@ extern "C"
struct json_object;
-namespace wl
-{
-struct display;
-}
-
-namespace compositor
-{
-struct controller;
-}
-
namespace wm
{
@@ -76,7 +64,6 @@ extern const char kKeyIds[];
struct id_allocator
{
unsigned next = 1;
-
// Surfaces that where requested but not yet created
std::unordered_map<unsigned, std::string> id2name;
std::unordered_map<std::string, unsigned> name2id;
@@ -141,10 +128,17 @@ struct id_allocator
}
};
+struct TmpClient
+{
+ std::string appid;
+ unsigned layer;
+};
+
+
class WindowManager
{
public:
- typedef std::unordered_map<uint32_t, struct compositor::rect> rect_map;
+ typedef std::unordered_map<uint32_t, struct rect> rect_map;
typedef std::function<void(const char *err_msg)> reply_func;
enum EventType
@@ -167,42 +161,7 @@ class WindowManager
Event_Val_Max = Event_Error,
};
- const std::vector<const char *> kListEventName{
- "active",
- "inactive",
- "visible",
- "invisible",
- "syncDraw",
- "flushDraw",
- "screenUpdated",
- "error"};
-
- struct controller_hooks chooks;
-
- // This is the one thing, we do not own.
- struct wl::display *display;
-
- std::unique_ptr<struct compositor::controller> controller;
- std::vector<std::unique_ptr<struct wl::output>> outputs;
-
- // track current layouts separately
- layer_map layers;
-
- // ID allocation and proxy methods for lookup
- struct id_allocator id_alloc;
-
- // Set by AFB API when wayland events need to be dispatched
- std::atomic<bool> pending_events;
-
- std::map<const char *, struct afb_event> map_afb_event;
-
- // Surface are info (x, y, w, h)
- rect_map area_info;
-
- // FOR CES DEMO
- std::vector<int> surface_bg;
-
- explicit WindowManager(wl::display *d);
+ explicit WindowManager();
~WindowManager() = default;
WindowManager(WindowManager const &) = delete;
@@ -211,23 +170,22 @@ class WindowManager
WindowManager &operator=(WindowManager &&) = delete;
int init();
- int dispatch_pending_events();
- void set_pending_events();
result<int> api_request_surface(char const *appid, char const *role);
char const *api_request_surface(char const *appid, char const *role, char const *ivi_id);
void api_activate_surface(char const *appid, char const *role, char const *drawing_area, const reply_func &reply);
void api_deactivate_surface(char const *appid, char const *role, const reply_func &reply);
- void api_enddraw(char const *appid, char const *role);
+ void api_enddraw(char const *appid, char const *role);
+ int api_subscribe(afb_req req, int event_id);
result<json_object *> api_get_display_info();
result<json_object *> api_get_area_info(char const *role);
void api_ping();
- void send_event(char const *evname, char const *label);
- void send_event(char const *evname, char const *label, char const *area, int x, int y, int w, int h);
+ void send_event(const std::string& evname, const std::string& role);
+ void send_event(const std::string& evname, const std::string& role, const std::string& area, int x, int y, int w, int h);
// Events from the compositor we are interested in
- void surface_created(uint32_t surface_id);
- void surface_removed(uint32_t surface_id);
+ void surface_created(unsigned surface_id);
+ void surface_removed(unsigned surface_id);
void removeClient(const std::string &appid);
void exceptionProcessForTransition();
@@ -239,35 +197,22 @@ class WindowManager
void processError(WMError error);
private:
- bool pop_pending_events();
- optional<int> lookup_id(char const *name);
- optional<std::string> lookup_name(int id);
- int init_layers();
- void surface_set_layout(int surface_id, const std::string& area = "");
- void layout_commit();
-
// WM Events to clients
- void emit_activated(char const *label);
- void emit_deactivated(char const *label);
- void emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h);
+ void emit_activated(const std::string& role);
+ void emit_deactivated(const std::string& role);
+ void emit_syncdraw(const std::string& role, char const *area, int x, int y, int w, int h);
void emit_syncdraw(const std::string &role, const std::string &area);
- void emit_flushdraw(char const *label);
- void emit_visible(char const *label, bool is_visible);
- void emit_invisible(char const *label);
- void emit_visible(char const *label);
+ void emit_flushdraw(const std::string& role);
+ void emit_visible(const std::string& role, bool is_visible);
+ void emit_invisible(const std::string& role);
+ void emit_visible(const std::string& role);
- void activate(int id);
- void deactivate(int id);
WMError setRequest(const std::string &appid, const std::string &role, const std::string &area,
Task task, unsigned *req_num);
- WMError doTransition(unsigned sequence_number);
WMError checkPolicy(unsigned req_num);
WMError startTransition(unsigned req_num);
WMError doEndDraw(unsigned req_num);
- WMError layoutChange(const WMAction &action);
- WMError visibilityChange(const WMAction &action);
- WMError setSurfaceSize(unsigned surface, const std::string& area);
void emitScreenUpdated(unsigned req_num);
void setTimer();
@@ -279,12 +224,17 @@ class WindowManager
const char *check_surface_exist(const char *role);
private:
- std::unordered_map<std::string, struct compositor::rect> area2size;
+ std::map<std::string, struct afb_event> map_afb_event;
+ std::unordered_map<std::string, struct rect> area2size;
std::unordered_map<std::string, std::string> roleold2new;
std::unordered_map<std::string, std::string> rolenew2old;
-
+ std::shared_ptr<LayerControl> lc;
PMWrapper pmw;
+ rect_map area_info;
+ struct id_allocator id_alloc;
+ // ID allocation and proxy methods for lookup
+ std::unordered_map<unsigned, struct TmpClient> tmp_surface2app;
static const char* kDefaultOldRoleDb;
};
diff --git a/src/wm_layer.cpp b/src/wm_layer.cpp
index 6a98884..c702651 100644
--- a/src/wm_layer.cpp
+++ b/src/wm_layer.cpp
@@ -15,338 +15,34 @@
*/
#include <regex>
-
+#include <ilm/ilm_control.h>
+#include <stdlib.h>
+#include "wm_client.hpp"
#include "wm_layer.hpp"
#include "json_helper.hpp"
#include "util.hpp"
-namespace wm
-{
-
-using json = nlohmann::json;
-
-layer::layer(nlohmann::json const &j)
-{
- this->role = j["role"];
- this->name = j["name"];
- this->layer_id = j["layer_id"];
-
- HMI_DEBUG("layer_id:%d name:%s", this->layer_id, this->name.c_str());
-}
-
-struct result<struct layer_map> to_layer_map(nlohmann::json const &j)
-{
- try
- {
- layer_map stl{};
- auto m = j["mappings"];
-
- std::transform(std::cbegin(m), std::cend(m),
- std::inserter(stl.mapping, stl.mapping.end()),
- [](nlohmann::json const &j) {
- return std::pair<int, struct layer>(
- j.value("layer_id", -1), layer(j));
- });
-
- // TODO: add sanity checks here?
- // * check for double IDs
- // * check for double names/roles
-
- stl.layers.reserve(m.size());
- std::transform(std::cbegin(stl.mapping), std::cend(stl.mapping),
- std::back_inserter(stl.layers),
- [&stl](std::pair<int, struct layer> const &k) {
- stl.roles.emplace_back(
- std::make_pair(k.second.role, k.second.layer_id));
- return unsigned(k.second.layer_id);
- });
-
- std::sort(stl.layers.begin(), stl.layers.end());
-
- for (auto i : stl.mapping)
- {
- if (i.second.name.empty())
- {
- return Err<struct layer_map>("Found mapping w/o name");
- }
- if (i.second.layer_id == -1)
- {
- return Err<struct layer_map>("Found invalid/unset IDs in mapping");
- }
- }
-
- auto msi = j.find("main_surface");
- if (msi != j.end())
- {
- stl.main_surface_name = msi->value("surface_role", "");
- stl.main_surface = -1;
- }
-
- return Ok(stl);
- }
- catch (std::exception &e)
- {
- return Err<struct layer_map>(e.what());
- }
-}
-
-optional<int>
-layer_map::get_layer_id(int surface_id)
-{
- auto i = this->surfaces.find(surface_id);
- if (i != this->surfaces.end())
- {
- return optional<int>(i->second);
- }
- return nullopt;
-}
-
-optional<int> layer_map::get_layer_id(std::string const &role)
-{
- for (auto const &r : this->roles)
- {
- auto re = std::regex(r.first);
- if (std::regex_match(role, re))
- {
- HMI_DEBUG("role %s matches layer %d", role.c_str(), r.second);
- return optional<int>(r.second);
- }
- }
- HMI_DEBUG("role %s does NOT match any layer", role.c_str());
- return nullopt;
-}
-
-json layer::to_json() const
-{
- auto is_full = this->rect == compositor::full_rect;
-
- json r{};
- if (is_full)
- {
- r = {{"type", "full"}};
- }
- else
- {
- r = {{"type", "rect"},
- {"rect",
- {{"x", this->rect.x},
- {"y", this->rect.y},
- {"width", this->rect.w},
- {"height", this->rect.h}}}};
- }
-
- return {
- {"name", this->name},
- {"role", this->role},
- {"layer_id", this->layer_id},
- {"area", r},
- };
-}
+using std::string;
-json layer_map::to_json() const
+namespace wm
{
- json j{};
- for (auto const &i : this->mapping)
- {
- j.push_back(i.second.to_json());
- }
- return j;
-}
-void layer_map::setupArea(double scaling)
+WMLayer::WMLayer(json_object* j)
{
- compositor::rect rct;
-
- rct = this->area2size["normal.full"];
- this->area2size["normalfull"] = rct;
- this->area2size["normal"] = rct;
-
- for (auto &i : this->area2size)
- {
- i.second.x = static_cast<int>(scaling * i.second.x + 0.5);
- i.second.y = static_cast<int>(scaling * i.second.y + 0.5);
- i.second.w = static_cast<int>(scaling * i.second.w + 0.5);
- i.second.h = static_cast<int>(scaling * i.second.h + 0.5);
-
- HMI_DEBUG("area:%s size(after) : x:%d y:%d w:%d h:%d",
- i.first.c_str(), i.second.x, i.second.y, i.second.w, i.second.h);
- }
-}
-
-compositor::rect layer_map::getAreaSize(const std::string &area)
-{
- return area2size[area];
+ this->name = jh::getStringFromJson(j, "name");
+ this->role_list = jh::getStringFromJson(j, "role");
+ this->layer_id = static_cast<unsigned>(jh::getIntFromJson(j, "layer_id"));
}
-int layer_map::loadAreaDb()
+bool WMLayer::hasRole(const string& role)
{
- // Get afm application installed dir
- char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR");
- HMI_DEBUG("afm_app_install_dir:%s", afm_app_install_dir);
-
- std::string file_name;
- if (!afm_app_install_dir)
- {
- HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
- }
- else
- {
- file_name = std::string(afm_app_install_dir) + std::string("/etc/areas.db");
- }
-
- // Load area.db
- json_object *json_obj;
- int ret = jh::inputJsonFilie(file_name.c_str(), &json_obj);
- if (0 > ret)
- {
- HMI_DEBUG("Could not open area.db, so use default area information");
- json_obj = json_tokener_parse(kDefaultAreaDb);
- }
- HMI_DEBUG("json_obj dump:%s", json_object_get_string(json_obj));
-
- // Perse areas
- HMI_DEBUG("Perse areas");
- json_object *json_cfg;
- if (!json_object_object_get_ex(json_obj, "areas", &json_cfg))
+ auto re = std::regex(this->role_list);
+ if (std::regex_match(role, re))
{
- HMI_ERROR("Parse Error!!");
- return -1;
+ HMI_DEBUG("role %s matches layer %s", role.c_str(), this->name.c_str());
+ return true;
}
-
- int len = json_object_array_length(json_cfg);
- HMI_DEBUG("json_cfg len:%d", len);
- HMI_DEBUG("json_cfg dump:%s", json_object_get_string(json_cfg));
-
- const char *area;
- for (int i = 0; i < len; i++)
- {
- json_object *json_tmp = json_object_array_get_idx(json_cfg, i);
- HMI_DEBUG("> json_tmp dump:%s", json_object_get_string(json_tmp));
-
- area = jh::getStringFromJson(json_tmp, "name");
- if (nullptr == area)
- {
- HMI_ERROR("Parse Error!!");
- return -1;
- }
- HMI_DEBUG("> area:%s", area);
-
- json_object *json_rect;
- if (!json_object_object_get_ex(json_tmp, "rect", &json_rect))
- {
- HMI_ERROR("Parse Error!!");
- return -1;
- }
- HMI_DEBUG("> json_rect dump:%s", json_object_get_string(json_rect));
-
- compositor::rect area_size;
- area_size.x = jh::getIntFromJson(json_rect, "x");
- area_size.y = jh::getIntFromJson(json_rect, "y");
- area_size.w = jh::getIntFromJson(json_rect, "w");
- area_size.h = jh::getIntFromJson(json_rect, "h");
-
- this->area2size[area] = area_size;
- }
-
- // Check
- for (auto itr = this->area2size.begin();
- itr != this->area2size.end(); ++itr)
- {
- HMI_DEBUG("area:%s x:%d y:%d w:%d h:%d",
- itr->first.c_str(), itr->second.x, itr->second.y,
- itr->second.w, itr->second.h);
- }
-
- // Release json_object
- json_object_put(json_obj);
-
- return 0;
+ return false;
}
-const char* layer_map::kDefaultAreaDb = "{ \
- \"areas\": [ \
- { \
- \"name\": \"fullscreen\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 0, \
- \"w\": 1080, \
- \"h\": 1920 \
- } \
- }, \
- { \
- \"name\": \"normal.full\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 218, \
- \"w\": 1080, \
- \"h\": 1488 \
- } \
- }, \
- { \
- \"name\": \"split.main\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 218, \
- \"w\": 1080, \
- \"h\": 744 \
- } \
- }, \
- { \
- \"name\": \"split.sub\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 962, \
- \"w\": 1080, \
- \"h\": 744 \
- } \
- }, \
- { \
- \"name\": \"software_keyboard\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 962, \
- \"w\": 1080, \
- \"h\": 744 \
- } \
- }, \
- { \
- \"name\": \"restriction.normal\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 218, \
- \"w\": 1080, \
- \"h\": 1488 \
- } \
- }, \
- { \
- \"name\": \"restriction.split.main\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 218, \
- \"w\": 1080, \
- \"h\": 744 \
- } \
- }, \
- { \
- \"name\": \"restriction.split.sub\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 962, \
- \"w\": 1080, \
- \"h\": 744 \
- } \
- }, \
- { \
- \"name\": \"on_screen\", \
- \"rect\": { \
- \"x\": 0, \
- \"y\": 218, \
- \"w\": 1080, \
- \"h\": 1488 \
- } \
- } \
- ] \
-}";
-
} // namespace wm
diff --git a/src/wm_layer.hpp b/src/wm_layer.hpp
index 4dd4616..1d9435b 100644
--- a/src/wm_layer.hpp
+++ b/src/wm_layer.hpp
@@ -14,145 +14,40 @@
* limitations under the License.
*/
-#ifndef WM_LAYERS_H
-#define WM_LAYERS_H
+#ifndef WM_LAYER_HPP
+#define WM_LAYER_HPP
#include <string>
+#include <vector>
+#include <unordered_map>
+#include <memory>
+#include "wm_error.hpp"
-#include "../include/json.hpp"
-#include "layout.hpp"
-#include "result.hpp"
-#include "wayland_ivi_wm.hpp"
+struct json_object;
namespace wm
{
-struct layer
+class WMLayer
{
- using json = nlohmann::json;
-
+ public:
+ explicit WMLayer(json_object* j);
+ ~WMLayer() = default;
// A more or less descriptive name?
+ const std::string& layerName(){ return this->role_list;}
+ unsigned layerID(){ return this->layer_id;}
+ const std::string& roleList();
+ bool hasRole(const std::string& role);
+ private:
std::string name = "";
// The actual layer ID
- int layer_id = -1;
- // The rectangular region surfaces are allowed to draw on
- // this layer.
- compositor::rect rect;
+ int layer_id = 0;
+
// Specify a role prefix for surfaces that should be
// put on this layer.
- std::string role;
-
- mutable struct LayoutState state;
-
- explicit layer(nlohmann::json const &j);
-
- json to_json() const;
+ std::string role_list;
};
-struct layer_map
-{
- using json = nlohmann::json;
-
- using storage_type = std::map<int, struct layer>;
- using layers_type = std::vector<uint32_t>;
- using role_to_layer_map = std::vector<std::pair<std::string, int>>;
- using addsurf_layer_map = std::map<int, int>;
-
- storage_type mapping; // map surface_id to layer
- layers_type layers; // the actual layer IDs we have
- int main_surface;
- std::string main_surface_name;
- role_to_layer_map roles;
- addsurf_layer_map surfaces; // additional surfaces on layers
-
- optional<int> get_layer_id(int surface_id);
- optional<int> get_layer_id(std::string const &role);
- optional<struct LayoutState *> get_layout_state(int surface_id)
- {
- int layer_id = *this->get_layer_id(surface_id);
- auto i = this->mapping.find(layer_id);
- return i == this->mapping.end()
- ? nullopt
- : optional<struct LayoutState *>(&i->second.state);
- }
- optional<struct layer> get_layer(int layer_id)
- {
- auto i = this->mapping.find(layer_id);
- return i == this->mapping.end() ? nullopt
- : optional<struct layer>(i->second);
- }
-
- layers_type::size_type get_layers_count() const
- {
- return this->layers.size();
- }
-
- void add_surface(int surface_id, int layer_id)
- {
- this->surfaces[surface_id] = layer_id;
- }
-
- void remove_surface(int surface_id)
- {
- this->surfaces.erase(surface_id);
- }
-
- json to_json() const;
- void setupArea(double scaling);
- compositor::rect getAreaSize(const std::string &area);
- int loadAreaDb();
-
- private:
- std::unordered_map<std::string, compositor::rect> area2size;
-
- static const char *kDefaultAreaDb;
-};
-
-struct result<struct layer_map> to_layer_map(nlohmann::json const &j);
-
-static const nlohmann::json default_layers_json = {
- {"main_surface", {
- {"surface_role", "HomeScreen"}
- }},
- {"mappings", {
- {
- {"role", "^HomeScreen$"},
- {"name", "HomeScreen"},
- {"layer_id", 1000},
- {"area", {
- {"type", "full"}
- }}
- },
- {
- {"role", "MediaPlayer|Radio|Phone|Navigation|HVAC|Settings|Dashboard|POI|Mixer"},
- {"name", "apps"},
- {"layer_id", 1001},
- {"area", {
- {"type", "rect"},
- {"rect", {
- {"x", 0},
- {"y", 218},
- {"width", -1},
- {"height", -433}
- }}
- }}
- },
- {
- {"role", "^OnScreen.*"},
- {"name", "popups"},
- {"layer_id", 9999},
- {"area", {
- {"type", "rect"},
- {"rect", {
- {"x", 0},
- {"y", 760},
- {"width", -1},
- {"height", 400}
- }}
- }}
- }
- }}
-};
} // namespace wm
-#endif // WM_LAYERS_H
+#endif // WM_LAYER_HPP
diff --git a/src/wm_layer_control.cpp b/src/wm_layer_control.cpp
new file mode 100644
index 0000000..951c840
--- /dev/null
+++ b/src/wm_layer_control.cpp
@@ -0,0 +1,594 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <assert.h>
+#include <unistd.h>
+#include "wm_layer_control.hpp"
+#include "wm_layer.hpp"
+#include "wm_client.hpp"
+#include "request.hpp"
+#include "json_helper.hpp"
+
+#define LC_AREA_PATH "/etc/areas.db"
+#define LC_LAYER_SETTING_PATH "/etc/layers.json"
+#define LC_DEFAULT_AREA "fullscreen"
+#define BACK_GROUND_LAYER "BackGroundLayer"
+
+using std::string;
+using std::vector;
+using std::shared_ptr;
+
+namespace wm {
+
+LayerControl* g_lc_ctxt;
+
+static void createCallback_static(ilmObjectType object,
+ t_ilm_uint id,
+ t_ilm_bool created,
+ void* data)
+{
+ static_cast<LayerControl*>(data)->dispatchCreateEvent(object, id, created);
+}
+
+static void surfaceCallback_static(t_ilm_surface surface,
+ struct ilmSurfaceProperties* surface_prop,
+ t_ilm_notification_mask mask)
+{
+ g_lc_ctxt->dispatchSurfacePropChangeEvent(surface, surface_prop, mask);
+}
+
+static void layerCallback_static(t_ilm_layer layer,
+ struct ilmLayerProperties* layer_prop,
+ t_ilm_notification_mask mask)
+{
+ g_lc_ctxt->dispatchLayerPropChangeEvent(layer, layer_prop, mask);
+}
+
+LayerControl::LayerControl(const std::string& root)
+{
+ string area_path = root + LC_AREA_PATH;
+ string layer_path= root + LC_LAYER_SETTING_PATH;
+ // load layers.setting.json
+ WMError ret = this->loadLayerSetting(layer_path);
+ assert(ret == WMError::SUCCESS);
+ // load areas.json
+ ret = this->loadAreaDb(area_path);
+ assert(ret == WMError::SUCCESS);
+}
+
+WMError LayerControl::init(const LayerControlCallbacks& cb)
+{
+ HMI_DEBUG("Initialize of ilm library and display");
+ t_ilm_uint num = 0;
+ t_ilm_uint *ids;
+ int cnt = 0;
+ ilmErrorTypes rc = ilm_init();
+
+ while (rc != ILM_SUCCESS)
+ {
+ cnt++;
+ if (20 <= cnt)
+ {
+ HMI_ERROR("Could not connect to compositor");
+ goto lc_init_error;
+ }
+ HMI_ERROR("Wait to start weston ...");
+ sleep(1);
+ rc = ilm_init();
+ }
+ if(rc != ILM_SUCCESS) goto lc_init_error;
+
+ // Get current screen setting
+ rc = ilm_getScreenIDs(&num, &ids);
+
+ if(rc != ILM_SUCCESS) goto lc_init_error;
+
+ for(unsigned i = 0; i < num; i++)
+ {
+ HMI_INFO("get screen: %d", ids[i]);
+ }
+ // Currently, 0 is only available
+ this->screenID = ids[0];
+
+ rc = ilm_getPropertiesOfScreen(this->screenID, &this->screen_prop);
+
+ if(rc != ILM_SUCCESS) goto lc_init_error;
+
+ // Register Callback to Window Manager and from ILM
+ this->cb = cb;
+ ilm_registerNotification(createCallback_static, this);
+
+ return WMError::SUCCESS;
+
+lc_init_error:
+ HMI_ERROR("Failed to initialize. Terminate WM");
+
+ return WMError::FAIL;
+}
+
+unsigned LayerControl::getLayerID(const string& role)
+{
+ unsigned ret = 0;
+ for(const auto& l: this->wm_layers)
+ {
+ if(l->hasRole(role))
+ {
+ ret = l->layerID();
+ }
+ }
+ return ret;
+}
+
+void LayerControl::addSurface(unsigned surface, unsigned layer)
+{
+ ilm_layerAddSurface(layer, surface);
+ ilm_commitChanges();
+}
+
+void LayerControl::createLayers()
+{
+ for(const auto &layer : this->wm_layers)
+ {
+ unsigned id = layer->layerID();
+ HMI_INFO("create new ID :%d", id);
+ struct rect rct = this->area2size[LC_DEFAULT_AREA];
+ ilm_layerCreateWithDimension(&id, rct.w, rct.h);
+ //ilm_layerSetSourceRectangle(id, rct.x, rct.y, rct.w, rct.h);
+ ilm_layerSetDestinationRectangle(id, this->offset_x, this->offset_y, rct.w, rct.h);
+ ilm_layerSetOpacity(id, 1.0);
+ ilm_layerSetVisibility(id, ILM_TRUE);
+ ilm_commitChanges();
+ /* auto wm_layer = getWMLayer(id);
+ wm_layer->addLayerToState(id); */
+ }
+ this->renderLayers();
+}
+
+shared_ptr<WMLayer> LayerControl::getWMLayer(unsigned layer)
+{
+ unsigned uuid = this->lid2wmlid[layer];
+ return this->wm_layers[uuid];
+}
+
+std::shared_ptr<WMLayer> LayerControl::getWMLayer(std::string layer_name)
+{
+ for(auto &l : this->wm_layers)
+ {
+ if(l->layerName() == layer_name)
+ {
+ return l;
+ }
+ }
+ return nullptr;
+}
+
+struct rect LayerControl::getAreaSize(const std::string& area)
+{
+ return area2size[area];
+}
+
+void LayerControl::setupArea(const rectangle& base_rct, double scaling)
+{
+ this->scaling = scaling;
+ this->offset_x = base_rct.left();
+ this->offset_y = base_rct.top();
+
+ for (auto &i : this->area2size)
+ {
+ i.second.x = static_cast<int>(scaling * i.second.x + 0.5);
+ i.second.y = static_cast<int>(scaling * i.second.y + 0.5);
+ i.second.w = static_cast<int>(scaling * i.second.w + 0.5);
+ i.second.h = static_cast<int>(scaling * i.second.h + 0.5);
+
+ HMI_DEBUG("area:%s size(after) : x:%d y:%d w:%d h:%d",
+ i.first.c_str(), i.second.x, i.second.y, i.second.w, i.second.h);
+ }
+}
+
+Screen LayerControl::getScreenInfo()
+{
+ return Screen(this->screen_prop.screenWidth, this->screen_prop.screenHeight);
+}
+
+double LayerControl::scale()
+{
+ return this->scaling;
+}
+
+WMError LayerControl::renderLayers()
+{
+ HMI_INFO("Commit change");
+ WMError rc = WMError::SUCCESS;
+
+ // Create render order
+ t_ilm_layer* id_array = new t_ilm_layer[this->wm_layers.size()];
+ if(id_array == nullptr)
+ {
+ HMI_WARNING("short memory");
+ return WMError::FAIL;
+ }
+ int count = 0;
+ for(const auto& i : this->wm_layers)
+ {
+ id_array[count] = i->layerID();
+ ++count;
+ }
+
+ // Display
+ ilmErrorTypes ret = ilm_displaySetRenderOrder(this->screenID, id_array, this->wm_layers.size());
+ if(ret != ILM_SUCCESS)
+ {
+ rc = WMError::FAIL;
+ }
+ ilm_commitChanges();
+ delete id_array;
+ return rc;
+}
+
+WMError LayerControl::setXDGSurfaceOriginSize(unsigned surface)
+{
+ WMError ret = WMError::NOT_REGISTERED;
+ ilmSurfaceProperties prop;
+ ilmErrorTypes rc = ilm_getPropertiesOfSurface(surface, &prop);
+ if(rc == ILM_SUCCESS)
+ {
+ HMI_INFO("xdg surface info %d, %d", prop.origSourceWidth, prop.origSourceHeight);
+ ilm_surfaceSetSourceRectangle(surface, 0, 0, prop.origSourceWidth, prop.origSourceHeight);
+ ret = WMError::SUCCESS;
+ }
+ return ret;
+}
+
+WMError LayerControl::loadLayerSetting(const string &path)
+{
+ HMI_DEBUG("loading WMLayer(Application Containers) Setting from %s", path);
+
+ json_object *json_obj, *json_cfg;
+ int ret = jh::inputJsonFilie(path.c_str(), &json_obj);
+ if (0 > ret)
+ {
+ HMI_ERROR("Could not open %s", path.c_str());
+ return WMError::FAIL;
+ }
+ HMI_INFO("json_obj dump:%s", json_object_get_string(json_obj));
+
+ if (!json_object_object_get_ex(json_obj, "mappings", &json_cfg))
+ {
+ HMI_ERROR("Parse Error!!");
+ return WMError::FAIL;
+ }
+
+ int len = json_object_array_length(json_cfg);
+ HMI_DEBUG("json_cfg len:%d", len);
+
+ for (int i = 0; i < len; i++)
+ {
+ json_object *json_tmp = json_object_array_get_idx(json_cfg, i);
+ HMI_DEBUG("> json_tmp dump:%s", json_object_get_string(json_tmp));
+
+ this->wm_layers.emplace_back(std::make_shared<WMLayer>(json_tmp));
+ }
+ json_object_put(json_obj);
+
+ return WMError::SUCCESS;
+}
+
+WMError LayerControl::loadAreaDb(const std::string& path)
+{
+ // Load area.db
+ json_object *json_obj;
+ int ret = jh::inputJsonFilie(path.c_str(), &json_obj);
+ if (0 > ret)
+ {
+ HMI_ERROR("Could not open %s", path.c_str());
+ return WMError::FAIL;
+ }
+ HMI_INFO("json_obj dump:%s", json_object_get_string(json_obj));
+
+ // Perse areas
+ json_object *json_cfg;
+ if (!json_object_object_get_ex(json_obj, "areas", &json_cfg))
+ {
+ HMI_ERROR("Parse Error!!");
+ return WMError::FAIL;
+ }
+
+ int len = json_object_array_length(json_cfg);
+ HMI_DEBUG("json_cfg len:%d", len);
+
+ const char *area;
+ for (int i = 0; i < len; i++)
+ {
+ json_object *json_tmp = json_object_array_get_idx(json_cfg, i);
+ HMI_DEBUG("> json_tmp dump:%s", json_object_get_string(json_tmp));
+
+ area = jh::getStringFromJson(json_tmp, "name");
+ if (nullptr == area)
+ {
+ HMI_ERROR("Parse Error!!");
+ return WMError::FAIL;
+ }
+ HMI_DEBUG("> area:%s", area);
+
+ json_object *json_rect;
+ if (!json_object_object_get_ex(json_tmp, "rect", &json_rect))
+ {
+ HMI_ERROR("Parse Error!!");
+ return WMError::FAIL;
+ }
+ HMI_DEBUG("> json_rect dump:%s", json_object_get_string(json_rect));
+
+ struct rect area_size;
+ area_size.x = jh::getIntFromJson(json_rect, "x");
+ area_size.y = jh::getIntFromJson(json_rect, "y");
+ area_size.w = jh::getIntFromJson(json_rect, "w");
+ area_size.h = jh::getIntFromJson(json_rect, "h");
+
+ this->area2size[area] = area_size;
+ }
+
+ // Check
+ for (const auto& itr : this->area2size)
+ {
+ HMI_DEBUG("area:%s x:%d y:%d w:%d h:%d",
+ itr.first.c_str(), itr.second.x, itr.second.y,
+ itr.second.w, itr.second.h);
+ }
+
+ // Release json_object
+ json_object_put(json_obj);
+
+ return WMError::SUCCESS;
+}
+
+WMError LayerControl::layoutChange(const WMAction& action)
+{
+ if (action.visible == TaskVisible::INVISIBLE)
+ {
+ // Visibility is not change -> no redraw is required
+ return WMError::SUCCESS;
+ }
+ if(action.client == nullptr)
+ {
+ HMI_SEQ_ERROR(action.req_num, "client may vanish");
+ return WMError::NOT_REGISTERED;
+ }
+ unsigned surface = action.client->surfaceID(action.role);
+
+ auto rect = this->getAreaSize(action.area);
+ HMI_DEBUG("Set layout %d, %d, %d, %d",rect.x, rect.y, rect.w, rect.h);
+ ilm_commitChanges();
+ ilm_surfaceSetDestinationRectangle(surface, rect.x, rect.y, rect.w, rect.h);
+ ilm_commitChanges();
+
+ return WMError::SUCCESS;
+}
+
+WMError LayerControl::visibilityChange(const WMAction& action)
+{
+ WMError ret = WMError::FAIL;
+ if(action.client == nullptr)
+ {
+ HMI_SEQ_ERROR(action.req_num, "client may vanish");
+ return WMError::NOT_REGISTERED;
+ }
+
+ if (action.visible == TaskVisible::VISIBLE)
+ {
+ ret = this->makeVisible(action.client, action.role);
+ }
+ else if (action.visible == TaskVisible::INVISIBLE)
+ {
+ ret = this->makeInvisible(action.client, action.role);
+ }
+ ilm_commitChanges();
+ return ret;
+}
+
+void LayerControl::dispatchCreateEvent(ilmObjectType object, unsigned id, bool created)
+{
+ if (ILM_SURFACE == object)
+ {
+ if (created)
+ {
+ ilmSurfaceProperties sp;
+ ilmErrorTypes rc;
+ rc = ilm_getPropertiesOfSurface(id, &sp);
+ if(rc != ILM_SUCCESS)
+ {
+ HMI_ERROR("Failed to get surface %d property due to %d", id, ilm_getError());
+ return;
+ }
+ this->cb.surfaceCreated(sp.creatorPid, id);
+ ilm_surfaceAddNotification(id, surfaceCallback_static);
+ ilm_surfaceSetType(id, ILM_SURFACETYPE_DESKTOP);
+ }
+ else
+ {
+ this->cb.surfaceDestroyed(id);
+ }
+ }
+ if (ILM_LAYER == object)
+ {
+ if(created)
+ {
+ ilm_layerAddNotification(id, layerCallback_static);
+ }
+ else
+ {
+ // Ignore here. Nothing to do currently.
+ // Process of application dead is handled by Window Manager
+ // from binder notification
+ }
+ }
+}
+
+void LayerControl::dispatchSurfacePropChangeEvent(unsigned id,
+ struct ilmSurfaceProperties* sprop,
+ t_ilm_notification_mask mask)
+{
+ /*
+ ILM_NOTIFICATION_CONTENT_AVAILABLE & ILM_NOTIFICATION_CONTENT_REMOVED
+ are not handled here, handled in create/destroy event
+ */
+ if (ILM_NOTIFICATION_VISIBILITY & mask)
+ {
+ HMI_DEBUG("surface %d turns visibility %d", id, sprop->visibility);
+ }
+ if (ILM_NOTIFICATION_OPACITY & mask)
+ {
+ HMI_DEBUG("surface %d turns opacity %f", id, sprop->opacity);
+ }
+ if (ILM_NOTIFICATION_SOURCE_RECT & mask)
+ {
+ HMI_DEBUG("surface %d source rect changes", id);
+ }
+ if (ILM_NOTIFICATION_DEST_RECT & mask)
+ {
+ HMI_DEBUG("surface %d dest rect changes", id);
+ }
+ if (ILM_NOTIFICATION_CONFIGURED & mask)
+ {
+ HMI_DEBUG("surface %d size %d, %d, %d, %d", id,
+ sprop->sourceX, sprop->sourceY, sprop->origSourceWidth, sprop->origSourceHeight);
+ ilm_surfaceSetSourceRectangle(id, 0, 0, sprop->origSourceWidth, sprop->origSourceHeight);
+ }
+}
+
+void LayerControl::dispatchLayerPropChangeEvent(unsigned id,
+ struct ilmLayerProperties* lprop,
+ t_ilm_notification_mask mask)
+{
+ if (ILM_NOTIFICATION_VISIBILITY & mask)
+ {
+ HMI_DEBUG("layer %d turns visibility %d", id, lprop->visibility);
+ }
+ if (ILM_NOTIFICATION_OPACITY & mask)
+ {
+ HMI_DEBUG("layer %d turns opacity %f", id, lprop->opacity);
+ }
+ if (ILM_NOTIFICATION_SOURCE_RECT & mask)
+ {
+ HMI_DEBUG("layer %d source rect changes", id);
+ }
+ if (ILM_NOTIFICATION_DEST_RECT & mask)
+ {
+ HMI_DEBUG("layer %d dest rect changes", id);
+ }
+}
+
+WMError LayerControl::makeVisible(const shared_ptr<WMClient> client, const string& role)
+{
+ WMError ret = WMError::SUCCESS;
+ // Don't check here the client is not nullptr
+ unsigned surface = client->surfaceID(role);
+
+ this->moveForeGround(client, role);
+
+ ilm_surfaceSetVisibility(surface, ILM_TRUE);
+
+ return ret;
+}
+
+WMError LayerControl::makeInvisible(const shared_ptr<WMClient> client, const string& role)
+{
+ WMError ret = WMError::SUCCESS;
+ unsigned surface = client->surfaceID(role); // Don't check here the client is not nullptr
+
+ bool mv_ok = this->moveBackGround(client, role);
+
+ if(!mv_ok)
+ {
+ HMI_INFO("make invisible client %s", client->appID().c_str());
+ ilm_surfaceSetVisibility(surface, ILM_FALSE);
+ }
+
+ return ret;
+}
+
+bool LayerControl::moveBackGround(const shared_ptr<WMClient> client, const string& role)
+{
+ bool ret = false;
+ const char* label = role.c_str();
+
+ if ((0 == strcmp(label, "radio")) ||
+ (0 == strcmp(label, "music")) ||
+ (0 == strcmp(label, "video")) ||
+ (0 == strcmp(label, "map")))
+ {
+ unsigned surface = client->surfaceID(role);
+ this->surface_bg.push_back(surface);
+ auto bg = this->getWMLayer(BACK_GROUND_LAYER);
+ auto layer = 0;
+ for(const auto& l : this->wm_layers)
+ {
+ if(l->hasRole(role))
+ {
+ layer = l->layerID();
+ ilm_layerRemoveSurface(layer, surface);
+ ilm_layerAddSurface(bg->layerID(), surface);
+ ret = true;
+ break;
+ }
+ }
+ }
+ ilm_commitChanges();
+ return ret;
+}
+
+bool LayerControl::moveForeGround(const shared_ptr<WMClient> client, const string& role)
+{
+ bool ret = false;
+ const char* label = role.c_str();
+
+ // Move foreground from foreground layer
+ if ((0 == strcmp(label, "radio")) ||
+ (0 == strcmp(label, "music")) ||
+ (0 == strcmp(label, "video")) ||
+ (0 == strcmp(label, "map")))
+ {
+ for (auto i = surface_bg.begin(); i != surface_bg.end(); ++i)
+ {
+ if (client->surfaceID(role) == *i)
+ {
+ // Remove id
+ unsigned surface = *i;
+
+ this->surface_bg.erase(i);
+
+ // Remove from BG layer (999)
+ HMI_DEBUG("wm", "Remove %s(%d) from BG layer", label, surface);
+ auto bg = this->getWMLayer(BACK_GROUND_LAYER);
+ unsigned layer = 0;
+ for(const auto& l : this->wm_layers)
+ {
+ if(l->hasRole(role))
+ {
+ layer = l->layerID();
+ break;
+ }
+ }
+ ilm_layerRemoveSurface(bg->layerID(), surface);
+ ilm_layerAddSurface(layer, surface);
+ ret = true;
+ break;
+ }
+ }
+ }
+ ilm_commitChanges();
+ return ret;
+}
+
+} // namespace wm \ No newline at end of file
diff --git a/src/wm_layer_control.hpp b/src/wm_layer_control.hpp
new file mode 100644
index 0000000..5244bf5
--- /dev/null
+++ b/src/wm_layer_control.hpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <memory>
+#include <vector>
+#include <unordered_map>
+#include <functional>
+#include <ilm/ilm_control.h>
+#include "wm_error.hpp"
+#include "util.hpp"
+
+namespace wm {
+
+class Screen {
+ public:
+ Screen(unsigned w, unsigned h) : _width(w), _height(h){}
+ unsigned width() { return _width; }
+ unsigned height() { return _height; }
+ private:
+ unsigned _width;
+ unsigned _height;
+ unsigned _pysical_width = 0;
+ unsigned _pysical_height = 0;
+};
+
+class LayerControlCallbacks {
+ public:
+ LayerControlCallbacks() {};
+ ~LayerControlCallbacks() = default;
+ LayerControlCallbacks(const LayerControlCallbacks &obj) = default;
+
+ // callback functions
+ std::function<void(unsigned, unsigned)> surfaceCreated;
+ std::function<void(unsigned)> surfaceDestroyed;
+ /*
+ std::function<void(unsigned)> layerCreated;
+ std::function<void(unsigned)> layerDestroyed;
+ */
+};
+
+class WMLayer;
+class LayerState;
+class WMAction;
+class WMClient;
+
+class LayerControl
+{
+ public:
+ explicit LayerControl(const std::string& root);
+ ~LayerControl() = default;
+ WMError init(const LayerControlCallbacks& cb);
+ void createLayers();
+ unsigned getLayerID(const std::string& role);
+ std::shared_ptr<WMLayer> getWMLayer(unsigned layer);
+ std::shared_ptr<WMLayer> getWMLayer(std::string layer_name);
+ struct rect getAreaSize(const std::string& area);
+ void setupArea(const rectangle& base_rct, double scaling);
+ Screen getScreenInfo();
+ double scale();
+ WMError renderLayers();
+ WMError setXDGSurfaceOriginSize(unsigned surface);
+ WMError layoutChange(const WMAction& action);
+ WMError visibilityChange(const WMAction &action);
+ void addSurface(unsigned surface, unsigned layer);
+
+ // Don't use this function.
+ void dispatchCreateEvent(ilmObjectType object, unsigned id, bool created);
+ void dispatchSurfacePropChangeEvent(unsigned id, struct ilmSurfaceProperties*, t_ilm_notification_mask);
+ void dispatchLayerPropChangeEvent(unsigned id, struct ilmLayerProperties*, t_ilm_notification_mask);
+
+ private:
+ WMError makeVisible(const std::shared_ptr<WMClient> client, const std::string& role);
+ WMError makeInvisible(const std::shared_ptr<WMClient> client, const std::string& role);
+ bool moveForeGround(const std::shared_ptr<WMClient> client, const std::string& role);
+ bool moveBackGround(const std::shared_ptr<WMClient> client, const std::string& role);
+ WMError loadLayerSetting(const std::string& path);
+ WMError loadAreaDb(const std::string& path);
+
+ std::vector<unsigned> surface_bg; // For CES demo
+ std::vector<std::shared_ptr<WMLayer>> wm_layers;
+ std::unordered_map<unsigned, unsigned> lid2wmlid;
+ std::unordered_map<std::string, struct rect> area2size;
+ unsigned screenID;
+ struct ilmScreenProperties screen_prop;
+ double scaling;
+ int offset_x;
+ int offset_y;
+ LayerControlCallbacks cb;
+};
+
+} // namespace wm \ No newline at end of file