Blender V5.0
GHOST_ISystem.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
12
13#include <vector>
14
15#include "GHOST_ISystem.hh"
17
18#if defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
19# include "GHOST_SystemWayland.hh"
20# include "GHOST_SystemX11.hh"
21#elif defined(WITH_GHOST_X11)
22# include "GHOST_SystemX11.hh"
23#elif defined(WITH_GHOST_WAYLAND)
24# include "GHOST_SystemWayland.hh"
25#elif defined(WITH_GHOST_SDL)
26# include "GHOST_SystemSDL.hh"
27#elif defined(WIN32)
28# include "GHOST_SystemWin32.hh"
29#elif defined(__APPLE__)
30# include "GHOST_SystemCocoa.hh"
31#endif
32
33#include "CLG_log.h"
34
35static CLG_LogRef LOG = {"ghost.system"};
36
38const char *GHOST_ISystem::system_backend_id_ = nullptr;
39
41
43
44GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose, [[maybe_unused]] bool background)
45{
46
47 /* When GHOST fails to start, report the back-ends that were attempted.
48 * A Verbose argument could be supported in printing isn't always desired. */
49 struct GHOST_BackendInfo {
50 const char *id = nullptr;
52 std::string failure_msg;
53 };
54 std::vector<GHOST_BackendInfo> backends_attempted;
55
56 GHOST_TSuccess success;
57 if (!system_) {
58#if defined(WITH_HEADLESS)
59 /* Pass. */
60#elif defined(WITH_GHOST_WAYLAND)
61# if defined(WITH_GHOST_WAYLAND_DYNLOAD)
62 /* Even if other systems support `--no-window-frame`, it's likely only WAYLAND
63 * needs to configure this when creating the system (based on LIBDECOR usage). */
64 const bool has_wayland_libraries = ghost_wl_dynload_libraries_init(
66# else
67 const bool has_wayland_libraries = true;
68# endif
69#endif
70
71#if defined(WITH_HEADLESS)
72 /* Pass. */
73#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
74 /* Special case, try Wayland, fall back to X11. */
75 if (has_wayland_libraries) {
76 backends_attempted.push_back({"WAYLAND"});
77 try {
78 CLOG_INFO(&LOG, "Create Wayland system");
79 system_ = new GHOST_SystemWayland(background);
80 }
81 catch (const std::runtime_error &e) {
82 if (verbose) {
83 backends_attempted.back().failure_msg = e.what();
84 }
85 CLOG_INFO(&LOG, "Wayland system not created, falling back to X11");
86 delete system_;
87 system_ = nullptr;
88# ifdef WITH_GHOST_WAYLAND_DYNLOAD
89 ghost_wl_dynload_libraries_exit();
90# endif
91 }
92 }
93 else {
94 system_ = nullptr;
95 }
96
97 if (!system_) {
98 /* Try to fall back to X11. */
99 backends_attempted.push_back({"X11"});
100 try {
101 CLOG_INFO(&LOG, "Create X11 system");
102 system_ = new GHOST_SystemX11();
103 }
104 catch (const std::runtime_error &e) {
105 if (verbose) {
106 backends_attempted.back().failure_msg = e.what();
107 }
108 delete system_;
109 system_ = nullptr;
110 }
111 }
112#elif defined(WITH_GHOST_X11)
113 backends_attempted.push_back({"X11"});
114 try {
115 CLOG_INFO(&LOG, "Create X11 system");
116 system_ = new GHOST_SystemX11();
117 }
118 catch (const std::runtime_error &e) {
119 if (verbose) {
120 backends_attempted.back().failure_msg = e.what();
121 }
122 delete system_;
123 system_ = nullptr;
124 }
125#elif defined(WITH_GHOST_WAYLAND)
126 if (has_wayland_libraries) {
127 backends_attempted.push_back({"WAYLAND"});
128 try {
129 CLOG_INFO(&LOG, "Create Wayland system");
130 system_ = new GHOST_SystemWayland(background);
131 }
132 catch (const std::runtime_error &e) {
133 if (verbose) {
134 backends_attempted.back().failure_msg = e.what();
135 }
136 delete system_;
137 system_ = nullptr;
138# ifdef WITH_GHOST_WAYLAND_DYNLOAD
139 ghost_wl_dynload_libraries_exit();
140# endif
141 }
142 }
143 else {
144 system_ = nullptr;
145 }
146#elif defined(WITH_GHOST_SDL)
147 backends_attempted.push_back({"SDL"});
148 try {
149 CLOG_INFO(&LOG, "Create SDL system");
150 system_ = new GHOST_SystemSDL();
151 }
152 catch (const std::runtime_error &e) {
153 if (verbose) {
154 backends_attempted.back().failure_msg = e.what();
155 }
156 delete system_;
157 system_ = nullptr;
158 }
159#elif defined(WIN32)
160 backends_attempted.push_back({"WIN32"});
161 CLOG_INFO(&LOG, "Create Windows system");
163#elif defined(__APPLE__)
164 backends_attempted.push_back({"COCOA"});
165 CLOG_INFO(&LOG, "Create Cocoa system");
167#endif
168
169 if (system_) {
170 system_backend_id_ = backends_attempted.back().id;
171 }
172 else if (verbose || CLOG_CHECK(&LOG, CLG_LEVEL_INFO)) {
173 bool show_messages = false;
174 std::string msg = "Failed to initialize display for back-end(s): [";
175 for (int i = 0; i < backends_attempted.size(); i++) {
176 const GHOST_BackendInfo &backend_item = backends_attempted[i];
177 if (i != 0) {
178 msg += ", ";
179 }
180 msg += "'" + std::string(backend_item.id) + "'";
181 if (!backend_item.failure_msg.empty()) {
182 show_messages = true;
183 }
184 }
185 msg += "]\n";
186 if (show_messages) {
187 for (int i = 0; i < backends_attempted.size(); i++) {
188 const GHOST_BackendInfo &backend_item = backends_attempted[i];
189 msg += " '";
190 msg += backend_item.id;
191 msg += "': ";
192 msg += backend_item.failure_msg.empty() ? "<unknown>" : backend_item.failure_msg.c_str();
193 msg += "\n";
194 }
195 }
196 CLOG_STR_INFO_NOCHECK(&LOG, msg.c_str());
197 }
198 success = system_ != nullptr ? GHOST_kSuccess : GHOST_kFailure;
199 }
200 else {
201 success = GHOST_kFailure;
202 }
203 if (success) {
204 success = system_->init();
205 }
206 return success;
207}
208
210{
211 GHOST_TSuccess success;
212 if (!system_) {
213#if !defined(WITH_HEADLESS)
214 /* Try to create a off-screen render surface with the graphical systems. */
215 CLOG_INFO(&LOG, "Create background system");
216 success = createSystem(false, true);
217 if (success) {
218 return success;
219 }
220 /* Try to fall back to headless mode if all else fails. */
221#endif
222 CLOG_INFO(&LOG, "Create headless system");
224 success = system_ != nullptr ? GHOST_kSuccess : GHOST_kFailure;
225 }
226 else {
227 success = GHOST_kFailure;
228 }
229 if (success) {
230 success = system_->init();
231 }
232 return success;
233}
234
236{
237 CLOG_DEBUG(&LOG, "Dispose system");
239 if (system_) {
240 delete system_;
241 system_ = nullptr;
242 }
243 else {
244 success = GHOST_kFailure;
245 }
246 return success;
247}
248
253
255{
256 return system_backend_id_;
257}
258
263
268
273
274void GHOST_ISystem::setUseWindowFrame(bool use_window_frame)
275{
276 GHOST_ISystem::use_window_frame_ = use_window_frame;
277}
#define CLOG_DEBUG(clg_ref,...)
Definition CLG_log.h:191
#define CLOG_STR_INFO_NOCHECK(clg_ref, str)
Definition CLG_log.h:206
#define CLOG_CHECK(clg_ref, verbose_level,...)
Definition CLG_log.h:147
@ CLG_LEVEL_INFO
Definition CLG_log.h:60
#define CLOG_INFO(clg_ref,...)
Definition CLG_log.h:190
GHOST_TSuccess
Definition GHOST_Types.h:57
@ GHOST_kFailure
Definition GHOST_Types.h:57
@ GHOST_kSuccess
Definition GHOST_Types.h:57
void(* GHOST_TBacktraceFn)(void *file_handle)
Definition GHOST_Types.h:53
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static int verbose
Definition cineonlib.cc:30
static GHOST_TBacktraceFn backtrace_fn_
static GHOST_ISystem * getSystem()
static void setUseWindowFrame(bool use_window_frame)
static GHOST_TBacktraceFn getBacktraceFn()
static void setBacktraceFn(GHOST_TBacktraceFn backtrace_fn)
static GHOST_ISystem * system_
static const char * system_backend_id_
static bool use_window_frame_
static GHOST_TSuccess createSystem(bool verbose, bool background)
static GHOST_TSuccess disposeSystem()
static bool getUseWindowFrame()
static const char * getSystemBackend()
static GHOST_TSuccess createSystemBackground()
#define LOG(level)
Definition log.h:97
i
Definition text_draw.cc:230