Welcome to mirror list, hosted at ThFree Co, Russian Federation.

GHOST_ISystem.cpp « intern « ghost « intern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 696848ce6236a3e4b00d6451a3c0af0219f2e211 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2001-2002 NaN Holding BV. All rights reserved. */

/** \file
 * \ingroup GHOST
 */

/**
 * Copyright (C) 2001 NaN Technologies B.V.
 */

#include <stdexcept>

#include "GHOST_ISystem.h"
#include "GHOST_SystemHeadless.h"

#if defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
#  include "GHOST_SystemWayland.h"
#  include "GHOST_SystemX11.h"
#elif defined(WITH_GHOST_X11)
#  include "GHOST_SystemX11.h"
#elif defined(WITH_GHOST_WAYLAND)
#  include "GHOST_SystemWayland.h"
#elif defined(WITH_GHOST_SDL)
#  include "GHOST_SystemSDL.h"
#elif defined(WIN32)
#  include "GHOST_SystemWin32.h"
#elif defined(__APPLE__)
#  include "GHOST_SystemCocoa.h"
#endif

GHOST_ISystem *GHOST_ISystem::m_system = nullptr;
const char *GHOST_ISystem::m_system_backend_id = nullptr;

GHOST_TBacktraceFn GHOST_ISystem::m_backtrace_fn = nullptr;

GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose, [[maybe_unused]] bool background)
{
  /* When GHOST fails to start, report the back-ends that were attempted.
   * A Verbose argument could be supported in printing isn't always desired. */
  const char *backends_attempted[8] = {nullptr};
  int backends_attempted_num = 0;

  GHOST_TSuccess success;
  if (!m_system) {

#if defined(WITH_HEADLESS)
    /* Pass. */
#elif defined(WITH_GHOST_WAYLAND)
#  if defined(WITH_GHOST_WAYLAND_DYNLOAD)
    const bool has_wayland_libraries = ghost_wl_dynload_libraries_init();
#  else
    const bool has_wayland_libraries = true;
#  endif
#endif

#if defined(WITH_HEADLESS)
    /* Pass. */
#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
    /* Special case, try Wayland, fall back to X11. */
    if (has_wayland_libraries) {
      backends_attempted[backends_attempted_num++] = "WAYLAND";
      try {
        m_system = new GHOST_SystemWayland(background);
      }
      catch (const std::runtime_error &) {
        delete m_system;
        m_system = nullptr;
#  ifdef WITH_GHOST_WAYLAND_DYNLOAD
        ghost_wl_dynload_libraries_exit();
#  endif
      }
    }
    else {
      m_system = nullptr;
    }

    if (!m_system) {
      /* Try to fallback to X11. */
      backends_attempted[backends_attempted_num++] = "X11";
      try {
        m_system = new GHOST_SystemX11();
      }
      catch (const std::runtime_error &) {
        delete m_system;
        m_system = nullptr;
      }
    }
#elif defined(WITH_GHOST_X11)
    backends_attempted[backends_attempted_num++] = "X11";
    try {
      m_system = new GHOST_SystemX11();
    }
    catch (const std::runtime_error &) {
      delete m_system;
      m_system = nullptr;
    }
#elif defined(WITH_GHOST_WAYLAND)
    if (has_wayland_libraries) {
      backends_attempted[backends_attempted_num++] = "WAYLAND";
      try {
        m_system = new GHOST_SystemWayland(background);
      }
      catch (const std::runtime_error &) {
        delete m_system;
        m_system = nullptr;
#  ifdef WITH_GHOST_WAYLAND_DYNLOAD
        ghost_wl_dynload_libraries_exit();
#  endif
      }
    }
    else {
      m_system = nullptr;
    }
#elif defined(WITH_GHOST_SDL)
    backends_attempted[backends_attempted_num++] = "SDL";
    try {
      m_system = new GHOST_SystemSDL();
    }
    catch (const std::runtime_error &) {
      delete m_system;
      m_system = nullptr;
    }
#elif defined(WIN32)
    backends_attempted[backends_attempted_num++] = "WIN32";
    m_system = new GHOST_SystemWin32();
#elif defined(__APPLE__)
    backends_attempted[backends_attempted_num++] = "COCOA";
    m_system = new GHOST_SystemCocoa();
#endif

    if (m_system) {
      m_system_backend_id = backends_attempted[backends_attempted_num - 1];
    }
    else if (verbose) {
      fprintf(stderr, "GHOST: failed to initialize display for back-end(s): [");
      for (int i = 0; i < backends_attempted_num; i++) {
        if (i != 0) {
          fprintf(stderr, ", ");
        }
        fprintf(stderr, "'%s'", backends_attempted[i]);
      }
      fprintf(stderr, "]\n");
    }

    success = m_system != nullptr ? GHOST_kSuccess : GHOST_kFailure;
  }
  else {
    success = GHOST_kFailure;
  }
  if (success) {
    success = m_system->init();
  }
  return success;
}

GHOST_TSuccess GHOST_ISystem::createSystemBackground()
{
  GHOST_TSuccess success;
  if (!m_system) {
#if !defined(WITH_HEADLESS)
    /* Try to create a off-screen render surface with the graphical systems. */
    success = createSystem(false, true);
    if (success) {
      return success;
    }
    /* Try to fallback to headless mode if all else fails. */
#endif
    m_system = new GHOST_SystemHeadless();
    success = m_system != nullptr ? GHOST_kSuccess : GHOST_kFailure;
  }
  else {
    success = GHOST_kFailure;
  }
  if (success) {
    success = m_system->init();
  }
  return success;
}

GHOST_TSuccess GHOST_ISystem::disposeSystem()
{
  GHOST_TSuccess success = GHOST_kSuccess;
  if (m_system) {
    delete m_system;
    m_system = nullptr;
  }
  else {
    success = GHOST_kFailure;
  }
  return success;
}

GHOST_ISystem *GHOST_ISystem::getSystem()
{
  return m_system;
}

const char *GHOST_ISystem::getSystemBackend()
{
  return m_system_backend_id;
}

GHOST_TBacktraceFn GHOST_ISystem::getBacktraceFn()
{
  return GHOST_ISystem::m_backtrace_fn;
}

void GHOST_ISystem::setBacktraceFn(GHOST_TBacktraceFn backtrace_fn)
{
  GHOST_ISystem::m_backtrace_fn = backtrace_fn;
}