aboutsummaryrefslogtreecommitdiffstats
path: root/src/layers.hpp
blob: c384895aa2bb3e0ccb01877730e5a1a2f0499363 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*
 * 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_LAYERS_H
#define TMCAGLWM_LAYERS_H

#include <string>

#include "../include/json.hpp"
#include "layout.hpp"
#include "result.hpp"
#include "wayland_ivi_wm.hpp"

namespace wm
{

struct split_layout
{
    std::string name;
    std::string main_match;
    std::string sub_match;
};

struct layer
{
    using json = nlohmann::json;

    // A more or less descriptive name?
    std::string name = "";
    // The actual layer ID
    int layer_id = -1;
    // The rectangular region surfaces are allowed to draw on
    // this layer, note however, width and hieght of the rect
    // can be negative, in which case they specify that
    // the actual value is computed using MAX + 1 - w
    // That is; allow us to specify dimensions dependent on
    // e.g. screen dimension, w/o knowing the actual screen size.
    compositor::rect rect;
    // Specify a role prefix for surfaces that should be
    // put on this layer.
    std::string role;
    // TODO: perhaps a zorder is needed here?
    std::vector<struct split_layout> layouts;

    mutable struct LayoutState state;

    // Flag of normal layout only
    bool is_normal_layout_only;

    explicit layer(nlohmann::json const &j);

    json to_json() const;
};

/*
 * WMLayer is the logical container of application/system application(such like HomeScreen)
 * This is handled by Window Manager to classify the application.
 */
class WMLayer
{
  public:
    enum MANAGEMENT_TYPE
    {
        TILE,
        STACK
    };

    explicit WMLayer(const std::string& name, MANAGEMENT_TYPE type, unsigned begin, unsigned end);
    virtual ~WMLayer();

    const std::string& layerName();
    MANAGEMENT_TYPE layerType();
    void appendRole(const std::string& name);
    void appendArea(const std::string& area);

/*     unsigned getNewID(const std::string& role);
    void remove(unsigned ivi_layer_id);
    void clear();
    bool attach(unsigned ivi_layer_id, const std::string& area);
    void stack(unsigned ivi_layer_id, const std::string& area);
    bool updateRenderOrder(const std::vector<unsigned> list); */

  private:
    std::string _name = ""; // Layer name
    MANAGEMENT_TYPE _type;
    std::vector<std::string> _roles;
    unsigned _id_begin;
    unsigned _id_end;
    // current holding apps. This dynamically changes.
    std::vector<unsigned> _ivi_layer_id_list;
    // std::map<std::string, unsigned> _render_order;
};

class LayerManager
{
  public:
    void setRenderOrder(const std::vector<unsigned> layer_render_order);
    std::vector<unsigned> getAllRenderOrder();
    std::vector<std::shared_ptr<WMLayer>>& getAllLayers();
    std::vector<unsigned> getRenderOrder(const std::string& layer_name);
};

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;
    compositor::rect getAreaSize(const std::string &area);
    const compositor::rect getScaleDestRect(int output_w, int output_h, const std::string &aspect_setting);
    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 // TMCAGLWM_LAYERS_H