📄 wgl.c
字号:
/* 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 + -