2 * Copyright 2006-2012 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Philippe Houdoin <philippe.houdoin@free.fr>
7 * Alexander von Gluck IV <kallisti5@unixzen.com>
11 #include <driver_settings.h>
14 #include <kernel/image.h>
15 #include <system/safemode_defs.h>
17 #include <Directory.h>
18 #include <FindDirectory.h>
21 #include "GLDispatcher.h"
22 #include "GLRendererRoster.h"
28 extern "C" status_t
_kern_get_safemode_option(const char* parameter
,
29 char* buffer
, size_t* _bufferSize
);
32 GLRendererRoster::GLRendererRoster(BGLView
* view
, ulong options
)
38 fABISubDirectory(NULL
)
41 size_t parameterLength
= sizeof(parameter
);
43 if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE
,
44 parameter
, ¶meterLength
) == B_OK
) {
45 if (!strcasecmp(parameter
, "enabled") || !strcasecmp(parameter
, "on")
46 || !strcasecmp(parameter
, "true") || !strcasecmp(parameter
, "yes")
47 || !strcasecmp(parameter
, "enable") || !strcmp(parameter
, "1"))
51 if (_kern_get_safemode_option(B_SAFEMODE_DISABLE_USER_ADD_ONS
,
52 parameter
, ¶meterLength
) == B_OK
) {
53 if (!strcasecmp(parameter
, "enabled") || !strcasecmp(parameter
, "on")
54 || !strcasecmp(parameter
, "true") || !strcasecmp(parameter
, "yes")
55 || !strcasecmp(parameter
, "enable") || !strcmp(parameter
, "1"))
59 // We might run in compatibility mode on a system with a different ABI. The
60 // renderers matching our ABI can usually be found in respective
61 // subdirectories of the opengl add-ons directories.
63 if (get_system_info(&info
) == B_OK
64 && (info
.abi
& B_HAIKU_ABI_MAJOR
)
65 != (B_HAIKU_ABI
& B_HAIKU_ABI_MAJOR
)) {
66 switch (B_HAIKU_ABI
& B_HAIKU_ABI_MAJOR
) {
67 case B_HAIKU_ABI_GCC_2
:
68 fABISubDirectory
= "gcc2";
70 case B_HAIKU_ABI_GCC_4
:
71 fABISubDirectory
= "gcc4";
80 GLRendererRoster::~GLRendererRoster()
87 GLRendererRoster::GetRenderer(int32 id
)
89 RendererMap::const_iterator iterator
= fRenderers
.find(id
);
90 if (iterator
== fRenderers
.end())
93 struct renderer_item item
= iterator
->second
;
99 GLRendererRoster::AddDefaultPaths()
101 // add user directories first, so that they can override system renderers
102 const directory_which paths
[] = {
103 B_USER_NONPACKAGED_ADDONS_DIRECTORY
,
104 B_USER_ADDONS_DIRECTORY
,
105 B_COMMON_NONPACKAGED_ADDONS_DIRECTORY
,
106 B_COMMON_ADDONS_DIRECTORY
,
107 B_SYSTEM_ADDONS_DIRECTORY
,
110 for (uint32 i
= fSafeMode
? 4 : 0;
111 i
< sizeof(paths
) / sizeof(paths
[0]); i
++) {
113 status_t status
= find_directory(paths
[i
], &path
, true);
114 if (status
== B_OK
&& path
.Append("opengl") == B_OK
)
115 AddPath(path
.Path());
121 GLRendererRoster::AddPath(const char* path
)
123 BDirectory
directory(path
);
124 status_t status
= directory
.InitCheck();
128 // if a subdirectory for our ABI exists, use that instead
129 if (fABISubDirectory
!= NULL
) {
130 BEntry
entry(&directory
, fABISubDirectory
);
131 if (entry
.IsDirectory()) {
132 status
= directory
.SetTo(&entry
);
139 status
= directory
.GetNodeRef(&nodeRef
);
148 while (directory
.GetNextRef(&ref
) == B_OK
) {
150 if (entry
.InitCheck() == B_OK
&& !entry
.IsFile())
153 if (CreateRenderer(ref
) == B_OK
)
159 if (files
!= 0 && count
== 0)
167 GLRendererRoster::AddRenderer(BGLRenderer
* renderer
,
168 image_id image
, const entry_ref
* ref
, ino_t node
)
171 item
.renderer
= renderer
;
178 fRenderers
[fNextID
] = item
;
183 renderer
->fOwningRoster
= this;
184 renderer
->fID
= fNextID
++;
190 GLRendererRoster::CreateRenderer(const entry_ref
& ref
)
194 status_t status
= entry
.GetNodeRef(&nodeRef
);
199 image_id image
= load_add_on(path
.Path());
203 BGLRenderer
* (*instantiate_renderer
)
204 (BGLView
* view
, ulong options
, BGLDispatcher
* dispatcher
);
206 status
= get_image_symbol(image
, "instantiate_gl_renderer",
207 B_SYMBOL_TYPE_TEXT
, (void**)&instantiate_renderer
);
208 if (status
== B_OK
) {
209 BGLRenderer
* renderer
210 = instantiate_renderer(fView
, fOptions
, new BGLDispatcher());
212 unload_add_on(image
);
213 return B_UNSUPPORTED
;
216 if (AddRenderer(renderer
, image
, &ref
, nodeRef
.node
) != B_OK
) {
218 // this will delete the renderer
219 unload_add_on(image
);
223 unload_add_on(image
);