Home | History | Annotate | Download | only in wgl
      1 /**************************************************************************
      2  *
      3  * Copyright 2008 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 /**
     29  * @file
     30  *
     31  * Fake WGL API implementation.
     32  *
     33  * These functions implement the WGL API, on top of the ICD DDI, so that the
     34  * resulting DLL can be used as a drop-in replacement for the system's
     35  * opengl32.dll.
     36  *
     37  * These functions never get called for ICD drivers, which use exclusively the
     38  * ICD DDI, i.e., the Drv* entrypoints.
     39  */
     40 
     41 #include <windows.h>
     42 
     43 #include "util/u_debug.h"
     44 #include "stw_icd.h"
     45 #include "stw_context.h"
     46 #include "stw_pixelformat.h"
     47 #include "stw_wgl.h"
     48 #include "stw_ext_context.h"
     49 
     50 
     51 static void
     52 overrideOpenGL32EntryPoints(void);
     53 
     54 WINGDIAPI BOOL APIENTRY
     55 wglCopyContext(
     56    HGLRC hglrcSrc,
     57    HGLRC hglrcDst,
     58    UINT mask )
     59 {
     60    return DrvCopyContext( (DHGLRC)(UINT_PTR)hglrcSrc,
     61                           (DHGLRC)(UINT_PTR)hglrcDst,
     62                           mask );
     63 }
     64 
     65 WINGDIAPI HGLRC APIENTRY
     66 wglCreateContext(
     67    HDC hdc )
     68 {
     69    overrideOpenGL32EntryPoints();
     70    return (HGLRC) DrvCreateContext(hdc);
     71 }
     72 
     73 WINGDIAPI HGLRC APIENTRY
     74 wglCreateLayerContext(
     75    HDC hdc,
     76    int iLayerPlane )
     77 {
     78    overrideOpenGL32EntryPoints();
     79    return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane );
     80 }
     81 
     82 WINGDIAPI BOOL APIENTRY
     83 wglDeleteContext(
     84    HGLRC hglrc )
     85 {
     86    return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc );
     87 }
     88 
     89 
     90 WINGDIAPI HGLRC APIENTRY
     91 wglGetCurrentContext( VOID )
     92 {
     93    return (HGLRC)(UINT_PTR)stw_get_current_context();
     94 }
     95 
     96 WINGDIAPI HDC APIENTRY
     97 wglGetCurrentDC( VOID )
     98 {
     99    return stw_get_current_dc();
    100 }
    101 
    102 WINGDIAPI HDC APIENTRY
    103 wglGetCurrentReadDCARB( VOID )
    104 {
    105    return stw_get_current_read_dc();
    106 }
    107 
    108 
    109 WINGDIAPI BOOL APIENTRY
    110 wglMakeCurrent(
    111    HDC hdc,
    112    HGLRC hglrc )
    113 {
    114    return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE;
    115 }
    116 
    117 
    118 WINGDIAPI BOOL APIENTRY
    119 wglSwapBuffers(
    120    HDC hdc )
    121 {
    122    return DrvSwapBuffers( hdc );
    123 }
    124 
    125 
    126 WINGDIAPI DWORD WINAPI
    127 wglSwapMultipleBuffers(UINT n,
    128                        CONST WGLSWAP *ps)
    129 {
    130    UINT i;
    131 
    132    for (i =0; i < n; ++i)
    133       wglSwapBuffers(ps->hdc);
    134 
    135    return 0;
    136 }
    137 
    138 
    139 WINGDIAPI BOOL APIENTRY
    140 wglSwapLayerBuffers(
    141    HDC hdc,
    142    UINT fuPlanes )
    143 {
    144    return DrvSwapLayerBuffers( hdc, fuPlanes );
    145 }
    146 
    147 WINGDIAPI PROC APIENTRY
    148 wglGetProcAddress(
    149     LPCSTR lpszProc )
    150 {
    151    return DrvGetProcAddress( lpszProc );
    152 }
    153 
    154 
    155 WINGDIAPI int APIENTRY
    156 wglChoosePixelFormat(
    157    HDC hdc,
    158    CONST PIXELFORMATDESCRIPTOR *ppfd )
    159 {
    160    if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ) || ppfd->nVersion != 1)
    161       return 0;
    162    if (ppfd->iPixelType != PFD_TYPE_RGBA)
    163       return 0;
    164    if (!(ppfd->dwFlags & PFD_DRAW_TO_WINDOW))
    165       return 0;
    166    if (!(ppfd->dwFlags & PFD_SUPPORT_OPENGL))
    167       return 0;
    168    if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP)
    169       return 0;
    170    if (ppfd->dwFlags & PFD_SUPPORT_GDI)
    171       return 0;
    172    if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE) && (ppfd->dwFlags & PFD_STEREO))
    173       return 0;
    174 
    175    return stw_pixelformat_choose( hdc, ppfd );
    176 }
    177 
    178 WINGDIAPI int APIENTRY
    179 wglDescribePixelFormat(
    180    HDC hdc,
    181    int iPixelFormat,
    182    UINT nBytes,
    183    LPPIXELFORMATDESCRIPTOR ppfd )
    184 {
    185    return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd );
    186 }
    187 
    188 WINGDIAPI int APIENTRY
    189 wglGetPixelFormat(
    190    HDC hdc )
    191 {
    192    return stw_pixelformat_get( hdc );
    193 }
    194 
    195 WINGDIAPI BOOL APIENTRY
    196 wglSetPixelFormat(
    197    HDC hdc,
    198    int iPixelFormat,
    199    const PIXELFORMATDESCRIPTOR *ppfd )
    200 {
    201     /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per
    202      * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx
    203      */
    204    (void) ppfd;
    205 
    206    return DrvSetPixelFormat( hdc, iPixelFormat );
    207 }
    208 
    209 
    210 WINGDIAPI BOOL APIENTRY
    211 wglUseFontBitmapsA(
    212    HDC hdc,
    213    DWORD first,
    214    DWORD count,
    215    DWORD listBase )
    216 {
    217    return wglUseFontBitmapsW(hdc, first, count, listBase);
    218 }
    219 
    220 WINGDIAPI BOOL APIENTRY
    221 wglShareLists(
    222    HGLRC hglrc1,
    223    HGLRC hglrc2 )
    224 {
    225    return DrvShareLists((DHGLRC)(UINT_PTR)hglrc1,
    226                         (DHGLRC)(UINT_PTR)hglrc2);
    227 }
    228 
    229 WINGDIAPI BOOL APIENTRY
    230 wglUseFontBitmapsW(
    231    HDC hdc,
    232    DWORD first,
    233    DWORD count,
    234    DWORD listBase )
    235 {
    236    GLYPHMETRICS gm;
    237    MAT2 tra;
    238    FIXED one, minus_one, zero;
    239    void *buffer = NULL;
    240    BOOL result = TRUE;
    241 
    242    one.value = 1;
    243    one.fract = 0;
    244    minus_one.value = -1;
    245    minus_one.fract = 0;
    246    zero.value = 0;
    247    zero.fract = 0;
    248 
    249    tra.eM11 = one;
    250    tra.eM22 = minus_one;
    251    tra.eM12 = tra.eM21 = zero;
    252 
    253    for (int i = 0; i < count; i++) {
    254       DWORD size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0,
    255                                    NULL, &tra);
    256 
    257       glNewList(listBase + i, GL_COMPILE);
    258 
    259       if (size != GDI_ERROR) {
    260          if (size == 0) {
    261             glBitmap(0, 0, -gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y,
    262                      gm.gmCellIncX, gm.gmCellIncY, NULL);
    263          }
    264          else {
    265             buffer = realloc(buffer, size);
    266             size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm,
    267                                    size, buffer, &tra);
    268 
    269             glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
    270                      -gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y,
    271                      gm.gmCellIncX, gm.gmCellIncY, buffer);
    272          }
    273       }
    274       else {
    275          result = FALSE;
    276       }
    277 
    278       glEndList();
    279    }
    280 
    281    free(buffer);
    282 
    283    return result;
    284 }
    285 
    286 WINGDIAPI BOOL APIENTRY
    287 wglUseFontOutlinesA(
    288    HDC hdc,
    289    DWORD first,
    290    DWORD count,
    291    DWORD listBase,
    292    FLOAT deviation,
    293    FLOAT extrusion,
    294    int format,
    295    LPGLYPHMETRICSFLOAT lpgmf )
    296 {
    297    (void) hdc;
    298    (void) first;
    299    (void) count;
    300    (void) listBase;
    301    (void) deviation;
    302    (void) extrusion;
    303    (void) format;
    304    (void) lpgmf;
    305 
    306    assert( 0 );
    307 
    308    return FALSE;
    309 }
    310 
    311 WINGDIAPI BOOL APIENTRY
    312 wglUseFontOutlinesW(
    313    HDC hdc,
    314    DWORD first,
    315    DWORD count,
    316    DWORD listBase,
    317    FLOAT deviation,
    318    FLOAT extrusion,
    319    int format,
    320    LPGLYPHMETRICSFLOAT lpgmf )
    321 {
    322    (void) hdc;
    323    (void) first;
    324    (void) count;
    325    (void) listBase;
    326    (void) deviation;
    327    (void) extrusion;
    328    (void) format;
    329    (void) lpgmf;
    330 
    331    assert( 0 );
    332 
    333    return FALSE;
    334 }
    335 
    336 WINGDIAPI BOOL APIENTRY
    337 wglDescribeLayerPlane(
    338    HDC hdc,
    339    int iPixelFormat,
    340    int iLayerPlane,
    341    UINT nBytes,
    342    LPLAYERPLANEDESCRIPTOR plpd )
    343 {
    344    return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
    345 }
    346 
    347 WINGDIAPI int APIENTRY
    348 wglSetLayerPaletteEntries(
    349    HDC hdc,
    350    int iLayerPlane,
    351    int iStart,
    352    int cEntries,
    353    CONST COLORREF *pcr )
    354 {
    355    return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
    356 }
    357 
    358 WINGDIAPI int APIENTRY
    359 wglGetLayerPaletteEntries(
    360    HDC hdc,
    361    int iLayerPlane,
    362    int iStart,
    363    int cEntries,
    364    COLORREF *pcr )
    365 {
    366    return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
    367 }
    368 
    369 WINGDIAPI BOOL APIENTRY
    370 wglRealizeLayerPalette(
    371    HDC hdc,
    372    int iLayerPlane,
    373    BOOL bRealize )
    374 {
    375    (void) hdc;
    376    (void) iLayerPlane;
    377    (void) bRealize;
    378 
    379    assert( 0 );
    380 
    381    return FALSE;
    382 }
    383 
    384 
    385 /* When this library is used as a opengl32.dll drop-in replacement, ensure we
    386  * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll,
    387  * which could happen if this library's name is not opengl32.dll exactly.
    388  *
    389  * For example, Qt 5.4 bundles this as opengl32sw.dll:
    390  * https://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/
    391  */
    392 static void
    393 overrideOpenGL32EntryPoints(void)
    394 {
    395    wglCreateContext_func = &wglCreateContext;
    396    wglDeleteContext_func = &wglDeleteContext;
    397 }
    398