Path: blob/21.2-virgl/src/gallium/frontends/wgl/stw_context.c
4561 views
/**************************************************************************1*2* Copyright 2008 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#include <windows.h>2829#define WGL_WGLEXT_PROTOTYPES3031#include <GL/gl.h>32#include <GL/wglext.h>3334#include "pipe/p_compiler.h"35#include "pipe/p_context.h"36#include "pipe/p_state.h"37#include "util/compiler.h"38#include "util/u_memory.h"39#include "util/u_atomic.h"40#include "frontend/api.h"41#include "hud/hud_context.h"4243#include "gldrv.h"44#include "stw_device.h"45#include "stw_winsys.h"46#include "stw_framebuffer.h"47#include "stw_pixelformat.h"48#include "stw_context.h"49#include "stw_tls.h"505152struct stw_context *53stw_current_context(void)54{55struct st_context_iface *st;5657st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL;5859return (struct stw_context *) ((st) ? st->st_manager_private : NULL);60}616263BOOL APIENTRY64DrvCopyContext(DHGLRC dhrcSource, DHGLRC dhrcDest, UINT fuMask)65{66struct stw_context *src;67struct stw_context *dst;68BOOL ret = FALSE;6970if (!stw_dev)71return FALSE;7273stw_lock_contexts(stw_dev);7475src = stw_lookup_context_locked( dhrcSource );76dst = stw_lookup_context_locked( dhrcDest );7778if (src && dst) {79/* FIXME */80assert(0);81(void) src;82(void) dst;83(void) fuMask;84}8586stw_unlock_contexts(stw_dev);8788return ret;89}909192BOOL APIENTRY93DrvShareLists(DHGLRC dhglrc1, DHGLRC dhglrc2)94{95struct stw_context *ctx1;96struct stw_context *ctx2;97BOOL ret = FALSE;9899if (!stw_dev)100return FALSE;101102stw_lock_contexts(stw_dev);103104ctx1 = stw_lookup_context_locked( dhglrc1 );105ctx2 = stw_lookup_context_locked( dhglrc2 );106107if (ctx1 && ctx2 && ctx2->st->share) {108ret = ctx2->st->share(ctx2->st, ctx1->st);109ctx1->shared = TRUE;110ctx2->shared = TRUE;111}112113stw_unlock_contexts(stw_dev);114115return ret;116}117118119DHGLRC APIENTRY120DrvCreateContext(HDC hdc)121{122return DrvCreateLayerContext( hdc, 0 );123}124125126DHGLRC APIENTRY127DrvCreateLayerContext(HDC hdc, INT iLayerPlane)128{129return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0,130WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,1310);132}133134135/**136* Return the stw pixel format that most closely matches the pixel format137* on HDC.138* Used to get a pixel format when SetPixelFormat() hasn't been called before.139*/140static int141get_matching_pixel_format(HDC hdc)142{143int iPixelFormat = GetPixelFormat(hdc);144PIXELFORMATDESCRIPTOR pfd;145146if (!iPixelFormat)147return 0;148if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd))149return 0;150return stw_pixelformat_choose(hdc, &pfd);151}152153154/**155* Called via DrvCreateContext(), DrvCreateLayerContext() and156* wglCreateContextAttribsARB() to actually create a rendering context.157* \param handle the desired DHGLRC handle to use for the context, or zero158* if a new handle should be allocated.159* \return the handle for the new context or zero if there was a problem.160*/161DHGLRC162stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,163int majorVersion, int minorVersion,164int contextFlags, int profileMask,165DHGLRC handle)166{167int iPixelFormat;168struct stw_framebuffer *fb;169const struct stw_pixelformat_info *pfi;170struct st_context_attribs attribs;171struct stw_context *ctx = NULL;172struct stw_context *shareCtx = NULL;173enum st_context_error ctx_err = 0;174175if (!stw_dev)176return 0;177178if (iLayerPlane != 0)179return 0;180181/*182* GDI only knows about displayable pixel formats, so determine the pixel183* format from the framebuffer.184*185* This also allows to use a OpenGL DLL / ICD without installing.186*/187fb = stw_framebuffer_from_hdc( hdc );188if (fb) {189iPixelFormat = fb->iPixelFormat;190stw_framebuffer_unlock(fb);191} else {192/* Applications should call SetPixelFormat before creating a context,193* but not all do, and the opengl32 runtime seems to use a default194* pixel format in some cases, so use that.195*/196iPixelFormat = get_matching_pixel_format(hdc);197if (!iPixelFormat)198return 0;199}200201pfi = stw_pixelformat_get_info( iPixelFormat );202203if (hShareContext != 0) {204stw_lock_contexts(stw_dev);205shareCtx = stw_lookup_context_locked( hShareContext );206shareCtx->shared = TRUE;207stw_unlock_contexts(stw_dev);208}209210ctx = CALLOC_STRUCT( stw_context );211if (ctx == NULL)212goto no_ctx;213214ctx->hDrawDC = hdc;215ctx->hReadDC = hdc;216ctx->iPixelFormat = iPixelFormat;217ctx->shared = shareCtx != NULL;218219memset(&attribs, 0, sizeof(attribs));220attribs.visual = pfi->stvis;221attribs.major = majorVersion;222attribs.minor = minorVersion;223if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)224attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;225if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB)226attribs.flags |= ST_CONTEXT_FLAG_DEBUG;227228switch (profileMask) {229case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:230/* There are no profiles before OpenGL 3.2. The231* WGL_ARB_create_context_profile spec says:232*233* "If the requested OpenGL version is less than 3.2,234* WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality235* of the context is determined solely by the requested version."236*/237if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) {238attribs.profile = ST_PROFILE_OPENGL_CORE;239break;240}241FALLTHROUGH;242case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:243/*244* The spec also says:245*246* "If version 3.1 is requested, the context returned may implement247* any of the following versions:248*249* * Version 3.1. The GL_ARB_compatibility extension may or may not250* be implemented, as determined by the implementation.251* * The core profile of version 3.2 or greater."252*253* But Mesa doesn't support GL_ARB_compatibility, while most prevalent254* Windows OpenGL implementations do, and unfortunately many Windows255* applications don't check whether they receive or not a context with256* GL_ARB_compatibility, so returning a core profile here does more harm257* than good.258*/259attribs.profile = ST_PROFILE_DEFAULT;260break;261case WGL_CONTEXT_ES_PROFILE_BIT_EXT:262if (majorVersion >= 2) {263attribs.profile = ST_PROFILE_OPENGL_ES2;264} else {265attribs.profile = ST_PROFILE_OPENGL_ES1;266}267break;268default:269assert(0);270goto no_st_ctx;271}272273ctx->st = stw_dev->stapi->create_context(stw_dev->stapi,274stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL);275if (ctx->st == NULL)276goto no_st_ctx;277278ctx->st->st_manager_private = (void *) ctx;279280if (ctx->st->cso_context) {281ctx->hud = hud_create(ctx->st->cso_context, ctx->st, NULL);282}283284stw_lock_contexts(stw_dev);285if (handle) {286/* We're replacing the context data for this handle. See the287* wglCreateContextAttribsARB() function.288*/289struct stw_context *old_ctx =290stw_lookup_context_locked((unsigned) handle);291if (old_ctx) {292/* free the old context data associated with this handle */293if (old_ctx->hud) {294hud_destroy(old_ctx->hud, NULL);295}296ctx->st->destroy(old_ctx->st);297FREE(old_ctx);298}299300/* replace table entry */301handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx);302}303else {304/* create new table entry */305handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx);306}307308ctx->dhglrc = handle;309310stw_unlock_contexts(stw_dev);311312if (!ctx->dhglrc)313goto no_hglrc;314315return ctx->dhglrc;316317no_hglrc:318if (ctx->hud) {319hud_destroy(ctx->hud, NULL);320}321ctx->st->destroy(ctx->st);322no_st_ctx:323FREE(ctx);324no_ctx:325return 0;326}327328329BOOL APIENTRY330DrvDeleteContext(DHGLRC dhglrc)331{332struct stw_context *ctx ;333BOOL ret = FALSE;334335if (!stw_dev)336return FALSE;337338stw_lock_contexts(stw_dev);339ctx = stw_lookup_context_locked(dhglrc);340handle_table_remove(stw_dev->ctx_table, dhglrc);341stw_unlock_contexts(stw_dev);342343if (ctx) {344struct stw_context *curctx = stw_current_context();345346/* Unbind current if deleting current context. */347if (curctx == ctx)348stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);349350if (ctx->hud) {351hud_destroy(ctx->hud, NULL);352}353354ctx->st->destroy(ctx->st);355FREE(ctx);356357ret = TRUE;358}359360return ret;361}362363364BOOL APIENTRY365DrvReleaseContext(DHGLRC dhglrc)366{367struct stw_context *ctx;368369if (!stw_dev)370return FALSE;371372stw_lock_contexts(stw_dev);373ctx = stw_lookup_context_locked( dhglrc );374stw_unlock_contexts(stw_dev);375376if (!ctx)377return FALSE;378379/* The expectation is that ctx is the same context which is380* current for this thread. We should check that and return False381* if not the case.382*/383if (ctx != stw_current_context())384return FALSE;385386if (stw_make_current( NULL, NULL, 0 ) == FALSE)387return FALSE;388389return TRUE;390}391392393DHGLRC394stw_get_current_context( void )395{396struct stw_context *ctx;397398ctx = stw_current_context();399if (!ctx)400return 0;401402return ctx->dhglrc;403}404405406HDC407stw_get_current_dc( void )408{409struct stw_context *ctx;410411ctx = stw_current_context();412if (!ctx)413return NULL;414415return ctx->hDrawDC;416}417418HDC419stw_get_current_read_dc( void )420{421struct stw_context *ctx;422423ctx = stw_current_context();424if (!ctx)425return NULL;426427return ctx->hReadDC;428}429430BOOL431stw_make_current(HDC hDrawDC, HDC hReadDC, DHGLRC dhglrc)432{433struct stw_context *old_ctx = NULL;434struct stw_context *ctx = NULL;435BOOL ret = FALSE;436437if (!stw_dev)438return FALSE;439440old_ctx = stw_current_context();441if (old_ctx != NULL) {442if (old_ctx->dhglrc == dhglrc) {443if (old_ctx->hDrawDC == hDrawDC && old_ctx->hReadDC == hReadDC) {444/* Return if already current. */445return TRUE;446}447} else {448if (old_ctx->shared) {449if (old_ctx->current_framebuffer) {450stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb,451ST_FLUSH_FRONT | ST_FLUSH_WAIT);452} else {453struct pipe_fence_handle *fence = NULL;454old_ctx->st->flush(old_ctx->st,455ST_FLUSH_FRONT | ST_FLUSH_WAIT, &fence,456NULL, NULL);457}458} else {459if (old_ctx->current_framebuffer)460stw_st_flush(old_ctx->st, old_ctx->current_framebuffer->stfb,461ST_FLUSH_FRONT);462else463old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL, NULL, NULL);464}465}466}467468if (dhglrc) {469struct stw_framebuffer *fb = NULL;470struct stw_framebuffer *fbRead = NULL;471stw_lock_contexts(stw_dev);472ctx = stw_lookup_context_locked( dhglrc );473stw_unlock_contexts(stw_dev);474if (!ctx) {475goto fail;476}477478/* This call locks fb's mutex */479fb = stw_framebuffer_from_hdc( hDrawDC );480if (fb) {481stw_framebuffer_update(fb);482}483else {484/* Applications should call SetPixelFormat before creating a context,485* but not all do, and the opengl32 runtime seems to use a default486* pixel format in some cases, so we must create a framebuffer for487* those here.488*/489int iPixelFormat = get_matching_pixel_format(hDrawDC);490if (iPixelFormat)491fb = stw_framebuffer_create( hDrawDC, iPixelFormat );492if (!fb)493goto fail;494}495496if (fb->iPixelFormat != ctx->iPixelFormat) {497stw_framebuffer_unlock(fb);498SetLastError(ERROR_INVALID_PIXEL_FORMAT);499goto fail;500}501502/* Bind the new framebuffer */503ctx->hDrawDC = hDrawDC;504ctx->hReadDC = hReadDC;505506struct stw_framebuffer *old_fb = ctx->current_framebuffer;507if (old_fb != fb) {508stw_framebuffer_reference_locked(fb);509ctx->current_framebuffer = fb;510}511stw_framebuffer_unlock(fb);512513if (hReadDC) {514if (hReadDC == hDrawDC) {515fbRead = fb;516}517else {518fbRead = stw_framebuffer_from_hdc( hReadDC );519520if (fbRead) {521stw_framebuffer_update(fbRead);522}523else {524/* Applications should call SetPixelFormat before creating a525* context, but not all do, and the opengl32 runtime seems to526* use a default pixel format in some cases, so we must create527* a framebuffer for those here.528*/529int iPixelFormat = GetPixelFormat(hReadDC);530if (iPixelFormat)531fbRead = stw_framebuffer_create( hReadDC, iPixelFormat );532if (!fbRead)533goto fail;534}535536if (fbRead->iPixelFormat != ctx->iPixelFormat) {537stw_framebuffer_unlock(fbRead);538SetLastError(ERROR_INVALID_PIXEL_FORMAT);539goto fail;540}541stw_framebuffer_unlock(fbRead);542}543ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,544fb->stfb, fbRead->stfb);545}546else {547/* Note: when we call this function we will wind up in the548* stw_st_framebuffer_validate_locked() function which will incur549* a recursive fb->mutex lock.550*/551ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,552fb->stfb, fb->stfb);553}554555if (old_fb && old_fb != fb) {556stw_lock_framebuffers(stw_dev);557stw_framebuffer_lock(old_fb);558stw_framebuffer_release_locked(old_fb, old_ctx->st);559stw_unlock_framebuffers(stw_dev);560}561562fail:563if (fb) {564/* fb must be unlocked at this point. */565assert(!stw_own_mutex(&fb->mutex));566}567568/* On failure, make the thread's current rendering context not current569* before returning.570*/571if (!ret) {572stw_make_current(NULL, NULL, 0);573}574} else {575ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);576}577578/* Unreference the previous framebuffer if any. It must be done after579* make_current, as it can be referenced inside.580*/581if (old_ctx && old_ctx != ctx) {582struct stw_framebuffer *old_fb = old_ctx->current_framebuffer;583if (old_fb) {584old_ctx->current_framebuffer = NULL;585stw_lock_framebuffers(stw_dev);586stw_framebuffer_lock(old_fb);587stw_framebuffer_release_locked(old_fb, old_ctx->st);588stw_unlock_framebuffers(stw_dev);589}590}591592return ret;593}594595596/**597* Notify the current context that the framebuffer has become invalid.598*/599void600stw_notify_current_locked( struct stw_framebuffer *fb )601{602p_atomic_inc(&fb->stfb->stamp);603}604605606/**607* Although WGL allows different dispatch entrypoints per context608*/609static const GLCLTPROCTABLE cpt =610{611OPENGL_VERSION_110_ENTRIES,612{613&glNewList,614&glEndList,615&glCallList,616&glCallLists,617&glDeleteLists,618&glGenLists,619&glListBase,620&glBegin,621&glBitmap,622&glColor3b,623&glColor3bv,624&glColor3d,625&glColor3dv,626&glColor3f,627&glColor3fv,628&glColor3i,629&glColor3iv,630&glColor3s,631&glColor3sv,632&glColor3ub,633&glColor3ubv,634&glColor3ui,635&glColor3uiv,636&glColor3us,637&glColor3usv,638&glColor4b,639&glColor4bv,640&glColor4d,641&glColor4dv,642&glColor4f,643&glColor4fv,644&glColor4i,645&glColor4iv,646&glColor4s,647&glColor4sv,648&glColor4ub,649&glColor4ubv,650&glColor4ui,651&glColor4uiv,652&glColor4us,653&glColor4usv,654&glEdgeFlag,655&glEdgeFlagv,656&glEnd,657&glIndexd,658&glIndexdv,659&glIndexf,660&glIndexfv,661&glIndexi,662&glIndexiv,663&glIndexs,664&glIndexsv,665&glNormal3b,666&glNormal3bv,667&glNormal3d,668&glNormal3dv,669&glNormal3f,670&glNormal3fv,671&glNormal3i,672&glNormal3iv,673&glNormal3s,674&glNormal3sv,675&glRasterPos2d,676&glRasterPos2dv,677&glRasterPos2f,678&glRasterPos2fv,679&glRasterPos2i,680&glRasterPos2iv,681&glRasterPos2s,682&glRasterPos2sv,683&glRasterPos3d,684&glRasterPos3dv,685&glRasterPos3f,686&glRasterPos3fv,687&glRasterPos3i,688&glRasterPos3iv,689&glRasterPos3s,690&glRasterPos3sv,691&glRasterPos4d,692&glRasterPos4dv,693&glRasterPos4f,694&glRasterPos4fv,695&glRasterPos4i,696&glRasterPos4iv,697&glRasterPos4s,698&glRasterPos4sv,699&glRectd,700&glRectdv,701&glRectf,702&glRectfv,703&glRecti,704&glRectiv,705&glRects,706&glRectsv,707&glTexCoord1d,708&glTexCoord1dv,709&glTexCoord1f,710&glTexCoord1fv,711&glTexCoord1i,712&glTexCoord1iv,713&glTexCoord1s,714&glTexCoord1sv,715&glTexCoord2d,716&glTexCoord2dv,717&glTexCoord2f,718&glTexCoord2fv,719&glTexCoord2i,720&glTexCoord2iv,721&glTexCoord2s,722&glTexCoord2sv,723&glTexCoord3d,724&glTexCoord3dv,725&glTexCoord3f,726&glTexCoord3fv,727&glTexCoord3i,728&glTexCoord3iv,729&glTexCoord3s,730&glTexCoord3sv,731&glTexCoord4d,732&glTexCoord4dv,733&glTexCoord4f,734&glTexCoord4fv,735&glTexCoord4i,736&glTexCoord4iv,737&glTexCoord4s,738&glTexCoord4sv,739&glVertex2d,740&glVertex2dv,741&glVertex2f,742&glVertex2fv,743&glVertex2i,744&glVertex2iv,745&glVertex2s,746&glVertex2sv,747&glVertex3d,748&glVertex3dv,749&glVertex3f,750&glVertex3fv,751&glVertex3i,752&glVertex3iv,753&glVertex3s,754&glVertex3sv,755&glVertex4d,756&glVertex4dv,757&glVertex4f,758&glVertex4fv,759&glVertex4i,760&glVertex4iv,761&glVertex4s,762&glVertex4sv,763&glClipPlane,764&glColorMaterial,765&glCullFace,766&glFogf,767&glFogfv,768&glFogi,769&glFogiv,770&glFrontFace,771&glHint,772&glLightf,773&glLightfv,774&glLighti,775&glLightiv,776&glLightModelf,777&glLightModelfv,778&glLightModeli,779&glLightModeliv,780&glLineStipple,781&glLineWidth,782&glMaterialf,783&glMaterialfv,784&glMateriali,785&glMaterialiv,786&glPointSize,787&glPolygonMode,788&glPolygonStipple,789&glScissor,790&glShadeModel,791&glTexParameterf,792&glTexParameterfv,793&glTexParameteri,794&glTexParameteriv,795&glTexImage1D,796&glTexImage2D,797&glTexEnvf,798&glTexEnvfv,799&glTexEnvi,800&glTexEnviv,801&glTexGend,802&glTexGendv,803&glTexGenf,804&glTexGenfv,805&glTexGeni,806&glTexGeniv,807&glFeedbackBuffer,808&glSelectBuffer,809&glRenderMode,810&glInitNames,811&glLoadName,812&glPassThrough,813&glPopName,814&glPushName,815&glDrawBuffer,816&glClear,817&glClearAccum,818&glClearIndex,819&glClearColor,820&glClearStencil,821&glClearDepth,822&glStencilMask,823&glColorMask,824&glDepthMask,825&glIndexMask,826&glAccum,827&glDisable,828&glEnable,829&glFinish,830&glFlush,831&glPopAttrib,832&glPushAttrib,833&glMap1d,834&glMap1f,835&glMap2d,836&glMap2f,837&glMapGrid1d,838&glMapGrid1f,839&glMapGrid2d,840&glMapGrid2f,841&glEvalCoord1d,842&glEvalCoord1dv,843&glEvalCoord1f,844&glEvalCoord1fv,845&glEvalCoord2d,846&glEvalCoord2dv,847&glEvalCoord2f,848&glEvalCoord2fv,849&glEvalMesh1,850&glEvalPoint1,851&glEvalMesh2,852&glEvalPoint2,853&glAlphaFunc,854&glBlendFunc,855&glLogicOp,856&glStencilFunc,857&glStencilOp,858&glDepthFunc,859&glPixelZoom,860&glPixelTransferf,861&glPixelTransferi,862&glPixelStoref,863&glPixelStorei,864&glPixelMapfv,865&glPixelMapuiv,866&glPixelMapusv,867&glReadBuffer,868&glCopyPixels,869&glReadPixels,870&glDrawPixels,871&glGetBooleanv,872&glGetClipPlane,873&glGetDoublev,874&glGetError,875&glGetFloatv,876&glGetIntegerv,877&glGetLightfv,878&glGetLightiv,879&glGetMapdv,880&glGetMapfv,881&glGetMapiv,882&glGetMaterialfv,883&glGetMaterialiv,884&glGetPixelMapfv,885&glGetPixelMapuiv,886&glGetPixelMapusv,887&glGetPolygonStipple,888&glGetString,889&glGetTexEnvfv,890&glGetTexEnviv,891&glGetTexGendv,892&glGetTexGenfv,893&glGetTexGeniv,894&glGetTexImage,895&glGetTexParameterfv,896&glGetTexParameteriv,897&glGetTexLevelParameterfv,898&glGetTexLevelParameteriv,899&glIsEnabled,900&glIsList,901&glDepthRange,902&glFrustum,903&glLoadIdentity,904&glLoadMatrixf,905&glLoadMatrixd,906&glMatrixMode,907&glMultMatrixf,908&glMultMatrixd,909&glOrtho,910&glPopMatrix,911&glPushMatrix,912&glRotated,913&glRotatef,914&glScaled,915&glScalef,916&glTranslated,917&glTranslatef,918&glViewport,919&glArrayElement,920&glBindTexture,921&glColorPointer,922&glDisableClientState,923&glDrawArrays,924&glDrawElements,925&glEdgeFlagPointer,926&glEnableClientState,927&glIndexPointer,928&glIndexub,929&glIndexubv,930&glInterleavedArrays,931&glNormalPointer,932&glPolygonOffset,933&glTexCoordPointer,934&glVertexPointer,935&glAreTexturesResident,936&glCopyTexImage1D,937&glCopyTexImage2D,938&glCopyTexSubImage1D,939&glCopyTexSubImage2D,940&glDeleteTextures,941&glGenTextures,942&glGetPointerv,943&glIsTexture,944&glPrioritizeTextures,945&glTexSubImage1D,946&glTexSubImage2D,947&glPopClientAttrib,948&glPushClientAttrib949}950};951952953PGLCLTPROCTABLE APIENTRY954DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)955{956PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;957958if (!stw_make_current(hdc, hdc, dhglrc))959r = NULL;960961return r;962}963964965