659 lines
19 KiB
C
659 lines
19 KiB
C
/******************************Module*Header*******************************\
|
|
* Module Name: makecur.c
|
|
*
|
|
* wglMakeCurrent implementation
|
|
*
|
|
* Created: 02-10-1997
|
|
*
|
|
* Copyright (c) 1993-1997 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include <context.h>
|
|
#include <global.h>
|
|
|
|
#include "metasup.h"
|
|
#include "wgldef.h"
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __wglSetProcTable
|
|
*
|
|
* Callback function given to ICDs to set a proc table
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void APIENTRY
|
|
__wglSetProcTable(PGLCLTPROCTABLE pglCltProcTable)
|
|
{
|
|
if (pglCltProcTable == (PGLCLTPROCTABLE) NULL)
|
|
return;
|
|
|
|
// It must have either 306 entries for version 1.0 or 336 entries for 1.1
|
|
|
|
if (pglCltProcTable->cEntries != OPENGL_VERSION_100_ENTRIES &&
|
|
pglCltProcTable->cEntries != OPENGL_VERSION_110_ENTRIES)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// This function is called by client drivers which do not use
|
|
// the EXT procs provided by opengl32. Use the null EXT proc
|
|
// table to disable those stubs since they should never be
|
|
// called anyway
|
|
SetCltProcTable(pglCltProcTable, &glNullExtProcTable, TRUE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* CheckDeviceModes
|
|
*
|
|
* Ensures that the HDC doesn't have any disallowed state
|
|
*
|
|
* History:
|
|
* Mon Aug 26 15:03:28 1996 -by- Drew Bliss [drewb]
|
|
* Split from wglMakeCurrent
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL CheckDeviceModes(HDC hdc)
|
|
{
|
|
SIZE szW, szV;
|
|
XFORM xform;
|
|
POINT pt;
|
|
HRGN hrgnTmp;
|
|
int iRgn;
|
|
|
|
// For release 1, GDI transforms must be identity.
|
|
// This is to allow GDI transform binding in future.
|
|
|
|
switch (GetMapMode(hdc))
|
|
{
|
|
case MM_TEXT:
|
|
break;
|
|
case MM_ANISOTROPIC:
|
|
if (!GetWindowExtEx(hdc, &szW)
|
|
|| !GetViewportExtEx(hdc, &szV)
|
|
|| szW.cx != szV.cx
|
|
|| szW.cy != szV.cy)
|
|
goto wglMakeCurrent_xform_error;
|
|
break;
|
|
default:
|
|
goto wglMakeCurrent_xform_error;
|
|
}
|
|
|
|
if (!GetViewportOrgEx(hdc, &pt) || pt.x != 0 || pt.y != 0)
|
|
goto wglMakeCurrent_xform_error;
|
|
|
|
if (!GetWindowOrgEx(hdc, &pt) || pt.x != 0 || pt.y != 0)
|
|
goto wglMakeCurrent_xform_error;
|
|
|
|
if (!GetWorldTransform(hdc, &xform))
|
|
{
|
|
// Win95 does not support GetWorldTransform.
|
|
|
|
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
|
|
goto wglMakeCurrent_xform_error;
|
|
}
|
|
else if (xform.eDx != 0.0f || xform.eDy != 0.0f
|
|
|| xform.eM12 != 0.0f || xform.eM21 != 0.0f
|
|
|| xform.eM11 < 0.999f || xform.eM11 > 1.001f // allow rounding errors
|
|
|| xform.eM22 < 0.999f || xform.eM22 > 1.001f)
|
|
{
|
|
wglMakeCurrent_xform_error:
|
|
DBGERROR("wglMakeCurrent: GDI transforms not identity\n");
|
|
SetLastError(ERROR_TRANSFORM_NOT_SUPPORTED);
|
|
return FALSE;
|
|
}
|
|
|
|
// For release 1, GDI clip region is not allowed.
|
|
// This is to allow GDI clip region binding in future.
|
|
|
|
if (!(hrgnTmp = CreateRectRgn(0, 0, 0, 0)))
|
|
return FALSE;
|
|
|
|
iRgn = GetClipRgn(hdc, hrgnTmp);
|
|
|
|
if (!DeleteObject(hrgnTmp))
|
|
ASSERTOPENGL(FALSE, "DeleteObject failed");
|
|
|
|
switch (iRgn)
|
|
{
|
|
case -1: // error
|
|
WARNING("wglMakeCurrent: GetClipRgn failed\n");
|
|
return FALSE;
|
|
|
|
case 0: // no initial clip region
|
|
break;
|
|
|
|
case 1: // has initial clip region
|
|
DBGERROR("wglMakeCurrent: GDI clip region not allowed\n");
|
|
SetLastError(ERROR_CLIPPING_NOT_SUPPORTED);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* MakeAnyCurrent
|
|
*
|
|
* Makes any type of context current
|
|
*
|
|
* History:
|
|
* Mon Aug 26 15:00:44 1996 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL MakeAnyCurrent(HGLRC hrc, int ipfd, DWORD dwObjectType,
|
|
GLWINDOWID *pgwid)
|
|
{
|
|
HGLRC hrcSrv;
|
|
PLRC plrc;
|
|
DWORD tidCurrent;
|
|
ULONG irc;
|
|
PLHE plheRC;
|
|
PGLCLTPROCTABLE pglProcTable;
|
|
PGLEXTPROCTABLE pglExtProcTable;
|
|
POLYARRAY *pa;
|
|
|
|
DBGENTRY("wglMakeCurrent\n");
|
|
|
|
// If this is a new, uninitialized thread, try to initialize it
|
|
if (CURRENT_GLTEBINFO() == NULL)
|
|
{
|
|
GLInitializeThread(DLL_THREAD_ATTACH);
|
|
|
|
// If the teb was not set up at thread initialization, return failure.
|
|
|
|
if (!CURRENT_GLTEBINFO())
|
|
{
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
// There are four cases:
|
|
//
|
|
// 1. hrc is NULL and there is no current RC.
|
|
// 2. hrc is NULL and there is a current RC.
|
|
// 3. hrc is not NULL and there is a current RC.
|
|
// 4. hrc is not NULL and there is no current RC.
|
|
|
|
// Case 1: hrc is NULL and there is no current RC.
|
|
// This is a noop, return success.
|
|
|
|
if (hrc == (HGLRC) 0 && (GLTEB_CLTCURRENTRC() == (PLRC) NULL))
|
|
return(TRUE);
|
|
|
|
// Case 2: hrc is NULL and there is a current RC.
|
|
// Make the current RC inactive.
|
|
|
|
if (hrc == (HGLRC) 0 && (GLTEB_CLTCURRENTRC() != (PLRC) NULL))
|
|
return(bMakeNoCurrent());
|
|
|
|
// Get the current thread id.
|
|
|
|
tidCurrent = GetCurrentThreadId();
|
|
ASSERTOPENGL(tidCurrent != INVALID_THREAD_ID,
|
|
"wglMakeCurrent: GetCurrentThreadId returned a bad value\n");
|
|
|
|
// Validate the handles. hrc is not NULL here.
|
|
|
|
ASSERTOPENGL(hrc != (HGLRC) NULL, "wglMakeCurrent: hrc is NULL\n");
|
|
|
|
// Validate the RC.
|
|
|
|
if (cLockHandle((ULONG_PTR)hrc) <= 0)
|
|
{
|
|
DBGLEVEL1(LEVEL_ERROR, "wglMakeCurrent: can't lock hrc 0x%lx\n", hrc);
|
|
goto wglMakeCurrent_error_nolock;
|
|
}
|
|
irc = MASKINDEX(hrc);
|
|
plheRC = pLocalTable + irc;
|
|
plrc = (PLRC) plheRC->pv;
|
|
hrcSrv = (HGLRC) plheRC->hgre;
|
|
ASSERTOPENGL(plrc->ident == LRC_IDENTIFIER, "wglMakeCurrent: Bad plrc\n");
|
|
|
|
#ifdef GL_METAFILE
|
|
// Ensure that metafile RC's are made current only to
|
|
// metafile DC's
|
|
if (plrc->uiGlsCaptureContext != 0 && dwObjectType != OBJ_ENHMETADC)
|
|
{
|
|
DBGLEVEL(LEVEL_ERROR,
|
|
"wglMakeCurrent: attempt to make meta RC current "
|
|
"to non-meta DC\n");
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
vUnlockHandle((ULONG_PTR)hrc);
|
|
return FALSE;
|
|
}
|
|
|
|
// Ensure that non-metafile RC's are made current only to
|
|
// non-metafile DC's
|
|
if (plrc->uiGlsCaptureContext == 0 && dwObjectType == OBJ_ENHMETADC)
|
|
{
|
|
DBGLEVEL(LEVEL_ERROR,
|
|
"wglMakeCurrent: attempt to make non-meta RC current "
|
|
"to meta DC\n");
|
|
SetLastError(ERROR_METAFILE_NOT_SUPPORTED);
|
|
vUnlockHandle((ULONG_PTR)hrc);
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
// If the RC is current, it must be current to this thread because
|
|
// makecurrent locks down the handle.
|
|
// If the given RC is already current to this thread, we will release it first,
|
|
// then make it current again. This is to support DC/RC attribute bindings in
|
|
// this function.
|
|
|
|
ASSERTOPENGL(plrc->tidCurrent == INVALID_THREAD_ID ||
|
|
plrc->tidCurrent == tidCurrent,
|
|
"wglMakeCurrent: hrc is current to another thread\n");
|
|
|
|
// Case 3: hrc is not NULL and there is a current RC.
|
|
// This is case 2 followed by case 4.
|
|
|
|
if (GLTEB_CLTCURRENTRC())
|
|
{
|
|
// First, make the current RC inactive.
|
|
|
|
if (!bMakeNoCurrent())
|
|
{
|
|
DBGERROR("wglMakeCurrent: bMakeNoCurrent failed\n");
|
|
vUnlockHandle((ULONG_PTR)hrc);
|
|
return(FALSE);
|
|
}
|
|
|
|
// Second, make hrc current. Fall through to case 4.
|
|
}
|
|
|
|
// Case 4: hrc is not NULL and there is no current RC.
|
|
|
|
ASSERTOPENGL(GLTEB_CLTCURRENTRC() == (PLRC) NULL,
|
|
"wglMakeCurrent: There is a current RC!\n");
|
|
|
|
// If the pixel format of the window or surface is different from that of
|
|
// the RC, return error.
|
|
|
|
if (ipfd != plrc->iPixelFormat)
|
|
{
|
|
DBGERROR("wglMakeCurrent: different hdc and hrc pixel formats\n");
|
|
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
|
goto wglMakeCurrent_error;
|
|
}
|
|
|
|
// Since the client code manages the function table, we will make
|
|
// either the server or the driver current.
|
|
|
|
if (!plrc->dhrc)
|
|
{
|
|
// If this is a generic format, tell the server to make it current.
|
|
|
|
#ifndef _CLIENTSIDE_
|
|
// If the subbatch data has not been set up for this thread, set it up now.
|
|
|
|
if (GLTEB_CLTSHAREDSECTIONINFO() == NULL)
|
|
{
|
|
if (!glsbCreateAndDuplicateSection(SHARED_SECTION_SIZE))
|
|
{
|
|
WARNING("wglMakeCurrent: unable to create section\n");
|
|
goto wglMakeCurrent_error;
|
|
}
|
|
}
|
|
#endif // !_CLIENTSIDE_
|
|
|
|
if (!__wglMakeCurrent(pgwid, hrcSrv, plrc->uiGlsCaptureContext != 0))
|
|
{
|
|
DBGERROR("wglMakeCurrent: server failed\n");
|
|
goto wglMakeCurrent_error;
|
|
}
|
|
|
|
// Get the generic function table or metafile function table
|
|
|
|
#ifdef GL_METAFILE
|
|
if (plrc->fCapturing)
|
|
{
|
|
MetaGlProcTables(&pglProcTable, &pglExtProcTable);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
// Use RGBA or CI proc table depending on the color mode.
|
|
|
|
// The gc should be available by now.
|
|
__GL_SETUP();
|
|
|
|
if (gc->modes.colorIndexMode)
|
|
pglProcTable = &glCltCIProcTable;
|
|
else
|
|
pglProcTable = &glCltRGBAProcTable;
|
|
pglExtProcTable = &glExtProcTable;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If this is a device format, tell the driver to make it current.
|
|
// Get the driver function table from the driver.
|
|
// pfnDrvSetContext returns the address of the driver OpenGL function
|
|
// table if successful; NULL otherwise.
|
|
|
|
ASSERTOPENGL(plrc->pGLDriver, "wglMakeCurrent: No GLDriver\n");
|
|
|
|
pglProcTable = plrc->pGLDriver->pfnDrvSetContext(pgwid->hdc,
|
|
plrc->dhrc,
|
|
__wglSetProcTable);
|
|
if (pglProcTable == (PGLCLTPROCTABLE) NULL)
|
|
{
|
|
DBGERROR("wglMakeCurrent: pfnDrvSetContext failed\n");
|
|
goto wglMakeCurrent_error;
|
|
}
|
|
|
|
// It must have either 306 entries for version 1.0 or 336 entries for 1.1
|
|
|
|
if (pglProcTable->cEntries != OPENGL_VERSION_100_ENTRIES &&
|
|
pglProcTable->cEntries != OPENGL_VERSION_110_ENTRIES)
|
|
{
|
|
DBGERROR("wglMakeCurrent: pfnDrvSetContext returned bad table\n");
|
|
plrc->pGLDriver->pfnDrvReleaseContext(plrc->dhrc);
|
|
SetLastError(ERROR_BAD_DRIVER);
|
|
goto wglMakeCurrent_error;
|
|
}
|
|
|
|
DBGLEVEL1(LEVEL_INFO, "wglMakeCurrent: driver function table 0x%lx\n",
|
|
pglProcTable);
|
|
|
|
// Always use the null EXT proc table since client drivers don't
|
|
// use opengl32's stubs for EXT procs
|
|
pglExtProcTable = &glNullExtProcTable;
|
|
}
|
|
|
|
// Make hrc current.
|
|
|
|
plrc->tidCurrent = tidCurrent;
|
|
plrc->gwidCurrent = *pgwid;
|
|
GLTEB_SET_CLTCURRENTRC(plrc);
|
|
SetCltProcTable(pglProcTable, pglExtProcTable, TRUE);
|
|
|
|
#ifdef GL_METAFILE
|
|
// Set up metafile context if necessary
|
|
if (plrc->fCapturing)
|
|
{
|
|
__GL_SETUP();
|
|
|
|
ActivateMetaRc(plrc, pgwid->hdc);
|
|
|
|
// Set the metafile's base dispatch table by resetting
|
|
// the proc table. Since we know we're capturing, this
|
|
// will cause the GLS capture exec table to be updated
|
|
// with the RGBA or CI proc table, preparing the
|
|
// GLS context for correct passthrough
|
|
|
|
if (gc->modes.colorIndexMode)
|
|
pglProcTable = &glCltCIProcTable;
|
|
else
|
|
pglProcTable = &glCltRGBAProcTable;
|
|
pglExtProcTable = &glExtProcTable;
|
|
SetCltProcTable(pglProcTable, pglExtProcTable, FALSE);
|
|
}
|
|
#endif
|
|
|
|
// Initialize polyarray structure in the TEB.
|
|
|
|
pa = GLTEB_CLTPOLYARRAY();
|
|
pa->flags = 0; // not in begin mode
|
|
if (!plrc->dhrc)
|
|
{
|
|
POLYMATERIAL *pm;
|
|
__GL_SETUP();
|
|
|
|
pa->pdBufferNext = &gc->vertex.pdBuf[0];
|
|
pa->pdBuffer0 = &gc->vertex.pdBuf[0];
|
|
pa->pdBufferMax = &gc->vertex.pdBuf[gc->vertex.pdBufSize - 1];
|
|
// reset next DPA message offset
|
|
pa->nextMsgOffset = PA_nextMsgOffset_RESET_VALUE;
|
|
|
|
// Vertex buffer size may have changed. For example, a generic gc's
|
|
// vertex buffer may be of a different size than a MCD vertex buffer.
|
|
// If it has changed, free the polymaterial array and realloc it later.
|
|
|
|
pm = GLTEB_CLTPOLYMATERIAL();
|
|
if (pm)
|
|
{
|
|
if (pm->aMatSize !=
|
|
gc->vertex.pdBufSize * 2 / POLYMATERIAL_ARRAY_SIZE + 1)
|
|
FreePolyMaterial();
|
|
}
|
|
}
|
|
|
|
// Keep the handle locked while it is current.
|
|
|
|
return(TRUE);
|
|
|
|
// An error has occured, release the current RC.
|
|
|
|
wglMakeCurrent_error:
|
|
vUnlockHandle((ULONG_PTR)hrc);
|
|
wglMakeCurrent_error_nolock:
|
|
if (GLTEB_CLTCURRENTRC() != (PLRC) NULL)
|
|
(void) bMakeNoCurrent();
|
|
return(FALSE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* WindowIdFromHdc
|
|
*
|
|
* Fills out a GLWINDOWID for an HDC
|
|
*
|
|
* History:
|
|
* Wed Aug 28 18:33:19 1996 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void APIENTRY WindowIdFromHdc(HDC hdc, GLWINDOWID *pgwid)
|
|
{
|
|
LPDIRECTDRAWSURFACE pdds;
|
|
HDC hdcDriver;
|
|
|
|
if (pfnGetSurfaceFromDC != NULL &&
|
|
pfnGetSurfaceFromDC(hdc, &pdds, &hdcDriver) == DD_OK)
|
|
{
|
|
// Release reference on the surface since this surface value
|
|
// is only used as an identifier.
|
|
pdds->lpVtbl->Release(pdds);
|
|
|
|
pgwid->iType = GLWID_DDRAW;
|
|
pgwid->hwnd = NULL;
|
|
pgwid->hdc = hdcDriver;
|
|
pgwid->pdds = pdds;
|
|
}
|
|
else
|
|
{
|
|
pgwid->hdc = hdc;
|
|
pgwid->hwnd = WindowFromDC(hdc);
|
|
if (pgwid->hwnd == NULL)
|
|
{
|
|
pgwid->iType = GLWID_HDC;
|
|
}
|
|
else
|
|
{
|
|
pgwid->iType = GLWID_HWND;
|
|
}
|
|
pgwid->pdds = NULL;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* wglMakeCurrent(HDC hdc, HGLRC hrc)
|
|
*
|
|
* Make the hrc current.
|
|
* Both hrc and hdc must have the same pixel format.
|
|
*
|
|
* If an error occurs, the current RC, if any, is made not current!
|
|
*
|
|
* Arguments:
|
|
* hdc - Device context.
|
|
* hrc - Rendering context.
|
|
*
|
|
* History:
|
|
* Tue Oct 26 10:25:26 1993 -by- Hock San Lee [hockl]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hrc)
|
|
{
|
|
int iPixelFormat;
|
|
DWORD dwObjectType;
|
|
GLWINDOWID gwid;
|
|
|
|
DBGENTRY("wglMakeCurrent\n");
|
|
|
|
if (GLTEB_CLTCURRENTRC() != NULL)
|
|
{
|
|
// Flush OpenGL calls.
|
|
glFlush();
|
|
|
|
// Avoid HDC validation for simple make-non-current cases
|
|
if (hrc == NULL)
|
|
{
|
|
return bMakeNoCurrent();
|
|
}
|
|
}
|
|
|
|
// Validate the DC.
|
|
|
|
dwObjectType = wglObjectType(hdc);
|
|
switch (dwObjectType)
|
|
{
|
|
case OBJ_DC:
|
|
case OBJ_MEMDC:
|
|
break;
|
|
|
|
case OBJ_ENHMETADC:
|
|
#ifdef GL_METAFILE
|
|
if (pfnGdiAddGlsRecord == NULL)
|
|
{
|
|
DBGLEVEL1(LEVEL_ERROR, "wglMakeCurrent: metafile hdc: 0x%lx\n",
|
|
hdc);
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
}
|
|
break;
|
|
#else
|
|
DBGLEVEL1(LEVEL_ERROR, "wglMakeCurrent: metafile hdc: 0x%lx\n", hdc);
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
#endif
|
|
|
|
case OBJ_METADC:
|
|
default:
|
|
// 16-bit metafiles are not supported
|
|
DBGLEVEL1(LEVEL_ERROR, "wglMakeCurrent: bad hdc: 0x%lx\n", hdc);
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!CheckDeviceModes(hdc))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef GL_METAFILE
|
|
// For metafile RC's, use the reference HDC rather than the
|
|
// metafile DC
|
|
// Skip pixel format checks
|
|
if (dwObjectType == OBJ_ENHMETADC)
|
|
{
|
|
iPixelFormat = 0;
|
|
goto NoPixelFormat;
|
|
}
|
|
#endif
|
|
|
|
// Get the current pixel format of the window or surface.
|
|
// If no pixel format has been set, return error.
|
|
|
|
if (!(iPixelFormat = GetPixelFormat(hdc)))
|
|
{
|
|
WARNING("wglMakeCurrent: No pixel format set in hdc\n");
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef GL_METAFILE
|
|
NoPixelFormat:
|
|
#endif
|
|
|
|
WindowIdFromHdc(hdc, &gwid);
|
|
return MakeAnyCurrent(hrc, iPixelFormat, dwObjectType, &gwid);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bMakeNoCurrent
|
|
*
|
|
* Make the current RC inactive.
|
|
*
|
|
* History:
|
|
* Tue Oct 26 10:25:26 1993 -by- Hock San Lee [hockl]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL bMakeNoCurrent(void)
|
|
{
|
|
BOOL bRet = FALSE; // assume error
|
|
PLRC plrc = GLTEB_CLTCURRENTRC();
|
|
|
|
DBGENTRY("bMakeNoCurrent\n");
|
|
|
|
ASSERTOPENGL(plrc != (PLRC) NULL, "bMakeNoCurrent: No current RC!\n");
|
|
ASSERTOPENGL(plrc->tidCurrent == GetCurrentThreadId(),
|
|
"bMakeNoCurrent: Current RC does not belong to this thread!\n");
|
|
ASSERTOPENGL(plrc->gwidCurrent.iType != GLWID_ERROR,
|
|
"bMakeNoCurrent: Current surface is NULL!\n");
|
|
|
|
if (!plrc->dhrc)
|
|
{
|
|
#ifdef GL_METAFILE
|
|
// Reset metafile context if necessary
|
|
if (plrc->uiGlsCaptureContext != 0)
|
|
{
|
|
DeactivateMetaRc(plrc);
|
|
}
|
|
#endif
|
|
|
|
// If this is a generic format, tell the server to make the current RC inactive.
|
|
|
|
bRet = __wglMakeCurrent(NULL, NULL, FALSE);
|
|
if (!bRet)
|
|
{
|
|
DBGERROR("bMakeNoCurrent: server failed\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If this is a device format, tell the driver to make the current RC inactive.
|
|
|
|
ASSERTOPENGL(plrc->pGLDriver, "wglMakeCurrent: No GLDriver\n");
|
|
|
|
bRet = plrc->pGLDriver->pfnDrvReleaseContext(plrc->dhrc);
|
|
if (!bRet)
|
|
{
|
|
DBGERROR("bMakeNoCurrent: pfnDrvReleaseContext failed\n");
|
|
}
|
|
}
|
|
|
|
// Always make the current RC inactive.
|
|
// The handle is also unlocked when the RC becomes inactive.
|
|
|
|
plrc->tidCurrent = INVALID_THREAD_ID;
|
|
plrc->gwidCurrent.iType = GLWID_ERROR;
|
|
GLTEB_SET_CLTCURRENTRC(NULL);
|
|
SetCltProcTable(&glNullCltProcTable, &glNullExtProcTable, TRUE);
|
|
vUnlockHandle((ULONG_PTR)(plrc->hrc));
|
|
return(bRet);
|
|
}
|