/* * Copyright (C) 2016 Simon Fels * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 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 warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, 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 . * */ #include "anbox/platform/sdlmir_display_connection.h" #include "anbox/logger.h" #include #include #include namespace { static const MirDisplayOutput *find_active_output( const MirDisplayConfiguration *conf) { const MirDisplayOutput *output = NULL; int d; for (d = 0; d < (int)conf->num_outputs; d++) { const MirDisplayOutput *out = conf->outputs + d; if (out->used && out->connected && out->num_modes && out->current_mode < out->num_modes) { output = out; break; } } return output; } } namespace anbox { namespace sdl { MirDisplayConnection::MirDisplayConnection() : connection_(nullptr), output_id_(-1), vertical_resolution_(0), horizontal_resolution_(0) { auto xdg_runtime_dir = ::getenv("XDG_RUNTIME_DIR"); if (!xdg_runtime_dir) BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find XDG_RUNTIME_DIR")); std::string socket_path = xdg_runtime_dir; socket_path += "/mir_socket"; connection_ = mir_connect_sync(socket_path.c_str(), "anbox"); if (!mir_connection_is_valid(connection_)) { std::string msg; msg += "Failed to connect with Mir server: "; msg += mir_connection_get_error_message(connection_); BOOST_THROW_EXCEPTION(std::runtime_error(msg.c_str())); } mir_connection_set_display_config_change_callback( connection_, [](MirConnection *connection, void *context) { auto thiz = reinterpret_cast(context); DEBUG(""); }, this); MirDisplayConfiguration *display_config = mir_connection_create_display_config(connection_); const MirDisplayOutput *output = find_active_output(display_config); if (!output) BOOST_THROW_EXCEPTION( std::runtime_error("Failed to find active output display")); DEBUG("Selecting output id %d", output->output_id); output_id_ = output->output_id; const MirDisplayMode *mode = &output->modes[output->current_mode]; vertical_resolution_ = mode->vertical_resolution; horizontal_resolution_ = mode->horizontal_resolution; mir_display_config_destroy(display_config); } MirDisplayConnection::~MirDisplayConnection() { mir_connection_release(connection_); } MirConnection *MirDisplayConnection::connection() const { return connection_; } MirPixelFormat MirDisplayConnection::default_pixel_format() const { MirPixelFormat format; unsigned int nformats; mir_connection_get_available_surface_formats(connection_, &format, 1, &nformats); return format; } EGLNativeDisplayType MirDisplayConnection::native_display() const { return mir_connection_get_egl_native_display(connection_); } int MirDisplayConnection::output_id() const { return output_id_; } int MirDisplayConnection::vertical_resolution() const { return vertical_resolution_; } int MirDisplayConnection::horizontal_resolution() const { return horizontal_resolution_; } } // namespace sdl } // namespace anbox