
/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

/*
 * File name 	: wgl.c
 * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru
 * Some things originated from the 3Dfx WGL functions
 */

/* 
 * This file contains the implementation of the wgl* functions for
 * Mesa on Windows.  Since these functions are provided by Windows in
 * GDI/OpenGL, we must supply our versions that work with Mesa here.
 */


#include <windows.h>

#include "main/config.h"
#include "glapi/glapi.h"
#include "swrast/swrast.h"
#include "GL/wmesa.h"   /* protos for wmesa* functions */

/*
 * Pixel Format Descriptors
 */

/* Extend the PFD to include DB flag */
struct __pixelformat__
{
    PIXELFORMATDESCRIPTOR pfd;
    GLboolean doubleBuffered;
};



/* These are the PFD's supported by this driver. */
struct __pixelformat__	pfd[] =
{
#if 0 
    /* Double Buffer, alpha */
    {	
	{	
	    sizeof(PIXELFORMATDESCRIPTOR),	1,
	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
	    PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
	    PFD_TYPE_RGBA,
	    24,	
	    8, 0,	
	    8, 8,	
	    8, 16,	
	    8, 24,
	    0, 0, 0, 0, 0,	
	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,	
	    0, 0, 0,	
	    0, 0, 0 
	},
        GL_TRUE
    },
    /* Single Buffer, alpha */
    {	
	{	
	    sizeof(PIXELFORMATDESCRIPTOR),	1,
	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
	    PFD_GENERIC_FORMAT,
	    PFD_TYPE_RGBA,
	    24,	
	    8, 0,	
	    8, 8,	
	    8, 16,	
	    8, 24,
	    0, 0, 0, 0,	0,	
	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,	
	    0, 0, 0,	
	    0, 0, 0
	},
        GL_FALSE
    },
#endif 
    /* Double Buffer, no alpha */
    {	
	{	
	    sizeof(PIXELFORMATDESCRIPTOR),	1,
	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
	    PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
	    PFD_TYPE_RGBA,
	    24,	
	    8, 0,
	    8, 8,
	    8, 16,
	    0, 0,
	    0, 0, 0, 0,	0,
	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,	
	    0, 0, 0, 
	    0, 0, 0 
	},
        GL_TRUE
    },
    /* Single Buffer, no alpha */
    {	
	{
	    sizeof(PIXELFORMATDESCRIPTOR),	1,
	    PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
	    PFD_GENERIC_FORMAT,
	    PFD_TYPE_RGBA,
	    24,	
	    8, 0,
	    8, 8,
	    8, 16,
	    0, 0,
	    0, 0, 0, 0,	0,
	    DEFAULT_SOFTWARE_DEPTH_BITS,	8,	
	    0, 0, 0,
	    0, 0, 0 
	},
        GL_FALSE
    },
};

int npfd = sizeof(pfd) / sizeof(pfd[0]);


/*
 * Contexts
 */

typedef struct {
    WMesaContext ctx;
} MesaWglCtx;

#define MESAWGL_CTX_MAX_COUNT 20

static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT];

static unsigned ctx_count = 0;
static int ctx_current = -1;
static unsigned curPFD = 0;

static HDC CurrentHDC = 0;


WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
{
    int i = 0;
    if (!ctx_count) {
	for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++) {
	    wgl_ctx[i].ctx = NULL;
	}
    }
    for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
        if ( wgl_ctx[i].ctx == NULL ) {
            wgl_ctx[i].ctx = 
		WMesaCreateContext(hdc, NULL, (GLboolean)GL_TRUE,
				   (GLboolean) (pfd[curPFD-1].doubleBuffered ?
                                   GL_TRUE : GL_FALSE), 
				   (GLboolean)(pfd[curPFD-1].pfd.cAlphaBits ? 
				   GL_TRUE : GL_FALSE) );
            if (wgl_ctx[i].ctx == NULL)
                break;
            ctx_count++;
            return ((HGLRC)wgl_ctx[i].ctx);
        }
    }
    SetLastError(0);
    return(NULL);
}

WINGDIAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
{
    int i;
    for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
    	if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ){
            WMesaMakeCurrent((WMesaContext) hglrc, NULL);
            WMesaDestroyContext(wgl_ctx[i].ctx);
            wgl_ctx[i].ctx = NULL;
            ctx_count--;
            return(TRUE);
    	}
    }
    SetLastError(0);
    return(FALSE);
}

WINGDIAPI HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
{
    if (ctx_current < 0)
	return 0;
    else
	return (HGLRC) wgl_ctx[ctx_current].ctx;
}

WINGDIAPI HDC GLAPIENTRY wglGetCurrentDC(VOID)
{
    return CurrentHDC;
}

WINGDIAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc)
{
    int i;
    
    CurrentHDC = hdc;

    if (!hdc || !hglrc) {
	WMesaMakeCurrent(NULL, NULL);
	ctx_current = -1;
	return TRUE;
    }
    
    for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
	if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ) {
	    WMesaMakeCurrent( (WMesaContext) hglrc, hdc );
	    ctx_current = i;
	    return TRUE;
	}
    }
    return FALSE;
}


WINGDIAPI int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
					      CONST 
					      PIXELFORMATDESCRIPTOR *ppfd)
{
    int		i,best = -1,bestdelta = 0x7FFFFFFF,delta;
    (void) hdc;
    
    if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)
	{
	    SetLastError(0);
	    return(0);
	}
    for(i = 0; i < npfd;i++)
	{
	    delta = 0;
	    if(
		(ppfd->dwFlags & PFD_DRAW_TO_WINDOW) &&
		!(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
		continue;
	    if(
		(ppfd->dwFlags & PFD_DRAW_TO_BITMAP) &&
		!(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
		continue;
	    if(
		(ppfd->dwFlags & PFD_SUPPORT_GDI) &&
		!(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI))
		continue;
	    if(
		(ppfd->dwFlags & PFD_SUPPORT_OPENGL) &&
		!(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
		continue;
	    if(
		!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
		((ppfd->dwFlags & PFD_DOUBLEBUFFER) != 
		 (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
		continue;
	    if(
		!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
		((ppfd->dwFlags & PFD_STEREO) != 
		 (pfd[i].pfd.dwFlags & PFD_STEREO)))
		continue;
	    if(ppfd->iPixelType != pfd[i].pfd.iPixelType)
		delta++;
	    if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits)
		delta++;
	    if(delta < bestdelta)
		{
		    best = i + 1;
		    bestdelta = delta;
		    if(bestdelta == 0)
			break;
		}
	}
    if(best == -1)
	{
	    SetLastError(0);
	    return(0);
	}
    return(best);
}

WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc,
					        int iPixelFormat,
					        UINT nBytes,
					        LPPIXELFORMATDESCRIPTOR ppfd)
{
    (void) hdc;
    
    if(ppfd == NULL)
	return(npfd);
    if(iPixelFormat < 1 || iPixelFormat > npfd || 
       nBytes != sizeof(PIXELFORMATDESCRIPTOR))
	{
	    SetLastError(0);
	    return(0);
	}
    *ppfd = pfd[iPixelFormat - 1].pfd;
    return(npfd);
}

WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
{
    PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc);
    if (p)
	return p;
    
    SetLastError(0);
    return(NULL);
}

WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc)
{
    (void) hdc;
    if(curPFD == 0) {
	SetLastError(0);
	return(0);
    }
    return(curPFD);
}

WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
					const PIXELFORMATDESCRIPTOR *ppfd)
{
    (void) hdc;

    /* SetPixelFormat (hence wglSetPixelFormat) must not touch ppfd, per
     * http://msdn.microsoft.com/en-us/library/dd369049(v=vs.85).aspx
     */
    (void) ppfd;

    if(iPixelFormat < 1 || iPixelFormat > npfd) {
	SetLastError(0);
	return(FALSE);
    }
    curPFD = iPixelFormat;
    return(TRUE);
}

WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
{
    WMesaSwapBuffers(hdc);
    return TRUE;
}

static FIXED FixedFromDouble(double d)
{
   long l = (long) (d * 65536L);
   return *(FIXED *) (void *) &l;
}


/*
** This is cribbed from FX/fxwgl.c, and seems to implement support
** for bitmap fonts where the wglUseFontBitmapsA() code implements
** support for outline fonts.  In combination they hopefully give
** fairly generic support for fonts.
*/
static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
                                 DWORD numChars, DWORD listBase)
{
#define VERIFY(a) (void)(a)
    
    TEXTMETRIC metric;
    BITMAPINFO *dibInfo;
    HDC bitDevice;
    COLORREF tempColor;
    int i;
    
    VERIFY(GetTextMetrics(fontDevice, &metric));
    
    dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
    dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    dibInfo->bmiHeader.biPlanes = 1;
    dibInfo->bmiHeader.biBitCount = 1;
    dibInfo->bmiHeader.biCompression = BI_RGB;
    
    bitDevice = CreateCompatibleDC(fontDevice);
    
    /* Swap fore and back colors so the bitmap has the right polarity */
    tempColor = GetBkColor(bitDevice);
    SetBkColor(bitDevice, GetTextColor(bitDevice));
    SetTextColor(bitDevice, tempColor);
    
    /* Place chars based on base line */
    VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0);
    
    for(i = 0; i < (int)numChars; i++) {
	SIZE size;
	char curChar;
	int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
	HBITMAP bitObject;
	HGDIOBJ origBmap;
	unsigned char *bmap;
	
	curChar = (char)(i + firstChar);
	
	/* Find how high/wide this character is */
	VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
	
	/* Create the output bitmap */
	charWidth = size.cx;
	charHeight = size.cy;
	/* Round up to the next multiple of 32 bits */
	bmapWidth = ((charWidth + 31) / 32) * 32;   
	bmapHeight = charHeight;
	bitObject = CreateCompatibleBitmap(bitDevice,
					   bmapWidth,
					   bmapHeight);
	/* VERIFY(bitObject); */
	
	/* Assign the output bitmap to the device */
	origBmap = SelectObject(bitDevice, bitObject);
	(void) VERIFY(origBmap);
	
	VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
	
	/* Use our source font on the device */
	VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
	
	/* Draw the character */
	VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
	
	/* Unselect our bmap object */
	VERIFY(SelectObject(bitDevice, origBmap));
	
	/* Convert the display dependant representation to a 1 bit deep DIB */
	numBytes = (bmapWidth * bmapHeight) / 8;
	bmap = malloc(numBytes);
	dibInfo->bmiHeader.biWidth = bmapWidth;
	dibInfo->bmiHeader.biHeight = bmapHeight;
	res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
			dibInfo,
			DIB_RGB_COLORS);
	/* VERIFY(res); */
	
	/* Create the GL object */
	glNewList(i + listBase, GL_COMPILE);
	glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent,
		 (GLfloat)charWidth, 0.0,
		 bmap);
	glEndList();
	/* CheckGL(); */
	
	/* Destroy the bmap object */
	DeleteObject(bitObject);
	
	/* Deallocate the bitmap data */
	free(bmap);
    }
    
    /* Destroy the DC */
    VERIFY(DeleteDC(bitDevice));
    
    free(dibInfo);
    
    return TRUE;
#undef VERIFY
}

WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first,
					     DWORD count, DWORD listBase)
{
    int i;
    GLuint font_list;
    DWORD size;
    GLYPHMETRICS gm;
    HANDLE hBits;
    LPSTR lpBits;
    MAT2 mat;
    int  success = TRUE;
    
    if (count == 0)
	return FALSE;
    
    font_list = listBase;
    
    mat.eM11 = FixedFromDouble(1);
    mat.eM12 = FixedFromDouble(0);
    mat.eM21 = FixedFromDouble(0);
    mat.eM22 = FixedFromDouble(-1);
    
    memset(&gm,0,sizeof(gm));
    
    /*
    ** If we can't get the glyph outline, it may be because this is a fixed
    ** font.  Try processing it that way.
    */
    if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat)
	== GDI_ERROR ) {
	return wglUseFontBitmaps_FX( hdc, first, count, listBase );
    }
    
    /*
    ** Otherwise process all desired characters.
    */
    for (i = 0; i < (int)count; i++) {
	DWORD err;
	
	glNewList( font_list+i, GL_COMPILE );
	
	/* allocate space for the bitmap/outline */
	size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, 
			       &gm, 0, NULL, &mat);
	if (size == GDI_ERROR) {
	    glEndList( );
	    err = GetLastError();
	    success = FALSE;
	    continue;
	}
	
	hBits  = GlobalAlloc(GHND, size+1);
	lpBits = GlobalLock(hBits);
	
	err = 
	    GetGlyphOutline(hdc,         /* handle to device context */
			    first + i,   /* character to query */
			    GGO_BITMAP,  /* format of data to return */
			    &gm,         /* ptr to structure for metrics*/
			    size,        /* size of buffer for data */
			    lpBits,      /* pointer to buffer for data */
			    &mat         /* pointer to transformation */
			    /* matrix structure */
		);
	
	if (err == GDI_ERROR) {
	    GlobalUnlock(hBits);
	    GlobalFree(hBits);
	    
	    glEndList( );
	    err = GetLastError();
	    success = FALSE;
	    continue;
	}
	
	glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,
		 (GLfloat)-gm.gmptGlyphOrigin.x,
		 (GLfloat)gm.gmptGlyphOrigin.y,
		 (GLfloat)gm.gmCellIncX,
		 (GLfloat)gm.gmCellIncY,
		 (const GLubyte * )lpBits);
	
	GlobalUnlock(hBits);
	GlobalFree(hBits);
	
	glEndList( );
    }
    
    return success;
}

WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,
					HGLRC hglrc2)
{
    WMesaShareLists((WMesaContext)hglrc1, (WMesaContext)hglrc2);
    return(TRUE);
}



/* NOT IMPLEMENTED YET */
WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,
					 HGLRC hglrcDst,
					 UINT mask)
{
    (void) hglrcSrc; (void) hglrcDst; (void) mask;
    return(FALSE);
}

WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,
						 int iLayerPlane)
{
    SetLastError(0);
    if (iLayerPlane == 0)
        return wglCreateContext( hdc );
    return(NULL);
}


WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,
					     DWORD first,
					     DWORD count,
					     DWORD listBase)
{
    (void) hdc; (void) first; (void) count; (void) listBase;
    return FALSE;
}

WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,
					      DWORD first,
					      DWORD count,
					      DWORD listBase,
					      FLOAT deviation,
					      FLOAT extrusion,
					      int format,
					      LPGLYPHMETRICSFLOAT lpgmf)
{
    (void) hdc; (void) first; (void) count;
    (void) listBase; (void) deviation; (void) extrusion; (void) format;
    (void) lpgmf;
    SetLastError(0);
    return(FALSE);
}

WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,
					      DWORD first,
					      DWORD count,
					      DWORD listBase,
					      FLOAT deviation,
					      FLOAT extrusion,
					      int format,
					      LPGLYPHMETRICSFLOAT lpgmf)
{
    (void) hdc; (void) first; (void) count;
    (void) listBase; (void) deviation; (void) extrusion; (void) format;
    (void) lpgmf;
    SetLastError(0);
    return(FALSE);
}

WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc,
						int iPixelFormat,
						int iLayerPlane,
						UINT nBytes,
						LPLAYERPLANEDESCRIPTOR plpd)
{
    (void) hdc; (void) iPixelFormat; (void) iLayerPlane; 
    (void) nBytes; (void) plpd;
    SetLastError(0);
    return(FALSE);
}

WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc,
						   int iLayerPlane,
						   int iStart,
						   int cEntries,
						   CONST COLORREF *pcr)
{
    (void) hdc; (void) iLayerPlane; (void) iStart; 
    (void) cEntries; (void) pcr;
    SetLastError(0);
    return(0);
}

WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc,
						   int iLayerPlane,
						   int iStart,
						   int cEntries,
						   COLORREF *pcr)
{
    (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr;
    SetLastError(0);
    return(0);
}

WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc,
						 int iLayerPlane,
						 BOOL bRealize)
{
    (void) hdc; (void) iLayerPlane; (void) bRealize;
    SetLastError(0);
    return(FALSE);
}

WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,
					      UINT fuPlanes)
{
    (void) hdc; (void) fuPlanes;
    SetLastError(0);
    return(FALSE);
}

WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc)
{
    return "WGL_ARB_extensions_string";
}
