481afbc511648c50389398baa383c803857077a4
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / platform / sdl / mir_display_connection.cpp
1 /*
2  * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
3  *
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.
7  *
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.
12  *
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/>.
15  *
16  */
17 #include "anbox/platform/sdlmir_display_connection.h"
18 #include "anbox/logger.h"
19
20 #include <boost/throw_exception.hpp>
21
22 #include <stdexcept>
23 #include <string>
24
25 namespace {
26 static const MirDisplayOutput *find_active_output(
27     const MirDisplayConfiguration *conf) {
28   const MirDisplayOutput *output = NULL;
29   int d;
30
31   for (d = 0; d < (int)conf->num_outputs; d++) {
32     const MirDisplayOutput *out = conf->outputs + d;
33
34     if (out->used && out->connected && out->num_modes &&
35         out->current_mode < out->num_modes) {
36       output = out;
37       break;
38     }
39   }
40
41   return output;
42 }
43 }
44
45 namespace anbox {
46 namespace sdl {
47 MirDisplayConnection::MirDisplayConnection()
48     : connection_(nullptr),
49       output_id_(-1),
50       vertical_resolution_(0),
51       horizontal_resolution_(0) {
52   auto xdg_runtime_dir = ::getenv("XDG_RUNTIME_DIR");
53   if (!xdg_runtime_dir)
54     BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find XDG_RUNTIME_DIR"));
55
56   std::string socket_path = xdg_runtime_dir;
57   socket_path += "/mir_socket";
58
59   connection_ = mir_connect_sync(socket_path.c_str(), "anbox");
60   if (!mir_connection_is_valid(connection_)) {
61     std::string msg;
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()));
65   }
66
67   mir_connection_set_display_config_change_callback(
68       connection_,
69       [](MirConnection *connection, void *context) {
70         auto thiz = reinterpret_cast<MirDisplayConnection *>(context);
71         DEBUG("");
72       },
73       this);
74
75   MirDisplayConfiguration *display_config =
76       mir_connection_create_display_config(connection_);
77
78   const MirDisplayOutput *output = find_active_output(display_config);
79   if (!output)
80     BOOST_THROW_EXCEPTION(
81         std::runtime_error("Failed to find active output display"));
82
83   DEBUG("Selecting output id %d", output->output_id);
84
85   output_id_ = output->output_id;
86
87   const MirDisplayMode *mode = &output->modes[output->current_mode];
88
89   vertical_resolution_ = mode->vertical_resolution;
90   horizontal_resolution_ = mode->horizontal_resolution;
91
92   mir_display_config_destroy(display_config);
93 }
94
95 MirDisplayConnection::~MirDisplayConnection() {
96   mir_connection_release(connection_);
97 }
98
99 MirConnection *MirDisplayConnection::connection() const { return connection_; }
100
101 MirPixelFormat MirDisplayConnection::default_pixel_format() const {
102   MirPixelFormat format;
103   unsigned int nformats;
104   mir_connection_get_available_surface_formats(connection_, &format, 1,
105                                                &nformats);
106   return format;
107 }
108
109 EGLNativeDisplayType MirDisplayConnection::native_display() const {
110   return mir_connection_get_egl_native_display(connection_);
111 }
112
113 int MirDisplayConnection::output_id() const { return output_id_; }
114
115 int MirDisplayConnection::vertical_resolution() const {
116   return vertical_resolution_;
117 }
118
119 int MirDisplayConnection::horizontal_resolution() const {
120   return horizontal_resolution_;
121 }
122 }  // namespace sdl
123 }  // namespace anbox