/* Wrapper for OpenGL includes...
     Copyright 1998 - Lionel Ulmer
     Copyright 2001 TransGaming Technologies, Inc.

   This wrapper is needed because Mesa uses also the CALLBACK / WINAPI
   constants.  It's also needed to work around certain common problems
   in Linux GL headers where key function pointers are not defined. */


#ifndef __WINE_WINE_GL_H
#define __WINE_WINE_GL_H

#ifndef __WINE_CONFIG_H
# error You must include config.h to use this header
#endif

#if defined(HAVE_OPENGL)

#include "ts_xlib.h"

/* As GLX relies on X, this is needed */
#define ENTER_GL() wine_tsx11_lock()
#define LEAVE_GL() wine_tsx11_unlock()

#undef APIENTRY
#undef CALLBACK
#undef WINAPI

#define XMD_H /* This is to prevent the Xmd.h inclusion bug to happen :-/ */
#include <GL/gl.h>
#include <GL/glu.h>
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>

/* Work around a gl.h vs glext.h snafu - gl.h may activate defines
   that prevent glext.h from giving us function pointer prototypes
   for the extensions below (which we need). If these defines are
   active, we have to define these prototypes ourselves. Of course
   this is further complicated by the fact that Mesa's gl.h header
   (if it's around instead of SGI's gl.h) includes glext.h itself.
   Hence the checks for GLEXT_VERSION for everything but
   GL_ARB_multitexture (prior to OpenGL 1.3, Mesa gl.h defined
   GL_ARB_multitexture itself, rather than leaving it up to glext.h
   - aak!) */
/* The nVidia gl.h also define extensions without giving us
   function pointer prototypes, and does declare OpenGL 1.3
   compatibility, but unlike Mesa, it doesn't include glext.h,
   so the check for GL_ARB_multitexture must check for this as well,
   sigh... */

#if defined(GL_ARB_multitexture) && (!defined(GL_GLEXT_VERSION) || !defined(GL_VERSION_1_3))
#define WINE_DDRAW_need_multitexture_pfns
#endif

#if defined(GL_EXT_secondary_color) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_secondary_color_pfns
#endif

#if defined(GL_EXT_fog_coord) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_fog_coord_pfns
#endif

#if defined(GL_ARB_texture_compression) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_texture_compression_pfns
#endif

#if defined(GL_EXT_vertex_weighting) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_vertex_weighting_pfns
#endif

#if defined(GL_NV_vertex_array_range) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_NV_VAR_pfns
#endif

#if defined(GL_NV_fence) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_NV_fence_pfns
#endif

#if defined(GL_NV_pixel_data_range) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_NV_PDR_pfns
#endif

#if defined(GL_NV_vertex_program) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_NV_vertex_program_pfns
#endif

#if defined(GL_ARB_vertex_program) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_ARB_vertex_program_pfns
#endif

#if defined(GL_ARB_vertex_blend) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_ARB_vertex_blend_pfns
#endif

#if defined(GL_ARB_vertex_buffer_object) && !defined(GL_GLEXT_VERSION)
#define WINE_DDRAW_need_ARB_VBO_pfns
#endif

#ifdef HAVE_GL_GLEXT_H
#include <GL/glext.h>
#endif

#ifndef APIENTRY
#define APIENTRY
#endif

#ifndef GL_VERSION_1_5
typedef ptrdiff_t GLintptr;
typedef ptrdiff_t GLsizeiptr;
#endif

#ifndef GL_ARB_vertex_buffer_object
typedef ptrdiff_t GLintptrARB;
typedef ptrdiff_t GLsizeiptrARB;
#endif

#ifndef GL_ARB_shader_objects
typedef char GLcharARB;
typedef unsigned int GLhandleARB;
#endif

#ifndef GL_NV_half_float
typedef unsigned short GLhalfNV;
#endif

#ifdef WINE_DDRAW_need_multitexture_pfns
typedef void (APIENTRY *PFNGLACTIVETEXTUREARBPROC)(GLenum texture);
typedef void (APIENTRY *PFNGLCLIENTACTIVETEXTUREARBPROC)(GLenum texture);
typedef void (APIENTRY *PFNGLMULTITEXCOORD2FARBPROC)(GLenum target, GLfloat u, GLfloat v);
#endif

#ifdef GL_VERSION_1_3
/* 1.3 moves the ARB multitexture extension into the core API, losing the ARB suffix on
 * the multitexture prototypes. However, dlls/opengl32/opengl_norm.c still need prototypes
 * with the ARB suffix, so we'll define them here. */
extern void APIENTRY glActiveTextureARB (GLenum);
extern void APIENTRY glClientActiveTextureARB (GLenum);
extern void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble);
extern void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *);
extern void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat);
extern void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *);
extern void APIENTRY glMultiTexCoord1iARB (GLenum, GLint);
extern void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *);
extern void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort);
extern void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *);
extern void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble);
extern void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *);
extern void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat);
extern void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *);
extern void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint);
extern void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *);
extern void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort);
extern void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *);
extern void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble);
extern void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *);
extern void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat);
extern void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *);
extern void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint);
extern void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *);
extern void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort);
extern void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *);
extern void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble);
extern void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *);
extern void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
extern void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *);
extern void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint);
extern void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *);
extern void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort);
extern void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *);
#endif

#ifdef WINE_DDRAW_need_secondary_color_pfns
typedef void (APIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
typedef void (APIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type,
              GLsizei stride, GLvoid *pointer);
#endif

#ifdef WINE_DDRAW_need_fog_coord_pfns
typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride,
              const GLvoid *pointer);
#endif

#ifdef WINE_DDRAW_need_texture_compression_pfns
typedef void (APIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level,
              GLenum internalformat, GLsizei width, GLsizei height, GLint border,
              GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level,
              GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
              GLenum format, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level,
              void *img);
#endif


#if defined(WINE_DDRAW_need_vertex_weighting_pfns) || !defined(GL_EXT_vertex_weighting)
typedef void (APIENTRY * PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
typedef void (APIENTRY * PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight);
typedef void (APIENTRY * PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
#endif


#if defined(WINE_DDRAW_need_NV_vertex_program_pfns) || !defined(GL_NV_vertex_program)
typedef void (APIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
typedef void (APIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
typedef void (APIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs);
typedef void (APIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v);
typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
typedef void (APIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v);
typedef void (APIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v);
typedef void (APIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v);
typedef void (APIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
typedef void (APIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params);
typedef void (APIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid **pointer);
#endif

#if defined(WINE_DDRAW_need_ARB_vertex_program_pfns) || !defined(GL_ARB_vertex_program)
typedef void (APIENTRY * PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY * PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
typedef void (APIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
typedef void (APIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
typedef void (APIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
typedef void (APIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs);
typedef void (APIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs);
typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
typedef void (APIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
typedef void (APIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
typedef void (APIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
typedef void (APIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
#endif

#if defined(WINE_DDRAW_need_ARB_vertex_blend_pfns) || !defined(GL_ARB_vertex_blend)
typedef void (APIENTRY * PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY * PFNGLVERTEXBLENDARBPROC) (GLint count);
#endif

#undef  XMD_H

#undef APIENTRY
#undef CALLBACK
#undef WINAPI

/* Redefines the constants */
#define CALLBACK    __stdcall
#define WINAPI      __stdcall
#define APIENTRY    WINAPI

#endif /* HAVE_OPENGL */

#endif /* __WINE_WINE_GL_H */
