~ubuntu-branches/ubuntu/wily/mir/wily-proposed

« back to all changes in this revision

Viewing changes to src/client/mir_blob.cpp

  • Committer: Package Import Robot
  • Author(s): Alexandros Frantzis
  • Date: 2015-10-08 16:12:19 UTC
  • mto: This revision was merged to the branch mainline in revision 109.
  • Revision ID: package-import@ubuntu.com-20151008161219-emk4a1ys51yy0wjb
Tags: upstream-0.17.0+15.10.20151008.2
Import upstream version 0.17.0+15.10.20151008.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2015 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU Lesser General Public License version 3,
 
6
 * as published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU Lesser General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by: Alan Griffiths <alan@octopull.co.uk>
 
17
 */
 
18
 
 
19
#include "mir_toolkit/mir_blob.h"
 
20
#include "mir_protobuf.pb.h"
 
21
 
 
22
#include "mir/uncaught.h"
 
23
 
 
24
namespace mp = mir::protobuf;
 
25
 
 
26
struct MirBlob
 
27
{
 
28
    virtual size_t size() const = 0;
 
29
    virtual void const* data() const = 0;
 
30
 
 
31
    virtual ~MirBlob() = default;
 
32
};
 
33
 
 
34
namespace
 
35
{
 
36
struct MirManagedBlob : MirBlob
 
37
{
 
38
 
 
39
    size_t size() const override { return size_; }
 
40
    void const* data() const override { return  data_; }
 
41
    google::protobuf::uint8* data() { return data_; }
 
42
 
 
43
    size_t const size_;
 
44
    google::protobuf::uint8*  const data_;
 
45
 
 
46
    MirManagedBlob(size_t const size) : size_{size}, data_{new google::protobuf::uint8[size]} {}
 
47
    ~MirManagedBlob() { delete[] data_; }
 
48
};
 
49
 
 
50
struct MirUnmanagedBlob : MirBlob
 
51
{
 
52
    size_t size() const override { return size_; }
 
53
    void const* data() const override { return  data_; }
 
54
 
 
55
    size_t const size_;
 
56
    void const* const data_;
 
57
 
 
58
    MirUnmanagedBlob(size_t const size, void const* data) : size_{size}, data_{data} {}
 
59
};
 
60
}
 
61
 
 
62
 
 
63
MirBlob* mir_blob_from_display_configuration(MirDisplayConfiguration* configuration)
 
64
try
 
65
{
 
66
    mp::DisplayConfiguration protobuf_config;
 
67
 
 
68
    for (auto const* card = configuration->cards; card != configuration->cards+configuration->num_cards; ++card)
 
69
    {
 
70
        auto protobuf_card = protobuf_config.add_display_card();
 
71
        protobuf_card->set_card_id(card->card_id);
 
72
        protobuf_card->set_max_simultaneous_outputs(card->max_simultaneous_outputs);
 
73
    }
 
74
 
 
75
    for (auto const* output = configuration->outputs;
 
76
         output != configuration->outputs+configuration->num_outputs;
 
77
         ++output)
 
78
    {
 
79
        auto protobuf_output = protobuf_config.add_display_output();
 
80
 
 
81
        protobuf_output->set_output_id(output->output_id);
 
82
        protobuf_output->set_card_id(output->card_id);
 
83
        protobuf_output->set_type(output->type);
 
84
 
 
85
        for (auto const* format = output->output_formats;
 
86
             format != output->output_formats+output->num_output_formats;
 
87
             ++format)
 
88
        {
 
89
            protobuf_output->add_pixel_format(*format);
 
90
        }
 
91
 
 
92
        for (auto const* mode = output->modes;
 
93
             mode != output->modes+output->num_modes;
 
94
             ++mode)
 
95
        {
 
96
            auto protobuf_output_mode = protobuf_output->add_mode();
 
97
            protobuf_output_mode->set_horizontal_resolution(mode->horizontal_resolution);
 
98
            protobuf_output_mode->set_vertical_resolution(mode->vertical_resolution);
 
99
            protobuf_output_mode->set_refresh_rate(mode->refresh_rate);
 
100
        }
 
101
 
 
102
        protobuf_output->set_preferred_mode(output->preferred_mode);
 
103
 
 
104
        protobuf_output->set_physical_width_mm(output->physical_width_mm);
 
105
        protobuf_output->set_physical_height_mm(output->physical_height_mm);
 
106
 
 
107
        protobuf_output->set_connected(output->connected);
 
108
        protobuf_output->set_used(output->used);
 
109
        protobuf_output->set_position_x(output->position_x);
 
110
        protobuf_output->set_position_y(output->position_y);
 
111
        protobuf_output->set_current_mode(output->current_mode);
 
112
        protobuf_output->set_current_format(output->current_format);
 
113
        protobuf_output->set_power_mode(output->power_mode);
 
114
        protobuf_output->set_orientation(output->orientation);
 
115
    }
 
116
 
 
117
    auto blob = std::make_unique<MirManagedBlob>(static_cast<size_t>(protobuf_config.ByteSize()));
 
118
 
 
119
    protobuf_config.SerializeWithCachedSizesToArray(blob->data());
 
120
 
 
121
    return blob.release();
 
122
}
 
123
catch (std::exception const& x)
 
124
{
 
125
    MIR_LOG_UNCAUGHT_EXCEPTION(x);
 
126
    return nullptr;
 
127
}
 
128
 
 
129
MirBlob* mir_blob_onto_buffer(void const* buffer, size_t buffer_size)
 
130
try
 
131
{
 
132
    return new MirUnmanagedBlob{buffer_size, buffer};
 
133
}
 
134
catch (std::exception const& x)
 
135
{
 
136
    MIR_LOG_UNCAUGHT_EXCEPTION(x);
 
137
    return nullptr;
 
138
}
 
139
 
 
140
MirDisplayConfiguration* mir_blob_to_display_configuration(MirBlob* blob)
 
141
try
 
142
{
 
143
    mp::DisplayConfiguration protobuf_config;
 
144
 
 
145
    protobuf_config.ParseFromArray(mir_blob_data(blob), mir_blob_size(blob));
 
146
 
 
147
    auto new_config = new MirDisplayConfiguration;
 
148
 
 
149
    new_config->num_cards = protobuf_config.display_card_size();
 
150
    new_config->cards = new MirDisplayCard[new_config->num_cards];
 
151
 
 
152
    for (auto i = 0u; i != new_config->num_cards; ++i)
 
153
    {
 
154
        auto const& protobuf_card = protobuf_config.display_card(i);
 
155
        auto& card = new_config->cards[i];
 
156
        card.card_id = protobuf_card.card_id();
 
157
        card.max_simultaneous_outputs = protobuf_card.max_simultaneous_outputs();
 
158
    }
 
159
 
 
160
    new_config->num_outputs = protobuf_config.display_output_size();
 
161
    new_config->outputs = new MirDisplayOutput[new_config->num_outputs];
 
162
 
 
163
    for (auto i = 0u; i != new_config->num_outputs; ++i)
 
164
    {
 
165
        auto const& protobuf_output = protobuf_config.display_output(i);
 
166
        auto& output = new_config->outputs[i];
 
167
 
 
168
        output.output_id = protobuf_output.output_id();
 
169
        output.card_id = protobuf_output.card_id();
 
170
        output.type = static_cast<MirDisplayOutputType>(protobuf_output.type());
 
171
 
 
172
        output.num_output_formats = protobuf_output.pixel_format_size();
 
173
        output.output_formats = new MirPixelFormat[output.num_output_formats];
 
174
 
 
175
        output.num_modes = protobuf_output.mode_size();
 
176
        output.modes = new MirDisplayMode[output.num_modes];
 
177
 
 
178
        for (auto i = 0u; i != output.num_output_formats; ++i)
 
179
        {
 
180
            output.output_formats[i] = static_cast<MirPixelFormat>(protobuf_output.pixel_format(i));
 
181
        }
 
182
 
 
183
        for (auto i = 0u; i != output.num_modes; ++i)
 
184
        {
 
185
            auto const& protobuf_mode = protobuf_output.mode(i);
 
186
            auto& mode = output.modes[i];
 
187
 
 
188
            mode.horizontal_resolution = protobuf_mode.horizontal_resolution();
 
189
            mode.vertical_resolution = protobuf_mode.vertical_resolution();
 
190
            mode.refresh_rate = protobuf_mode.refresh_rate();
 
191
        }
 
192
 
 
193
        output.preferred_mode = protobuf_output.preferred_mode();
 
194
 
 
195
        output.physical_width_mm = protobuf_output.physical_width_mm();
 
196
        output.physical_height_mm = protobuf_output.physical_height_mm();
 
197
 
 
198
        output.connected = protobuf_output.connected();
 
199
        output.used = protobuf_output.used();
 
200
        output.position_x = protobuf_output.position_x();
 
201
        output.position_y = protobuf_output.position_y();
 
202
        output.current_mode = protobuf_output.current_mode();
 
203
        output.current_format = static_cast<MirPixelFormat>(protobuf_output.current_format());
 
204
        output.orientation = static_cast<MirOrientation>(protobuf_output.orientation());
 
205
        output.power_mode = static_cast<MirPowerMode>(protobuf_output.power_mode());
 
206
    }
 
207
 
 
208
    return new_config;
 
209
}
 
210
catch (std::exception const& x)
 
211
{
 
212
    MIR_LOG_UNCAUGHT_EXCEPTION(x);
 
213
    abort();
 
214
}
 
215
 
 
216
size_t mir_blob_size(MirBlob* blob)
 
217
{
 
218
    return blob->size();
 
219
}
 
220
 
 
221
void const* mir_blob_data(MirBlob* blob)
 
222
{
 
223
    return blob->data();
 
224
}
 
225
 
 
226
void mir_blob_release(MirBlob* blob)
 
227
{
 
228
    delete blob;
 
229
}