int  CFont::getMaxFittingLength(const String &string, int bounds)
{
  int index         = 0,
                      currentLength = 0;
                      
  if (!bounds || !string.getLength() || !fontTexture.getID())
    return 0;
    
  for (size_t i = 0; i < string.getLength(); i++)
    if (currentLength < bounds)
    {
      currentLength += spaces[int(string[i])];
      index++;
    }
    else
      break;
      
  return (currentLength < bounds) ? index : index - 1;
}
Beispiel #2
0
void
Path::split(const String &path,String& dirpath, String& filename)
{	
	if (path.isEmpty ())
		THROW("IDS_ILLEGAL_PATH");

	if (path.findFirstOf (Path::invalidPathChars, 0) != String::NO_POSITION)
		THROW("IDS_ILLEGAL_PATH");

    dirpath.clear();
    filename.clear();
    String p = Path::adaptSep(path);
#ifdef __WINDOWS__
    // TODO
    // deal route like \\.\device\somthing
    // and \\?\volume\something
    // and driver: like C:
    // C:dir should throw an error?
#endif
    // deal when start with separator
    size_t headSlashNum = 0;
    if (isSeparator(p[0])) {
        while (isSeparator( p[headSlashNum])) { 
            dirpath += Path::separator; 
            headSlashNum++;
            if (headSlashNum == p.getLength()) {
                break;
            }
        }
    }
    p = p.subString(headSlashNum);
    // find most right sep pos
    size_t posLastSlash = p.findLastOf(Path::separator);
    if (posLastSlash == p.getLength() - 1) { 
        dirpath += p.subString(0, p.getLength() - 1);
        filename = String::EMPTY;
    } else if (posLastSlash == String::NO_POSITION) {
        filename = p;
    } else {
        dirpath += String(p, 0, posLastSlash);
        filename.assign(p, posLastSlash + 1, String::NO_POSITION);
    }
}
Beispiel #3
0
void
PathTestCase::testCombine(void) 
{
    String p1,p2;
    //cout<<endl<< Path::getInvalidPathChars().getCStr()<<endl;
    //test empty path
    CPPUNIT_ASSERT_THROW(Path::combine(p1, p2), Exception);
    
    //test illegal chars
    String invalid = Path::getInvalidPathChars();
    p1 = "root";
    p2 = "home";
    for(size_t i=0; i<invalid.getLength(); i++) {
        CPPUNIT_ASSERT_THROW(Path::combine(p1+invalid[i], p2), Exception);
    }

    for(size_t i=0; i<invalid.getLength(); i++) {
        CPPUNIT_ASSERT_THROW(Path::combine(p1, p2+invalid[i]), Exception);
    }

    //test a empty combine one legal path
    CPPUNIT_ASSERT(Path::combine(String(), p1) == p1);
    CPPUNIT_ASSERT(Path::combine(p2,String()) == p2);

#ifdef __WINDOWS__
    p2 = _T("c:\\windows");
#else
    p2 = "/home";
#endif
    //test absolute path
    CPPUNIT_ASSERT(Path::combine(p1, p2) == p2);

    p1 = "root";
    p2 = "home";
    //test normal case
#ifdef __WINDOWS__
    CPPUNIT_ASSERT(Path::combine(p1, p2) == _T("root\\home"));
    CPPUNIT_ASSERT(Path::combine(p1+'\\', p2) == _T("root\\home"));
#else
    CPPUNIT_ASSERT(Path::combine(p1, p2) == "root/home");
    CPPUNIT_ASSERT(Path::combine(p1+'/', p2) == "root/home");
#endif
}
Beispiel #4
0
String CudaCompiler::removeOption(const String& opts, const String& tag, bool hasParam)
{
    String res = opts;
    for (int i = 0; i < res.getLength(); i++)
    {
        bool match = true;
        for (int j = 0; match && j < tag.getLength(); j++)
            match = (i + j < res.getLength() && res[i + j] == tag[j]);
        if (!match)
            continue;

        int idx = res.indexOf(' ', i);
        if (idx != -1 && hasParam)
            idx = res.indexOf(' ', idx + 1);

        res = res.substring(0, i) + ((idx == -1) ? "" : res.substring(idx + 1));
        i--;
    }
    return res;
}
Beispiel #5
0
Commandline::Ptr Commandline::createFromQuotedString(const String& commandline)
{
    Commandline::Ptr rslt(new Commandline());
    
    const int len = commandline.getLength();
    
    int i = 0;
    
    while (i < len)
    {
        while (i < len && commandline[i] == ' ') {
            ++i;
        }
        if (i < len && commandline[i] == '"') {
            ++i;

            String s;
            
            while (i < len && commandline[i] != '"')
            {
                if (commandline[i] == '\\' && i + 1 < len) {
                    s << commandline[i + 1];
                    ++i;
                } else {
                    s << commandline[i];
                }
                ++i;
            }
            if (i < len && commandline[i] == '"') {
                ++i;
            }
            rslt->append(s);
        }
        else {
            String s;
            
            while (i < len && commandline[i] != ' ')
            {
                if (commandline[i] == '\\' && i + 1 < len) {
                    s << commandline[i + 1];
                    ++i;
                } else {
                    s << commandline[i];
                }
                ++i;
            }
            if (i < len && commandline[i] == ' ') {
                ++i;
            }
            rslt->append(s);
        }
    }
    return rslt;
}
Beispiel #6
0
inline size_t 
findExt (const String& path)
{
	//
	// This method should return the index of the path extension
	// start or -1 if no valid extension.
	//
	// if (!path.isEmpty ()) {
	if (!path.isEmpty () && path.getLength() > 1) {
		// size_t lastDot = path.findLastOf ('.', path.getLength () - 1);  
        // when '.' is lastchar of file, it not means separator of filename and extname
		size_t lastDot = path.findLastOf ('.', path.getLength () - 2); 
		size_t lastSep = path.findLastOf (Path::getSeparatorChars (), path.getLength () - 1);

		if (lastSep == String::NO_POSITION || lastDot > (size_t) lastSep)
			return lastDot;
	}

	return String::NO_POSITION;
}
Beispiel #7
0
// public ctor
WinSysLogImpl::WinSysLogImpl (const String& appName)
	: _eventHandle (0)
{
	tchar_t msgFileName [AB_MAX_PATH];

	if (!GetModuleFileName (0, msgFileName, AB_MAX_PATH)) {
    	assert (false);
    	return;
    }
    	
	String cflname = Path::combine (Path::getDirectoryName (msgFileName), _T("cfl.dll"));
  	
	unsigned int cflnameLen = ((cflname.getLength () + 1) * sizeof (tchar_t));

	//
	// Information is stored in the registry at a location based on the
	// program name.
	//
	String regkey (_T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"));
	regkey.append (appName);
	
	//
	// Add the event source to the registry. Note that if this fails it
	// is not fatal. The application will still be able to write entries
	// to the event log, they just won't be formatted correctly.
	//
  	HKEY hkey;
  	if (RegCreateKey (HKEY_LOCAL_MACHINE, regkey.getCStr (), &hkey) != ERROR_SUCCESS) {
  		assert (false);
  		// Ignore error instead of throw exception.
  		return; 
  	}
  
  	unsigned int flags = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
  	RegSetValueEx (hkey,
                   _T("TypesSupported"),
				   0,
				   REG_DWORD,
				   (LPBYTE) &flags,
				   sizeof (unsigned int));
				   
  	RegSetValueEx (hkey,
                   _T("EventMessageFile"),
                   0,
                   REG_SZ,
                   (LPBYTE) cflname.getCStr (),
                   cflnameLen);
  	::RegCloseKey (hkey);

  	// Obtain a handle to the event source.
  	this->_eventHandle = ::RegisterEventSource (0, appName.getCStr ());
}
Beispiel #8
0
void
StringBuffer::append( const String& aString )
{
	//	//Debug::entering( "StringBuffer", "append", "const String&" );

	long last = aString.getLength();
	for ( long i=0; i < last; i++ )
	{
 		this->append( aString.charAt( i ) );
	}

	//	//Debug::leaving();
}
Beispiel #9
0
void JsonDb::writeJsonEscaped(File& f, const String& string)
{
  const char* data = string.getData();
  for(size_t i = 0; i < string.getLength(); i++)
  {
    if(data[i] == '\\')
      f.write("\\\\", 2);
    else if(data[i] == '\"')
      f.write("\\\"", 2);
    else
      f.write(data + i, 1);
  }
}
Beispiel #10
0
bool
StringUtf32::equals(const String& other) const throw()
{
  if (getLength() != other.getLength())
    return false;
  const utf32_char_type * s = other.as_utf32();
  if (s == 0) {
    return String::equals(other);
  }
  else {
    return memcmp(str, s, sizeof(utf32_char_type) * size) == 0;
  }
}
Beispiel #11
0
bool
StringLat1::equals(const String& other) const throw()
{
  if (getLength() != other.getLength())
    return false;
  const lat1_char_type * s = other.as_lat1();
  if (s == 0) {
    return String::equals(other);
  }
  else {
    return strncmp(str, s, size) == 0;
  }
}
Beispiel #12
0
// public static 
String 
Path::getExtensionName (const String& path)
{
	if (path.findFirstOf ( Path::invalidPathChars) != String::NO_POSITION)
		THROW ("IDS_ILLEGAL_PATH");

	size_t ext = findExt (path);

	if (ext != String::NO_POSITION) {
		if ((size_t) ext < (path.getLength () - 1))
			return path.subString (ext);
	}

	return String::EMPTY;
}
Beispiel #13
0
    int String::stringLength(String & aString)
    {
        char * characters = aString.getString();

        int index = 0;
        //While there hasnt been a null terminator or reach end of string length
        while(index < aString.getLength())
        {
            if(characters[index] == '\0')
            {
                break;
            }
            index ++;
        }
        return index;
    }
Beispiel #14
0
String::String(const String &str, size_t start, size_t chars)
{
    init();
    char *ptr = str.getText();
    size_t len = str.getLength();

    if(start >= len)
        return;

    ptr += start;
    len -= start;

    if(chars >= len)
        chars = len;

    set(ptr, chars);
}
Beispiel #15
0
bool Brackets::checkBrackets(String str)
{
	Stack<int>stack;

	for (size_t i = 0; i < str.getLength(); i++)
	{
		int tmp = findBrackets(str.getChars(i), brackets);
		if (tmp < brackets.getLength()/2) stack.push(tmp);
		else if (tmp <= brackets.getLength())
		{
			if (stack.peek() == tmp % (brackets.getLength()/2)) stack.pop();
			else return false;
		}
	}
	bool result = stack.isEmpty();
	return result;
};
Beispiel #16
0
String String::replace(XCHAR cFrom, XCHAR cTo) const
{
	if (!m_pString)
	{
		return String();
	}

	String ret = *this;
	int32 len = ret.getLength();
	for (int32 i=0; i < len; i++)
	{
		if (ret.m_pString[i] == cFrom)
			ret.m_pString[i] = cTo;
	}

	return ret;
}
App::App(void)
:   m_action        (Action_None),
    m_commonCtrl    (CommonControls::Feature_Default & ~CommonControls::Feature_RepaintOnF5),
    m_cullMode      (CullMode_None),

    m_mousePressed  (false),
    m_drawSkeleton  (true),
    m_drawAxes      (true),


    m_x             (0.0f),
    m_y             (0.0f),
    m_z             (0.0f),
    m_sliderChanged (false),
    m_jointChanged  (false),
    
    m_controlIndex  (0)
    
   
{
    m_window.setTitle("basis");
    m_window.addListener(this);
    m_window.addListener(&m_commonCtrl);

    String name = m_window.showFileLoadDialog("Load model");
    if (name.getLength())
        loadModel(name);

    // Make ui controls.
    for (unsigned i = 0; i < NUM_JOINTS; ++i)
    {
       m_controls.push_back(tuple<ModelerControl, 3>(  ModelerControl(&jointNames[i][0], -M_PI, M_PI, 0.1f, 0),
                                                       ModelerControl(&jointNames[i][0], -M_PI, M_PI, 0.1f, 0),
                                                       ModelerControl(&jointNames[i][0], -M_PI, M_PI, 0.1f, 0)));
    }

    updateUI();

    m_window.getGL()->swapBuffers();

    initRendering();

    m_camera.SetDistance( 2 );
    m_camera.SetCenter( Vec3f( 0.5, 0.5, 0.5 ) );
    
}
Beispiel #18
0
	void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
	{
		Application& app = Application::instance();
		try
		{
			WebSocket ws(request, response);
			app.logger().information("WebSocket connection established.");
			char buffer[BUFF_LEN];
			int flags;
			int n;
			do
			{	
				int recvLen = 0;
				while (recvLen < BUFF_LEN) {
					n = ws.receiveFrame(buffer, BUFF_LEN - recvLen, flags);
					recvLen += n;
				}
				
				app.logger().information(Poco::format("Frame received (length=%d, flags=0x%x).", n, unsigned(flags)));
				
				String resp ("aaaaaaaaaa");
				
				ws.sendFrame(resp.getCStr(), resp.getLength(), flags);
			}
			while (n > 0 || (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
			app.logger().information("WebSocket connection closed.");
		}
		catch (WebSocketException& exc)
		{
			app.logger().log(exc);
			switch (exc.code())
			{
				case WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
					response.set("Sec-WebSocket-Version", WebSocket::WEBSOCKET_VERSION);
					// fallthrough
				case WebSocket::WS_ERR_NO_HANDSHAKE:
				case WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
				case WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
					response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
					response.setContentLength(0);
					response.send();
					break;
			}
		}
	}
Beispiel #19
0
String
StreamReader::readString (const String& anyEndChars)
{
	if (_file == NULL)
		return "";	
	
	String word;
	int count = 0;
	size_t loop = 1;
	int length = anyEndChars.getLength();
	char tmp_char;	
	char tmp_short;	
	do{
		tmp_char = fgetc(_file);
		tmp_short = anyEndChars[0];

		if(tmp_char == tmp_short)
		{
			fseek(_file, -(sizeof(char)*1),SEEK_CUR);
			count = 0;
			
			do{
				tmp_char = fgetc(_file);
				tmp_short = anyEndChars[count];
				count = count + 1;
			}while((tmp_char == tmp_short) && (count < length) && (!feof(_file)));
			
			if((tmp_char == tmp_short) && (count == length))
				loop = 0;				
			else{
				count = 0 - count;
				fseek(_file, (sizeof(char)*count), SEEK_CUR);
				tmp_char = fgetc(_file);
				word.append(tmp_char, 1);	
			}
		}
		else{
			word.append(tmp_char, 1);
		}
	}while((!feof(_file)) && (loop == 1));

	return word;	
}
Beispiel #20
0
void CFont::printProportional(float widthRatio, float heightRatio,
                              float width,      float height,
                              float r, float g, float b,
                              const String &string)
{
  Tuple4i viewport;
  
  if (!string.getLength())
    return;
    
  glGetIntegerv(GL_VIEWPORT, viewport);
  
  Tuple2i dimensions = getStringDimensions(string);
  
  float xPosition = (viewport.z - dimensions.x*width)*widthRatio,
                    yPosition = (viewport.w - dimensions.y*height)*heightRatio;
                    
  print(xPosition, yPosition, width, height, r, g, b, string);
}
Beispiel #21
0
bool
Path::isAbsolutePath (const String& path)
{

	if (path.isEmpty ())
		return false;

	size_t pos = path.findFirstOf (Path::invalidPathChars, 0);
	if (pos != String::NO_POSITION)
		THROW ("invalid path!");

	// Check the first character.
	tchar_t ch = path [0];

	return (ch == Path::separator || 
			ch == Path::altSeparator ||
			((separator !=Path::volumeSeparator) && path.getLength () > 1 && path [1] == Path::volumeSeparator));

}
Beispiel #22
0
void String::copy(const String &original)
{
    clear();

    if(original.getLength() < minsize) {
        content.ministring.length = (unsigned)original.getLength();
        memmove(content.ministring.text, original.getText(), original.getLength() + 1);
        content.ministring.big = false;
        return;
    }

//  ptr = original.getText();
    content.bigstring.length = original.getLength();
    content.bigstring.size = setSize(original.getLength() + 1);
    content.bigstring.text = getSpace(original.getLength() + 1);
    content.ministring.big = true;
    memmove(content.bigstring.text, original.getText(), original.getLength() + 1);
}
Beispiel #23
0
String Commandline::toQuotedString() const
{
    const int argc = this->getLength();
    String rslt;
    int firstIndex = 0;
    
    for (int i = firstIndex; i < argc; ++i)
    {
        const String argument = this->get(i);
        
        if (i > firstIndex) {
            rslt << ' ';
        }
        if (argument.containsAny("\"\\ "))
        {
            rslt << '"';
    
            for (int j = 0; j < argument.getLength(); ++j)
            {
                switch (argument[j]) {
                    case '"': {
                        rslt << "\\\"";  //    "   ->   \"
                        break;
                    }
                    case '\\': {
                        rslt << "\\\\";  //    \   ->   \\
                        break;
                    }
                    default: {
                        rslt << argument[j];
                        break;
                    }
                }
            }
            rslt << '"';
        }
        else {
            rslt << argument;
        }
    }
    return rslt;
}
Beispiel #24
0
// public static 
bool 
Path::isValidPath (const String& path)
{
#ifdef __WINDOWS__
	static String validChars;

	if (validChars.isEmpty ()) {
		const tchar_t vchars[] = {
			'"',				/* double quote, which seems allowed in MS.NET but should be rejected */
			'<',				/* less than */
			'>',				/* greater than */
			'|',				/* pipe */
			'*',
			'?',
		};

		validChars.append (vchars, 7);
	}

	if (path.findFirstOf (validChars) != String::NO_POSITION)
		return false;

	// Check invalid ':' character
	if (Path::isAbsolutePath (path)) {
		// absolute path, skip the volume token
		if (path.find (':', 2) != String::NO_POSITION) 
			return false;
	}
	else {
		if (path.find (':') != String::NO_POSITION) 
			return false;
	}

	return true;
#else
	if (path.getLength () > NAME_MAX)
		return false;

	return true;
#endif
}
Beispiel #25
0
void JumpropesCommon::HttpClient::locateAndParseHeader() {
   connection->bufferlock.lockWhenAvailable( GFLOCK_INFINITEWAIT );

   StringVectorRange *tmpRange = new StringVectorRange(0,0);

   bool bPos = connection->receivedData.pos( tmpRange, crlfcrlf, strlen(crlfcrlf) );
   if ( bPos ) {
      lastChunkRange.copyValues( tmpRange );
      lastChunkRange.start_ind = 0;
      lastChunkRange.start_pos = 0;

      rHeader.copyValues( &lastChunkRange );

      lastChunkRange.end_pos++;

      String *sHeaderData = connection->receivedData.copy( &rHeader );
      iHeaderSize = sHeaderData->getLength();

      header.parse( sHeaderData );
      parsedHeader.setValue( sHeaderData );
      delete sHeaderData;

      rLastSend.start_pos = iHeaderSize;
      rLastSend.end_pos = iHeaderSize;

      bHeaderParsed  = true;

      if ( !bHeaderParsed ) {
         stop();

         onStatusUpdate.execute( JRHTTPSTATUS_ERROR );
      } else {
         onStatusUpdate.execute( JRHTTPSTATUS_HEADER );
      }
   }

   delete tmpRange;

   connection->bufferlock.unlock();
}
Beispiel #26
0
// public static 
unsigned int 
UInt::getValue (const String& s)
{
	// TODO: pls reimplement it.
	if (s.isEmpty () == true)
		THROW ("param is null");
	
	const tchar_t* ptr = s.getCStr ();
	size_t len = s.getLength ();
	size_t i = 0;
	for (; i < len; ++i)////假如*ptr不为0,break
		if (ptr[i] != '0')
			break;
			
	if (i == len)/////假如*ptr为0,return 0
		return 0;

#ifdef __WINDOWS__
	unsigned value = 0;
	//
	// TODO: Windows版本暂不兼容
	//
	THROW ("Windows is not supported UInt::getValue!");
	
#else
	tchar_t* endptr;
	unsigned int value = strtoul(s.getCStr(), &endptr, 10);///以十进制输出
#endif
	if (value == 0) {
		String msg ("UInt getValue error");
#ifdef __WINDOWS__
		THROW (msg);
#else
		THROW (msg);
#endif
	}

	return value;
}
Beispiel #27
0
void StatusLine::drawFileName()
{
    String displayText;
    if (hasMessage) {
        displayText = message;
    } else {
        displayText = fileName;
    }

    GuiClipping::Holder clippingHolder(getGuiWidget()->getClipping(),
                                       GuiWidget::getRaisedBoxBorderWidth(), 
                                       GuiWidget::getRaisedBoxBorderWidth(), 
                                       getPosition().w - 2 * GuiWidget::getRaisedBoxBorderWidth(), 
                                       getPosition().h - 2 * GuiWidget::getRaisedBoxBorderWidth());
    
    getGuiWidget()->drawGuiTextUtf8String(4, 2, displayText);

    RawPtr<TextStyle> guiTextStyle = GuiWidget::getGuiTextStyle();

    lengthPos = guiTextStyle->getTextWidth(displayText.toCString(), displayText.getLength())
                + 3 * guiTextStyle->getSpaceWidth();
}
GLuint GLContext::Program::createGLShader(GLenum type, const String& typeStr, const String& source, bool bThrow)
{
    GLuint shader = glCreateShader(type);
    const char* sourcePtr = source.getPtr();
    int sourceLen = source.getLength();
    glShaderSource(shader, 1, &sourcePtr, &sourceLen);
    glCompileShader(shader);

    GLint status = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (!status)
    {
        GLint infoLen = 0;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
        if (!infoLen)
			if ( !bThrow )
				fail("glCompileShader(%s) failed!", typeStr.getPtr());
			else
			{
				glDeleteShader(shader);
				throw ShaderCompilationException( sprintf( "glCompileShader(%s) failed!", typeStr.getPtr() ) );
			}

        Array<char> info(NULL, infoLen);
        info[0] = '\0';
        glGetShaderInfoLog(shader, infoLen, &infoLen, info.getPtr());
		if ( !bThrow )
			fail("glCompileShader(%s) failed!\n\n%s", typeStr.getPtr(), info.getPtr());
		else
		{
			glDeleteShader(shader);
			throw ShaderCompilationException( sprintf( "glCompileShader(%s) failed!\n\n%s", typeStr.getPtr(), info.getPtr() ) );
		}

    }

    GLContext::checkErrors();
    return shader;
}
Beispiel #29
0
void SaveAsPanel::show()
{
    RawPtr<TextData> textData = editorWidget->getTextData();
    
    String newContent;
    if (textData->isFileNamePseudo()) 
    {
        String dirName = File(textData->getFileName()).getDirName();
        newContent = String() << EncodingConverter::convertLocaleToUtf8StringIgnoreErrors(dirName)
                              << "/";
    } else {
        String absName = File(textData->getFileName()).getAbsoluteName();
        newContent     = EncodingConverter::convertLocaleToUtf8StringIgnoreErrors(absName);
    }
    editField->getTextData()->setToString(newContent);
    editField->getTextData()->clearHistory();
    editField->setCursorPosition(newContent.getLength());

    setFocus(editField);

    DialogPanel::show();
}
Beispiel #30
0
void GLContext::Program::init(
    const String& vertexSource,
    GLenum geomInputType, GLenum geomOutputType, int geomVerticesOut, const String& geometrySource,
    const String& fragmentSource)
{
    GLContext::staticInit();
    m_glProgram = glCreateProgram();

    // Setup vertex shader.

    m_glVertexShader = createGLShader(GL_VERTEX_SHADER, "GL_VERTEX_SHADER", vertexSource);
    glAttachShader(m_glProgram, m_glVertexShader);

    // Setup geometry shader (GL_ARB_geometry_shader4).

    if (geometrySource.getLength() == 0)
        m_glGeometryShader = 0;
    else
    {
        m_glGeometryShader = createGLShader(GL_GEOMETRY_SHADER_ARB, "GL_GEOMETRY_SHADER_ARB", geometrySource);
        glAttachShader(m_glProgram, m_glGeometryShader);

        if (!GL_FUNC_AVAILABLE(glProgramParameteriARB))
            fail("glProgramParameteriARB() not available!");
        glProgramParameteriARB(m_glProgram, GL_GEOMETRY_INPUT_TYPE_ARB, geomInputType);
        glProgramParameteriARB(m_glProgram, GL_GEOMETRY_OUTPUT_TYPE_ARB, geomOutputType);
        glProgramParameteriARB(m_glProgram, GL_GEOMETRY_VERTICES_OUT_ARB, geomVerticesOut);
    }

    // Setup fragment shader.

    m_glFragmentShader = createGLShader(GL_FRAGMENT_SHADER, "GL_FRAGMENT_SHADER", fragmentSource);
    glAttachShader(m_glProgram, m_glFragmentShader);

    // Link.

    linkGLProgram(m_glProgram);
}