ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

wgl.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:            See COPYING in the top level directory
00003  * PROJECT:              ReactOS kernel
00004  * FILE:                 lib/opengl32/wgl.c
00005  * PURPOSE:              OpenGL32 lib, rosglXXX functions
00006  * PROGRAMMER:           Anich Gregor (blight)
00007  * UPDATE HISTORY:
00008  *                       Feb 2, 2004: Created
00009  */
00010 
00011 #define OPENGL32_GL_FUNC_PROTOTYPES
00012 #include "opengl32.h"
00013 
00014 #ifdef __cplusplus
00015 extern "C" {
00016 #endif /* __cplusplus */
00017 
00018 #if !defined(UNIMPLEMENTED)
00019 # define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
00020 #endif
00021 
00022 
00023 typedef struct _OPENGL_INFO
00024 {
00025     DWORD Version;          
00026     DWORD DriverVersion;    
00027     WCHAR DriverName[256];  
00028 } OPENGL_INFO, *POPENGL_INFO;
00029 
00034 static
00035 void
00036 ROSGL_AppendContext( GLRC *glrc )
00037 {
00038     /* synchronize */
00039     if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
00040         WAIT_FAILED)
00041     {
00042         DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
00043         return; /* FIXME: do we have to expect such an error and handle it? */
00044     }
00045 
00046     if (OPENGL32_processdata.glrc_list == NULL)
00047         OPENGL32_processdata.glrc_list = glrc;
00048     else
00049     {
00050         GLRC *p = OPENGL32_processdata.glrc_list;
00051         while (p->next != NULL)
00052             p = p->next;
00053         p->next = glrc;
00054     }
00055 
00056     /* release mutex */
00057     if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
00058         DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
00059 }
00060 
00061 
00066 static
00067 void
00068 ROSGL_RemoveContext( GLRC *glrc )
00069 {
00070     /* synchronize */
00071     if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
00072         WAIT_FAILED)
00073     {
00074         DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
00075         return; /* FIXME: do we have to expect such an error and handle it? */
00076     }
00077 
00078     if (glrc == OPENGL32_processdata.glrc_list)
00079         OPENGL32_processdata.glrc_list = glrc->next;
00080     else
00081     {
00082         GLRC *p = OPENGL32_processdata.glrc_list;
00083         while (p != NULL)
00084         {
00085             if (p->next == glrc)
00086             {
00087                 p->next = glrc->next;
00088                 break;
00089             }
00090             p = p->next;
00091         }
00092         if (p == NULL)
00093             DBGPRINT( "Error: GLRC 0x%08x not found in list!", glrc );
00094     }
00095 
00096     /* release mutex */
00097     if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
00098         DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
00099 }
00100 
00101 
00107 static
00108 GLRC *
00109 ROSGL_NewContext(void)
00110 {
00111     GLRC *glrc;
00112 
00113     /* allocate GLRC */
00114     glrc = (GLRC*)HeapAlloc( GetProcessHeap(),
00115                   HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, sizeof (GLRC) );
00116 
00117     /* append to list */
00118     ROSGL_AppendContext( glrc );
00119 
00120     return glrc;
00121 }
00122 
00127 static
00128 VOID
00129 ROSGL_DeleteDCDataForICD( GLDRIVERDATA *icd )
00130 {
00131     GLDCDATA *p, **pptr;
00132 
00133     /* synchronize */
00134     if (WaitForSingleObject( OPENGL32_processdata.dcdata_mutex, INFINITE ) ==
00135         WAIT_FAILED)
00136     {
00137         DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
00138         return;
00139     }
00140 
00141     p = OPENGL32_processdata.dcdata_list;
00142     pptr = &OPENGL32_processdata.dcdata_list;
00143     while (p != NULL)
00144     {
00145         if (p->icd == icd)
00146         {
00147             *pptr = p->next;
00148             OPENGL32_UnloadICD( p->icd );
00149 
00150             if (!HeapFree( GetProcessHeap(), 0, p ))
00151                 DBGPRINT( "Warning: HeapFree() on GLDCDATA failed (%d)",
00152                           GetLastError() );
00153 
00154             p = *pptr;
00155         }
00156         else
00157         {
00158             pptr = &p->next;
00159             p = p->next;
00160         }
00161     }
00162 
00163     /* release mutex */
00164     if (!ReleaseMutex( OPENGL32_processdata.dcdata_mutex ))
00165         DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
00166 }
00167 
00168 
00176 static
00177 BOOL
00178 ROSGL_DeleteContext( GLRC *glrc )
00179 {
00180     /* unload icd */
00181     if ((glrc->icd != NULL) && (!InterlockedDecrement((LONG*)&glrc->icd->refcount)))
00182     {
00183         /* This is the last context, remove the ICD*/
00184         ROSGL_DeleteDCDataForICD( glrc->icd );
00185     }
00186 
00187     /* remove from list */
00188     ROSGL_RemoveContext( glrc );
00189 
00190     /* free memory */
00191     HeapFree( GetProcessHeap(), 0, glrc );
00192 
00193     return TRUE;
00194 }
00195 
00196 
00204 static
00205 BOOL
00206 ROSGL_ContainsContext( GLRC *glrc )
00207 {
00208     GLRC *p;
00209     BOOL found = FALSE;
00210 
00211     /* synchronize */
00212     if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
00213         WAIT_FAILED)
00214     {
00215         DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
00216         return FALSE; /* FIXME: do we have to expect such an error and handle it? */
00217     }
00218 
00219     p = OPENGL32_processdata.glrc_list;
00220     while (p != NULL)
00221     {
00222         if (p == glrc)
00223         {
00224             found = TRUE;
00225             break;
00226         }
00227         p = p->next;
00228     }
00229 
00230     /* release mutex */
00231     if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
00232         DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
00233 
00234     return found;
00235 }
00236 
00237 
00248 static
00249 GLDCDATA *
00250 ROSGL_GetPrivateDCData( HDC hdc )
00251 {
00252     GLDCDATA *data;
00253 
00254     /* check hdc */
00255     if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
00256     {
00257         DBGPRINT( "Error: hdc is not a DC handle!" );
00258         SetLastError( ERROR_INVALID_HANDLE );
00259         return FALSE;
00260     }
00261 
00262     /* synchronize */
00263     if (WaitForSingleObject( OPENGL32_processdata.dcdata_mutex, INFINITE ) ==
00264         WAIT_FAILED)
00265     {
00266         DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
00267         return NULL; /* FIXME: do we have to expect such an error and handle it? */
00268     }
00269 
00270     /* look for data in list */
00271     data = OPENGL32_processdata.dcdata_list;
00272     while (data != NULL)
00273     {
00274         if (data->hdc == hdc) /* found */
00275             break;
00276         data = data->next;
00277     }
00278 
00279     /* allocate new data if not found in list */
00280     if (data == NULL)
00281     {
00282         data = HeapAlloc( GetProcessHeap(),
00283                           HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
00284                           sizeof (GLDCDATA) );
00285         if (data == NULL)
00286         {
00287             DBGPRINT( "Error: HeapAlloc() failed (%d)", GetLastError() );
00288         }
00289         else
00290         {
00291             data->hdc = hdc;
00292 
00293             /* append data to list */
00294             if (OPENGL32_processdata.dcdata_list == NULL)
00295                 OPENGL32_processdata.dcdata_list = data;
00296             else
00297             {
00298                 GLDCDATA *p = OPENGL32_processdata.dcdata_list;
00299                 while (p->next != NULL)
00300                     p = p->next;
00301                 p->next = data;
00302             }
00303         }
00304     }
00305 
00306     /* release mutex */
00307     if (!ReleaseMutex( OPENGL32_processdata.dcdata_mutex ))
00308         DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
00309 
00310     return data;
00311 }
00312 
00313 
00324 static
00325 GLDRIVERDATA *
00326 ROSGL_ICDForHDC( HDC hdc )
00327 {
00328     GLDCDATA *dcdata;
00329     GLDRIVERDATA *drvdata;
00330 
00331     dcdata = ROSGL_GetPrivateDCData( hdc );
00332     if (dcdata == NULL)
00333         return NULL;
00334 
00335     if (dcdata->icd == NULL)
00336     {
00337         LPCWSTR driverName;
00338         OPENGL_INFO info;
00339 
00340         /* NOTE: This might be done by multiple threads simultaneously, but only the fastest
00341                  actually gets to set the ICD! */
00342 
00343         driverName = _wgetenv( L"OPENGL32_DRIVER" );
00344         if (driverName == NULL)
00345         {
00346             DWORD dwInput;
00347             LONG ret;
00348 
00349             /* get driver name */
00350             dwInput = OPENGL_GETINFO;
00351             ret = ExtEscape( hdc, QUERYESCSUPPORT, sizeof (dwInput), (LPCSTR)&dwInput, 0, NULL );
00352             if (ret > 0)
00353             {
00354                 dwInput = 0;
00355                 ret = ExtEscape( hdc, OPENGL_GETINFO, sizeof (dwInput),
00356                                  (LPCSTR)&dwInput, sizeof (OPENGL_INFO),
00357                                  (LPSTR)&info );
00358             }
00359             if (ret <= 0)
00360             {
00361                 HKEY hKey;
00362                 DWORD type, size;
00363 
00364                 if (ret < 0)
00365                 {
00366                     DBGPRINT( "Warning: ExtEscape to get the drivername failed! (%d)", GetLastError() );
00367                     if (MessageBox( WindowFromDC( hdc ), L"Couldn't get installable client driver name!\nUsing default driver.",
00368                                     L"OPENGL32.dll: Warning", MB_OKCANCEL | MB_ICONWARNING ) == IDCANCEL)
00369                     {
00370                         return NULL;
00371                     }
00372                 }
00373 
00374                 /* open registry key */
00375                 ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, OPENGL_DRIVERS_SUBKEY, 0, KEY_QUERY_VALUE, &hKey );
00376                 if (ret != ERROR_SUCCESS)
00377                 {
00378                     DBGPRINT( "Error: Couldn't open registry key '%ws'", OPENGL_DRIVERS_SUBKEY );
00379                     SetLastError( ret );
00380                     return NULL;
00381                 }
00382 
00383                 /* query value */
00384                 size = sizeof (info.DriverName);
00385                 ret = RegQueryValueExW( hKey, L"DefaultDriver", 0, &type, (LPBYTE)info.DriverName, &size );
00386                 RegCloseKey( hKey );
00387                 if (ret != ERROR_SUCCESS || type != REG_SZ)
00388                 {
00389                     DBGPRINT( "Error: Couldn't query DefaultDriver value or not a string" );
00390                     SetLastError( ret );
00391                     return NULL;
00392                 }
00393             }
00394         }
00395         else
00396         {
00397             wcsncpy( info.DriverName, driverName, sizeof (info.DriverName) / sizeof (info.DriverName[0]) );
00398         }
00399         /* load driver (or get a reference) */
00400         drvdata = OPENGL32_LoadICD( info.DriverName );
00401         if (drvdata == NULL)
00402         {
00403             WCHAR Buffer[256];
00404             snwprintf(Buffer, sizeof(Buffer)/sizeof(WCHAR),
00405                       L"Couldn't load driver \"%s\".", info.DriverName);
00406             MessageBox(WindowFromDC( hdc ), Buffer,
00407                        L"OPENGL32.dll: Warning",
00408                        MB_OK | MB_ICONWARNING);
00409         }
00410         else
00411         {
00412             /* Atomically set the ICD!!! */
00413             if (InterlockedCompareExchangePointer((PVOID*)&dcdata->icd,
00414                                                   (PVOID)drvdata,
00415                                                   NULL) != NULL)
00416             {
00417                 /* Too bad, somebody else was faster... */
00418                 DBGTRACE("ICD is already set!\n");
00419             }
00420         }
00421     }
00422 
00423     return dcdata->icd;
00424 }
00425 
00426 
00436 DWORD
00437 CALLBACK
00438 ROSGL_SetContextCallBack( const ICDTable *table )
00439 {
00440     TEB *teb;
00441     PROC *tebTable, *tebDispatchTable;
00442     INT size;
00443 
00444     teb = NtCurrentTeb();
00445     tebTable = (PROC *)teb->glTable;
00446     tebDispatchTable = (PROC *)teb->glDispatchTable;
00447 
00448     DBGTRACE( "Called!" );
00449 
00450     if (table != NULL)
00451     {
00452         DBGPRINT( "Function count: %d\n", table->num_funcs );
00453 
00454         /* save table */
00455         size = sizeof (PROC) * table->num_funcs;
00456         memcpy( tebTable, table->dispatch_table, size );
00457         memset( tebTable + table->num_funcs, 0, DISPATCH_TABLE_SIZE - size );
00458     }
00459     else
00460     {
00461         DBGPRINT( "Unsetting current context" );
00462         memset( tebTable, 0, DISPATCH_TABLE_SIZE );
00463     }
00464 
00465     /* put in empty functions as long as we dont have a fallback */
00466     #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
00467         if (tebTable[icdidx] == NULL) \
00468         { \
00469             if (table != NULL) \
00470                 DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
00471             tebTable[icdidx] = (PROC)glEmptyFunc##stack; \
00472         }
00473     GLFUNCS_MACRO
00474 #undef X
00475 
00476     /* fill teb->glDispatchTable for fast calls */
00477 #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
00478         if (tebidx >= 0) \
00479             tebDispatchTable[tebidx] = tebTable[icdidx];
00480     GLFUNCS_MACRO
00481 #undef X
00482 
00483     DBGPRINT( "Done." );
00484 
00485     return ERROR_SUCCESS;
00486 }
00487 
00488 
00504 #define BUFFERDEPTH_SCORE(want, have) \
00505     ((want == 0) ? (0) : ((want < have) ? (1) : ((want > have) ? (3) : (0))))
00506 
00507 /* Score if we want and not have it */
00508 #define FLAG_SCORE(want, have, flag) \
00509     (((want & ~have) & flag) ? (1) : (0))
00510 
00511 /* Score if what we want is different than what we have, except when
00512    _DONTCARE was set */
00513 #define FLAG_SCORE_DONTCARE(want, have, flag) \
00514     ((!(have & flag ## _DONTCARE)) && ((want & flag) != (have & flag)) ? (1) : (0))
00515 
00516 int
00517 APIENTRY
00518 rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
00519 {
00520     GLDRIVERDATA *icd;
00521     PIXELFORMATDESCRIPTOR icdPfd;
00522     int i;
00523     int best = 0;
00524     int score, bestScore = 0x7fff; /* used to choose a pfd if no exact match */
00525     int icdNumFormats;
00526 
00527     DBGTRACE( "Called!" );
00528 
00529     /* load ICD */
00530     icd = ROSGL_ICDForHDC( hdc );
00531     if (icd == NULL)
00532         return 0;
00533 
00534     /* check input */
00535     if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
00536     {
00537         SetLastError( ERROR_INVALID_PARAMETER );
00538         return 0;
00539     }
00540 
00541     /* get number of formats */
00542     icdNumFormats = icd->DrvDescribePixelFormat( hdc, 1,
00543                     sizeof (PIXELFORMATDESCRIPTOR), &icdPfd );
00544     if (icdNumFormats == 0)
00545     {
00546         DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
00547         return 0;
00548     }
00549     DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
00550 
00551     /* try to find best format */
00552     for (i = 0; i < icdNumFormats; i++)
00553     {
00554         if (icd->DrvDescribePixelFormat( hdc, i + 1,
00555             sizeof (PIXELFORMATDESCRIPTOR), &icdPfd ) == 0)
00556         {
00557             DBGPRINT( "Warning: DrvDescribePixelFormat failed (%d)",
00558                       GetLastError() );
00559             break;
00560         }
00561 
00562         if ((pfd->dwFlags & PFD_GENERIC_ACCELERATED) != 0) /* we do not support such kind of drivers */
00563         {
00564             continue;
00565         }
00566 
00567         score = 0; /* higher is worse */
00568 
00569         /* compare flags */
00570         score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_DRAW_TO_WINDOW);
00571         score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_DRAW_TO_BITMAP);
00572         score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_SUPPORT_GDI);
00573         score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_SUPPORT_OPENGL);
00574         score += FLAG_SCORE_DONTCARE(pfd->dwFlags, icdPfd.dwFlags, PFD_DOUBLEBUFFER);
00575         score += FLAG_SCORE_DONTCARE(pfd->dwFlags, icdPfd.dwFlags, PFD_STEREO);
00576 
00577         /* check other attribs */
00578         if (pfd->iPixelType != icdPfd.iPixelType)
00579             score += 5; /* this is really bad i think */
00580         if (pfd->iLayerType != icdPfd.iLayerType)
00581             score += 15; /* this is very very bad ;) */
00582 
00583         score += BUFFERDEPTH_SCORE(pfd->cAlphaBits, icdPfd.cAlphaBits);
00584         score += BUFFERDEPTH_SCORE(pfd->cAccumBits, icdPfd.cAccumBits);
00585         score += BUFFERDEPTH_SCORE(pfd->cDepthBits, icdPfd.cDepthBits);
00586         score += BUFFERDEPTH_SCORE(pfd->cStencilBits, icdPfd.cStencilBits);
00587         score += BUFFERDEPTH_SCORE(pfd->cAuxBuffers, icdPfd.cAuxBuffers);
00588 
00589         /* check score */
00590         if (score < bestScore)
00591         {
00592             bestScore = score;
00593             best = i + 1;
00594             if (bestScore == 0)
00595                 break;
00596         }
00597     }
00598 
00599     if (best == 0)
00600         SetLastError( 0 ); /* FIXME: set appropriate error */
00601 
00602     DBGPRINT( "Info: Suggesting pixelformat %d", best );
00603     return best;
00604 }
00605 
00606 
00616 BOOL
00617 APIENTRY
00618 rosglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
00619 {
00620     GLRC *src = (GLRC *)hsrc;
00621     GLRC *dst = (GLRC *)hdst;
00622 
00623     /* check glrcs */
00624     if (!ROSGL_ContainsContext( src ))
00625     {
00626         DBGPRINT( "Error: src GLRC not found!" );
00627         SetLastError( ERROR_INVALID_HANDLE );
00628         return FALSE;
00629     }
00630     if (!ROSGL_ContainsContext( dst ))
00631     {
00632         DBGPRINT( "Error: dst GLRC not found!" );
00633         SetLastError( ERROR_INVALID_HANDLE );
00634         return FALSE;
00635     }
00636 
00637     /* I think this is only possible within one ICD */
00638     if (src->icd != dst->icd)
00639     {
00640         DBGPRINT( "Error: src and dst GLRC use different ICDs!" );
00641         SetLastError( ERROR_INVALID_HANDLE );
00642         return FALSE;
00643     }
00644 
00645     /* copy data (call ICD) */
00646     return src->icd->DrvCopyContext( src->hglrc, dst->hglrc, mask );
00647 }
00648 
00649 
00660 HGLRC
00661 APIENTRY
00662 rosglCreateLayerContext( HDC hdc, int layer )
00663 {
00664     GLDRIVERDATA *icd = NULL;
00665     GLRC *glrc;
00666     HGLRC drvHglrc = NULL;
00667 
00668     DBGTRACE( "Called!" );
00669 
00670 /*  if (GetObjectType( hdc ) != OBJ_DC)
00671     {
00672         DBGPRINT( "Error: hdc is not a DC handle!" );
00673         return NULL;
00674     }
00675 */
00676     /* create new GLRC */
00677     glrc = ROSGL_NewContext();
00678     if (glrc == NULL)
00679         return NULL;
00680 
00681     /* load ICD */
00682     icd = ROSGL_ICDForHDC( hdc );
00683     if (icd == NULL)
00684     {
00685         ROSGL_DeleteContext( glrc );
00686         DBGPRINT( "Couldn't get ICD by HDC :-(" );
00687         /* FIXME: fallback? */
00688         return NULL;
00689     }
00690     /* Don't forget to refcount it, icd will be released when last context is deleted */
00691     InterlockedIncrement((LONG*)&icd->refcount);
00692     
00693 
00694     /* create context */
00695     if (icd->DrvCreateLayerContext != NULL)
00696         drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
00697     if (drvHglrc == NULL)
00698     {
00699         if (layer == 0 && icd->DrvCreateContext != NULL)
00700             drvHglrc = icd->DrvCreateContext( hdc );
00701         else
00702             DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
00703     }
00704 
00705     if (drvHglrc == NULL)
00706     {
00707         /* FIXME: fallback to mesa? */
00708         DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() );
00709         ROSGL_DeleteContext( glrc );
00710         return NULL;
00711     }
00712 
00713     /* we have our GLRC in glrc and the ICD's GLRC in drvHglrc */
00714     glrc->hglrc = drvHglrc;
00715     glrc->icd = icd;
00716 
00717     return (HGLRC)glrc;
00718 }
00719 
00720 
00728 HGLRC
00729 APIENTRY
00730 rosglCreateContext( HDC hdc )
00731 {
00732     return rosglCreateLayerContext( hdc, 0 );
00733 }
00734 
00735 
00743 BOOL
00744 APIENTRY
00745 rosglDeleteContext( HGLRC hglrc )
00746 {
00747     GLRC *glrc = (GLRC *)hglrc;
00748 
00749     /* check if we know about this context */
00750     if (!ROSGL_ContainsContext( glrc ))
00751     {
00752         DBGPRINT( "Error: hglrc not found!" );
00753         SetLastError( ERROR_INVALID_HANDLE );
00754         return FALSE;
00755     }
00756 
00757     /* make sure GLRC is not current for some thread */
00758     if (glrc->is_current)
00759     {
00760         DBGPRINT( "Error: GLRC is current for DC 0x%08x", glrc->hdc );
00761         SetLastError( ERROR_INVALID_FUNCTION );
00762         return FALSE;
00763     }
00764 
00765     /* release ICD's context */
00766     if (glrc->hglrc != NULL)
00767     {
00768         if (!glrc->icd->DrvDeleteContext( glrc->hglrc ))
00769         {
00770             DBGPRINT( "Warning: DrvDeleteContext() failed (%d)", GetLastError() );
00771             return FALSE;
00772         }
00773     }
00774 
00775     /* free resources */
00776     return ROSGL_DeleteContext( glrc );
00777 }
00778 
00779 
00780 BOOL
00781 APIENTRY
00782 rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
00783                          UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd )
00784 {
00785     UNIMPLEMENTED;
00786     SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
00787     return FALSE;
00788 }
00789 
00790 
00801 int
00802 APIENTRY
00803 rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
00804                           LPPIXELFORMATDESCRIPTOR pfd )
00805 {
00806     int ret = 0;
00807     GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
00808 
00809     if (icd != NULL)
00810     {
00811         ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
00812         if (ret == 0)
00813             DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
00814     }
00815     else
00816     {
00817         SetLastError( ERROR_INVALID_FUNCTION );
00818     }
00819 
00820     return ret;
00821 }
00822 
00823 
00829 HGLRC
00830 APIENTRY
00831 rosglGetCurrentContext()
00832 {
00833     return (HGLRC)(OPENGL32_threaddata->glrc);
00834 }
00835 
00836 
00842 HDC
00843 APIENTRY
00844 rosglGetCurrentDC()
00845 {
00846     /* FIXME: is it correct to return NULL when there is no current GLRC or
00847        is there another way to find out the wanted HDC? */
00848     if (OPENGL32_threaddata->glrc == NULL)
00849         return NULL;
00850     return (HDC)(OPENGL32_threaddata->glrc->hdc);
00851 }
00852 
00853 
00854 int
00855 APIENTRY
00856 rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
00857                              int cEntries, COLORREF *pcr )
00858 {
00859     UNIMPLEMENTED;
00860     SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
00861     return 0;
00862 }
00863 
00864 
00872 int
00873 WINAPI
00874 rosglGetPixelFormat( HDC hdc )
00875 {
00876     GLDCDATA *dcdata;
00877 
00878     DBGTRACE( "Called!" );
00879 
00880     dcdata = ROSGL_GetPrivateDCData( hdc );
00881     if (dcdata == NULL)
00882     {
00883         DBGPRINT( "Error: ROSGL_GetPrivateDCData failed!" );
00884         return 0;
00885     }
00886 
00887     return dcdata->pixel_format;
00888 }
00889 
00890 
00901 PROC
00902 APIENTRY
00903 rosglGetProcAddress( LPCSTR proc )
00904 {
00905     PROC func;
00906     GLDRIVERDATA *icd;
00907 
00908     /* FIXME we should Flush the gl here */
00909 
00910     if (OPENGL32_threaddata->glrc == NULL)
00911     {
00912         DBGPRINT( "Error: No current GLRC!" );
00913         SetLastError( ERROR_INVALID_FUNCTION );
00914         return NULL;
00915     }
00916 
00917     icd = OPENGL32_threaddata->glrc->icd;
00918     func = icd->DrvGetProcAddress( proc );
00919     if (func != NULL)
00920     {
00921         DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
00922         return func;
00923     }
00924 
00925     /* FIXME: Should we return wgl/gl 1.1 functions? */
00926     SetLastError( ERROR_PROC_NOT_FOUND );
00927     return NULL;
00928 }
00929 
00930 PROC
00931 APIENTRY
00932 rosglGetDefaultProcAddress( LPCSTR proc )
00933 {
00934     PROC func;
00935     GLDRIVERDATA *icd;
00936 
00937     /*  wglGetDefaultProcAddress does not flush the gl */
00938 
00939     if (OPENGL32_threaddata->glrc == NULL)
00940     {
00941         DBGPRINT( "Error: No current GLRC!" );
00942         SetLastError( ERROR_INVALID_FUNCTION );
00943         return NULL;
00944     }
00945 
00946     icd = OPENGL32_threaddata->glrc->icd;
00947     func = icd->DrvGetProcAddress( proc );
00948     if (func != NULL)
00949     {
00950         DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
00951         return func;
00952     }
00953 
00954     /* FIXME: Should we return wgl/gl 1.1 functions? */
00955     SetLastError( ERROR_PROC_NOT_FOUND );
00956     return NULL;
00957 }
00958 
00959 
00968 BOOL
00969 APIENTRY
00970 rosglMakeCurrent( HDC hdc, HGLRC hglrc )
00971 {
00972     GLRC *glrc = (GLRC *)hglrc;
00973     ICDTable *icdTable = NULL;
00974 
00975     DBGTRACE( "Called!" );
00976 
00977     if (OPENGL32_threaddata == NULL)
00978         return FALSE;
00979 
00980     /* flush current context */
00981     if (OPENGL32_threaddata->glrc != NULL)
00982     {
00983         glFlush();
00984     }
00985 
00986     /* check if current context is unset */
00987     if (glrc == NULL)
00988     {
00989         if (OPENGL32_threaddata->glrc != NULL)
00990         {
00991             glrc = OPENGL32_threaddata->glrc;
00992             glrc->icd->DrvReleaseContext( glrc->hglrc );
00993             glrc->is_current = FALSE;
00994             OPENGL32_threaddata->glrc = NULL;
00995         }
00996     }
00997     else
00998     {
00999         /* check hdc */
01000         if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
01001         {
01002             DBGPRINT( "Error: hdc is not a DC handle!" );
01003             SetLastError( ERROR_INVALID_HANDLE );
01004             return FALSE;
01005         }
01006 
01007         /* check if we know about this glrc */
01008         if (!ROSGL_ContainsContext( glrc ))
01009         {
01010             DBGPRINT( "Error: hglrc not found!" );
01011             SetLastError( ERROR_INVALID_HANDLE );
01012             return FALSE;
01013         }
01014 
01015         /* check if it is available */
01016         if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */
01017         {
01018             DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
01019             SetLastError( ERROR_INVALID_HANDLE );
01020             return FALSE;
01021         }
01022 
01023         /* call the ICD */
01024         if (glrc->hglrc != NULL)
01025         {
01026             DBGPRINT( "Info: Calling DrvSetContext!" );
01027             SetLastError( ERROR_SUCCESS );
01028             icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
01029                                                  (void *)ROSGL_SetContextCallBack );
01030             if (icdTable == NULL)
01031             {
01032                 DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
01033                 return FALSE;
01034             }
01035             DBGPRINT( "Info: DrvSetContext succeeded!" );
01036         }
01037 
01038         /* make it current */
01039         if (OPENGL32_threaddata->glrc != NULL)
01040             OPENGL32_threaddata->glrc->is_current = FALSE;
01041         glrc->is_current = TRUE;
01042         glrc->thread_id = GetCurrentThreadId();
01043         glrc->hdc = hdc;
01044         OPENGL32_threaddata->glrc = glrc;
01045     }
01046 
01047     if (ROSGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS && icdTable == NULL)
01048     {
01049         DBGPRINT( "Warning: ROSGL_SetContextCallBack failed!" );
01050     }
01051 
01052     return TRUE;
01053 }
01054 
01055 
01056 BOOL
01057 APIENTRY
01058 rosglRealizeLayerPalette( HDC hdc, int iLayerPlane, BOOL bRealize )
01059 {
01060     UNIMPLEMENTED;
01061     SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
01062     return FALSE;
01063 }
01064 
01065 
01066 int
01067 APIENTRY
01068 rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
01069                              int cEntries, CONST COLORREF *pcr )
01070 {
01071     UNIMPLEMENTED;
01072     SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
01073     return 0;
01074 }
01075 
01076 
01086 BOOL
01087 WINAPI
01088 rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
01089 {
01090     GLDRIVERDATA *icd;
01091     GLDCDATA *dcdata;
01092 
01093     DBGTRACE( "Called!" );
01094 
01095     /* load ICD */
01096     icd = ROSGL_ICDForHDC( hdc );
01097     if (icd == NULL)
01098     {
01099         DBGPRINT( "Warning: ICDForHDC() failed" );
01100         return FALSE;
01101     }
01102 
01103     /* call ICD */
01104     if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd ))
01105     {
01106         DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
01107                   iFormat, GetLastError() );
01108         return FALSE;
01109     }
01110 
01111     /* store format in private DC data */
01112     dcdata = ROSGL_GetPrivateDCData( hdc );
01113     if (dcdata == NULL)
01114     {
01115         DBGPRINT( "Error: ROSGL_GetPrivateDCData() failed!" );
01116         return FALSE;
01117     }
01118     dcdata->pixel_format = iFormat;
01119 
01120     return TRUE;
01121 }
01122 
01123 
01134 BOOL
01135 APIENTRY
01136 rosglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
01137 {
01138     GLRC *glrc1 = (GLRC *)hglrc1;
01139     GLRC *glrc2 = (GLRC *)hglrc2;
01140 
01141     /* check glrcs */
01142     if (!ROSGL_ContainsContext( glrc1 ))
01143     {
01144         DBGPRINT( "Error: hglrc1 not found!" );
01145         SetLastError( ERROR_INVALID_HANDLE );
01146         return FALSE;
01147     }
01148     if (!ROSGL_ContainsContext( glrc2 ))
01149     {
01150         DBGPRINT( "Error: hglrc2 not found!" );
01151         SetLastError( ERROR_INVALID_HANDLE );
01152         return FALSE;
01153     }
01154 
01155     /* I think this is only possible within one ICD */
01156     if (glrc1->icd != glrc2->icd)
01157     {
01158         DBGPRINT( "Error: hglrc1 and hglrc2 use different ICDs!" );
01159         SetLastError( ERROR_INVALID_HANDLE );
01160         return FALSE;
01161     }
01162 
01163     /* share lists (call ICD) */
01164     return glrc1->icd->DrvShareLists( glrc1->hglrc, glrc2->hglrc );
01165 }
01166 
01167 
01175 BOOL
01176 APIENTRY
01177 rosglSwapBuffers( HDC hdc )
01178 {
01179     GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
01180     DBGTRACE( "Called!" );
01181     if (icd != NULL)
01182     {
01183         DBGPRINT( "Swapping buffers!" );
01184         if (!icd->DrvSwapBuffers( hdc ))
01185         {
01186             DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
01187             return FALSE;
01188         }
01189         return TRUE;
01190     }
01191 
01192     /* FIXME: implement own functionality? */
01193     SetLastError( ERROR_INVALID_FUNCTION );
01194     return FALSE;
01195 }
01196 
01197 
01198 BOOL
01199 APIENTRY
01200 rosglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
01201 {
01202     BOOL ret = FALSE;
01203 
01204     if(fuPlanes & WGL_SWAP_MAIN_PLANE)
01205         ret = rosglSwapBuffers(hdc);
01206 
01207     if(fuPlanes &~WGL_SWAP_MAIN_PLANE)
01208         DBGTRACE("wglSwapLayerBuffers is not fully implemented\n");
01209 
01210     return ret;
01211 }
01212 
01213 
01214 BOOL
01215 APIENTRY
01216 rosglUseFontBitmapsA( HDC hdc, DWORD first, DWORD count, DWORD listBase )
01217 {
01218     return IntUseFontBitmapsA(hdc, first, count, listBase);
01219 }
01220 
01221 
01222 BOOL
01223 APIENTRY
01224 rosglUseFontBitmapsW( HDC hdc, DWORD first, DWORD count, DWORD listBase )
01225 {
01226     return IntUseFontBitmapsW(hdc, first, count, listBase);
01227 }
01228 
01229 BOOL
01230 APIENTRY
01231 rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
01232                        FLOAT deviation, FLOAT extrusion, int format,
01233                        GLYPHMETRICSFLOAT *pgmf )
01234 {
01235     return IntUseFontOutlinesA(hdc, first, count, listBase, deviation, extrusion, format, pgmf);
01236 }
01237 
01238 
01239 BOOL
01240 APIENTRY
01241 rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
01242                        FLOAT deviation, FLOAT extrusion, int format,
01243                        GLYPHMETRICSFLOAT *pgmf )
01244 {
01245     return IntUseFontOutlinesW(hdc, first, count, listBase, deviation, extrusion, format, pgmf);
01246 }
01247 
01248 #ifdef __cplusplus
01249 }; /* extern "C" */
01250 #endif /* __cplusplus */
01251 
01252 /* EOF */

Generated on Sun May 27 2012 04:19:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.