GLRendererRoster.cpp revision 01e04c3f
1af69d88dSmrg/* 2af69d88dSmrg * Copyright 2006-2012 Haiku, Inc. All Rights Reserved. 3af69d88dSmrg * Distributed under the terms of the MIT License. 4af69d88dSmrg * 5af69d88dSmrg * Authors: 6af69d88dSmrg * Philippe Houdoin <philippe.houdoin@free.fr> 7af69d88dSmrg * Alexander von Gluck IV <kallisti5@unixzen.com> 8af69d88dSmrg */ 9af69d88dSmrg 10af69d88dSmrg 11af69d88dSmrg#include <driver_settings.h> 12af69d88dSmrg#include <image.h> 13af69d88dSmrg 14af69d88dSmrg#include <kernel/image.h> 15af69d88dSmrg#include <system/safemode_defs.h> 16af69d88dSmrg 17af69d88dSmrg#include <Directory.h> 18af69d88dSmrg#include <FindDirectory.h> 19af69d88dSmrg#include <Path.h> 2001e04c3fSmrg#include <strings.h> 21af69d88dSmrg#include "GLDispatcher.h" 22af69d88dSmrg#include "GLRendererRoster.h" 23af69d88dSmrg 24af69d88dSmrg#include <new> 25af69d88dSmrg#include <string.h> 26af69d88dSmrg 27af69d88dSmrg 28af69d88dSmrgextern "C" status_t _kern_get_safemode_option(const char* parameter, 29af69d88dSmrg char* buffer, size_t* _bufferSize); 30af69d88dSmrg 31af69d88dSmrg 32af69d88dSmrgGLRendererRoster::GLRendererRoster(BGLView* view, ulong options) 33af69d88dSmrg : 34af69d88dSmrg fNextID(0), 35af69d88dSmrg fView(view), 36af69d88dSmrg fOptions(options), 37af69d88dSmrg fSafeMode(false), 38af69d88dSmrg fABISubDirectory(NULL) 39af69d88dSmrg{ 40af69d88dSmrg char parameter[32]; 41af69d88dSmrg size_t parameterLength = sizeof(parameter); 42af69d88dSmrg 43af69d88dSmrg if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, 44af69d88dSmrg parameter, ¶meterLength) == B_OK) { 45af69d88dSmrg if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") 46af69d88dSmrg || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") 47af69d88dSmrg || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) 48af69d88dSmrg fSafeMode = true; 49af69d88dSmrg } 50af69d88dSmrg 51af69d88dSmrg if (_kern_get_safemode_option(B_SAFEMODE_DISABLE_USER_ADD_ONS, 52af69d88dSmrg parameter, ¶meterLength) == B_OK) { 53af69d88dSmrg if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") 54af69d88dSmrg || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") 55af69d88dSmrg || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) 56af69d88dSmrg fSafeMode = true; 57af69d88dSmrg } 58af69d88dSmrg 59af69d88dSmrg // We might run in compatibility mode on a system with a different ABI. The 60af69d88dSmrg // renderers matching our ABI can usually be found in respective 61af69d88dSmrg // subdirectories of the opengl add-ons directories. 62af69d88dSmrg system_info info; 63af69d88dSmrg if (get_system_info(&info) == B_OK 64af69d88dSmrg && (info.abi & B_HAIKU_ABI_MAJOR) 65af69d88dSmrg != (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR)) { 66af69d88dSmrg switch (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) { 67af69d88dSmrg case B_HAIKU_ABI_GCC_2: 68af69d88dSmrg fABISubDirectory = "gcc2"; 69af69d88dSmrg break; 70af69d88dSmrg case B_HAIKU_ABI_GCC_4: 71af69d88dSmrg fABISubDirectory = "gcc4"; 72af69d88dSmrg break; 73af69d88dSmrg } 74af69d88dSmrg } 75af69d88dSmrg 76af69d88dSmrg AddDefaultPaths(); 77af69d88dSmrg} 78af69d88dSmrg 79af69d88dSmrg 80af69d88dSmrgGLRendererRoster::~GLRendererRoster() 81af69d88dSmrg{ 82af69d88dSmrg 83af69d88dSmrg} 84af69d88dSmrg 85af69d88dSmrg 86af69d88dSmrgBGLRenderer* 87af69d88dSmrgGLRendererRoster::GetRenderer(int32 id) 88af69d88dSmrg{ 89af69d88dSmrg RendererMap::const_iterator iterator = fRenderers.find(id); 90af69d88dSmrg if (iterator == fRenderers.end()) 91af69d88dSmrg return NULL; 92af69d88dSmrg 93af69d88dSmrg struct renderer_item item = iterator->second; 94af69d88dSmrg return item.renderer; 95af69d88dSmrg} 96af69d88dSmrg 97af69d88dSmrg 98af69d88dSmrgvoid 99af69d88dSmrgGLRendererRoster::AddDefaultPaths() 100af69d88dSmrg{ 101af69d88dSmrg // add user directories first, so that they can override system renderers 102af69d88dSmrg const directory_which paths[] = { 103af69d88dSmrg B_USER_NONPACKAGED_ADDONS_DIRECTORY, 104af69d88dSmrg B_USER_ADDONS_DIRECTORY, 105af69d88dSmrg B_SYSTEM_ADDONS_DIRECTORY, 106af69d88dSmrg }; 107af69d88dSmrg 108af69d88dSmrg for (uint32 i = fSafeMode ? 4 : 0; 109af69d88dSmrg i < sizeof(paths) / sizeof(paths[0]); i++) { 110af69d88dSmrg BPath path; 111af69d88dSmrg status_t status = find_directory(paths[i], &path, true); 112af69d88dSmrg if (status == B_OK && path.Append("opengl") == B_OK) 113af69d88dSmrg AddPath(path.Path()); 114af69d88dSmrg } 115af69d88dSmrg} 116af69d88dSmrg 117af69d88dSmrg 118af69d88dSmrgstatus_t 119af69d88dSmrgGLRendererRoster::AddPath(const char* path) 120af69d88dSmrg{ 121af69d88dSmrg BDirectory directory(path); 122af69d88dSmrg status_t status = directory.InitCheck(); 123af69d88dSmrg if (status < B_OK) 124af69d88dSmrg return status; 125af69d88dSmrg 126af69d88dSmrg // if a subdirectory for our ABI exists, use that instead 127af69d88dSmrg if (fABISubDirectory != NULL) { 128af69d88dSmrg BEntry entry(&directory, fABISubDirectory); 129af69d88dSmrg if (entry.IsDirectory()) { 130af69d88dSmrg status = directory.SetTo(&entry); 131af69d88dSmrg if (status != B_OK) 132af69d88dSmrg return status; 133af69d88dSmrg } 134af69d88dSmrg } 135af69d88dSmrg 136af69d88dSmrg node_ref nodeRef; 137af69d88dSmrg status = directory.GetNodeRef(&nodeRef); 138af69d88dSmrg if (status < B_OK) 139af69d88dSmrg return status; 140af69d88dSmrg 141af69d88dSmrg int32 count = 0; 142af69d88dSmrg int32 files = 0; 143af69d88dSmrg 144af69d88dSmrg entry_ref ref; 145af69d88dSmrg BEntry entry; 146af69d88dSmrg while (directory.GetNextRef(&ref) == B_OK) { 14701e04c3fSmrg entry.SetTo(&ref, true); 148af69d88dSmrg if (entry.InitCheck() == B_OK && !entry.IsFile()) 149af69d88dSmrg continue; 150af69d88dSmrg 151af69d88dSmrg if (CreateRenderer(ref) == B_OK) 152af69d88dSmrg count++; 153af69d88dSmrg 154af69d88dSmrg files++; 155af69d88dSmrg } 156af69d88dSmrg 157af69d88dSmrg if (files != 0 && count == 0) 158af69d88dSmrg return B_BAD_VALUE; 159af69d88dSmrg 160af69d88dSmrg return B_OK; 161af69d88dSmrg} 162af69d88dSmrg 163af69d88dSmrg 164af69d88dSmrgstatus_t 165af69d88dSmrgGLRendererRoster::AddRenderer(BGLRenderer* renderer, 166af69d88dSmrg image_id image, const entry_ref* ref, ino_t node) 167af69d88dSmrg{ 168af69d88dSmrg renderer_item item; 169af69d88dSmrg item.renderer = renderer; 170af69d88dSmrg item.image = image; 171af69d88dSmrg item.node = node; 172af69d88dSmrg if (ref != NULL) 173af69d88dSmrg item.ref = *ref; 174af69d88dSmrg 175af69d88dSmrg try { 176af69d88dSmrg fRenderers[fNextID] = item; 177af69d88dSmrg } catch (...) { 178af69d88dSmrg return B_NO_MEMORY; 179af69d88dSmrg } 180af69d88dSmrg 181af69d88dSmrg renderer->fOwningRoster = this; 182af69d88dSmrg renderer->fID = fNextID++; 183af69d88dSmrg return B_OK; 184af69d88dSmrg} 185af69d88dSmrg 186af69d88dSmrg 187af69d88dSmrgstatus_t 188af69d88dSmrgGLRendererRoster::CreateRenderer(const entry_ref& ref) 189af69d88dSmrg{ 19001e04c3fSmrg BEntry entry(&ref, true); 191af69d88dSmrg node_ref nodeRef; 192af69d88dSmrg status_t status = entry.GetNodeRef(&nodeRef); 193af69d88dSmrg if (status < B_OK) 194af69d88dSmrg return status; 195af69d88dSmrg 196af69d88dSmrg BPath path(&ref); 197af69d88dSmrg image_id image = load_add_on(path.Path()); 198af69d88dSmrg if (image < B_OK) 199af69d88dSmrg return image; 200af69d88dSmrg 201af69d88dSmrg BGLRenderer* (*instantiate_renderer) 202af69d88dSmrg (BGLView* view, ulong options, BGLDispatcher* dispatcher); 203af69d88dSmrg 204af69d88dSmrg status = get_image_symbol(image, "instantiate_gl_renderer", 205af69d88dSmrg B_SYMBOL_TYPE_TEXT, (void**)&instantiate_renderer); 206af69d88dSmrg if (status == B_OK) { 207af69d88dSmrg BGLRenderer* renderer 208af69d88dSmrg = instantiate_renderer(fView, fOptions, new BGLDispatcher()); 209af69d88dSmrg if (!renderer) { 210af69d88dSmrg unload_add_on(image); 211af69d88dSmrg return B_UNSUPPORTED; 212af69d88dSmrg } 213af69d88dSmrg 214af69d88dSmrg if (AddRenderer(renderer, image, &ref, nodeRef.node) != B_OK) { 215af69d88dSmrg renderer->Release(); 216af69d88dSmrg // this will delete the renderer 217af69d88dSmrg unload_add_on(image); 218af69d88dSmrg } 219af69d88dSmrg return B_OK; 220af69d88dSmrg } 221af69d88dSmrg unload_add_on(image); 222af69d88dSmrg 223af69d88dSmrg return status; 224af69d88dSmrg} 225