Windows2003-3790/multimedia/opengl/toolkits/libtk/tk.c
2020-09-30 16:53:55 +02:00

1553 lines
47 KiB
C

/*
* (c) Copyright 1993, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* US Government Users Restricted Rights
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tk.h"
#include "windows.h"
#if defined(__cplusplus) || defined(c_plusplus)
#define class c_class
#endif
#if DBG
#define TKASSERT(x) \
if ( !(x) ) { \
PrintMessage("%s(%d) Assertion failed %s\n", \
__FILE__, __LINE__, #x); \
}
#else
#define TKASSERT(x)
#endif /* DBG */
/******************************************************************************/
static struct _WINDOWINFO {
int x, y;
int width, height;
GLenum type;
BOOL bDefPos;
} windInfo = {
0, 0, 100, 100, TK_INDEX | TK_SINGLE, TRUE
};
static HWND tkhwnd = NULL;
static HDC tkhdc = NULL;
static HGLRC tkhrc = NULL;
static HPALETTE tkhpalette = NULL;
static void (*ExposeFunc)(int, int) = NULL;
static void (*ReshapeFunc)(int, int) = NULL;
static void (*DisplayFunc)(void) = NULL;
static GLenum (*KeyDownFunc)(int, GLenum) = NULL;
static GLenum (*MouseDownFunc)(int, int, GLenum) = NULL;
static GLenum (*MouseUpFunc)(int, int, GLenum) = NULL;
static GLenum (*MouseMoveFunc)(int, int, GLenum) = NULL;
static void (*IdleFunc)(void) = NULL;
static char *lpszClassName = "tkLibWClass";
static WCHAR *lpszClassNameW = L"tkLibWClass";
static long tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam);
static unsigned char ComponentFromIndex(int i, int nbits, int shift );
static void PrintMessage( const char *Format, ... );
static PALETTEENTRY *FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd, PALETTEENTRY *Entries, UINT Count );
static HPALETTE CreateCIPalette( HDC Dc );
static HPALETTE CreateRGBPalette( HDC hdc );
static void DestroyThisWindow( HWND Window );
static void CleanUp( void );
static void DelayPaletteRealization( void );
static BOOL RealizePaletteNow( HDC Dc, HPALETTE Palette );
static void ForceRedraw( HWND Window );
static BOOL FindPixelFormat(HDC hdc, GLenum type);
static int PixelFormatDescriptorFromDc( HDC Dc, PIXELFORMATDESCRIPTOR *Pfd );
static void *AllocateMemory( size_t Size );
static void *AllocateZeroedMemory( size_t Size );
static void FreeMemory( void *Chunk );
/*
* Prototypes for the debugging functions go here
*/
#define DBGFUNC 0
#if DBGFUNC
static void DbgPrintf( const char *Format, ... );
static void pwi( void );
static void pwr(RECT *pr);
static void ShowPixelFormat(HDC hdc);
#endif
static float colorMaps[] = {
0.000000F, 1.000000F, 0.000000F, 1.000000F, 0.000000F, 1.000000F,
0.000000F, 1.000000F, 0.333333F, 0.776471F, 0.443137F, 0.556863F,
0.443137F, 0.556863F, 0.219608F, 0.666667F, 0.666667F, 0.333333F,
0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
0.666667F, 0.333333F, 0.039216F, 0.078431F, 0.117647F, 0.156863F,
0.200000F, 0.239216F, 0.278431F, 0.317647F, 0.356863F, 0.400000F,
0.439216F, 0.478431F, 0.517647F, 0.556863F, 0.600000F, 0.639216F,
0.678431F, 0.717647F, 0.756863F, 0.800000F, 0.839216F, 0.878431F,
0.917647F, 0.956863F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.000000F, 0.000000F,
1.000000F, 1.000000F, 0.000000F, 0.000000F, 1.000000F, 1.000000F,
0.333333F, 0.443137F, 0.776471F, 0.556863F, 0.443137F, 0.219608F,
0.556863F, 0.666667F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
0.039216F, 0.078431F, 0.117647F, 0.156863F, 0.200000F, 0.239216F,
0.278431F, 0.317647F, 0.356863F, 0.400000F, 0.439216F, 0.478431F,
0.517647F, 0.556863F, 0.600000F, 0.639216F, 0.678431F, 0.717647F,
0.756863F, 0.800000F, 0.839216F, 0.878431F, 0.917647F, 0.956863F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.141176F, 0.282353F, 0.427451F,
0.568627F, 0.713726F, 0.854902F, 1.000000F, 0.000000F, 0.141176F,
0.282353F, 0.427451F, 0.568627F, 0.713726F, 0.854902F, 1.000000F,
0.000000F, 0.141176F, 0.282353F, 0.427451F, 0.568627F, 0.713726F,
0.854902F, 1.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 0.333333F, 0.443137F,
0.443137F, 0.219608F, 0.776471F, 0.556863F, 0.556863F, 0.666667F,
0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.666667F, 0.333333F,
0.666667F, 0.333333F, 0.666667F, 0.333333F, 0.039216F, 0.078431F,
0.117647F, 0.156863F, 0.200000F, 0.239216F, 0.278431F, 0.317647F,
0.356863F, 0.400000F, 0.439216F, 0.478431F, 0.517647F, 0.556863F,
0.600000F, 0.639216F, 0.678431F, 0.717647F, 0.756863F, 0.800000F,
0.839216F, 0.878431F, 0.917647F, 0.956863F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F, 0.000000F,
0.000000F, 0.000000F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F, 0.247059F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.498039F,
0.498039F, 0.498039F, 0.498039F, 0.498039F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F, 0.749020F,
0.749020F, 0.749020F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F, 1.000000F,
};
/* Default Palette */
float auxRGBMap[20][3] = {
{ 0.0F, 0.0F, 0.0F }, /* 0: black */
{ 0x80/255.0F, 0.0F, 0.0F }, /* 1: Half red */
{ 0.0F, 0x80/255.0F, 0.0F }, /* 2: Half green */
{ 0x80/255.0F, 0x80/255.0F, 0.0F }, /* 3: Half yellow */
{ 0.0F, 0.0F, 0x80/255.0F }, /* 4: Half blue */
{ 0x80/255.0F, 0.0F, 0x80/255.0F }, /* 5: Half magenta */
{ 0.0F, 0x80/255.0F, 0x80/255.0F }, /* 6: Half cyan */
{ 0xC0/255.0F, 0xC0/255.0F, 0xC0/255.0F }, /* 7: Light gray */
{ 0xC0/255.0F, 0xDC/255.0F, 0xC0/255.0F }, /* 8: Green gray */
{ 0xA6/255.0F, 0xCA/255.0F, 0xF0/255.0F }, /* 9: Half gray */
{ 1.0F, 0xFB/255.0F, 0xF0/255.0F }, /* 10: Pale */
{ 0xA0/255.0F, 0xA0/255.0F, 0xA4/255.0F }, /* 11: Med gray */
{ 0x80/255.0F, 0x80/255.0F, 0x80/255.0F }, /* 12: Dark gray */
{ 1.0F, 0.0F, 0.0F }, /* 13: red */
{ 0.0F, 1.0F, 0.0F }, /* 14: green */
{ 1.0F, 1.0F, 0.0F }, /* 15: yellow */
{ 0.0F, 0.0F, 1.0F }, /* 16: blue */
{ 1.0F, 0.0F, 1.0F }, /* 17: magenta */
{ 0.0F, 1.0F, 1.0F }, /* 18: cyan */
{ 1.0F, 1.0F, 1.0F }, /* 19: white */
};
/***************************************************************
* *
* Exported Functions go here *
* *
***************************************************************/
void tkCloseWindow(void)
{
DestroyThisWindow(tkhwnd);
}
void tkExec(void)
{
MSG Message;
/*
* WM_SIZE gets delivered before we get here!
*/
if (ReshapeFunc)
{
RECT ClientRect;
GetClientRect(tkhwnd, &ClientRect);
(*ReshapeFunc)(ClientRect.right, ClientRect.bottom);
}
while (GL_TRUE)
{
/*
* Process all pending messages
*/
while (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (GetMessage(&Message, NULL, 0, 0) )
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
else
{
/*
* Nothing else to do here, just return
*/
return;
}
}
/*
* If an idle function was defined, call it
*/
if (IdleFunc)
{
(*IdleFunc)();
}
}
}
void tkExposeFunc(void (*Func)(int, int))
{
ExposeFunc = Func;
}
void tkReshapeFunc(void (*Func)(int, int))
{
ReshapeFunc = Func;
}
void tkDisplayFunc(void (*Func)(void))
{
DisplayFunc = Func;
}
void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
{
KeyDownFunc = Func;
}
void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
{
MouseDownFunc = Func;
}
void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
{
MouseUpFunc = Func;
}
void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
{
MouseMoveFunc = Func;
}
void tkIdleFunc(void (*Func)(void))
{
IdleFunc = Func;
}
void tkInitPosition(int x, int y, int width, int height)
{
if (x == CW_USEDEFAULT)
{
x = 0;
y = 0;
windInfo.bDefPos = TRUE;
}
else
windInfo.bDefPos = FALSE;
windInfo.x = x + GetSystemMetrics(SM_CXFRAME);
windInfo.y = y + GetSystemMetrics(SM_CYCAPTION)
- GetSystemMetrics(SM_CYBORDER)
+ GetSystemMetrics(SM_CYFRAME);
windInfo.width = width;
windInfo.height = height;
}
void tkInitDisplayMode(GLenum type)
{
windInfo.type = type;
}
// Initialize a window, create a rendering context for that window
GLenum tkInitWindow(char *title)
{
TKASSERT( NULL==tkhwnd );
TKASSERT( NULL==tkhdc );
TKASSERT( NULL==tkhrc );
TKASSERT( NULL==tkhpalette );
return tkInitWindowAW(title, FALSE);
}
GLenum tkInitWindowAW(char *title, BOOL bUnicode)
{
WNDCLASS wndclass;
RECT WinRect;
HANDLE hInstance;
ATOM aRegister;
GLenum Result = GL_FALSE;
hInstance = GetModuleHandle(NULL);
// Must not define CS_CS_PARENTDC style.
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = tkWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
if (bUnicode)
wndclass.lpszClassName = (LPCSTR)lpszClassNameW;
else
wndclass.lpszClassName = (LPCSTR)lpszClassName;
if (bUnicode)
{
aRegister = RegisterClassW((CONST WNDCLASSW *)&wndclass);
}
else
{
aRegister = RegisterClass(&wndclass);
}
/*
* If the window failed to register, then there's no
* need to continue further.
*/
if(0 == aRegister)
{
PrintMessage("Failed to register window class\n");
return(Result);
}
/*
* Make window large enough to hold a client area as large as windInfo
*/
WinRect.left = windInfo.x;
WinRect.right = windInfo.x + windInfo.width;
WinRect.top = windInfo.y;
WinRect.bottom = windInfo.y + windInfo.height;
AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
/*
* Must use WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles.
*/
if (bUnicode)
{
tkhwnd = CreateWindowW(
(LPCWSTR)lpszClassNameW,
(LPCWSTR)title,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
(windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
(windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
WinRect.right - WinRect.left,
WinRect.bottom - WinRect.top,
NULL,
NULL,
hInstance,
NULL);
}
else
{
tkhwnd = CreateWindow(
lpszClassName,
title,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
(windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
(windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
WinRect.right - WinRect.left,
WinRect.bottom - WinRect.top,
NULL,
NULL,
hInstance,
NULL);
}
if ( NULL != tkhwnd )
{
// If default window positioning used, find out window position and fix
// up the windInfo position info.
if (windInfo.bDefPos)
{
GetWindowRect(tkhwnd, &WinRect);
windInfo.x = WinRect.left + GetSystemMetrics(SM_CXFRAME);
windInfo.y = WinRect.top + GetSystemMetrics(SM_CYCAPTION)
- GetSystemMetrics(SM_CYBORDER)
+ GetSystemMetrics(SM_CYFRAME);
}
tkhdc = GetDC(tkhwnd);
if ( NULL != tkhdc )
{
ShowWindow(tkhwnd, SW_SHOWDEFAULT);
if ( FindPixelFormat(tkhdc, windInfo.type) )
{
/*
* Create a Rendering Context
*/
tkhrc = wglCreateContext(tkhdc);
if ( NULL != tkhrc )
{
/*
* Make it Current
*/
if ( wglMakeCurrent(tkhdc, tkhrc) )
{
Result = GL_TRUE;
}
else
{
PrintMessage("wglMakeCurrent Failed\n");
}
}
else
{
PrintMessage("wglCreateContext Failed\n");
}
}
}
else
{
PrintMessage("Could not get an HDC for window 0x%08lX\n", tkhwnd );
}
}
else
{
PrintMessage("create window failed\n");
}
if ( GL_FALSE == Result )
{
DestroyThisWindow(tkhwnd); // Something Failed, Destroy this window
}
return( Result );
}
/******************************************************************************/
/*
* You cannot just call DestroyWindow() here. The programs do not expect
* tkQuit() to return; DestroyWindow() just posts a WM_DESTROY message
*/
void tkQuit(void)
{
DestroyThisWindow(tkhwnd);
ExitProcess(0);
}
/******************************************************************************/
void tkSetOneColor(int index, float r, float g, float b)
{
PALETTEENTRY PalEntry;
HPALETTE Palette;
if ( NULL != (Palette = CreateCIPalette( tkhdc )) )
{
PalEntry.peRed = (BYTE)(r*(float)255.0 + (float)0.5);
PalEntry.peGreen = (BYTE)(g*(float)255.0 + (float)0.5);
PalEntry.peBlue = (BYTE)(b*(float)255.0 + (float)0.5);
PalEntry.peFlags = (BYTE)0;
SetPaletteEntries( Palette, index, 1, &PalEntry);
DelayPaletteRealization();
}
}
void tkSetFogRamp(int density, int startIndex)
{
HPALETTE CurrentPal;
PALETTEENTRY *pPalEntry;
UINT n, i, j, k, intensity, fogValues, colorValues;
if ( NULL != (CurrentPal = CreateCIPalette(tkhdc)) )
{
n = GetPaletteEntries( CurrentPal, 0, 0, NULL );
pPalEntry = AllocateMemory( n * sizeof(PALETTEENTRY) );
if ( NULL != pPalEntry)
{
fogValues = 1 << density;
colorValues = 1 << startIndex;
for (i = 0; i < colorValues; i++) {
for (j = 0; j < fogValues; j++) {
k = i * fogValues + j;
intensity = i * fogValues + j * colorValues;
//mf: not sure what they're trying to do here
if (intensity > 0xFF) {
intensity = 0xFF;
}
//intensity = (intensity << 8) | intensity; ???
pPalEntry[k].peRed =
pPalEntry[k].peGreen =
pPalEntry[k].peBlue = (BYTE) intensity;
pPalEntry[k].peFlags = 0;
}
}
SetPaletteEntries(CurrentPal, 0, n, pPalEntry);
FreeMemory( pPalEntry );
DelayPaletteRealization();
}
}
}
void tkSetGreyRamp(void)
{
HPALETTE CurrentPal;
PALETTEENTRY *Entries;
UINT Count, i;
float intensity;
if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
{
Count = GetPaletteEntries( CurrentPal, 0, 0, NULL );
Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
if ( NULL != Entries )
{
for (i = 0; i < Count; i++)
{
intensity = (float)(((double)i / (double)(Count-1)) * (double)255.0 + (double)0.5);
Entries[i].peRed =
Entries[i].peGreen =
Entries[i].peBlue = (BYTE) intensity;
Entries[i].peFlags = 0;
}
SetPaletteEntries( CurrentPal, 0, Count, Entries );
FreeMemory( Entries );
DelayPaletteRealization();
}
}
}
void tkSetRGBMap( int Size, float *Values )
{
HPALETTE CurrentPal;
PIXELFORMATDESCRIPTOR Pfd, *pPfd;
PALETTEENTRY *Entries;
UINT Count;
if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
{
pPfd = &Pfd;
if ( PixelFormatDescriptorFromDc( tkhdc, pPfd ) )
{
Count = 1 << pPfd->cColorBits;
Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
if ( NULL != Entries )
{
FillRgbPaletteEntries( pPfd, Entries, Count );
SetPaletteEntries( CurrentPal, 0, Count, Entries );
FreeMemory(Entries);
RealizePaletteNow( tkhdc, tkhpalette );
}
}
}
}
/******************************************************************************/
void tkSwapBuffers(void)
{
SwapBuffers(tkhdc);
}
/******************************************************************************/
GLint tkGetColorMapSize(void)
{
CreateCIPalette( tkhdc );
if ( NULL == tkhpalette )
return( 0 );
return( GetPaletteEntries( tkhpalette, 0, 0, NULL ) );
}
void tkGetMouseLoc(int *x, int *y)
{
POINT Point;
*x = 0;
*y = 0;
GetCursorPos(&Point);
/*
* GetCursorPos returns screen coordinates,
* we want window coordinates
*/
*x = Point.x - windInfo.x;
*y = Point.y - windInfo.y;
}
HWND tkGetHWND(void)
{
return tkhwnd;
}
HDC tkGetHDC(void)
{
return tkhdc;
}
HGLRC tkGetHRC(void)
{
return tkhrc;
}
/***********************************************************************
* *
* The Following functions are for our own use only. (ie static) *
* *
***********************************************************************/
static long
tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam)
{
int key;
PAINTSTRUCT paint;
HDC hdc;
switch (message) {
case WM_USER:
if ( RealizePaletteNow( tkhdc, tkhpalette ) )
{
ForceRedraw( hWnd );
}
return(0);
case WM_SIZE:
windInfo.width = LOWORD(lParam);
windInfo.height = HIWORD(lParam);
if (ReshapeFunc)
{
(*ReshapeFunc)(windInfo.width, windInfo.height);
ForceRedraw( hWnd );
}
return (0);
case WM_MOVE:
windInfo.x = LOWORD(lParam);
windInfo.y = HIWORD(lParam);
return (0);
case WM_PAINT:
/*
* Validate the region even if there are no DisplayFunc.
* Otherwise, USER will not stop sending WM_PAINT messages.
*/
hdc = BeginPaint(tkhwnd, &paint);
if (DisplayFunc)
{
(*DisplayFunc)();
}
EndPaint(tkhwnd, &paint);
return (0);
/*
* WM_QUERYNEWPALETTE and WM_ACTIVATE were tried here.
* They would not work all the time (except on fridays)
* WM_NCACTIVATE seems more reliable
*/
case WM_NCACTIVATE:
if ( wParam )
{
if ( NULL != tkhpalette )
{
RealizePaletteNow( tkhdc, tkhpalette );
}
}
/*
* Pretend you didn't do anything let DefWindowProc() handle it.
*/
break;
case WM_MOUSEMOVE:
if (MouseMoveFunc)
{
GLenum mask;
mask = 0;
if (wParam & MK_LBUTTON) {
mask |= TK_LEFTBUTTON;
}
if (wParam & MK_MBUTTON) {
mask |= TK_MIDDLEBUTTON;
}
if (wParam & MK_RBUTTON) {
mask |= TK_RIGHTBUTTON;
}
if ((*MouseMoveFunc)( LOWORD(lParam), HIWORD(lParam), mask ))
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_LBUTTONDOWN:
SetCapture(hWnd);
if (MouseDownFunc)
{
if ( (*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
TK_LEFTBUTTON) )
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_LBUTTONUP:
ReleaseCapture();
if (MouseUpFunc)
{
if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam), TK_LEFTBUTTON))
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_MBUTTONDOWN:
SetCapture(hWnd);
if (MouseDownFunc)
{
if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
TK_MIDDLEBUTTON))
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_MBUTTONUP:
ReleaseCapture();
if (MouseUpFunc)
{
if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
TK_MIDDLEBUTTON))
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_RBUTTONDOWN:
SetCapture(hWnd);
if (MouseDownFunc)
{
if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
TK_RIGHTBUTTON))
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_RBUTTONUP:
ReleaseCapture();
if (MouseUpFunc)
{
if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
TK_RIGHTBUTTON))
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_KEYDOWN:
switch (wParam) {
case VK_SPACE: key = TK_SPACE; break;
case VK_RETURN: key = TK_RETURN; break;
case VK_ESCAPE: key = TK_ESCAPE; break;
case VK_LEFT: key = TK_LEFT; break;
case VK_UP: key = TK_UP; break;
case VK_RIGHT: key = TK_RIGHT; break;
case VK_DOWN: key = TK_DOWN; break;
default: key = GL_FALSE; break;
}
if (key && KeyDownFunc)
{
GLenum mask;
mask = 0;
if (GetKeyState(VK_CONTROL)) {
mask |= TK_CONTROL;
}
if (GetKeyState(VK_SHIFT)) {
mask |= TK_SHIFT;
}
if ( (*KeyDownFunc)(key, mask) )
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_CHAR:
if (('0' <= wParam && wParam <= '9') ||
('a' <= wParam && wParam <= 'z') ||
('A' <= wParam && wParam <= 'Z')) {
key = wParam;
} else {
key = GL_FALSE;
}
if (key && KeyDownFunc) {
GLenum mask;
mask = 0;
if (GetKeyState(VK_CONTROL)) {
mask |= TK_CONTROL;
}
if (GetKeyState(VK_SHIFT)) {
mask |= TK_SHIFT;
}
if ( (*KeyDownFunc)(key, mask) )
{
ForceRedraw( hWnd );
}
}
return (0);
case WM_CLOSE:
DestroyWindow(tkhwnd);
return(0);
case WM_DESTROY:
CleanUp();
PostQuitMessage(TRUE);
return 0;
}
return(DefWindowProc( hWnd, message, wParam, lParam));
}
#ifdef GAMMA_1_0
static unsigned char threeto8[8] = {
0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
};
static unsigned char twoto8[4] = {
0, 0x55, 0xaa, 0xff
};
static int defaultOverride[13] = {
0, 4, 32, 36, 128, 132, 160, 173, 181, 245, 247, 164, 156
};
#endif
// The following tables use gamma 1.4
static unsigned char threeto8[8] = {
0, 63, 104, 139, 171, 200, 229, 255
};
static unsigned char twoto8[4] = {
0, 116, 191, 255
};
static unsigned char oneto8[2] = {
0, 255
};
static int defaultOverride[13] = {
0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
};
// These are the ones GMT (tarolli) calculated (note 247 vs 191)
// 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 191, 164, 91
static unsigned char
ComponentFromIndex(int i, int nbits, int shift)
{
unsigned char val;
val = i >> shift;
switch (nbits) {
case 1:
val &= 0x1;
return oneto8[val];
case 2:
val &= 0x3;
return twoto8[val];
case 3:
val &= 0x7;
return threeto8[val];
default:
//PrintMessage("default case in Component from index, nbits %d\n", nbits);
return 0;
}
}
static PALETTEENTRY defaultPalEntry[20] = {
{ 0, 0, 0, 0 },
{ 0x80,0, 0, 0 },
{ 0, 0x80,0, 0 },
{ 0x80,0x80,0, 0 },
{ 0, 0, 0x80, 0 },
{ 0x80,0, 0x80, 0 },
{ 0, 0x80,0x80, 0 },
{ 0xC0,0xC0,0xC0, 0 },
{ 192, 220, 192, 0 },
{ 166, 202, 240, 0 },
{ 255, 251, 240, 0 },
{ 160, 160, 164, 0 },
{ 0x80,0x80,0x80, 0 },
{ 0xFF,0, 0, 0 },
{ 0, 0xFF,0, 0 },
{ 0xFF,0xFF,0, 0 },
{ 0, 0, 0xFF, 0 },
{ 0xFF,0, 0xFF, 0 },
{ 0, 0xFF,0xFF, 0 },
{ 0xFF,0xFF,0xFF, 0 }
};
static PALETTEENTRY *
FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd,
PALETTEENTRY *Entries,
UINT Count
)
{
PALETTEENTRY *Entry;
UINT i;
if ( NULL != Entries )
{
for ( i = 0, Entry = Entries ; i < Count ; i++, Entry++ )
{
Entry->peRed = ComponentFromIndex(i, Pfd->cRedBits,
Pfd->cRedShift);
Entry->peGreen = ComponentFromIndex(i, Pfd->cGreenBits,
Pfd->cGreenShift);
Entry->peBlue = ComponentFromIndex(i, Pfd->cBlueBits,
Pfd->cBlueShift);
Entry->peFlags = 0;
}
// XXX fix this up
if ( (256 == Count) &&
(3 == Pfd->cRedBits) && (0 == Pfd->cRedShift) &&
(3 == Pfd->cGreenBits) && (3 == Pfd->cGreenShift) &&
(2 == Pfd->cBlueBits) && (6 == Pfd->cBlueShift)
)
{
for ( i = 1 ; i <= 12 ; i++)
{
Entries[defaultOverride[i]] = defaultPalEntry[i];
}
}
}
return( Entries );
}
static HPALETTE
CreateRGBPalette( HDC Dc )
{
PIXELFORMATDESCRIPTOR Pfd, *pPfd;
LOGPALETTE *LogPalette;
UINT Count;
if ( NULL == tkhpalette )
{
pPfd = &Pfd;
if ( PixelFormatDescriptorFromDc( Dc, pPfd ) )
{
/*
* Make sure we need a palette
*/
if (pPfd->dwFlags & PFD_NEED_PALETTE)
{
Count = 1 << pPfd->cColorBits;
LogPalette = AllocateMemory( sizeof(LOGPALETTE) +
Count * sizeof(PALETTEENTRY));
if ( NULL != LogPalette )
{
LogPalette->palVersion = 0x300;
LogPalette->palNumEntries = Count;
FillRgbPaletteEntries( pPfd,
&LogPalette->palPalEntry[0], Count );
tkhpalette = CreatePalette(LogPalette);
FreeMemory(LogPalette);
RealizePaletteNow( Dc, tkhpalette );
}
}
}
}
return( tkhpalette );
}
static HPALETTE
CreateCIPalette( HDC Dc )
{
PIXELFORMATDESCRIPTOR Pfd;
LOGPALETTE *LogicalPalette;
HPALETTE StockPalette;
UINT PaletteSize, StockPaletteSize, EntriesToCopy;
if ( (Dc != NULL) && (NULL == tkhpalette) )
{
PixelFormatDescriptorFromDc( Dc, &Pfd );
if ( Pfd.iPixelType & PFD_TYPE_COLORINDEX )
{
/*
* Limit the size of the palette to 256 colors.
* Why? Because this is what was decided.
*/
PaletteSize = (Pfd.cColorBits >= 8) ? 256 : (1 << Pfd.cColorBits);
LogicalPalette = AllocateZeroedMemory( sizeof(LOGPALETTE) +
(PaletteSize * sizeof(PALETTEENTRY)) );
if ( NULL != LogicalPalette )
{
LogicalPalette->palVersion = 0x300;
LogicalPalette->palNumEntries = PaletteSize;
StockPalette = GetStockObject(DEFAULT_PALETTE);
StockPaletteSize = GetPaletteEntries( StockPalette, 0, 0, NULL );
/*
* start by copying default palette into new one
*/
EntriesToCopy = StockPaletteSize < PaletteSize ?
StockPaletteSize : PaletteSize;
GetPaletteEntries( StockPalette, 0, EntriesToCopy,
LogicalPalette->palPalEntry );
tkhpalette = CreatePalette(LogicalPalette);
FreeMemory(LogicalPalette);
RealizePaletteNow( Dc, tkhpalette );
}
}
}
return( tkhpalette );
}
static BOOL
FindPixelFormat(HDC hdc, GLenum type)
{
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int PfdIndex;
BOOL Result = FALSE;
ppfd = &pfd;
ppfd->nSize = sizeof(pfd);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
ppfd->dwLayerMask = PFD_MAIN_PLANE;
if (TK_IS_DOUBLE(type)) {
ppfd->dwFlags |= PFD_DOUBLEBUFFER;
}
if (TK_IS_INDEX(type)) {
ppfd->iPixelType = PFD_TYPE_COLORINDEX;
ppfd->cColorBits = 8;
}
if (TK_IS_RGB(type)) {
ppfd->iPixelType = PFD_TYPE_RGBA;
ppfd->cColorBits = 24;
}
if (TK_HAS_ACCUM(type)) {
ppfd->cAccumBits = ppfd->cColorBits;
} else {
ppfd->cAccumBits = 0;
}
if (TK_HAS_DEPTH(type)) {
ppfd->cDepthBits = 24;
} else {
ppfd->cDepthBits = 0;
}
if (TK_HAS_STENCIL(type)) {
ppfd->cStencilBits = 8;
} else {
ppfd->cStencilBits = 0;
}
PfdIndex = ChoosePixelFormat(hdc, ppfd);
if ( PfdIndex )
{
if ( SetPixelFormat(hdc, PfdIndex, ppfd) )
{
/*
* If this pixel format requires a palette do it now.
* In colorindex mode, create a logical palette only
* if the application needs to modify it.
*/
CreateRGBPalette( hdc );
Result = TRUE;
}
else
{
PrintMessage("SetPixelFormat failed\n");
}
}
else
{
PrintMessage("ChoosePixelFormat failed\n");
}
return(Result);
}
static void
PrintMessage( const char *Format, ... )
{
va_list ArgList;
char Buffer[256];
va_start(ArgList, Format);
vsprintf(Buffer, Format, ArgList);
va_end(ArgList);
MessageBox(NULL, Buffer, "Error", MB_OK);
}
static void
DelayPaletteRealization( void )
{
MSG Message;
TKASSERT(NULL!=tkhwnd);
/*
* Add a WM_USER message to the queue, if there isn't one there already.
*/
if (!PeekMessage(&Message, tkhwnd, WM_USER, WM_USER, PM_NOREMOVE) )
{
PostMessage( tkhwnd, WM_USER, 0, 0);
}
}
static BOOL
RealizePaletteNow( HDC Dc, HPALETTE Palette )
{
BOOL Result = FALSE;
TKASSERT( NULL!=Dc );
TKASSERT( NULL!=Palette );
if ( NULL != SelectPalette( Dc, Palette, FALSE) )
{
if ( GDI_ERROR != RealizePalette( Dc ) )
{
Result = TRUE;
}
}
return( Result );
}
static void
ForceRedraw( HWND Window )
{
MSG Message;
if (!PeekMessage(&Message, Window, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
{
InvalidateRect( Window, NULL, FALSE );
}
}
static int
PixelFormatDescriptorFromDc( HDC Dc, PIXELFORMATDESCRIPTOR *Pfd )
{
int PfdIndex;
if ( 0 < (PfdIndex = GetPixelFormat( Dc )) )
{
if ( 0 < DescribePixelFormat( Dc, PfdIndex, sizeof(*Pfd), Pfd ) )
{
return(PfdIndex);
}
else
{
PrintMessage("Could not get a description of pixel format %d\n",
PfdIndex );
}
}
else
{
PrintMessage("Could not get pixel format for Dc 0x%08lX\n", Dc );
}
return( 0 );
}
static void
DestroyThisWindow( HWND Window )
{
if ( NULL != Window )
{
DestroyWindow( Window );
}
}
/*
* This Should be called in response to a WM_DESTROY message
*/
static void
CleanUp( void )
{
HPALETTE hStock;
if ( NULL != tkhrc )
{
wglMakeCurrent( tkhdc, NULL ); // No current context
wglDeleteContext(tkhrc); // Delete this context
}
if ( NULL != tkhdc )
{
ReleaseDC( tkhwnd, tkhdc );
}
if ( NULL != tkhpalette )
{
if(hStock = GetStockObject(DEFAULT_PALETTE))
SelectPalette(tkhdc,hStock,FALSE);
DeleteObject(tkhpalette);
}
/*
* Programs maybe using printf's
*/
flushall();
tkhwnd = NULL;
tkhdc = NULL;
tkhrc = NULL;
tkhpalette = NULL;
ExposeFunc = NULL;
ReshapeFunc = NULL;
IdleFunc = NULL;
DisplayFunc = NULL;
KeyDownFunc = NULL;
MouseDownFunc = NULL;
MouseUpFunc = NULL;
MouseMoveFunc = NULL;
}
static void *
AllocateMemory( size_t Size )
{
return( LocalAlloc( LMEM_FIXED, Size ) );
}
static void *
AllocateZeroedMemory( size_t Size )
{
return( LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, Size ) );
}
static void
FreeMemory( void *Chunk )
{
TKASSERT( NULL!=Chunk );
LocalFree( Chunk );
}
/*******************************************************************
* *
* Debugging functions go here *
* *
*******************************************************************/
#if DBGFUNC
static void
DbgPrintf( const char *Format, ... )
{
va_list ArgList;
char Buffer[256];
va_start(ArgList, Format);
vsprintf(Buffer, Format, ArgList);
va_end(ArgList);
printf("%s", Buffer );
fflush(stdout);
}
static void
pwi( void )
{
DbgPrintf("windInfo: x %d, y %d, w %d, h %d\n", windInfo.x, windInfo.y, windInfo.width, windInfo.height);
}
static void
pwr(RECT *pr)
{
DbgPrintf("Rect: left %d, top %d, right %d, bottom %d\n", pr->left, pr->top, pr->right, pr->bottom);
}
static void
ShowPixelFormat(HDC hdc)
{
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int format;
ppfd = &pfd;
format = PixelFormatDescriptorFromDc( hdc, ppfd );
DbgPrintf("Pixel format %d\n", format);
DbgPrintf(" dwFlags - 0x%x", ppfd->dwFlags);
if (ppfd->dwFlags & PFD_DOUBLEBUFFER) DbgPrintf("PFD_DOUBLEBUFFER ");
if (ppfd->dwFlags & PFD_STEREO) DbgPrintf("PFD_STEREO ");
if (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) DbgPrintf("PFD_DRAW_TO_WINDOW ");
if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) DbgPrintf("PFD_DRAW_TO_BITMAP ");
if (ppfd->dwFlags & PFD_SUPPORT_GDI) DbgPrintf("PFD_SUPPORT_GDI ");
if (ppfd->dwFlags & PFD_SUPPORT_OPENGL) DbgPrintf("PFD_SUPPORT_OPENGL ");
if (ppfd->dwFlags & PFD_GENERIC_FORMAT) DbgPrintf("PFD_GENERIC_FORMAT ");
if (ppfd->dwFlags & PFD_NEED_PALETTE) DbgPrintf("PFD_NEED_PALETTE ");
DbgPrintf("\n");
DbgPrintf(" iPixelType - %d", ppfd->iPixelType);
if (ppfd->iPixelType == PFD_TYPE_RGBA) DbgPrintf("PGD_TYPE_RGBA\n");
if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) DbgPrintf("PGD_TYPE_COLORINDEX\n");
DbgPrintf(" cColorBits - %d\n", ppfd->cColorBits);
DbgPrintf(" cRedBits - %d\n", ppfd->cRedBits);
DbgPrintf(" cRedShift - %d\n", ppfd->cRedShift);
DbgPrintf(" cGreenBits - %d\n", ppfd->cGreenBits);
DbgPrintf(" cGreenShift - %d\n", ppfd->cGreenShift);
DbgPrintf(" cBlueBits - %d\n", ppfd->cBlueBits);
DbgPrintf(" cBlueShift - %d\n", ppfd->cBlueShift);
DbgPrintf(" cAlphaBits - %d\n", ppfd->cAlphaBits);
DbgPrintf(" cAlphaShift - 0x%x\n", ppfd->cAlphaShift);
DbgPrintf(" cAccumBits - %d\n", ppfd->cAccumBits);
DbgPrintf(" cAccumRedBits - %d\n", ppfd->cAccumRedBits);
DbgPrintf(" cAccumGreenBits - %d\n", ppfd->cAccumGreenBits);
DbgPrintf(" cAccumBlueBits - %d\n", ppfd->cAccumBlueBits);
DbgPrintf(" cAccumAlphaBits - %d\n", ppfd->cAccumAlphaBits);
DbgPrintf(" cDepthBits - %d\n", ppfd->cDepthBits);
DbgPrintf(" cStencilBits - %d\n", ppfd->cStencilBits);
DbgPrintf(" cAuxBuffers - %d\n", ppfd->cAuxBuffers);
DbgPrintf(" iLayerType - %d\n", ppfd->iLayerType);
DbgPrintf(" bReserved - %d\n", ppfd->bReserved);
DbgPrintf(" dwLayerMask - 0x%x\n", ppfd->dwLayerMask);
DbgPrintf(" dwVisibleMask - 0x%x\n", ppfd->dwVisibleMask);
DbgPrintf(" dwDamageMask - 0x%x\n", ppfd->dwDamageMask);
}
#endif /* DBG */