2
* Copyright © 2015 Canonical Ltd.
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.
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.
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/>.
16
* Authored by: Alan Griffiths <alan@octopull.co.uk>
19
#include "mir_toolkit/mir_blob.h"
20
#include "mir_protobuf.pb.h"
22
#include "mir/uncaught.h"
24
namespace mp = mir::protobuf;
28
virtual size_t size() const = 0;
29
virtual void const* data() const = 0;
31
virtual ~MirBlob() = default;
36
struct MirManagedBlob : MirBlob
39
size_t size() const override { return size_; }
40
void const* data() const override { return data_; }
41
google::protobuf::uint8* data() { return data_; }
44
google::protobuf::uint8* const data_;
46
MirManagedBlob(size_t const size) : size_{size}, data_{new google::protobuf::uint8[size]} {}
47
~MirManagedBlob() { delete[] data_; }
50
struct MirUnmanagedBlob : MirBlob
52
size_t size() const override { return size_; }
53
void const* data() const override { return data_; }
56
void const* const data_;
58
MirUnmanagedBlob(size_t const size, void const* data) : size_{size}, data_{data} {}
63
MirBlob* mir_blob_from_display_configuration(MirDisplayConfiguration* configuration)
66
mp::DisplayConfiguration protobuf_config;
68
for (auto const* card = configuration->cards; card != configuration->cards+configuration->num_cards; ++card)
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);
75
for (auto const* output = configuration->outputs;
76
output != configuration->outputs+configuration->num_outputs;
79
auto protobuf_output = protobuf_config.add_display_output();
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);
85
for (auto const* format = output->output_formats;
86
format != output->output_formats+output->num_output_formats;
89
protobuf_output->add_pixel_format(*format);
92
for (auto const* mode = output->modes;
93
mode != output->modes+output->num_modes;
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);
102
protobuf_output->set_preferred_mode(output->preferred_mode);
104
protobuf_output->set_physical_width_mm(output->physical_width_mm);
105
protobuf_output->set_physical_height_mm(output->physical_height_mm);
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);
117
auto blob = std::make_unique<MirManagedBlob>(static_cast<size_t>(protobuf_config.ByteSize()));
119
protobuf_config.SerializeWithCachedSizesToArray(blob->data());
121
return blob.release();
123
catch (std::exception const& x)
125
MIR_LOG_UNCAUGHT_EXCEPTION(x);
129
MirBlob* mir_blob_onto_buffer(void const* buffer, size_t buffer_size)
132
return new MirUnmanagedBlob{buffer_size, buffer};
134
catch (std::exception const& x)
136
MIR_LOG_UNCAUGHT_EXCEPTION(x);
140
MirDisplayConfiguration* mir_blob_to_display_configuration(MirBlob* blob)
143
mp::DisplayConfiguration protobuf_config;
145
protobuf_config.ParseFromArray(mir_blob_data(blob), mir_blob_size(blob));
147
auto new_config = new MirDisplayConfiguration;
149
new_config->num_cards = protobuf_config.display_card_size();
150
new_config->cards = new MirDisplayCard[new_config->num_cards];
152
for (auto i = 0u; i != new_config->num_cards; ++i)
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();
160
new_config->num_outputs = protobuf_config.display_output_size();
161
new_config->outputs = new MirDisplayOutput[new_config->num_outputs];
163
for (auto i = 0u; i != new_config->num_outputs; ++i)
165
auto const& protobuf_output = protobuf_config.display_output(i);
166
auto& output = new_config->outputs[i];
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());
172
output.num_output_formats = protobuf_output.pixel_format_size();
173
output.output_formats = new MirPixelFormat[output.num_output_formats];
175
output.num_modes = protobuf_output.mode_size();
176
output.modes = new MirDisplayMode[output.num_modes];
178
for (auto i = 0u; i != output.num_output_formats; ++i)
180
output.output_formats[i] = static_cast<MirPixelFormat>(protobuf_output.pixel_format(i));
183
for (auto i = 0u; i != output.num_modes; ++i)
185
auto const& protobuf_mode = protobuf_output.mode(i);
186
auto& mode = output.modes[i];
188
mode.horizontal_resolution = protobuf_mode.horizontal_resolution();
189
mode.vertical_resolution = protobuf_mode.vertical_resolution();
190
mode.refresh_rate = protobuf_mode.refresh_rate();
193
output.preferred_mode = protobuf_output.preferred_mode();
195
output.physical_width_mm = protobuf_output.physical_width_mm();
196
output.physical_height_mm = protobuf_output.physical_height_mm();
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());
210
catch (std::exception const& x)
212
MIR_LOG_UNCAUGHT_EXCEPTION(x);
216
size_t mir_blob_size(MirBlob* blob)
221
void const* mir_blob_data(MirBlob* blob)
226
void mir_blob_release(MirBlob* blob)