2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/opengl32/wgl.c
5 * PURPOSE: OpenGL32 lib, rosglXXX functions
6 * PROGRAMMER: Anich Gregor (blight)
11 #define WIN32_LEAN_AND_MEAN
12 #define WIN32_NO_STATUS
15 #define NTOS_MODE_USER
26 #define OPENGL32_GL_FUNC_PROTOTYPES
31 #endif /* __cplusplus */
33 #if !defined(UNIMPLEMENTED)
34 # define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
38 typedef struct _OPENGL_INFO
40 DWORD Version
; /*!< Driver interface version */
41 DWORD DriverVersion
; /*!< Driver version */
42 WCHAR DriverName
[256]; /*!< Driver name */
43 } OPENGL_INFO
, *POPENGL_INFO
;
46 /*! \brief Append OpenGL Rendering Context (GLRC) to list
48 * \param glrc [IN] Pointer to GLRC to append to list
52 ROSGL_AppendContext( GLRC
*glrc
)
55 if (WaitForSingleObject( OPENGL32_processdata
.glrc_mutex
, INFINITE
) ==
58 DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
59 return; /* FIXME: do we have to expect such an error and handle it? */
62 if (OPENGL32_processdata
.glrc_list
== NULL
)
63 OPENGL32_processdata
.glrc_list
= glrc
;
66 GLRC
*p
= OPENGL32_processdata
.glrc_list
;
67 while (p
->next
!= NULL
)
73 if (!ReleaseMutex( OPENGL32_processdata
.glrc_mutex
))
74 DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
78 /*! \brief Remove OpenGL Rendering Context (GLRC) from list
80 * \param glrc [IN] Pointer to GLRC to remove from list
84 ROSGL_RemoveContext( GLRC
*glrc
)
87 if (WaitForSingleObject( OPENGL32_processdata
.glrc_mutex
, INFINITE
) ==
90 DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
91 return; /* FIXME: do we have to expect such an error and handle it? */
94 if (glrc
== OPENGL32_processdata
.glrc_list
)
95 OPENGL32_processdata
.glrc_list
= glrc
->next
;
98 GLRC
*p
= OPENGL32_processdata
.glrc_list
;
103 p
->next
= glrc
->next
;
109 DBGPRINT( "Error: GLRC 0x%08x not found in list!", glrc
);
113 if (!ReleaseMutex( OPENGL32_processdata
.glrc_mutex
))
114 DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
118 /*! \brief Create a new GL Context (GLRC) and append it to the list
120 * \return Pointer to new GLRC on success
121 * \retval NULL Returned on failure (i.e. Out of memory)
130 glrc
= (GLRC
*)HeapAlloc( GetProcessHeap(),
131 HEAP_ZERO_MEMORY
| HEAP_GENERATE_EXCEPTIONS
, sizeof (GLRC
) );
134 ROSGL_AppendContext( glrc
);
140 /*! \brief Delete a GL Context (GLRC) and remove it from the list
142 * \param glrc [IN] Pointer to GLRC to delete
144 * \retval TRUE Success
145 * \retval FALSE Failure
149 ROSGL_DeleteContext( GLRC
*glrc
)
152 if (glrc
->icd
!= NULL
)
153 OPENGL32_UnloadICD( glrc
->icd
);
155 /* remove from list */
156 ROSGL_RemoveContext( glrc
);
159 HeapFree( GetProcessHeap(), 0, glrc
);
165 /*! \brief Check wether a GLRC is in the list
167 * \param glrc [IN] Pointer to GLRC to look for in the list
169 * \retval TRUE GLRC was found
170 * \retval FALSE GLRC was not found
174 ROSGL_ContainsContext( GLRC
*glrc
)
180 if (WaitForSingleObject( OPENGL32_processdata
.glrc_mutex
, INFINITE
) ==
183 DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
184 return FALSE
; /* FIXME: do we have to expect such an error and handle it? */
187 p
= OPENGL32_processdata
.glrc_list
;
199 if (!ReleaseMutex( OPENGL32_processdata
.glrc_mutex
))
200 DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
206 /*! \brief Get GL private DC data.
208 * This function adds an empty GLDCDATA to the list if there is no data for the
211 * \param hdc [IN] Handle to a Device Context for which to get the data
213 * \return Pointer to GLDCDATA on success
214 * \retval NULL on failure
218 ROSGL_GetPrivateDCData( HDC hdc
)
223 if (GetObjectType( hdc
) != OBJ_DC
&& GetObjectType( hdc
) != OBJ_MEMDC
)
225 DBGPRINT( "Error: hdc is not a DC handle!" );
226 SetLastError( ERROR_INVALID_HANDLE
);
231 if (WaitForSingleObject( OPENGL32_processdata
.dcdata_mutex
, INFINITE
) ==
234 DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
235 return NULL
; /* FIXME: do we have to expect such an error and handle it? */
238 /* look for data in list */
239 data
= OPENGL32_processdata
.dcdata_list
;
242 if (data
->hdc
== hdc
) /* found */
247 /* allocate new data if not found in list */
250 data
= HeapAlloc( GetProcessHeap(),
251 HEAP_ZERO_MEMORY
| HEAP_GENERATE_EXCEPTIONS
,
255 DBGPRINT( "Error: HeapAlloc() failed (%d)", GetLastError() );
261 /* append data to list */
262 if (OPENGL32_processdata
.dcdata_list
== NULL
)
263 OPENGL32_processdata
.dcdata_list
= data
;
266 GLDCDATA
*p
= OPENGL32_processdata
.dcdata_list
;
267 while (p
->next
!= NULL
)
275 if (!ReleaseMutex( OPENGL32_processdata
.dcdata_mutex
))
276 DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
282 /*! \brief Get ICD from HDC.
284 * This function asks the display driver which OpenGL ICD to load for the given
285 * HDC, loads it and returns a pointer to a GLDRIVERDATA struct on success.
287 * \param hdc [IN] Handle for DC for which to load/get the ICD
289 * \return Pointer to GLDRIVERDATA
290 * \retval NULL Failure.
294 ROSGL_ICDForHDC( HDC hdc
)
298 dcdata
= ROSGL_GetPrivateDCData( hdc
);
302 if (dcdata
->icd
== NULL
)
307 driverName
= _wgetenv( L
"OPENGL32_DRIVER" );
308 if (driverName
== NULL
)
313 /* get driver name */
314 dwInput
= OPENGL_GETINFO
;
315 ret
= ExtEscape( hdc
, QUERYESCSUPPORT
, sizeof (dwInput
), (LPCSTR
)&dwInput
, 0, NULL
);
319 ret
= ExtEscape( hdc
, OPENGL_GETINFO
, sizeof (dwInput
),
320 (LPCSTR
)&dwInput
, sizeof (OPENGL_INFO
),
330 DBGPRINT( "Warning: ExtEscape to get the drivername failed! (%d)", GetLastError() );
331 if (MessageBox( WindowFromDC( hdc
), L
"Couldn't get installable client driver name!\nUsing default driver.",
332 L
"OPENGL32.dll: Warning", MB_OKCANCEL
| MB_ICONWARNING
) == IDCANCEL
)
338 /* open registry key */
339 ret
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, OPENGL_DRIVERS_SUBKEY
, 0, KEY_READ
, &hKey
);
340 if (ret
!= ERROR_SUCCESS
)
342 DBGPRINT( "Error: Couldn't open registry key '%ws'", OPENGL_DRIVERS_SUBKEY
);
348 size
= sizeof (info
.DriverName
);
349 ret
= RegQueryValueExW( hKey
, L
"DefaultDriver", 0, &type
, (LPBYTE
)info
.DriverName
, &size
);
351 if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
)
353 DBGPRINT( "Error: Couldn't query DefaultDriver value or not a string" );
361 wcsncpy( info
.DriverName
, driverName
, sizeof (info
.DriverName
) / sizeof (info
.DriverName
[0]) );
363 /* load driver (or get a reference) */
364 dcdata
->icd
= OPENGL32_LoadICD( info
.DriverName
);
365 if (dcdata
->icd
== NULL
)
368 snwprintf(Buffer
, sizeof(Buffer
)/sizeof(WCHAR
),
369 L
"Couldn't load driver \"%s\".", driverName
);
370 MessageBox(WindowFromDC( hdc
), Buffer
,
371 L
"OPENGL32.dll: Warning",
372 MB_OK
| MB_ICONWARNING
);
380 /*! \brief SetContextCallBack passed to DrvSetContext.
382 * This function gets called by the OpenGL driver whenever the current GL
383 * context (dispatch table) is to be changed.
385 * \param table [IN] Function pointer table (first DWORD is number of functions)
387 * \return unkown (maybe void? ERROR_SUCCESS at the moment)
391 ROSGL_SetContextCallBack( const ICDTable
*table
)
394 PROC
*tebTable
, *tebDispatchTable
;
397 teb
= NtCurrentTeb();
398 tebTable
= (PROC
*)teb
->glTable
;
399 tebDispatchTable
= (PROC
*)teb
->glDispatchTable
;
401 DBGTRACE( "Called!" );
405 DBGPRINT( "Function count: %d\n", table
->num_funcs
);
408 size
= sizeof (PROC
) * table
->num_funcs
;
409 memcpy( tebTable
, table
->dispatch_table
, size
);
410 memset( tebTable
+ table
->num_funcs
, 0,
411 sizeof (table
->dispatch_table
) - size
);
415 DBGPRINT( "Unsetting current context" );
416 memset( tebTable
, 0, sizeof (table
->dispatch_table
) );
419 /* put in empty functions as long as we dont have a fallback */
420 #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
421 if (tebTable[icdidx] == NULL) \
424 DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
425 tebTable[icdidx] = (PROC)glEmptyFunc##stack; \
430 /* fill teb->glDispatchTable for fast calls */
431 #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
433 tebDispatchTable[tebidx] = tebTable[icdidx];
439 return ERROR_SUCCESS
;
443 /*! \brief Attempts to find the best matching pixel format for HDC
445 * This function is comparing each available format with the preferred one
446 * and returns the one which is closest to it.
447 * If PFD_DOUBLEBUFFER, PFD_STEREO or one of PFD_DRAW_TO_WINDOW,
448 * PFD_DRAW_TO_BITMAP, PFD_SUPPORT_GDI and PDF_SUPPORT_OPENGL is given then
449 * only formats which also support those will be enumerated (unless
450 * PFD_DOUBLEBUFFER_DONTCARE or PFD_STEREO_DONTCARE is also set)
452 * \param hdc [IN] Handle to DC for which to get a pixel format index
453 * \param pfd [IN] PFD describing what kind of format you want
455 * \return Pixel format index
456 * \retval 0 Failed to find a suitable format
458 #define BUFFERDEPTH_SCORE(want, have) \
459 ((want == 0) ? (0) : ((want < have) ? (1) : ((want > have) ? (3) : (0))))
462 rosglChoosePixelFormat( HDC hdc
, CONST PIXELFORMATDESCRIPTOR
*pfd
)
465 PIXELFORMATDESCRIPTOR icdPfd
;
468 int score
, bestScore
= 0x7fff; /* used to choose a pfd if no exact match */
470 const DWORD compareFlags
= PFD_DRAW_TO_WINDOW
| PFD_DRAW_TO_BITMAP
|
471 PFD_SUPPORT_GDI
| PFD_SUPPORT_OPENGL
;
473 DBGTRACE( "Called!" );
476 icd
= ROSGL_ICDForHDC( hdc
);
481 if (pfd
->nSize
!= sizeof (PIXELFORMATDESCRIPTOR
) || pfd
->nVersion
!= 1)
483 SetLastError( ERROR_INVALID_PARAMETER
);
487 /* get number of formats */
488 icdNumFormats
= icd
->DrvDescribePixelFormat( hdc
, 1,
489 sizeof (PIXELFORMATDESCRIPTOR
), &icdPfd
);
490 if (icdNumFormats
== 0)
492 DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
495 DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats
);
497 /* try to find best format */
498 for (i
= 0; i
< icdNumFormats
; i
++)
500 if (icd
->DrvDescribePixelFormat( hdc
, i
+ 1,
501 sizeof (PIXELFORMATDESCRIPTOR
), &icdPfd
) == 0)
503 DBGPRINT( "Warning: DrvDescribePixelFormat failed (%d)",
508 if ((pfd
->dwFlags
& PFD_GENERIC_ACCELERATED
) != 0) /* we do not support such kind of drivers */
514 if ((pfd
->dwFlags
& compareFlags
) != (icdPfd
.dwFlags
& compareFlags
))
516 if (!(pfd
->dwFlags
& PFD_DOUBLEBUFFER_DONTCARE
) &&
517 ((pfd
->dwFlags
& PFD_DOUBLEBUFFER
) != (icdPfd
.dwFlags
& PFD_DOUBLEBUFFER
)))
519 if (!(pfd
->dwFlags
& PFD_STEREO_DONTCARE
) &&
520 ((pfd
->dwFlags
& PFD_STEREO
) != (icdPfd
.dwFlags
& PFD_STEREO
)))
523 /* check other attribs */
524 score
= 0; /* higher is worse */
525 if (pfd
->iPixelType
!= icdPfd
.iPixelType
)
526 score
+= 5; /* this is really bad i think */
527 if (pfd
->iLayerType
!= icdPfd
.iLayerType
)
528 score
+= 15; /* this is very very bad ;) */
530 score
+= BUFFERDEPTH_SCORE(pfd
->cAlphaBits
, icdPfd
.cAlphaBits
);
531 score
+= BUFFERDEPTH_SCORE(pfd
->cAccumBits
, icdPfd
.cAccumBits
);
532 score
+= BUFFERDEPTH_SCORE(pfd
->cDepthBits
, icdPfd
.cDepthBits
);
533 score
+= BUFFERDEPTH_SCORE(pfd
->cStencilBits
, icdPfd
.cStencilBits
);
534 score
+= BUFFERDEPTH_SCORE(pfd
->cAuxBuffers
, icdPfd
.cAuxBuffers
);
537 if (score
< bestScore
)
547 SetLastError( 0 ); /* FIXME: set appropriate error */
549 DBGPRINT( "Info: Suggesting pixelformat %d", best
);
554 /*! \brief Copy data specified by mask from one GLRC to another.
556 * \param src [IN] Source GLRC
557 * \param src [OUT] Destination GLRC
558 * \param mask [IN] Bitfield like given to glPushAttrib()
560 * \retval TRUE Success
561 * \retval FALSE Failure
565 rosglCopyContext( HGLRC hsrc
, HGLRC hdst
, UINT mask
)
567 GLRC
*src
= (GLRC
*)hsrc
;
568 GLRC
*dst
= (GLRC
*)hdst
;
571 if (!ROSGL_ContainsContext( src
))
573 DBGPRINT( "Error: src GLRC not found!" );
574 SetLastError( ERROR_INVALID_HANDLE
);
577 if (!ROSGL_ContainsContext( dst
))
579 DBGPRINT( "Error: dst GLRC not found!" );
580 SetLastError( ERROR_INVALID_HANDLE
);
584 /* I think this is only possible within one ICD */
585 if (src
->icd
!= src
->icd
)
587 DBGPRINT( "Error: src and dst GLRC use different ICDs!" );
588 SetLastError( ERROR_INVALID_HANDLE
);
592 /* copy data (call ICD) */
593 return src
->icd
->DrvCopyContext( src
->hglrc
, dst
->hglrc
, mask
);
597 /*! \brief Create a new GL Rendering Context.
599 * This function can create over- or underlay surfaces.
601 * \param hdc [IN] Handle for DC for which to create context
602 * \param layer [IN] Layer number to bind (draw?) to
604 * \return Handle for the created GLRC
605 * \retval NULL Failure
609 rosglCreateLayerContext( HDC hdc
, int layer
)
611 GLDRIVERDATA
*icd
= NULL
;
613 HGLRC drvHglrc
= NULL
;
615 DBGTRACE( "Called!" );
617 /* if (GetObjectType( hdc ) != OBJ_DC)
619 DBGPRINT( "Error: hdc is not a DC handle!" );
623 /* create new GLRC */
624 glrc
= ROSGL_NewContext();
629 icd
= ROSGL_ICDForHDC( hdc
);
632 ROSGL_DeleteContext( glrc
);
633 DBGPRINT( "Couldn't get ICD by HDC :-(" );
634 /* FIXME: fallback? */
639 if (icd
->DrvCreateLayerContext
!= NULL
)
640 drvHglrc
= icd
->DrvCreateLayerContext( hdc
, layer
);
641 if (drvHglrc
== NULL
)
643 if (layer
== 0 && icd
->DrvCreateContext
!= NULL
)
644 drvHglrc
= icd
->DrvCreateContext( hdc
);
646 DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
649 if (drvHglrc
== NULL
)
651 /* FIXME: fallback to mesa? */
652 DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() );
653 ROSGL_DeleteContext( glrc
);
657 /* we have our GLRC in glrc and the ICD's GLRC in drvHglrc */
658 glrc
->hglrc
= drvHglrc
;
665 /*! \brief Create a new GL Rendering Context.
667 * \param hdc [IN] Handle for DC for which to create context
669 * \return Handle for the created GLRC
670 * \retval NULL Failure
674 rosglCreateContext( HDC hdc
)
676 return rosglCreateLayerContext( hdc
, 0 );
680 /*! \brief Delete an OpenGL context
682 * \param hglrc [IN] Handle to GLRC to delete; must not be a threads current RC!
684 * \retval TRUE Success
685 * \retval FALSE Failure (i.e. GLRC is current for a thread)
689 rosglDeleteContext( HGLRC hglrc
)
691 GLRC
*glrc
= (GLRC
*)hglrc
;
693 /* check if we know about this context */
694 if (!ROSGL_ContainsContext( glrc
))
696 DBGPRINT( "Error: hglrc not found!" );
697 SetLastError( ERROR_INVALID_HANDLE
);
701 /* make sure GLRC is not current for some thread */
702 if (glrc
->is_current
)
704 DBGPRINT( "Error: GLRC is current for DC 0x%08x", glrc
->hdc
);
705 SetLastError( ERROR_INVALID_FUNCTION
);
709 /* release ICD's context */
710 if (glrc
->hglrc
!= NULL
)
712 if (!glrc
->icd
->DrvDeleteContext( glrc
->hglrc
))
714 DBGPRINT( "Warning: DrvDeleteContext() failed (%d)", GetLastError() );
720 return ROSGL_DeleteContext( glrc
);
726 rosglDescribeLayerPlane( HDC hdc
, int iPixelFormat
, int iLayerPlane
,
727 UINT nBytes
, LPLAYERPLANEDESCRIPTOR plpd
)
730 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
735 /*! \brief Gets information about a pixelformat.
737 * \param hdc [IN] Handle to DC
738 * \param iFormat [IN] Pixelformat index
739 * \param nBytes [IN] sizeof (pfd) - at most nBytes are copied into pfd
740 * \param pfd [OUT] Pointer to a PIXELFORMATDESCRIPTOR
742 * \return Maximum pixelformat index/number of formats
747 rosglDescribePixelFormat( HDC hdc
, int iFormat
, UINT nBytes
,
748 LPPIXELFORMATDESCRIPTOR pfd
)
751 GLDRIVERDATA
*icd
= ROSGL_ICDForHDC( hdc
);
755 ret
= icd
->DrvDescribePixelFormat( hdc
, iFormat
, nBytes
, pfd
);
757 DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat
, GetLastError() );
761 SetLastError( ERROR_INVALID_FUNCTION
);
768 /*! \brief Return the thread's current GLRC
770 * \return Handle for thread's current GLRC
771 * \retval NULL No current GLRC set
775 rosglGetCurrentContext()
777 return (HGLRC
)(OPENGL32_threaddata
->glrc
);
781 /*! \brief Return the thread's current DC
783 * \return Handle for thread's current DC
784 * \retval NULL No current DC/GLRC set
790 /* FIXME: is it correct to return NULL when there is no current GLRC or
791 is there another way to find out the wanted HDC? */
792 if (OPENGL32_threaddata
->glrc
== NULL
)
794 return (HDC
)(OPENGL32_threaddata
->glrc
->hdc
);
800 rosglGetLayerPaletteEntries( HDC hdc
, int iLayerPlane
, int iStart
,
801 int cEntries
, COLORREF
*pcr
)
804 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
809 /*! \brief Returns the current pixelformat.
811 * \param hdc [IN] Handle to DC to get the pixelformat from
813 * \return Pixelformat index
818 rosglGetPixelFormat( HDC hdc
)
822 DBGTRACE( "Called!" );
824 dcdata
= ROSGL_GetPrivateDCData( hdc
);
827 DBGPRINT( "Error: ROSGL_GetPrivateDCData failed!" );
831 return dcdata
->pixel_format
;
835 /*! \brief Get the address for an OpenGL extension function.
837 * The addresses this function returns are only valid within the same thread
838 * which it was called from.
840 * \param proc [IN] Name of the function to look for
842 * \return The address of the proc
843 * \retval NULL Failure
847 rosglGetProcAddress( LPCSTR proc
)
852 if (OPENGL32_threaddata
->glrc
== NULL
)
854 DBGPRINT( "Error: No current GLRC!" );
855 SetLastError( ERROR_INVALID_FUNCTION
);
859 icd
= OPENGL32_threaddata
->glrc
->icd
;
860 func
= icd
->DrvGetProcAddress( proc
);
863 DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc
);
867 /* FIXME: Should we return wgl/gl 1.1 functions? */
868 SetLastError( ERROR_PROC_NOT_FOUND
);
873 /*! \brief Make the given GLRC the threads current GLRC for hdc
875 * \param hdc [IN] Handle for a DC to be drawn on
876 * \param hglrc [IN] Handle for a GLRC to make current
878 * \retval TRUE Success
879 * \retval FALSE Failure
883 rosglMakeCurrent( HDC hdc
, HGLRC hglrc
)
885 GLRC
*glrc
= (GLRC
*)hglrc
;
886 ICDTable
*icdTable
= NULL
;
888 DBGTRACE( "Called!" );
890 /* flush current context */
891 if (OPENGL32_threaddata
->glrc
!= NULL
)
896 /* check if current context is unset */
899 if (OPENGL32_threaddata
->glrc
!= NULL
)
901 glrc
= OPENGL32_threaddata
->glrc
;
902 glrc
->icd
->DrvReleaseContext( glrc
->hglrc
);
903 glrc
->is_current
= FALSE
;
904 OPENGL32_threaddata
->glrc
= NULL
;
910 if (GetObjectType( hdc
) != OBJ_DC
&& GetObjectType( hdc
) != OBJ_MEMDC
)
912 DBGPRINT( "Error: hdc is not a DC handle!" );
913 SetLastError( ERROR_INVALID_HANDLE
);
917 /* check if we know about this glrc */
918 if (!ROSGL_ContainsContext( glrc
))
920 DBGPRINT( "Error: hglrc not found!" );
921 SetLastError( ERROR_INVALID_HANDLE
);
925 /* check if it is available */
926 if (glrc
->is_current
&& glrc
->thread_id
!= GetCurrentThreadId()) /* used by another thread */
928 DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc
->thread_id
);
929 SetLastError( ERROR_INVALID_HANDLE
);
934 if (glrc
->hglrc
!= NULL
)
936 DBGPRINT( "Info: Calling DrvSetContext!" );
937 SetLastError( ERROR_SUCCESS
);
938 icdTable
= glrc
->icd
->DrvSetContext( hdc
, glrc
->hglrc
,
939 ROSGL_SetContextCallBack
);
940 if (icdTable
== NULL
)
942 DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
945 DBGPRINT( "Info: DrvSetContext succeeded!" );
948 /* make it current */
949 if (OPENGL32_threaddata
->glrc
!= NULL
)
950 OPENGL32_threaddata
->glrc
->is_current
= FALSE
;
951 glrc
->is_current
= TRUE
;
952 glrc
->thread_id
= GetCurrentThreadId();
954 OPENGL32_threaddata
->glrc
= glrc
;
957 if (ROSGL_SetContextCallBack( icdTable
) != ERROR_SUCCESS
&& icdTable
== NULL
)
959 DBGPRINT( "Warning: ROSGL_SetContextCallBack failed!" );
968 rosglRealizeLayerPalette( HDC hdc
, int iLayerPlane
, BOOL bRealize
)
971 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
978 rosglSetLayerPaletteEntries( HDC hdc
, int iLayerPlane
, int iStart
,
979 int cEntries
, CONST COLORREF
*pcr
)
982 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
987 /*! \brief Set a DCs pixelformat
989 * \param hdc [IN] Handle to DC for which to set the format
990 * \param iFormat [IN] Index of the pixelformat to set
991 * \param pfd [IN] Not sure what this is for
993 * \retval TRUE Success
994 * \retval FALSE Failure
998 rosglSetPixelFormat( HDC hdc
, int iFormat
, CONST PIXELFORMATDESCRIPTOR
*pfd
)
1003 DBGTRACE( "Called!" );
1006 icd
= ROSGL_ICDForHDC( hdc
);
1009 DBGPRINT( "Warning: ICDForHDC() failed" );
1014 if (!icd
->DrvSetPixelFormat( hdc
, iFormat
/*, pfd*/ ))
1016 DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
1017 iFormat
, GetLastError() );
1021 /* store format in private DC data */
1022 dcdata
= ROSGL_GetPrivateDCData( hdc
);
1025 DBGPRINT( "Error: ROSGL_GetPrivateDCData() failed!" );
1028 dcdata
->pixel_format
= iFormat
;
1034 /*! \brief Enable display-list sharing between multiple GLRCs
1036 * This will only work if both GLRCs are from the same driver.
1038 * \param hglrc1 [IN] GLRC number 1
1039 * \param hglrc2 [IN] GLRC number 2
1041 * \retval TRUE Success
1042 * \retval FALSE Failure
1046 rosglShareLists( HGLRC hglrc1
, HGLRC hglrc2
)
1048 GLRC
*glrc1
= (GLRC
*)hglrc1
;
1049 GLRC
*glrc2
= (GLRC
*)hglrc2
;
1052 if (!ROSGL_ContainsContext( glrc1
))
1054 DBGPRINT( "Error: hglrc1 not found!" );
1055 SetLastError( ERROR_INVALID_HANDLE
);
1058 if (!ROSGL_ContainsContext( glrc2
))
1060 DBGPRINT( "Error: hglrc2 not found!" );
1061 SetLastError( ERROR_INVALID_HANDLE
);
1065 /* I think this is only possible within one ICD */
1066 if (glrc1
->icd
!= glrc2
->icd
)
1068 DBGPRINT( "Error: hglrc1 and hglrc2 use different ICDs!" );
1069 SetLastError( ERROR_INVALID_HANDLE
);
1073 /* share lists (call ICD) */
1074 return glrc1
->icd
->DrvShareLists( glrc1
->hglrc
, glrc2
->hglrc
);
1078 /*! \brief Flushes GL and swaps front/back buffer if appropriate
1080 * \param hdc [IN] Handle to device context to swap buffers for
1082 * \retval TRUE Success
1083 * \retval FALSE Failure
1087 rosglSwapBuffers( HDC hdc
)
1089 GLDRIVERDATA
*icd
= ROSGL_ICDForHDC( hdc
);
1090 DBGTRACE( "Called!" );
1093 DBGPRINT( "Swapping buffers!" );
1094 if (!icd
->DrvSwapBuffers( hdc
))
1096 DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
1102 /* FIXME: implement own functionality? */
1103 SetLastError( ERROR_INVALID_FUNCTION
);
1110 rosglSwapLayerBuffers( HDC hdc
, UINT fuPlanes
)
1113 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
1120 rosglUseFontBitmapsA( HDC hdc
, DWORD first
, DWORD count
, DWORD listBase
)
1123 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
1130 rosglUseFontBitmapsW( HDC hdc
, DWORD first
, DWORD count
, DWORD listBase
)
1133 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
1140 rosglUseFontOutlinesA( HDC hdc
, DWORD first
, DWORD count
, DWORD listBase
,
1141 FLOAT deviation
, FLOAT extrusion
, int format
,
1142 GLYPHMETRICSFLOAT
*pgmf
)
1145 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
1152 rosglUseFontOutlinesW( HDC hdc
, DWORD first
, DWORD count
, DWORD listBase
,
1153 FLOAT deviation
, FLOAT extrusion
, int format
,
1154 GLYPHMETRICSFLOAT
*pgmf
)
1157 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
1163 #endif /* __cplusplus */