⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wgl.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* I think this is only possible within one ICD */
	if (src->icd != src->icd)
	{
		DBGPRINT( "Error: src and dst GLRC use different ICDs!" );
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}

	/* copy data (call ICD) */
	return src->icd->DrvCopyContext( src->hglrc, dst->hglrc, mask );
}


/*! \brief Create a new GL Rendering Context.
 *
 * This function can create over- or underlay surfaces.
 *
 * \param hdc [IN] Handle for DC for which to create context
 * \param layer [IN] Layer number to bind (draw?) to
 *
 * \return Handle for the created GLRC
 * \retval NULL Failure
 */
HGLRC
APIENTRY
rosglCreateLayerContext( HDC hdc, int layer )
{
	GLDRIVERDATA *icd = NULL;
	GLRC *glrc;
	HGLRC drvHglrc = NULL;

	DBGTRACE( "Called!" );

/*	if (GetObjectType( hdc ) != OBJ_DC)
	{
		DBGPRINT( "Error: hdc is not a DC handle!" );
		return NULL;
	}
*/
	/* create new GLRC */
	glrc = ROSGL_NewContext();
	if (glrc == NULL)
		return NULL;

	/* load ICD */
	icd = ROSGL_ICDForHDC( hdc );
	if (icd == NULL)
	{
		ROSGL_DeleteContext( glrc );
		DBGPRINT( "Couldn't get ICD by HDC :-(" );
		/* FIXME: fallback? */
		return NULL;
	}

	/* create context */
	if (icd->DrvCreateLayerContext != NULL)
		drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
	if (drvHglrc == NULL)
	{
		if (layer == 0 && icd->DrvCreateContext != NULL)
			drvHglrc = icd->DrvCreateContext( hdc );
		else
			DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
	}

	if (drvHglrc == NULL)
	{
		/* FIXME: fallback to mesa? */
		DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() );
		ROSGL_DeleteContext( glrc );
		return NULL;
	}

	/* we have our GLRC in glrc and the ICD's GLRC in drvHglrc */
	glrc->hglrc = drvHglrc;
	glrc->icd = icd;

	return (HGLRC)glrc;
}


/*! \brief Create a new GL Rendering Context.
 *
 * \param hdc [IN] Handle for DC for which to create context
 *
 * \return Handle for the created GLRC
 * \retval NULL Failure
 */
HGLRC
APIENTRY
rosglCreateContext( HDC hdc )
{
	return rosglCreateLayerContext( hdc, 0 );
}


/*! \brief Delete an OpenGL context
 *
 * \param hglrc [IN] Handle to GLRC to delete; must not be a threads current RC!
 *
 * \retval TRUE  Success
 * \retval FALSE Failure (i.e. GLRC is current for a thread)
 */
BOOL
APIENTRY
rosglDeleteContext( HGLRC hglrc )
{
	GLRC *glrc = (GLRC *)hglrc;

	/* check if we know about this context */
	if (!ROSGL_ContainsContext( glrc ))
	{
		DBGPRINT( "Error: hglrc not found!" );
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}

	/* make sure GLRC is not current for some thread */
	if (glrc->is_current)
	{
		DBGPRINT( "Error: GLRC is current for DC 0x%08x", glrc->hdc );
		SetLastError( ERROR_INVALID_FUNCTION );
		return FALSE;
	}

	/* release ICD's context */
	if (glrc->hglrc != NULL)
	{
		if (!glrc->icd->DrvDeleteContext( glrc->hglrc ))
		{
			DBGPRINT( "Warning: DrvDeleteContext() failed (%d)", GetLastError() );
			return FALSE;
		}
	}

	/* free resources */
	return ROSGL_DeleteContext( glrc );
}


BOOL
APIENTRY
rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
                         UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return FALSE;
}


/*! \brief Gets information about a pixelformat.
 *
 * \param hdc     [IN]  Handle to DC
 * \param iFormat [IN]  Pixelformat index
 * \param nBytes  [IN]  sizeof (pfd) - at most nBytes are copied into pfd
 * \param pfd     [OUT] Pointer to a PIXELFORMATDESCRIPTOR
 *
 * \return Maximum pixelformat index/number of formats
 * \retval 0 Failure
 */
int
APIENTRY
rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
                          LPPIXELFORMATDESCRIPTOR pfd )
{
	int ret = 0;
	GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );

	if (icd != NULL)
	{
		ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
		if (ret == 0)
			DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
	}
	else
	{
		SetLastError( ERROR_INVALID_FUNCTION );
	}

	return ret;
}


/*! \brief Return the thread's current GLRC
 *
 * \return Handle for thread's current GLRC
 * \retval NULL No current GLRC set
 */
HGLRC
APIENTRY
rosglGetCurrentContext()
{
	return (HGLRC)(OPENGL32_threaddata->glrc);
}


/*! \brief Return the thread's current DC
 *
 * \return Handle for thread's current DC
 * \retval NULL No current DC/GLRC set
 */
HDC
APIENTRY
rosglGetCurrentDC()
{
	/* FIXME: is it correct to return NULL when there is no current GLRC or
	   is there another way to find out the wanted HDC? */
	if (OPENGL32_threaddata->glrc == NULL)
		return NULL;
	return (HDC)(OPENGL32_threaddata->glrc->hdc);
}


int
APIENTRY
rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
                             int cEntries, COLORREF *pcr )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return 0;
}


/*! \brief Returns the current pixelformat.
 *
 * \param hdc [IN] Handle to DC to get the pixelformat from
 *
 * \return Pixelformat index
 * \retval 0 Failure
 */
int
WINAPI
rosglGetPixelFormat( HDC hdc )
{
	GLDCDATA *dcdata;

	DBGTRACE( "Called!" );

	dcdata = ROSGL_GetPrivateDCData( hdc );
	if (dcdata == NULL)
	{
		DBGPRINT( "Error: ROSGL_GetPrivateDCData failed!" );
		return 0;
	}

	return dcdata->pixel_format;
}


/*! \brief Get the address for an OpenGL extension function.
 *
 * The addresses this function returns are only valid within the same thread
 * which it was called from.
 *
 * \param proc [IN] Name of the function to look for
 *
 * \return The address of the proc
 * \retval NULL Failure
 */
PROC
APIENTRY
rosglGetProcAddress( LPCSTR proc )
{
	PROC func;
	GLDRIVERDATA *icd;

	if (OPENGL32_threaddata->glrc == NULL)
	{
		DBGPRINT( "Error: No current GLRC!" );
		SetLastError( ERROR_INVALID_FUNCTION );
		return NULL;
	}

	icd = OPENGL32_threaddata->glrc->icd;
	func = icd->DrvGetProcAddress( proc );
	if (func != NULL)
	{
		DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
		return func;
	}

	/* FIXME: Should we return wgl/gl 1.1 functions? */
	SetLastError( ERROR_PROC_NOT_FOUND );
	return NULL;
}


/*! \brief Make the given GLRC the threads current GLRC for hdc
 *
 * \param hdc   [IN] Handle for a DC to be drawn on
 * \param hglrc [IN] Handle for a GLRC to make current
 *
 * \retval TRUE  Success
 * \retval FALSE Failure
 */
BOOL
APIENTRY
rosglMakeCurrent( HDC hdc, HGLRC hglrc )
{
	GLRC *glrc = (GLRC *)hglrc;
	ICDTable *icdTable = NULL;

	DBGTRACE( "Called!" );

	/* flush current context */
	if (OPENGL32_threaddata->glrc != NULL)
	{
		glFlush();
	}

	/* check if current context is unset */
	if (glrc == NULL)
	{
		if (OPENGL32_threaddata->glrc != NULL)
		{
			glrc = OPENGL32_threaddata->glrc;
			glrc->icd->DrvReleaseContext( glrc->hglrc );
			glrc->is_current = FALSE;
			OPENGL32_threaddata->glrc = NULL;
		}
	}
	else
	{
		/* check hdc */
		if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
		{
			DBGPRINT( "Error: hdc is not a DC handle!" );
			SetLastError( ERROR_INVALID_HANDLE );
			return FALSE;
		}

		/* check if we know about this glrc */
		if (!ROSGL_ContainsContext( glrc ))
		{
			DBGPRINT( "Error: hglrc not found!" );
			SetLastError( ERROR_INVALID_HANDLE );
			return FALSE;
		}

		/* check if it is available */
		if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */
		{
			DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
			SetLastError( ERROR_INVALID_HANDLE );
			return FALSE;
		}

		/* call the ICD */
		if (glrc->hglrc != NULL)
		{
			DBGPRINT( "Info: Calling DrvSetContext!" );
			SetLastError( ERROR_SUCCESS );
			icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
			                                     ROSGL_SetContextCallBack );
			if (icdTable == NULL)
			{
				DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
				return FALSE;
			}
			DBGPRINT( "Info: DrvSetContext succeeded!" );
		}

		/* make it current */
		if (OPENGL32_threaddata->glrc != NULL)
			OPENGL32_threaddata->glrc->is_current = FALSE;
		glrc->is_current = TRUE;
		glrc->thread_id = GetCurrentThreadId();
		glrc->hdc = hdc;
		OPENGL32_threaddata->glrc = glrc;
	}

	if (ROSGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS && icdTable == NULL)
	{
		DBGPRINT( "Warning: ROSGL_SetContextCallBack failed!" );
	}

	return TRUE;
}


BOOL
APIENTRY
rosglRealizeLayerPalette( HDC hdc, int iLayerPlane, BOOL bRealize )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return FALSE;
}


int
APIENTRY
rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
                             int cEntries, CONST COLORREF *pcr )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return 0;
}


/*! \brief Set a DCs pixelformat
 *
 * \param hdc     [IN] Handle to DC for which to set the format
 * \param iFormat [IN] Index of the pixelformat to set
 * \param pfd     [IN] Not sure what this is for
 *
 * \retval TRUE  Success
 * \retval FALSE Failure
 */
BOOL
WINAPI
rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
{
	GLDRIVERDATA *icd;
	GLDCDATA *dcdata;

	DBGTRACE( "Called!" );

	/* load ICD */
	icd = ROSGL_ICDForHDC( hdc );
	if (icd == NULL)
	{
		DBGPRINT( "Warning: ICDForHDC() failed" );
		return FALSE;
	}

	/* call ICD */
	if (!icd->DrvSetPixelFormat( hdc, iFormat/*, pfd*/ ))
	{
		DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
		          iFormat, GetLastError() );
		return FALSE;
	}

	/* store format in private DC data */
	dcdata = ROSGL_GetPrivateDCData( hdc );
	if (dcdata == NULL)
	{
		DBGPRINT( "Error: ROSGL_GetPrivateDCData() failed!" );
		return FALSE;
	}
	dcdata->pixel_format = iFormat;

	return TRUE;
}


/*! \brief Enable display-list sharing between multiple GLRCs
 *
 * This will only work if both GLRCs are from the same driver.
 *
 * \param hglrc1 [IN] GLRC number 1
 * \param hglrc2 [IN] GLRC number 2
 *
 * \retval TRUE  Success
 * \retval FALSE Failure
 */
BOOL
APIENTRY
rosglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
{
	GLRC *glrc1 = (GLRC *)hglrc1;
	GLRC *glrc2 = (GLRC *)hglrc2;

	/* check glrcs */
	if (!ROSGL_ContainsContext( glrc1 ))
	{
		DBGPRINT( "Error: hglrc1 not found!" );
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}
	if (!ROSGL_ContainsContext( glrc2 ))
	{
		DBGPRINT( "Error: hglrc2 not found!" );
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}

	/* I think this is only possible within one ICD */
	if (glrc1->icd != glrc2->icd)
	{
		DBGPRINT( "Error: hglrc1 and hglrc2 use different ICDs!" );
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}

	/* share lists (call ICD) */
	return glrc1->icd->DrvShareLists( glrc1->hglrc, glrc2->hglrc );
}


/*! \brief Flushes GL and swaps front/back buffer if appropriate
 *
 * \param hdc [IN] Handle to device context to swap buffers for
 *
 * \retval TRUE  Success
 * \retval FALSE Failure
 */
BOOL
APIENTRY
rosglSwapBuffers( HDC hdc )
{
	GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
	DBGTRACE( "Called!" );
	if (icd != NULL)
	{
		DBGPRINT( "Swapping buffers!" );
		if (!icd->DrvSwapBuffers( hdc ))
		{
			DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
			return FALSE;
		}
		return TRUE;
	}

	/* FIXME: implement own functionality? */
	SetLastError( ERROR_INVALID_FUNCTION );
	return FALSE;
}


BOOL
APIENTRY
rosglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return FALSE;
}


BOOL
APIENTRY
rosglUseFontBitmapsA( HDC hdc, DWORD  first, DWORD count, DWORD listBase )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return FALSE;
}


BOOL
APIENTRY
rosglUseFontBitmapsW( HDC hdc, DWORD  first, DWORD count, DWORD listBase )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return FALSE;
}


BOOL
APIENTRY
rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
                       FLOAT deviation, FLOAT extrusion, int format,
                       GLYPHMETRICSFLOAT *pgmf )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return FALSE;
}


BOOL
APIENTRY
rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
                       FLOAT deviation, FLOAT extrusion, int format,
                       GLYPHMETRICSFLOAT *pgmf )
{
	UNIMPLEMENTED;
	SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
	return FALSE;
}

#ifdef __cplusplus
}; /* extern "C" */
#endif /* __cplusplus */

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -