Commit 8b4487da authored by David Cole's avatar David Cole
Browse files

BUG: Fixed and simplified vtkOpenGLExtensionManager and updated OpenGL header...

BUG: Fixed and simplified vtkOpenGLExtensionManager and updated OpenGL header files (Merge Francois's changes from main tree into VTK-5-0 branch...) The following file revisions were copied directly into the VTK-5-0 branch for this commit:
Rendering/vtkOpenGLExtensionManager.cxx            1.27
Rendering/vtkOpenGLExtensionManager.h              1.9
Rendering/Testing/Cxx/LoadOpenGLExtension.cxx      1.18
Utilities/ParseOGLExt/ParseOGLExt.cxx              1.22
Utilities/ParseOGLExt/headers/glext.h              1.3
Utilities/ParseOGLExt/headers/glxext.h             1.4
Utilities/ParseOGLExt/headers/wglext.h             1.2
VolumeRendering/vtkOpenGLVolumeTextureMapper3D.cxx 1.11
parent cac0d484
......@@ -40,6 +40,8 @@
#include "vtkRegressionTestImage.h"
#include "vtkOpenGLExtensionManager.h"
#include "vtkgl.h"
#include "vtkTextActor.h"
#include "vtkTextProperty.h"
vtkUnsignedCharArray *image;
......@@ -86,58 +88,127 @@ static void ImageCallback(vtkObject *__renwin, unsigned long, void *, void *)
int LoadOpenGLExtension(int argc, char *argv[])
{
cout << "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)" << endl;
vtkRenderWindow *renwin = vtkRenderWindow::New();
renwin->SetSize(250, 250);
vtkRenderer *renderer = vtkRenderer::New();
renwin->AddRenderer(renderer);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
renwin->SetInteractor(iren);
vtkOpenGLExtensionManager *extensions = vtkOpenGLExtensionManager::New();
extensions->SetRenderWindow(renwin);
cout << "Query extension." << endl;
if (!extensions->ExtensionSupported("GL_VERSION_1_2"))
// Force a Render here so that we can call glGetString reliably:
//
renwin->Render();
const char *gl_vendor =
reinterpret_cast<const char *>(glGetString(GL_VENDOR));
const char *gl_version =
reinterpret_cast<const char *>(glGetString(GL_VERSION));
const char *gl_renderer =
reinterpret_cast<const char *>(glGetString(GL_RENDERER));
cout << endl;
cout << "GL_VENDOR: " << (gl_vendor ? gl_vendor : "(null)") << endl;
cout << "GL_VERSION: " << (gl_version ? gl_version : "(null)") << endl;
cout << "GL_RENDERER: " << (gl_renderer ? gl_renderer : "(null)") << endl;
cout << endl;
renwin->Print(cout);
cout << "LoadSupportedExtension..." << endl;
int supported=extensions->ExtensionSupported("GL_VERSION_1_2");
int loaded=0;
if(supported)
{
cout << "Driver claims to support OpenGL 1.2" <<endl;
loaded=extensions->LoadSupportedExtension("GL_VERSION_1_2");
if(loaded)
{
cout << "OpenGL 1.2 features loaded." <<endl;
}
else
{
cout << "Failed to load OpenGL 1.2 features!" <<endl;
}
}
supported=extensions->ExtensionSupported("GL_VERSION_1_3");
if(supported)
{
cout << "Driver claims to support OpenGL 1.3" <<endl;
loaded=extensions->LoadSupportedExtension("GL_VERSION_1_3");
if(loaded)
{
cout << "OpenGL 1.3 features loaded." <<endl;
}
else
{
cout << "Failed to load OpenGL 1.3 features!" <<endl;
}
}
supported=extensions->ExtensionSupported("GL_VERSION_1_4");
if(supported)
{
cout << "Driver claims to support OpenGL 1.4" <<endl;
loaded=extensions->LoadSupportedExtension("GL_VERSION_1_4");
if(loaded)
{
cout << "OpenGL 1.4 features loaded." <<endl;
}
else
{
cout << "Failed to load OpenGL 1.4 features!" <<endl;
}
}
supported=extensions->ExtensionSupported("GL_VERSION_1_5");
if(supported)
{
cout << "Driver claims to support OpenGL 1.5" <<endl;
loaded=extensions->LoadSupportedExtension("GL_VERSION_1_5");
if(loaded)
{
cout << "OpenGL 1.5 features loaded." <<endl;
}
else
{
cout << "Failed to load OpenGL 1.5 features!" <<endl;
}
}
supported=extensions->ExtensionSupported("GL_VERSION_2_0");
if(supported)
{
cout << "Is it possible that your driver does not support OpenGL 1.2?"
<< endl << endl;;
int forceLoad = 0;
for (int i = 0; i < argc; i++)
cout << "Driver claims to support OpenGL 2.0" <<endl;
loaded=extensions->LoadSupportedExtension("GL_VERSION_2_0");
if(loaded)
{
cout << "OpenGL 2.0 features loaded." <<endl;
}
else
{
if (strcmp("-ForceLoad", argv[i]) == 0)
{
forceLoad = 1;
break;
}
cout << "Failed to load OpenGL 2.0 features!" <<endl;
}
if (forceLoad)
}
supported=extensions->ExtensionSupported("GL_VERSION_2_1");
if(supported)
{
cout << "Driver claims to support OpenGL 2.1" <<endl;
loaded=extensions->LoadSupportedExtension("GL_VERSION_2_1");
if(loaded)
{
cout << "Some drivers report supporting only GL 1.1 even though they\n"
<< "actually support 1.2 (and probably higher). I'm going to\n"
<< "try to load the extension anyway. You will definitely get\n"
<< "a warning from vtkOpenGLExtensionManager about it. If GL 1.2\n"
<< "really is not supported (or something else is wrong), I will\n"
<< "seg fault." << endl << endl;
cout << "OpenGL 2.1 features loaded." <<endl;
}
else
{
cout << "Your OpenGL driver reports that it does not support\n"
<< "OpenGL 1.2. If this is true, I cannot perform this test.\n"
<< "There are a few drivers that report only supporting GL 1.1\n"
<< "when they in fact actually support 1.2 (and probably higher).\n"
<< "If you think this might be the case, try rerunning this test\n"
<< "with the -ForceLoad flag. However, if Opengl 1.2 is really\n"
<< "not supported, a seg fault will occur." << endl;
cout << extensions->GetExtensionsString() << endl;
renwin->Delete();
iren->Delete();
extensions->Delete();
return 0;
cout << "Failed to load OpenGL 2.1 features!" <<endl;
}
}
cout << "GetExtensionsString..." << endl;
cout << extensions->GetExtensionsString() << endl;
cout << "Load extension." << endl;
extensions->LoadExtension("GL_VERSION_1_2");
extensions->Delete();
cout << "Set up pipeline." << endl;
vtkConeSource *cone = vtkConeSource::New();
......@@ -148,11 +219,8 @@ int LoadOpenGLExtension(int argc, char *argv[])
vtkActor *actor = vtkActor::New();
actor->SetMapper(mapper);
vtkRenderer *renderer = vtkRenderer::New();
renderer->AddActor(actor);
renwin->AddRenderer(renderer);
renderer->ResetCamera();
vtkCamera *camera = renderer->GetActiveCamera();
camera->Elevation(-45);
......@@ -160,42 +228,60 @@ int LoadOpenGLExtension(int argc, char *argv[])
cout << "Do a render without convolution." << endl;
renwin->Render();
// Set up a convolution filter. We are using the Laplacian filter, which
// is basically an edge detector. Once vtkgl::CONVOLUTION_2D is enabled,
// the filter will be applied any time an image is transfered in the
// pipeline.
cout << "Set up convolution filter." << endl;
vtkgl::ConvolutionFilter2D(vtkgl::CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
GL_LUMINANCE, GL_FLOAT, laplacian);
vtkgl::ConvolutionParameteri(vtkgl::CONVOLUTION_2D,
image=0;
if (extensions->LoadSupportedExtension("GL_ARB_imaging"))
{
// Set up a convolution filter. We are using the Laplacian filter, which
// is basically an edge detector. Once vtkgl::CONVOLUTION_2D is enabled,
// the filter will be applied any time an image is transfered in the
// pipeline.
cout << "Set up convolution filter." << endl;
vtkgl::ConvolutionFilter2D(vtkgl::CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
GL_LUMINANCE, GL_FLOAT, laplacian);
vtkgl::ConvolutionParameteri(vtkgl::CONVOLUTION_2D,
vtkgl::CONVOLUTION_BORDER_MODE,
vtkgl::REPLICATE_BORDER);
image = vtkUnsignedCharArray::New();
vtkCallbackCommand *cbc = vtkCallbackCommand::New();
cbc->SetCallback(ImageCallback);
renwin->AddObserver(vtkCommand::EndEvent, cbc);
cbc->Delete();
// This is a bit of a hack. The EndEvent on the render window will swap
// the buffers.
renwin->SwapBuffersOff();
cout << "Do test render with convolution on." << endl;
renwin->Render();
vtkgl::REPLICATE_BORDER);
image = vtkUnsignedCharArray::New();
vtkCallbackCommand *cbc = vtkCallbackCommand::New();
cbc->SetCallback(ImageCallback);
renwin->AddObserver(vtkCommand::EndEvent, cbc);
cbc->Delete();
// This is a bit of a hack. The EndEvent on the render window will swap
// the buffers.
renwin->SwapBuffersOff();
cout << "Do test render with convolution on." << endl;
renwin->Render();
}
else
{
renderer->RemoveAllViewProps();
vtkTextActor *t=vtkTextActor::New();
t->SetInput("GL_ARB_imaging not supported.");
t->SetDisplayPosition(125,125);
t->GetTextProperty()->SetJustificationToCentered();
renderer->AddViewProp(t);
t->Delete();
renwin->Render();
}
extensions->Delete();
int retVal = vtkRegressionTestImage(renwin);
if (retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
cone->Delete();
mapper->Delete();
actor->Delete();
renderer->Delete();
renwin->Delete();
iren->Delete();
image->Delete();
if(image!=0)
{
image->Delete();
}
return !retVal;
}
This diff is collapsed.
......@@ -52,7 +52,7 @@
// The vtkgl.h include file contains all the constants and function
// pointers required for using OpenGL extensions in a portable and
// namespace safe way. vtkgl.h is built from parsed glext.h, glxext.h, and
// wglext.h files. Snapshots of these files are distributed with vtkSNL,
// wglext.h files. Snapshots of these files are distributed with VTK,
// but you can also set CMake options to use other files.
//
// To use an OpenGL extension, you first need to make an instance of
......@@ -60,9 +60,9 @@
// query the vtkOpenGLExtensionManager to see if the extension is supported
// with the ExtensionSupported method. Valid names for extensions are
// given in the OpenGL extension registry at
// \ref http://oss.sgi.com/projects/ogl-sample/registry/ .
// \ref http://www.opengl.org/registry/ .
// You can also grep vtkgl.h (which will be in the binary build directory
// if vtkSNL is not installed) for appropriate names. There are also
// if VTK is not installed) for appropriate names. There are also
// special extensions GL_VERSION_X_X (where X_X is replaced with a major
// and minor version, respectively) which contain all the constants and
// functions for OpenGL versions for which the gl.h header file is of an
......@@ -71,37 +71,55 @@
// \code
// if ( !extensions->ExtensionSupported("GL_VERSION_1_2")
// || !extensions->ExtensionSupported("GL_ARB_multitexture") ) {
// {
// vtkErrorMacro("Required extensions not supported!");
// }
// {
// vtkErrorMacro("Required extensions not supported!");
// }
// \endcode
//
// Once you have verified that the extensions you want exist, before you
// use them you have to loaded them with the LoadExtension method.
// use them you have to load them with the LoadExtension method.
//
// \code
// extensions->LoadExtension("GL_VERSION_1_2");
// extensions->LoadExtension("GL_ARB_multitexture");
// \endcode
//
// Alternatively, you can use the LoadSupportedExtension method, which checks
// whether the requested extension is supported and, if so, loads it. The
// LoadSupportedExtension method will not raise any errors or warnings if it
// fails, so it is important for callers to pay attention to the return value.
//
// \code
// if ( extensions->LoadSupportedExtension("GL_VERSION_1_2")
// && extensions->LoadSupportedExtension("GL_ARB_multitexture") ) {
// {
// vtkgl::ActiveTexture(vtkgl::TEXTURE0_ARB);
// }
// else
// {
// vtkErrorMacro("Required extensions could not be loaded!");
// }
// \endcode
//
// Once you have queried and loaded all of the extensions you need, you can
// delete the vtkExtensionManager. To use a constant of an extension, simply
// replace the "GL_" prefix with "vtkgl::". Likewise, replace the "gl" prefix
// of functions with "vtkgl::". In rare cases, an extension will add a type.
// In this case, add vtkgl:: to the type (i.e. vtkgl::GLchar).
// delete the vtkOpenGLExtensionManager. To use a constant of an extension,
// simply replace the "GL_" prefix with "vtkgl::". Likewise, replace the
// "gl" prefix of functions with "vtkgl::". In rare cases, an extension will
// add a type. In this case, add vtkgl:: to the type (i.e. vtkgl::GLchar).
//
// \code
// extensions->Delete();
// ...
// vtkgl::ActiveTexture(vtkgl::TEXTURE0_ARB);
// \endcode
//
// For wgl extensions, replace the "WGL_" and "wgl" prefixes with
// "vtkwgl::". For glX extensions, replace the "GLX_" and "glX" prefixes
// with "vtkglX::".
//
#ifndef __vtkOpenGLExtensionManager
#define __vtkOpenGLExtensionManager
#ifndef __vtkOpenGLExtensionManager_h
#define __vtkOpenGLExtensionManager_h
#include <vtkObject.h>
......@@ -148,14 +166,95 @@ public:
// Description:
// Returns a function pointer to the OpenGL extension function with the
// given name. Returns NULL if the function could not be retrieved.
virtual vtkOpenGLExtensionManagerFunctionPointer GetProcAddress(const char *fname);
virtual vtkOpenGLExtensionManagerFunctionPointer GetProcAddress(
const char *fname);
//ETX
// Description:
// Loads all the functions associated with the given extension into the
// appropriate static members of vtkgl.
// appropriate static members of vtkgl. This method emits a warning if the
// requested extension is not supported. It emits an error if the extension
// does not load successfully.
virtual void LoadExtension(const char *name);
// Description:
// Returns true if the extension is supported and loaded successfully,
// false otherwise. This method will "fail silently/gracefully" if the
// extension is not supported or does not load properly. It emits neither
// warnings nor errors. It is up to the caller to determine if the
// extension loaded properly by paying attention to the return value.
virtual int LoadSupportedExtension(const char *name);
// Description:
// Loads all the functions associated with the given core-promoted extension
// into the appropriate static members of vtkgl associated with the OpenGL
// version that promoted the extension as a core feature. This method emits a
// warning if the requested extension is not supported. It emits an error if
// the extension does not load successfully.
//
// For instance, extension GL_ARB_multitexture was promoted as a core
// feature into OpenGL 1.3. An implementation that uses this
// feature has to (IN THIS ORDER), check if OpenGL 1.3 is supported
// with ExtensionSupported("GL_VERSION_1_3"), if true, load the extension
// with LoadExtension("GL_VERSION_1_3"). If false, test for the extension
// with ExtensionSupported("GL_ARB_multitexture"),if true load the extension
// with this method LoadCorePromotedExtension("GL_ARB_multitexture").
// If any of those loading stage succeeded, use vtgl::ActiveTexture() in
// any case, NOT vtgl::ActiveTextureARB().
// This method avoids the use of if statements everywhere in implementations
// using core-promoted extensions.
// Without this method, the implementation code should look like:
// \code
// int opengl_1_3=extensions->ExtensionSupported("GL_VERSION_1_3");
// if(opengl_1_3)
// {
// extensions->LoadExtension("GL_VERSION_1_3");
// }
// else
// {
// if(extensions->ExtensionSupported("GL_ARB_multitexture"))
// {
// extensions->LoadCorePromotedExtension("GL_ARB_multitexture");
// }
// else
// {
// vtkErrorMacro("Required multitexture feature is not supported!");
// }
// }
// ...
// if(opengl_1_3)
// {
// vtkgl::ActiveTexture(vtkgl::TEXTURE0)
// }
// else
// {
// vtkgl::ActiveTextureARB(vtkgl::TEXTURE0_ARB)
// }
// \endcode
// Thanks to this method, the code looks like:
// \code
// int opengl_1_3=extensions->ExtensionSupported("GL_VERSION_1_3");
// if(opengl_1_3)
// {
// extensions->LoadExtension("GL_VERSION_1_3");
// }
// else
// {
// if(extensions->ExtensionSupported("GL_ARB_multitexture"))
// {
// extensions->LoadCorePromotedExtension("GL_ARB_multitexture");
// }
// else
// {
// vtkErrorMacro("Required multitexture feature is not supported!");
// }
// }
// ...
// vtkgl::ActiveTexture(vtkgl::TEXTURE0);
// \endcode
virtual void LoadCorePromotedExtension(const char *name);
protected:
vtkOpenGLExtensionManager();
virtual ~vtkOpenGLExtensionManager();
......@@ -167,6 +266,13 @@ protected:
vtkTimeStamp BuildTime;
virtual void ReadOpenGLExtensions();
// Description:
// Wrap around the generated vtkgl::LoadExtension to deal with OpenGL 1.2
// and its optional part GL_ARB_imaging. Also functions like
// glBlendEquation() or glBlendColor() are optional in OpenGL 1.2 or 1.3 and
// provided by the GL_ARB_imaging but there are core features in OpenGL 1.4.
virtual int SafeLoadExtension(const char *name);
private:
vtkOpenGLExtensionManager(const vtkOpenGLExtensionManager&); // Not implemented
......@@ -174,4 +280,3 @@ private:
};
#endif //__vtkOpenGLExtensionManager
......@@ -50,7 +50,7 @@ static vtkstd::string ToUpper(vtkstd::string s)
for (vtkstd::string::size_type i = 0; i < s.length(); i++)
{
u.append(1, (char)toupper(s[i]));
u.append(1, static_cast<char>(toupper(s[i])));
}
return u;
......@@ -526,18 +526,14 @@ static void WriteClassDeclarationGuts(ostream &hfile, int type)
iextension != extensions.end(); iextension++)
{
if (iextension->type != type) continue;
hfile << " //Definitions for " << iextension->name.c_str() << endl;
hfile << endl << " //Definitions for " << iextension->name.c_str() << endl;
vtkstd::map<Extension, vtkstd::list<Constant> >::iterator cExts
= consts.find(*iextension);
if (cExts != consts.end())
{
hfile << " enum " << cExts->first.name.c_str() << "_consts {" << endl;
bool wroteFirst = false;
for (vtkstd::list<Constant>::iterator iconst = cExts->second.begin();
iconst != cExts->second.end(); iconst++)
{
// New versions of the NVIDIA OpenGL headers for Linux can
// #define the same constant with the same value in multiple
// sections. This utility will happily parse those and write
......@@ -549,16 +545,8 @@ static void WriteClassDeclarationGuts(ostream &hfile, int type)
iconst->value ) )
== ConstantsAlreadyWritten.end() )
{
if (wroteFirst)
{
hfile << "," << endl;
}
else
{
wroteFirst = true;
}
hfile << " " << iconst->name.c_str() << " = "
<< iconst->value.c_str();
hfile << " const GLenum " << iconst->name.c_str()
<< " = static_cast<GLenum>(" << iconst->value.c_str() << ");" << endl;
ConstantsAlreadyWritten.insert( vtkstd::make_pair( iconst->name,
iconst->value ) );
......@@ -566,11 +554,10 @@ static void WriteClassDeclarationGuts(ostream &hfile, int type)
}
else
{
hfile << "/* skipping duplicate " << iconst->name.c_str()
hfile << " /* skipping duplicate " << iconst->name.c_str()
<< " = " << iconst->value.c_str() << " */" << endl;
}
}
hfile << endl << " };" << endl;
}
vtkstd::map<Extension, vtkstd::list<Typedef> >::iterator tExts
= types.find(*iextension);
......@@ -621,8 +608,8 @@ static void WriteFunctionPointerDeclarations(ostream &cxxfile, int type)
static void WriteCode(ostream &hfile, ostream &cxxfile)
{
// Write data for header file ---------------------------------
hfile << "#ifndef _vtkgl_h" << endl
<< "#define _vtkgl_h" << endl << endl;
hfile << "#ifndef __vtkgl_h" << endl
<< "#define __vtkgl_h" << endl << endl;
hfile << "#include \"vtkToolkits.h\"" << endl;
hfile << "#include \"vtkSystemIncludes.h\"" << endl;
hfile << "#include \"vtkWindows.h\"" << endl;
......@@ -664,6 +651,11 @@ static void WriteCode(ostream &hfile, ostream &cxxfile)
Extension::WriteSupportWrapperBegin(hfile, Extension::GL);
hfile << endl << "namespace vtkgl {" << endl;
// Add necessary type declarations.
hfile << " //Define int32_t, int64_t, and uint64_t." << endl;
hfile << " typedef vtkTypeInt32 int32_t;" << endl;
hfile << " typedef vtkTypeInt64 int64_t;" << endl;
hfile << " typedef vtkTypeUInt64 uint64_t;" << endl;
ConstantsAlreadyWritten.clear();
WriteClassDeclarationGuts(hfile, Extension::GL);
hfile << endl << " // Method to load functions for a particular extension.";
......@@ -685,8 +677,8 @@ static void WriteCode(ostream &hfile, ostream &cxxfile)
hfile << " typedef XID GLXWindow;" << endl;
hfile << " typedef XID GLXFBConfigID;" << endl;
hfile << " typedef struct __GLXFBConfigRec *GLXFBConfig;" << endl;
hfile << " typedef int int32_t;" << endl;
hfile << " typedef long long int64_t;" << endl;
hfile << " typedef vtkTypeInt32 int32_t;" << endl;
hfile << " typedef vtkTypeInt64 int64_t;" << endl;
ConstantsAlreadyWritten.clear();
WriteClassDeclarationGuts(hfile, Extension::GLX);
hfile << "}" << endl;
......@@ -736,11 +728,11 @@ static void WriteCode(ostream &hfile, ostream &cxxfile)
ifunct != functs[*iextension].end(); ifunct++)
{
cxxfile << " " << vtkglclass.c_str() << "::"
<< ifunct->name.c_str() << " = (" << vtkglclass.c_str() << "::"
<< ifunct->name.c_str() << " = reinterpret_cast<" << vtkglclass.c_str() << "::"
<< ifunct->GetProcType()
<< ")manager->GetProcAddress(\""
<< ">(manager->GetProcAddress(\""
<< Extension::TypeToString(iextension->type)
<< ifunct->name.c_str() << "\");" << endl;
<< ifunct->name.c_str() << "\"));" << endl;
}
cxxfile << " return 1";
for (ifunct = functs[*iextension].begin();
......
This diff is collapsed.
......@@ -6,32 +6,26 @@ extern "C" {
#endif
/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
** Copyright (c) 2007 The Khronos Group Inc.
**
** http://oss.sgi.com/projects/FreeB
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated