~alan-griffiths/miral/pre_init-CommandLineOption

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
/*
 * Copyright © 2017 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 or 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authored by: Alan Griffiths <alan@octopull.co.uk>
 */

#include "display_configuration_listeners.h"

#include "miral/active_outputs.h"

#include <mir/graphics/display_configuration.h>

#include <algorithm>

void miral::DisplayConfigurationListeners::add_listener(ActiveOutputsListener* listener)
{
    std::lock_guard<decltype(mutex)> lock{mutex};
    active_output_listeners.push_back(listener);
}

void miral::DisplayConfigurationListeners::delete_listener(ActiveOutputsListener* listener)
{
    std::lock_guard<decltype(mutex)> lock{mutex};

    auto const new_end = std::remove(active_output_listeners.begin(), active_output_listeners.end(), listener);
    active_output_listeners.erase(new_end, active_output_listeners.end());
}

void miral::DisplayConfigurationListeners::process_active_outputs(
    std::function<void(std::vector<Output> const& outputs)> const& functor) const
{
    std::lock_guard<decltype(mutex)> lock{mutex};
    functor(active_outputs);
}

void miral::DisplayConfigurationListeners::initial_configuration(std::shared_ptr<mir::graphics::DisplayConfiguration const> const& configuration)
{
    configuration_applied(configuration);
}

void miral::DisplayConfigurationListeners::configuration_failed(
    std::shared_ptr<mir::graphics::DisplayConfiguration const> const&,
    std::exception const&)
{
}

void miral::DisplayConfigurationListeners::catastrophic_configuration_error(
    std::shared_ptr<mir::graphics::DisplayConfiguration const> const&,
    std::exception const&)
{
}

void miral::DisplayConfigurationListeners::base_configuration_updated(std::shared_ptr<mir::graphics::DisplayConfiguration const> const& ) {}

void miral::DisplayConfigurationListeners::session_configuration_applied(std::shared_ptr<mir::frontend::Session> const&,
                                   std::shared_ptr<mir::graphics::DisplayConfiguration> const&) {}

void miral::DisplayConfigurationListeners::session_configuration_removed(std::shared_ptr<mir::frontend::Session> const&) {}

void miral::DisplayConfigurationListeners::configuration_applied(std::shared_ptr<mir::graphics::DisplayConfiguration const> const& config)
{
    std::lock_guard<decltype(mutex)> lock{mutex};

    decltype(active_outputs) current_outputs;

    for (auto const l : active_output_listeners)
        l->advise_output_begin();

    config->for_each_output(
        [&current_outputs, this](mir::graphics::DisplayConfigurationOutput const& output)
            {
            Output o{output};

            if (!o.connected() || !o.valid()) return;

            auto op = find_if(
                begin(active_outputs), end(active_outputs), [&](Output const& oo)
                    { return oo.is_same_output(o); });

            if (op == end(active_outputs))
            {
                for (auto const l : active_output_listeners)
                    l->advise_output_create(o);
            }
            else if (!equivalent_display_area(o, *op))
            {
                for (auto const l : active_output_listeners)
                    l->advise_output_update(o, *op);
            }

            current_outputs.push_back(o);
            });

    for (auto const& o : active_outputs)
    {
        auto op = find_if(
            begin(current_outputs), end(current_outputs), [&](Output const& oo)
                { return oo.is_same_output(o); });

        if (op == end(current_outputs))
            for (auto const l : active_output_listeners)
                l->advise_output_delete(o);
    }

    current_outputs.swap(active_outputs);
    for (auto const l : active_output_listeners)
        l->advise_output_end();
}