TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / src / anbox / ui / splash_screen.cpp
1 /*
2  * Copyright (C) 2017 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
18 #include "anbox/ui/splash_screen.h"
19 #include "anbox/system_configuration.h"
20 #include "anbox/utils.h"
21 #include "anbox/logger.h"
22
23 #include <SDL2/SDL_image.h>
24
25 namespace anbox {
26 namespace ui {
27 SplashScreen::SplashScreen() {
28 #ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
29   // Don't disable compositing
30   // Available since SDL 2.0.8
31   SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
32 #endif
33
34   if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) {
35     const auto message = utils::string_format("Failed to initialize SDL: %s", SDL_GetError());
36     BOOST_THROW_EXCEPTION(std::runtime_error(message));
37   }
38
39   const auto width = 1024, height = 768;
40   window_ = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
41                              width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
42   if (!window_) {
43     const auto message = utils::string_format("Failed to create window: %s", SDL_GetError());
44     BOOST_THROW_EXCEPTION(std::runtime_error(message));
45   }
46
47   auto surface = SDL_GetWindowSurface(window_);
48   if (!surface)
49     BOOST_THROW_EXCEPTION(std::runtime_error("Could not retrieve surface for our window"));
50
51   SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 0xee, 0xee, 0xee));
52   SDL_UpdateWindowSurface(window_);
53
54   auto renderer = SDL_GetRenderer(window_);
55   if (!renderer) {
56     DEBUG("Window has no associated renderer yet, creating one ...");
57     renderer = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED);
58     if (!renderer) {
59       const auto msg = utils::string_format("Could not create renderer: %s", SDL_GetError());
60       BOOST_THROW_EXCEPTION(std::runtime_error(msg));
61     }
62   }
63
64   const auto icon_path = utils::string_format("%s/ui/loading-screen.png", SystemConfiguration::instance().resource_dir());
65   auto img = IMG_LoadTexture(renderer, icon_path.c_str());
66   if (!img) {
67     const auto msg = utils::string_format("Failed to create texture from %s", icon_path);
68     BOOST_THROW_EXCEPTION(std::runtime_error(msg));
69   }
70
71   SDL_RenderClear(renderer);
72
73   SDL_Rect r{0, 0, width, height};
74   SDL_RenderCopy(renderer, img, nullptr, &r);
75   SDL_RenderPresent(renderer);
76
77   SDL_ShowWindow(window_);
78
79   event_thread_ = std::thread(&SplashScreen::process_events, this);
80 }
81
82 SplashScreen::~SplashScreen() {
83   if (event_thread_running_) {
84     event_thread_running_ = false;
85     if (event_thread_.joinable())
86       event_thread_.join();
87   }
88
89   if (window_)
90     SDL_DestroyWindow(window_);
91 }
92
93 void SplashScreen::process_events() {
94   event_thread_running_ = true;
95   while (event_thread_running_) {
96     SDL_Event event;
97     while (SDL_WaitEventTimeout(&event, 100)) {
98       // Keep running until we're terminated
99     }
100   }
101 }
102 } // namespace ui
103 } // namespace anbox