// xmPlatformMapDirectoryPath : Map absoulte path to virtual path.
KDvoid xmPlatformMapDirectoryPath ( KDchar** paths )
{
	KDint    i;

	for ( i = 0; i < XM_DIRECTORY_COUNT; i++ )
	{
		if ( ( paths[ i ] = (KDchar *) kdCalloc ( 1, 256 ) ) )
		{
			switch ( i )
			{
				case 0 : strcpy ( paths[ i ], "/Home/Resource" );     break; // "/res"
				case 1 : strcpy ( paths[ i ], "/Home/Data" );         break; // "/data"
				case 2 : strcpy ( paths[ i ], "/Home/Temp" );         break; // "/tmp"
				case 3 : strcpy ( paths[ i ], "/Storagecard");        break; // "/removable"
				case 4 : strcpy ( paths[ i ], "/Storagecard/Media");  break; // "/storage"
				case 5 : break; // "/native"
				case 6 : strcpy ( paths[ i ], "/Home" );              break; // "/"
			}
		}
		else
		{
			kdLogMessage ( "Alloc memory failed." );
			kdExit ( -3 );
		}
	}
}
KDvoid CTutorial::Redraw ( KDvoid )
{
	/*
		Ok, now we have set up the scene, lets draw everything: We run the
		device in a while() loop, until the device does not want to run any
		more. This would be when the user closes the window or presses ALT+F4
		(or whatever keycode closes a window).
	*/
	if ( s_pDevice && s_pDevice->run ( ) )
	{
		/*
			Anything can be drawn between a beginScene() and an endScene()
			call. The beginScene() call clears the screen with a color and
			the depth buffer, if desired. Then we let the Scene Manager and
			the GUI Environment draw their content. With the endScene()
			call everything is presented on the screen.
		*/
		s_pDriver->beginScene ( true, true, s_pTutorial->getClear ( ) );

		s_pTutorial->Draw ( );

		s_pDriver->endScene ( );
	}
	else
	{
		kdExit ( 0 );
	}
}
KDvoid xmCreateTSS ( KDvoid )
{
	l_tss = xmQueueCreate ( );

	if ( !l_tss )
	{
		kdLogMessage ( "Thread storage key manager create failed." );
		kdExit ( 3 );
	}
}
// xmPlatformMapDirectoryPath : Map absoulte path to virtual path.
KDvoid xmPlatformMapDirectoryPath ( KDchar** paths )
{
	KDchar    rootdir[256] = "";
	KDint     rootlen = 0;
	KDint     i;
	
	if ( ( getcwd ( rootdir, 256 ) ) )
	{
		rootlen = kdStrlen ( rootdir );

		for ( i = 0; i < XM_DIRECTORY_COUNT; i++ )
		{
			if ( ( paths[ i ] = (KDchar *) kdCalloc ( 1, rootlen + 25 ) ) )
			{
				switch ( i ) 
				{					
					case 0 : kdSprintfKHR ( paths[ i ], "%s/../../Resource" , rootdir ); break; // "/res"	
					case 1 : kdSprintfKHR ( paths[ i ], "%s/../../Data"		, rootdir ); break; // "/data"					
					case 2 : kdSprintfKHR ( paths[ i ], "%s/Temp"			, rootdir ); break; // "/tmp"	
					case 3 : break;	// "/removable"				
					case 4 : kdSprintfKHR ( paths[ i ], "/media/psf/Home/XMStorage"); break; // "/storage"
					case 5 : break; // "/native"
					case 6 : kdSprintfKHR ( paths[ i ], "%s"           , rootdir ); break; // "/"	
				}		
			}
			else
			{
				kdLogMessage ( "Alloc memory failed." );
				kdExit ( -3 );
			}
		}
	}
	else
	{
		kdLogMessage ( "Get root directory failed." );
		kdExit ( -3 );
	}
}
/* Initializes the OpenGL ES context into a KDWindow */
void initEGL(KDWindow *wnd)
{
    GLbyte *buf = KD_NULL;
    GLbyte *walk;
    KDint i, k;
    const KDint sizes[9] = { 256, 128, 64, 32, 16, 8, 4, 2, 1 };
    const GLubyte rs[9] = { 255, 0, 255, 0, 255, 0, 255, 0, 255 };
    const GLubyte gs[9] = { 0, 0, 255, 0, 0, 255, 0, 0, 255};
    const GLubyte bs[9] = { 0, 255, 0, 255, 0, 255, 0, 255, 0 };

    /* Set the attributes for the window surface */
    static const EGLint s_surfaceAttribs[] =
    {
        EGL_COLORSPACE,		EGL_COLORSPACE_LINEAR,
        EGL_ALPHA_FORMAT,	EGL_ALPHA_FORMAT_NONPRE,
        EGL_NONE
    };
    EGLNativeWindowType nativeType;
    if(kdRealizeWindow(wnd, &nativeType) != 0)
        kdExit(20);

    /* Create a window surface for OpenGL ES */
    GLOBALS->eglWindowSurface	= eglCreateWindowSurface(GLOBALS->eglDisplay, GLOBALS->eglConfig, nativeType, s_surfaceAttribs);

    /* Create a context for OpenGL ES */
#ifndef TEST_LOCKSURFACE
    eglBindAPI (EGL_OPENGL_ES_API);
    GLOBALS->eglContextOpenGLES	= eglCreateContext(GLOBALS->eglDisplay, GLOBALS->eglConfig, KD_NULL, KD_NULL);
    eglMakeCurrent	(GLOBALS->eglDisplay, GLOBALS->eglWindowSurface, GLOBALS->eglWindowSurface, GLOBALS->eglContextOpenGLES);
#endif

    /* Generate a texture */
    glGenTextures(1, &GLOBALS->tex);
    glBindTexture(GL_TEXTURE_2D, GLOBALS->tex);

    buf = kdMalloc(sizes[0] * sizes[0] * 3);

    for(k = 0; k < 9; k++)
    {
        walk = buf;
        for(i = 0; i < sizes[k] * sizes[k]; i++)
        {
            *(walk++) = (i % 3 == 0) ? rs[k] : 0;
            *(walk++) = (i % 3 == 0) ? gs[k] : 0;
            *(walk++) = (i % 3 == 0) ? bs[k] : 0;
        }
        glTexImage2D(GL_TEXTURE_2D, k, GL_RGB, sizes[k], sizes[k], 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
    }
    kdFree(buf);
}
// kdThreadExit : Terminate this thread.
KD_API KD_NORETURN KDvoid KD_APIENTRY kdThreadExit ( KDvoid* retval )
{	
	XMQueue*       contexts = 0;
	XMContext*     context  = 0;
	KDThread*      thread   = 0;
	
	contexts = xmGetContexts ( );
	context  = (XMContext *) xmQueueGet ( contexts , 0 );
	thread   = kdThreadSelf ( );

	if ( context->thread == thread )
	{
		kdExit ( 0 );
	}
	else
	{
		pthread_exit ( retval );
	}
}