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_SYSTEM_ADDONS_DIRECTORY
,
108 for (uint32 i
= fSafeMode
? 4 : 0;
109 i
< sizeof(paths
) / sizeof(paths
[0]); i
++) {
111 status_t status
= find_directory(paths
[i
], &path
, true);
112 if (status
== B_OK
&& path
.Append("opengl") == B_OK
)
113 AddPath(path
.Path());
119 GLRendererRoster::AddPath(const char* path
)
121 BDirectory
directory(path
);
122 status_t status
= directory
.InitCheck();
126 // if a subdirectory for our ABI exists, use that instead
127 if (fABISubDirectory
!= NULL
) {
128 BEntry
entry(&directory
, fABISubDirectory
);
129 if (entry
.IsDirectory()) {
130 status
= directory
.SetTo(&entry
);
137 status
= directory
.GetNodeRef(&nodeRef
);
146 while (directory
.GetNextRef(&ref
) == B_OK
) {
148 if (entry
.InitCheck() == B_OK
&& !entry
.IsFile())
151 if (CreateRenderer(ref
) == B_OK
)
157 if (files
!= 0 && count
== 0)
165 GLRendererRoster::AddRenderer(BGLRenderer
* renderer
,
166 image_id image
, const entry_ref
* ref
, ino_t node
)
169 item
.renderer
= renderer
;
176 fRenderers
[fNextID
] = item
;
181 renderer
->fOwningRoster
= this;
182 renderer
->fID
= fNextID
++;
188 GLRendererRoster::CreateRenderer(const entry_ref
& ref
)
192 status_t status
= entry
.GetNodeRef(&nodeRef
);
197 image_id image
= load_add_on(path
.Path());
201 BGLRenderer
* (*instantiate_renderer
)
202 (BGLView
* view
, ulong options
, BGLDispatcher
* dispatcher
);
204 status
= get_image_symbol(image
, "instantiate_gl_renderer",
205 B_SYMBOL_TYPE_TEXT
, (void**)&instantiate_renderer
);
206 if (status
== B_OK
) {
207 BGLRenderer
* renderer
208 = instantiate_renderer(fView
, fOptions
, new BGLDispatcher());
210 unload_add_on(image
);
211 return B_UNSUPPORTED
;
214 if (AddRenderer(renderer
, image
, &ref
, nodeRef
.node
) != B_OK
) {
216 // this will delete the renderer
217 unload_add_on(image
);
221 unload_add_on(image
);