2 * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "anbox/platform/sdlmir_display_connection.h"
18 #include "anbox/logger.h"
20 #include <boost/throw_exception.hpp>
26 static const MirDisplayOutput *find_active_output(
27 const MirDisplayConfiguration *conf) {
28 const MirDisplayOutput *output = NULL;
31 for (d = 0; d < (int)conf->num_outputs; d++) {
32 const MirDisplayOutput *out = conf->outputs + d;
34 if (out->used && out->connected && out->num_modes &&
35 out->current_mode < out->num_modes) {
47 MirDisplayConnection::MirDisplayConnection()
48 : connection_(nullptr),
50 vertical_resolution_(0),
51 horizontal_resolution_(0) {
52 auto xdg_runtime_dir = ::getenv("XDG_RUNTIME_DIR");
54 BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find XDG_RUNTIME_DIR"));
56 std::string socket_path = xdg_runtime_dir;
57 socket_path += "/mir_socket";
59 connection_ = mir_connect_sync(socket_path.c_str(), "anbox");
60 if (!mir_connection_is_valid(connection_)) {
62 msg += "Failed to connect with Mir server: ";
63 msg += mir_connection_get_error_message(connection_);
64 BOOST_THROW_EXCEPTION(std::runtime_error(msg.c_str()));
67 mir_connection_set_display_config_change_callback(
69 [](MirConnection *connection, void *context) {
70 auto thiz = reinterpret_cast<MirDisplayConnection *>(context);
75 MirDisplayConfiguration *display_config =
76 mir_connection_create_display_config(connection_);
78 const MirDisplayOutput *output = find_active_output(display_config);
80 BOOST_THROW_EXCEPTION(
81 std::runtime_error("Failed to find active output display"));
83 DEBUG("Selecting output id %d", output->output_id);
85 output_id_ = output->output_id;
87 const MirDisplayMode *mode = &output->modes[output->current_mode];
89 vertical_resolution_ = mode->vertical_resolution;
90 horizontal_resolution_ = mode->horizontal_resolution;
92 mir_display_config_destroy(display_config);
95 MirDisplayConnection::~MirDisplayConnection() {
96 mir_connection_release(connection_);
99 MirConnection *MirDisplayConnection::connection() const { return connection_; }
101 MirPixelFormat MirDisplayConnection::default_pixel_format() const {
102 MirPixelFormat format;
103 unsigned int nformats;
104 mir_connection_get_available_surface_formats(connection_, &format, 1,
109 EGLNativeDisplayType MirDisplayConnection::native_display() const {
110 return mir_connection_get_egl_native_display(connection_);
113 int MirDisplayConnection::output_id() const { return output_id_; }
115 int MirDisplayConnection::vertical_resolution() const {
116 return vertical_resolution_;
119 int MirDisplayConnection::horizontal_resolution() const {
120 return horizontal_resolution_;