/* Window-specific OpenGL functions implementation.
 *
 * Copyright (c) 1999 Lionel Ulmer
 * Copyright (c) 2005 Raphael Junqueira
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "winreg.h"
#include "wingdi.h"

#include "wgl_ext.h"
#include "opengl_ext.h"
#include "wine/library.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(opengl);

/** global glx object */
wine_glx_t wine_glx;

/* x11drv GDI escapes */
#define X11DRV_ESCAPE 6789
enum x11drv_escape_codes
{
    X11DRV_GET_DISPLAY,         /* get X11 display for a DC */
    X11DRV_GET_DRAWABLE,        /* get current drawable for a DC */
    X11DRV_GET_FONT,            /* get current X font for a DC */
    X11DRV_SET_DRAWABLE,        /* set current drawable for a DC */
    X11DRV_START_EXPOSURES,     /* start graphics exposures */
    X11DRV_END_EXPOSURES,       /* end graphics exposures */
    X11DRV_GET_DCE,             /* get the DCE pointer */
    X11DRV_SET_DCE,             /* set the DCE pointer */
    X11DRV_GET_GLX_DRAWABLE,    /* get current glx drawable for a DC */
    X11DRV_SYNC_PIXMAP          /* sync the dibsection to its pixmap */
};

void (*wine_tsx11_lock_ptr)(void) = NULL;
void (*wine_tsx11_unlock_ptr)(void) = NULL;

static GLXContext default_cx = NULL;
static Display *default_display;  /* display to use for default context */

static HMODULE opengl32_handle;

static glXGetProcAddressARB_t p_glXGetProcAddressARB = NULL;

static char  internal_gl_disabled_extensions[512];
static char* internal_gl_extensions = NULL;

typedef struct wine_glcontext {
  HDC hdc;
  Display *display;
  XVisualInfo *vis;
  GLXFBConfig fb_conf;
  GLXContext ctx;
  struct wine_glcontext *next;
  struct wine_glcontext *prev;
} Wine_GLContext;
static Wine_GLContext *context_list;

static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx)
{
    Wine_GLContext *ret;
    for (ret = context_list; ret; ret = ret->next) if (ctx == ret->ctx) break;
    return ret;
}

void enter_gl(void)
{
    GLXContext gl_ctx;
    Wine_GLContext *ctx;
    enum x11drv_escape_codes escape = X11DRV_SYNC_PIXMAP;

    wine_tsx11_lock_ptr();
    gl_ctx = glXGetCurrentContext();
    if(!gl_ctx) return;
    ctx = get_context_from_GLXContext(gl_ctx);
    wine_tsx11_unlock_ptr(); /* unlock before calling GDI apis */

    if(ctx && GetObjectType(ctx->hdc) == OBJ_MEMDC)
        ExtEscape(ctx->hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, 0, NULL);

    wine_tsx11_lock_ptr();
    return;
}

static inline void free_context(Wine_GLContext *context)
{
  if (context->next != NULL) context->next->prev = context->prev;
  if (context->prev != NULL) context->prev->next = context->next;
  else context_list = context->next;

  HeapFree(GetProcessHeap(), 0, context);
}

static inline Wine_GLContext *alloc_context(void)
{
  Wine_GLContext *ret;

  if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext))))
  {
      ret->next = context_list;
      if (context_list) context_list->prev = ret;
      context_list = ret;
  }
  return ret;
}

inline static BOOL is_valid_context( Wine_GLContext *ctx )
{
    Wine_GLContext *ptr;
    for (ptr = context_list; ptr; ptr = ptr->next) if (ptr == ctx) break;
    return (ptr != NULL);
}

/* retrieve the X display to use on a given DC */
inline static Display *get_display( HDC hdc )
{
    Display *display;
    enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;

    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
                    sizeof(display), (LPSTR)&display )) display = NULL;
    return display;
}


/* retrieve the GLX drawable to use on a given DC */
inline static Drawable get_drawable( HDC hdc )
{
    GLXDrawable drawable;
    enum x11drv_escape_codes escape = X11DRV_GET_GLX_DRAWABLE;

    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
                    sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
    return drawable;
}

/** for use of wglGetCurrentReadDCARB */
inline static HDC get_hdc_from_Drawable(GLXDrawable d)
{
  Wine_GLContext *ret;
  for (ret = context_list; ret; ret = ret->next) {  
    if (d == get_drawable( ret->hdc )) {
      return ret->hdc;
    }
  }
  return NULL;
}

/* retrieve the X font to use on a given DC */
inline static Font get_font( HDC hdc )
{
    Font font;
    enum x11drv_escape_codes escape = X11DRV_GET_FONT;

    if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
                    sizeof(font), (LPSTR)&font )) font = 0;
    return font;
}


/***********************************************************************
 *		wglCreateContext (OPENGL32.@)
 */
HGLRC WINAPI wglCreateContext(HDC hdc)
{
  Wine_GLContext *ret;
  int num;
  XVisualInfo template;
  XVisualInfo *vis = NULL;
  Display *display = get_display( hdc );
  int hdcPF = GetPixelFormat(hdc);
  GLXFBConfig cur_cfg;

  TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);

  /* First, get the visual in use by the X11DRV */
  if (!display) return 0;
  template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
  vis = XGetVisualInfo(display, VisualIDMask, &template, &num);

  if (vis == NULL) {
    ERR("NULL visual !!!\n");
    /* Need to set errors here */
    return NULL;
  }
  if (0 >= hdcPF) {
    SetLastError(ERROR_INVALID_PIXEL_FORMAT);
    return NULL;
  }

  {
    int nCfgs_fmt = 0;
    GLXFBConfig* cfgs_fmt = NULL;
    int value;
    int gl_test = 0;
    cfgs_fmt = wine_glx.p_glXGetFBConfigs(display, DefaultScreen(display), &nCfgs_fmt);
    if (NULL == cfgs_fmt || 0 == nCfgs_fmt) {
      ERR("Cannot get FB Configs, expect problems.\n");
      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
      return NULL;
    }
    if (nCfgs_fmt < hdcPF) {
      ERR("(%p): unexpected pixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, hdcPF, nCfgs_fmt);
      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
      return NULL;
    }
    cur_cfg = cfgs_fmt[hdcPF - 1];
    gl_test = wine_glx.p_glXGetFBConfigAttrib(display, cur_cfg, GLX_FBCONFIG_ID, &value);
    if (gl_test) {
      ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
      return NULL;
    }
    XFree(cfgs_fmt);
  }

  /* The context will be allocated in the wglMakeCurrent call */
  ENTER_GL();
  ret = alloc_context();
  LEAVE_GL();
  ret->hdc = hdc;
  ret->display = display;
  ret->fb_conf = cur_cfg;
  /*ret->vis = vis;*/
  ret->vis = wine_glx.p_glXGetVisualFromFBConfig(display, cur_cfg);

  TRACE(" creating context %p (GL context creation delayed)\n", ret);
  return (HGLRC) ret;
}

/***********************************************************************
 *		wglCreateLayerContext (OPENGL32.@)
 */
HGLRC WINAPI wglCreateLayerContext(HDC hdc,
				   int iLayerPlane) {
  TRACE("(%p,%d)\n", hdc, iLayerPlane);

  if (iLayerPlane == 0) {
      return wglCreateContext(hdc);
  }
  FIXME(" no handler for layer %d\n", iLayerPlane);

  return NULL;
}

/***********************************************************************
 *		wglCopyContext (OPENGL32.@)
 */
BOOL WINAPI wglCopyContext(HGLRC hglrcSrc,
			   HGLRC hglrcDst,
			   UINT mask) {
  FIXME("(%p,%p,%d)\n", hglrcSrc, hglrcDst, mask);

  return FALSE;
}

/***********************************************************************
 *		wglDeleteContext (OPENGL32.@)
 */
BOOL WINAPI wglDeleteContext(HGLRC hglrc)
{
  Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
  BOOL ret = TRUE;

  TRACE("(%p)\n", hglrc);

  ENTER_GL();
  /* A game (Half Life not to name it) deletes twice the same context,
   * so make sure it is valid first */
  if (is_valid_context( ctx ))
  {
      if (ctx->ctx) glXDestroyContext(ctx->display, ctx->ctx);
      free_context(ctx);
  }
  else
  {
    WARN("Error deleting context !\n");
    SetLastError(ERROR_INVALID_HANDLE);
    ret = FALSE;
  }
  LEAVE_GL();

  return ret;
}

/***********************************************************************
 *		wglDescribeLayerPlane (OPENGL32.@)
 */
BOOL WINAPI wglDescribeLayerPlane(HDC hdc,
				  int iPixelFormat,
				  int iLayerPlane,
				  UINT nBytes,
				  LPLAYERPLANEDESCRIPTOR plpd) {
  FIXME("(%p,%d,%d,%d,%p)\n", hdc, iPixelFormat, iLayerPlane, nBytes, plpd);

  return FALSE;
}

/***********************************************************************
 *		wglGetCurrentContext (OPENGL32.@)
 */
HGLRC WINAPI wglGetCurrentContext(void) {
  GLXContext gl_ctx;
  Wine_GLContext *ret;

  TRACE("()\n");

  ENTER_GL();
  gl_ctx = glXGetCurrentContext();
  ret = get_context_from_GLXContext(gl_ctx);
  LEAVE_GL();

  TRACE(" returning %p (GL context %p)\n", ret, gl_ctx);

  return (HGLRC)ret;
}

/***********************************************************************
 *		wglGetCurrentDC (OPENGL32.@)
 */
HDC WINAPI wglGetCurrentDC(void) {
  GLXContext gl_ctx;
  Wine_GLContext *ret;

  TRACE("()\n");

  ENTER_GL();
  gl_ctx = glXGetCurrentContext();
  ret = get_context_from_GLXContext(gl_ctx);
  LEAVE_GL();

  if (ret) {
    TRACE(" returning %p (GL context %p - Wine context %p)\n", ret->hdc, gl_ctx, ret);
    return ret->hdc;
  } else {
    TRACE(" no Wine context found for GLX context %p\n", gl_ctx);
    return 0;
  }
}

/***********************************************************************
 *		wglGetLayerPaletteEntries (OPENGL32.@)
 */
int WINAPI wglGetLayerPaletteEntries(HDC hdc,
				     int iLayerPlane,
				     int iStart,
				     int cEntries,
				     const COLORREF *pcr) {
  FIXME("(): stub !\n");

  return 0;
}

/***********************************************************************
 *		wglGetProcAddress (OPENGL32.@)
 */
static int compar(const void *elt_a, const void *elt_b) {
  return strcmp(((const OpenGL_extension *) elt_a)->name,
		((const OpenGL_extension *) elt_b)->name);
}

static int wgl_compar(const void *elt_a, const void *elt_b) {
  return strcmp(((const WGL_extension *) elt_a)->func_name,
		((const WGL_extension *) elt_b)->func_name);
}

PROC WINAPI wglGetProcAddress(LPCSTR  lpszProc) {
  void *local_func;
  OpenGL_extension  ext;
  OpenGL_extension *ext_ret;

  TRACE("(%s)\n", lpszProc);

  /* First, look if it's not already defined in the 'standard' OpenGL functions */
  if ((local_func = GetProcAddress(opengl32_handle, lpszProc)) != NULL) {
    TRACE(" found function in 'standard' OpenGL functions (%p)\n", local_func);
    return local_func;
  }

  if (p_glXGetProcAddressARB == NULL) {
    ERR("Warning : dynamic GL extension loading not supported by native GL library.\n");
    return NULL;
  }
  
  /* After that, search in the thunks to find the real name of the extension */
  ext.name = (char *) lpszProc;
  ext_ret = (OpenGL_extension *) bsearch(&ext, extension_registry,
					 extension_registry_size, sizeof(OpenGL_extension), compar);

  if (ext_ret == NULL) {
    WGL_extension wgl_ext, *wgl_ext_ret;

    /* Try to find the function in the WGL extensions ... */
    wgl_ext.func_name = (char *) lpszProc;
    wgl_ext_ret = (WGL_extension *) bsearch(&wgl_ext, wgl_extension_registry,
					    wgl_extension_registry_size, sizeof(WGL_extension), wgl_compar);

    if (wgl_ext_ret == NULL) {
      /* Some sanity checks :-) */
      ENTER_GL();
      local_func = p_glXGetProcAddressARB( (const GLubyte *) lpszProc);
      LEAVE_GL();
      if (local_func != NULL) {
	WARN("Extension %s defined in the OpenGL library but NOT in opengl_ext.c...\n", lpszProc);
	return NULL;
      }
      
      WARN("Did not find extension %s in either Wine or your OpenGL library.\n", lpszProc);
      return NULL;
    } else {
	void *ret = NULL;

	if (wgl_ext_ret->func_init != NULL) {
	    const char *err_msg;
	    if ((err_msg = wgl_ext_ret->func_init(p_glXGetProcAddressARB,
						  wgl_ext_ret->context)) == NULL) {
		ret = wgl_ext_ret->func_address;
	    } else {
		WARN("Error when getting WGL extension '%s' : %s.\n", debugstr_a(lpszProc), err_msg);
		return NULL;
	    }
	} else {
	  ret = wgl_ext_ret->func_address;
	}

	if (ret)
	    TRACE(" returning WGL function  (%p)\n", ret);
	return ret;
    }
  } else {
    ENTER_GL();
    local_func = p_glXGetProcAddressARB( (const GLubyte*) ext_ret->glx_name);
    LEAVE_GL();
    
    /* After that, look at the extensions defined in the Linux OpenGL library */
    if (local_func == NULL) {
      char buf[256];
      void *ret = NULL;

      /* Remove the 3 last letters (EXT, ARB, ...).

	 I know that some extensions have more than 3 letters (MESA, NV,
	 INTEL, ...), but this is only a stop-gap measure to fix buggy
	 OpenGL drivers (moreover, it is only useful for old 1.0 apps
	 that query the glBindTextureEXT extension).
      */
      memcpy(buf, ext_ret->glx_name, strlen(ext_ret->glx_name) - 3);
      buf[strlen(ext_ret->glx_name) - 3] = '\0';
      TRACE(" extension not found in the Linux OpenGL library, checking against libGL bug with %s..\n", buf);

      ret = GetProcAddress(opengl32_handle, buf);
      if (ret != NULL) {
	TRACE(" found function in main OpenGL library (%p) !\n", ret);
      } else {
	WARN("Did not find function %s (%s) in your OpenGL library !\n", lpszProc, ext_ret->glx_name);
      }

      return ret;
    } else {
      TRACE(" returning function  (%p)\n", ext_ret->func);
      *(ext_ret->func_ptr) = local_func;

      return ext_ret->func;
    }
  }
}

static int describeContext(Wine_GLContext* ctx) {
  int tmp;
  int ctx_vis_id;
  TRACE(" Context %p have (vis:%p):\n", ctx, ctx->vis);
  wine_glx.p_glXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_FBCONFIG_ID, &tmp);
  TRACE(" - FBCONFIG_ID 0x%x\n", tmp);
  wine_glx.p_glXGetFBConfigAttrib(ctx->display, ctx->fb_conf, GLX_VISUAL_ID, &tmp);
  TRACE(" - VISUAL_ID 0x%x\n", tmp);
  ctx_vis_id = tmp;
  return ctx_vis_id;
}

static int describeDrawable(Wine_GLContext* ctx, Drawable drawable) {
  int tmp;
  int draw_vis_id;
  if (3 > wine_glx.version || NULL == wine_glx.p_glXQueryDrawable)  {
    /** glXQueryDrawable not available so returns not supported */
    return -1;
  }
  TRACE(" Drawable %p have :\n", (void*) drawable);
  wine_glx.p_glXQueryDrawable(ctx->display, drawable, GLX_FBCONFIG_ID, (unsigned int*) &tmp);
  TRACE(" - FBCONFIG_ID as 0x%x\n", tmp);
  wine_glx.p_glXQueryDrawable(ctx->display, drawable, GLX_VISUAL_ID, (unsigned int*) &tmp);
  TRACE(" - VISUAL_ID as 0x%x\n", tmp);
  draw_vis_id = tmp;
  wine_glx.p_glXQueryDrawable(ctx->display, drawable, GLX_WIDTH, (unsigned int*) &tmp);
  TRACE(" - WIDTH as %d\n", tmp);
  wine_glx.p_glXQueryDrawable(ctx->display, drawable, GLX_HEIGHT, (unsigned int*) &tmp);
  TRACE(" - HEIGHT as %d\n", tmp);
  return draw_vis_id;
}

/***********************************************************************
 *		wglMakeCurrent (OPENGL32.@)
 */
BOOL WINAPI wglMakeCurrent(HDC hdc,
			   HGLRC hglrc) {
  BOOL ret;
  DWORD type = GetObjectType(hdc);

  TRACE("(%p,%p)\n", hdc, hglrc);

  ENTER_GL();
  if (hglrc == NULL) {
      ret = glXMakeCurrent(default_display, None, NULL);
  } else {
      Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
      Drawable drawable = get_drawable( hdc );
      if (ctx->ctx == NULL) {
	int draw_vis_id, ctx_vis_id;
        VisualID visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" );
	TRACE(" Wine desktop VISUAL_ID is 0x%x\n", (unsigned int) visualid);
	draw_vis_id = describeDrawable(ctx, drawable);
	ctx_vis_id = describeContext(ctx);

	if (-1 == draw_vis_id || (draw_vis_id == visualid && draw_vis_id != ctx_vis_id)) {
	  /**
	   * Inherits from root window so reuse desktop visual
	   */
	  XVisualInfo template;
	  XVisualInfo *vis;
	  int num;
	  template.visualid = visualid;
	  vis = XGetVisualInfo(ctx->display, VisualIDMask, &template, &num);

	  TRACE(" Creating GLX Context\n");
	  ctx->ctx = glXCreateContext(ctx->display, vis, NULL, type == OBJ_MEMDC ? False : True);
	} else {
	  TRACE(" Creating GLX Context\n");
	  ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, type == OBJ_MEMDC ? False : True);
	}
	TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
      }
      TRACE(" make current for dis %p, drawable %p, ctx %p\n", ctx->display, (void*) drawable, ctx->ctx);
      ret = glXMakeCurrent(ctx->display, drawable, ctx->ctx);
      if(ret && type == OBJ_MEMDC)
          glDrawBuffer(GL_FRONT_LEFT);
  }
  LEAVE_GL();
  TRACE(" returning %s\n", (ret ? "True" : "False"));
  return ret;
}

/***********************************************************************
 *		wglMakeContextCurrentARB (OPENGL32.@)
 */
BOOL WINAPI wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc) 
{
  BOOL ret;
  TRACE("(%p,%p,%p)\n", hDrawDC, hReadDC, hglrc);

  ENTER_GL();
  if (hglrc == NULL) {
    ret = glXMakeCurrent(default_display, None, NULL);
  } else {
    if (NULL == wine_glx.p_glXMakeContextCurrent) {
      ret = FALSE;
    } else {
      Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
      Drawable d_draw = get_drawable( hDrawDC );
      Drawable d_read = get_drawable( hReadDC );
      
      if (ctx->ctx == NULL) {
        ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, GetObjectType(hDrawDC) == OBJ_MEMDC ? False : True);
        TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
      }
      ret = wine_glx.p_glXMakeContextCurrent(ctx->display, d_draw, d_read, ctx->ctx);
    }
  }
  LEAVE_GL();
  
  TRACE(" returning %s\n", (ret ? "True" : "False"));
  return ret;
}

/***********************************************************************
 *		wglGetCurrentReadDCARB (OPENGL32.@)
 */
HDC WINAPI wglGetCurrentReadDCARB(void) 
{
  GLXDrawable gl_d;
  HDC ret;

  TRACE("()\n");

  ENTER_GL();
  gl_d = glXGetCurrentReadDrawable();
  ret = get_hdc_from_Drawable(gl_d);
  LEAVE_GL();

  TRACE(" returning %p (GL drawable %lu)\n", ret, gl_d);
  return ret;
}



/***********************************************************************
 *		wglRealizeLayerPalette (OPENGL32.@)
 */
BOOL WINAPI wglRealizeLayerPalette(HDC hdc,
				   int iLayerPlane,
				   BOOL bRealize) {
  FIXME("()\n");

  return FALSE;
}

/***********************************************************************
 *		wglSetLayerPaletteEntries (OPENGL32.@)
 */
int WINAPI wglSetLayerPaletteEntries(HDC hdc,
				     int iLayerPlane,
				     int iStart,
				     int cEntries,
				     const COLORREF *pcr) {
  FIXME("(): stub !\n");

  return 0;
}

/***********************************************************************
 *		wglShareLists (OPENGL32.@)
 */
BOOL WINAPI wglShareLists(HGLRC hglrc1,
			  HGLRC hglrc2) {
  Wine_GLContext *org  = (Wine_GLContext *) hglrc1;
  Wine_GLContext *dest = (Wine_GLContext *) hglrc2;

  TRACE("(%p, %p)\n", org, dest);

  if (NULL != dest && dest->ctx != NULL) {
    ERR("Could not share display lists, context already created !\n");
    return FALSE;
  } else {
    if (org->ctx == NULL) {
      ENTER_GL();
      describeContext(org);
      org->ctx = glXCreateContext(org->display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
      LEAVE_GL();
      TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
    }
    if (NULL != dest) {
      ENTER_GL();
      describeContext(dest);
      /* Create the destination context with display lists shared */
      dest->ctx = glXCreateContext(org->display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
      LEAVE_GL();
      TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
      return TRUE;
    }
  }
  return FALSE;
}

/***********************************************************************
 *		wglSwapLayerBuffers (OPENGL32.@)
 */
BOOL WINAPI wglSwapLayerBuffers(HDC hdc,
				UINT fuPlanes) {
  TRACE("(%p, %08x)\n", hdc, fuPlanes);

  if (fuPlanes & WGL_SWAP_MAIN_PLANE) {
    if (!SwapBuffers(hdc)) return FALSE;
    fuPlanes &= ~WGL_SWAP_MAIN_PLANE;
  }

  if (fuPlanes) {
    WARN("Following layers unhandled : %08x\n", fuPlanes);
  }

  return TRUE;
}

static BOOL internal_wglUseFontBitmaps(HDC hdc,
				       DWORD first,
				       DWORD count,
				       DWORD listBase,
				       DWORD (WINAPI *GetGlyphOutline_ptr)(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*))
{
    /* We are running using client-side rendering fonts... */
    GLYPHMETRICS gm;
    unsigned int glyph;
    int size = 0;
    void *bitmap = NULL, *gl_bitmap = NULL;
    int org_alignment;

    ENTER_GL();
    glGetIntegerv(GL_UNPACK_ALIGNMENT, &org_alignment);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    LEAVE_GL();

    for (glyph = first; glyph < first + count; glyph++) {
	unsigned int needed_size = GetGlyphOutline_ptr(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, NULL);
	int height, width_int;

	TRACE("Glyph : %3d / List : %ld\n", glyph, listBase);
	if (needed_size == GDI_ERROR) {
	    TRACE("  - needed size : %d (GDI_ERROR)\n", needed_size);
	    goto error;
	} else {
	    TRACE("  - needed size : %d\n", needed_size);
	}

	if (needed_size > size) {
	    size = needed_size;
            HeapFree(GetProcessHeap(), 0, bitmap);
            HeapFree(GetProcessHeap(), 0, gl_bitmap);
	    bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
	    gl_bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
	}
	if (GetGlyphOutline_ptr(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, NULL) == GDI_ERROR) goto error;
	if (TRACE_ON(opengl)) {
	    unsigned int height, width, bitmask;
	    unsigned char *bitmap_ = (unsigned char *) bitmap;
	    
	    TRACE("  - bbox : %d x %d\n", gm.gmBlackBoxX, gm.gmBlackBoxY);
	    TRACE("  - origin : (%ld , %ld)\n", gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y);
	    TRACE("  - increment : %d - %d\n", gm.gmCellIncX, gm.gmCellIncY);
	    if (needed_size != 0) {
		TRACE("  - bitmap :\n");
		for (height = 0; height < gm.gmBlackBoxY; height++) {
		    TRACE("      ");
		    for (width = 0, bitmask = 0x80; width < gm.gmBlackBoxX; width++, bitmask >>= 1) {
			if (bitmask == 0) {
			    bitmap_ += 1;
			    bitmask = 0x80;
			}
			if (*bitmap_ & bitmask)
			    TRACE("*");
			else
			    TRACE(" ");
		    }
		    bitmap_ += (4 - ((UINT_PTR)bitmap_ & 0x03));
		    TRACE("\n");
		}
	    }
	}
	
	/* In OpenGL, the bitmap is drawn from the bottom to the top... So we need to invert the
	 * glyph for it to be drawn properly.
	 */
	if (needed_size != 0) {
	    width_int = (gm.gmBlackBoxX + 31) / 32;
	    for (height = 0; height < gm.gmBlackBoxY; height++) {
		int width;
		for (width = 0; width < width_int; width++) {
		    ((int *) gl_bitmap)[(gm.gmBlackBoxY - height - 1) * width_int + width] =
			((int *) bitmap)[height * width_int + width];
		}
	    }
	}
	
	ENTER_GL();
	glNewList(listBase++, GL_COMPILE);
	if (needed_size != 0) {
	    glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
		     0 - (int) gm.gmptGlyphOrigin.x, (int) gm.gmBlackBoxY - (int) gm.gmptGlyphOrigin.y,
		     gm.gmCellIncX, gm.gmCellIncY,
		     gl_bitmap);
	} else {
	    /* This is the case of 'empty' glyphs like the space character */
	    glBitmap(0, 0, 0, 0, gm.gmCellIncX, gm.gmCellIncY, NULL);
	}
	glEndList();
	LEAVE_GL();
    }
    
    ENTER_GL();
    glPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
    LEAVE_GL();
    
    HeapFree(GetProcessHeap(), 0, bitmap);
    HeapFree(GetProcessHeap(), 0, gl_bitmap);
    return TRUE;

  error:
    ENTER_GL();
    glPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
    LEAVE_GL();

    HeapFree(GetProcessHeap(), 0, bitmap);
    HeapFree(GetProcessHeap(), 0, gl_bitmap);
    return FALSE;    
}

/***********************************************************************
 *		wglUseFontBitmapsA (OPENGL32.@)
 */
BOOL WINAPI wglUseFontBitmapsA(HDC hdc,
			       DWORD first,
			       DWORD count,
			       DWORD listBase)
{
  Font fid = get_font( hdc );

  TRACE("(%p, %ld, %ld, %ld) using font %ld\n", hdc, first, count, listBase, fid);

  if (fid == 0) {
      return internal_wglUseFontBitmaps(hdc, first, count, listBase, GetGlyphOutlineA);
  }

  ENTER_GL();
  /* I assume that the glyphs are at the same position for X and for Windows */
  glXUseXFont(fid, first, count, listBase);
  LEAVE_GL();
  return TRUE;
}

/***********************************************************************
 *		wglUseFontBitmapsW (OPENGL32.@)
 */
BOOL WINAPI wglUseFontBitmapsW(HDC hdc,
			       DWORD first,
			       DWORD count,
			       DWORD listBase)
{
  Font fid = get_font( hdc );

  TRACE("(%p, %ld, %ld, %ld) using font %ld\n", hdc, first, count, listBase, fid);

  if (fid == 0) {
      return internal_wglUseFontBitmaps(hdc, first, count, listBase, GetGlyphOutlineW);
  }

  WARN("Using the glX API for the WCHAR variant - some characters may come out incorrectly !\n");
  
  ENTER_GL();
  /* I assume that the glyphs are at the same position for X and for Windows */
  glXUseXFont(fid, first, count, listBase);
  LEAVE_GL();
  return TRUE;
}

/***********************************************************************
 *		wglUseFontOutlinesA (OPENGL32.@)
 */
BOOL WINAPI wglUseFontOutlinesA(HDC hdc,
				DWORD first,
				DWORD count,
				DWORD listBase,
				FLOAT deviation,
				FLOAT extrusion,
				int format,
				LPGLYPHMETRICSFLOAT lpgmf) {
  FIXME("(): stub !\n");

  return FALSE;
}

const GLubyte * internal_glGetString(GLenum name) {
  const char* GL_Extensions = NULL;
  
  if (GL_EXTENSIONS != name) {
    return glGetString(name);
  }

  if (NULL == internal_gl_extensions) {
    GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);

    TRACE("GL_EXTENSIONS reported:\n");  
    if (NULL == GL_Extensions) {
      ERR("GL_EXTENSIONS returns NULL\n");      
      return NULL;
    } else {
      size_t len = strlen(GL_Extensions);
      internal_gl_extensions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len + 2);

      while (*GL_Extensions != 0x00) {
	const char* Start = GL_Extensions;
	char        ThisExtn[256];
	 
	memset(ThisExtn, 0x00, sizeof(ThisExtn));
	while (*GL_Extensions != ' ' && *GL_Extensions != 0x00) {
	  GL_Extensions++;
	}
	memcpy(ThisExtn, Start, (GL_Extensions - Start));
	TRACE("- %s:", ThisExtn);
	
	/* test if supported API is disabled by config */
	if (NULL == strstr(internal_gl_disabled_extensions, ThisExtn)) {
	  strcat(internal_gl_extensions, " ");
	  strcat(internal_gl_extensions, ThisExtn);
	  TRACE(" active\n");
	} else {
	  TRACE(" deactived (by config)\n");
	}

	if (*GL_Extensions == ' ') GL_Extensions++;
      }
    }
  }
  return (const GLubyte *) internal_gl_extensions;
}

void internal_glGetIntegerv(GLenum pname, GLint* params) {
  glGetIntegerv(pname, params);
  if (pname == GL_DEPTH_BITS) { 
    GLXContext gl_ctx = glXGetCurrentContext();
    Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
    /*TRACE("returns Wine Ctx as %p\n", ret);*/
    /** 
     * if we cannot find a Wine Context
     * we only have the default wine desktop context, 
     * so if we have only a 24 depth say we have 32
     */
    if (NULL == ret && 24 == *params) { 
      *params = 32;
    }
    TRACE("returns GL_DEPTH_BITS as '%d'\n", *params);
  }
  if (pname == GL_ALPHA_BITS) {
    GLint tmp;
    GLXContext gl_ctx = glXGetCurrentContext();
    Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
    glXGetFBConfigAttrib(ret->display, ret->fb_conf, GLX_ALPHA_SIZE, &tmp);
    TRACE("returns GL_ALPHA_BITS as '%d'\n", tmp);
    *params = tmp;
  }
}


/* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and
   include all dependencies
*/
#ifndef SONAME_LIBGL
#define SONAME_LIBGL "libGL.so"
#endif

static void wgl_initialize_glx(Display *display, int screen, glXGetProcAddressARB_t proc) 
{
  const char *server_glx_version = glXQueryServerString(display, screen, GLX_VERSION);
  const char *server_glx_extensions = glXQueryServerString(display, screen, GLX_EXTENSIONS);
  /*
  const char *client_glx_version = glXGetClientString(display, GLX_VERSION);
  const char *client_glx_extensions = glXGetClientString(display, GLX_EXTENSIONS);
  const char *glx_extensions = glXQueryExtensionsString(display, screen);
  */

  memset(&wine_glx, 0, sizeof(wine_glx));

  if (!strcmp("1.2", server_glx_version)) {
    wine_glx.version = 2;
  } else {
    wine_glx.version = 3;
  }

  if (2 < wine_glx.version) {
    wine_glx.p_glXChooseFBConfig = proc( (const GLubyte *) "glXChooseFBConfig");
    wine_glx.p_glXGetFBConfigAttrib = proc( (const GLubyte *) "glXGetFBConfigAttrib");
    wine_glx.p_glXGetVisualFromFBConfig = proc( (const GLubyte *) "glXGetVisualFromFBConfig");

    /*wine_glx.p_glXGetFBConfigs = proc( (const GLubyte *) "glXGetFBConfigs");*/
    wine_glx.p_glXQueryDrawable = proc( (const GLubyte *) "glXQueryDrawable");
  } else {
    if (NULL != strstr(server_glx_extensions, "GLX_SGIX_fbconfig")) {
      wine_glx.p_glXChooseFBConfig = proc( (const GLubyte *) "glXChooseFBConfigSGIX");
      wine_glx.p_glXGetFBConfigAttrib = proc( (const GLubyte *) "glXGetFBConfigAttribSGIX");
      wine_glx.p_glXGetVisualFromFBConfig = proc( (const GLubyte *) "glXGetVisualFromFBConfigSGIX");
    } else {
      ERR(" glx_version as %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems.\n", server_glx_version);
    }
  }
  /** try anyway to retrieve that calls, maybe they works using glx client tricks */
  wine_glx.p_glXGetFBConfigs = proc( (const GLubyte *) "glXGetFBConfigs");
  wine_glx.p_glXMakeContextCurrent = proc( (const GLubyte *) "glXMakeContextCurrent");
}

/* This is for brain-dead applications that use OpenGL functions before even
   creating a rendering context.... */
static BOOL process_attach(void)
{
  XWindowAttributes win_attr;
  Visual *rootVisual;
  int num;
  XVisualInfo template;
  HDC hdc;
  XVisualInfo *vis = NULL;
  Window root = (Window)GetPropA( GetDesktopWindow(), "__wine_x11_whole_window" );
  HMODULE mod = GetModuleHandleA( "winex11.drv" );
  void *opengl_handle;
  DWORD size = sizeof(internal_gl_disabled_extensions);
  HKEY hkey = 0;

  if (!root || !mod)
  {
      ERR("X11DRV not loaded. Cannot create default context.\n");
      return FALSE;
  }

  wine_tsx11_lock_ptr   = (void *)GetProcAddress( mod, "wine_tsx11_lock" );
  wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" );

  hdc = GetDC(0);
  default_display = get_display( hdc );
  ReleaseDC( 0, hdc );
  if (!default_display)
  {
      ERR("X11DRV not loaded. Cannot get display for screen DC.\n");
      return FALSE;
  }

  ENTER_GL();

  /* Try to get the visual from the Root Window.  We can't use the standard (presumably
     double buffered) X11DRV visual with the Root Window, since we don't know if the Root
     Window was created using the standard X11DRV visual, and glXMakeCurrent can't deal
     with mismatched visuals.  Note that the Root Window visual may not be double
     buffered, so apps actually attempting to render this way may flicker */
  if (XGetWindowAttributes( default_display, root, &win_attr ))
  {
    rootVisual = win_attr.visual;
  }
  else
  {
    /* Get the default visual, since we can't seem to get the attributes from the
       Root Window.  Let's hope that the Root Window Visual matches the DefaultVisual */
    rootVisual = DefaultVisual( default_display, DefaultScreen(default_display) );
  }

  template.visualid = XVisualIDFromVisual(rootVisual);
  vis = XGetVisualInfo(default_display, VisualIDMask, &template, &num);
  if (vis != NULL) default_cx = glXCreateContext(default_display, vis, 0, GL_TRUE);
  if (default_cx != NULL) glXMakeCurrent(default_display, root, default_cx);
  XFree(vis);
  LEAVE_GL();

  opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, NULL, 0);
  if (opengl_handle != NULL) {
   p_glXGetProcAddressARB = wine_dlsym(opengl_handle, "glXGetProcAddressARB", NULL, 0);
   wine_dlclose(opengl_handle, NULL, 0);
   if (p_glXGetProcAddressARB == NULL)
	   TRACE("could not find glXGetProcAddressARB in libGL.\n");
  }

  internal_gl_disabled_extensions[0] = 0;
  if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\OpenGL", &hkey)) {
    if (!RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, (LPBYTE)internal_gl_disabled_extensions, &size)) {
      TRACE("found DisabledExtensions=\"%s\"\n", internal_gl_disabled_extensions);
    }
    RegCloseKey(hkey);
  }

  if (default_cx == NULL) {
    ERR("Could not create default context.\n");
  }
  else
  {
    /* After context initialize also the list of supported WGL extensions. */
    wgl_initialize_glx(default_display, DefaultScreen(default_display), p_glXGetProcAddressARB);
    wgl_ext_initialize_extensions(default_display, DefaultScreen(default_display), p_glXGetProcAddressARB, internal_gl_disabled_extensions);
  }
  return TRUE;
}


/**********************************************************************/

static void process_detach(void)
{
  glXDestroyContext(default_display, default_cx);

  /* Do not leak memory... */
  wgl_ext_finalize_extensions();
  if (NULL != internal_gl_extensions) {
    HeapFree(GetProcessHeap(), 0, internal_gl_extensions);
  }
}

/***********************************************************************
 *           OpenGL initialisation routine
 */
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
    switch(reason)
    {
    case DLL_PROCESS_ATTACH:
        opengl32_handle = hinst;
        DisableThreadLibraryCalls(hinst);
        return process_attach();
    case DLL_PROCESS_DETACH:
        process_detach();
        break;
    }
    return TRUE;
}
