|
|
/*
* (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(WINVER < 0x0400)
// Ordinarily not defined for versions before 4.00.
#define COLOR_3DDKSHADOW 21
#define COLOR_3DLIGHT 22
#define COLOR_INFOTEXT 23
#define COLOR_INFOBK 24
#endif
#define static
#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; GLenum dmPolicy; int ipfd; BOOL bDefPos; } windInfo = { 0, 0, 100, 100, TK_INDEX | TK_SINGLE, TK_MINIMUM_CRITERIA, 0, TRUE };
HWND tkhwnd = NULL; HDC tkhdc = NULL; static HGLRC tkhrc = NULL; HPALETTE tkhpalette = NULL; static OSVERSIONINFO tkOSVerInfo; GLboolean tkPopupEnable = TRUE;
// Fixed palette support.
#define BLACK PALETTERGB(0,0,0)
#define WHITE PALETTERGB(255,255,255)
#define MAX_STATIC_COLORS (COLOR_INFOBK - COLOR_SCROLLBAR + 1)
static int tkNumStaticColors = MAX_STATIC_COLORS;
// TRUE if app wants to take over palette
static BOOL tkUseStaticColors = FALSE;
// TRUE if static system color settings have been replaced with B&W settings.
BOOL tkSystemColorsInUse = FALSE;
// TRUE if original static colors saved
static BOOL tkStaticColorsSaved = FALSE;
// saved system static colors (initialize with default colors)
static COLORREF gacrSave[MAX_STATIC_COLORS];
// new B&W system static colors
static COLORREF gacrBlackAndWhite[] = { WHITE, // COLOR_SCROLLBAR
BLACK, // COLOR_BACKGROUND
BLACK, // COLOR_ACTIVECAPTION
WHITE, // COLOR_INACTIVECAPTION
WHITE, // COLOR_MENU
WHITE, // COLOR_WINDOW
BLACK, // COLOR_WINDOWFRAME
BLACK, // COLOR_MENUTEXT
BLACK, // COLOR_WINDOWTEXT
WHITE, // COLOR_CAPTIONTEXT
WHITE, // COLOR_ACTIVEBORDER
WHITE, // COLOR_INACTIVEBORDER
WHITE, // COLOR_APPWORKSPACE
BLACK, // COLOR_HIGHLIGHT
WHITE, // COLOR_HIGHLIGHTTEXT
WHITE, // COLOR_BTNFACE
BLACK, // COLOR_BTNSHADOW
BLACK, // COLOR_GRAYTEXT
BLACK, // COLOR_BTNTEXT
BLACK, // COLOR_INACTIVECAPTIONTEXT
BLACK, // COLOR_BTNHIGHLIGHT
BLACK, // COLOR_3DDKSHADOW
WHITE, // COLOR_3DLIGHT
BLACK, // COLOR_INFOTEXT
WHITE // COLOR_INFOBK
}; static INT gaiStaticIndex[] = { COLOR_SCROLLBAR , COLOR_BACKGROUND , COLOR_ACTIVECAPTION , COLOR_INACTIVECAPTION , COLOR_MENU , COLOR_WINDOW , COLOR_WINDOWFRAME , COLOR_MENUTEXT , COLOR_WINDOWTEXT , COLOR_CAPTIONTEXT , COLOR_ACTIVEBORDER , COLOR_INACTIVEBORDER , COLOR_APPWORKSPACE , COLOR_HIGHLIGHT , COLOR_HIGHLIGHTTEXT , COLOR_BTNFACE , COLOR_BTNSHADOW , COLOR_GRAYTEXT , COLOR_BTNTEXT , COLOR_INACTIVECAPTIONTEXT, COLOR_BTNHIGHLIGHT , COLOR_3DDKSHADOW , COLOR_3DLIGHT , COLOR_INFOTEXT , COLOR_INFOBK };
static BOOL GrabStaticEntries(HDC); static BOOL ReleaseStaticEntries(HDC);
#define RESTORE_FROM_REGISTRY 1
#if RESTORE_FROM_REGISTRY
// Registry names for the system colors.
CHAR *gaszSysClrNames[] = { "Scrollbar", // COLOR_SCROLLBAR 0
"Background", // COLOR_BACKGROUND 1 (also COLOR_DESKTOP)
"ActiveTitle", // COLOR_ACTIVECAPTION 2
"InactiveTitle", // COLOR_INACTIVECAPTION 3
"Menu", // COLOR_MENU 4
"Window", // COLOR_WINDOW 5
"WindowFrame", // COLOR_WINDOWFRAME 6
"MenuText", // COLOR_MENUTEXT 7
"WindowText", // COLOR_WINDOWTEXT 8
"TitleText", // COLOR_CAPTIONTEXT 9
"ActiveBorder", // COLOR_ACTIVEBORDER 10
"InactiveBorder", // COLOR_INACTIVEBORDER 11
"AppWorkspace", // COLOR_APPWORKSPACE 12
"Hilight", // COLOR_HIGHLIGHT 13
"HilightText", // COLOR_HIGHLIGHTTEXT 14
"ButtonFace", // COLOR_BTNFACE 15 (also COLOR_3DFACE)
"ButtonShadow", // COLOR_BTNSHADOW 16 (also COLOR_3DSHADOW)
"GrayText", // COLOR_GRAYTEXT 17
"ButtonText", // COLOR_BTNTEXT 18
"InactiveTitleText", // COLOR_INACTIVECAPTIONTEXT 19
"ButtonHilight", // COLOR_BTNHIGHLIGHT 20 (also COLOR_3DHILIGHT)
"ButtonDkShadow", // COLOR_3DDKSHADOW 21
"ButtonLight", // COLOR_3DLIGHT 22
"InfoText", // COLOR_INFOTEXT 23
"InfoWindow" // COLOR_INFOBK 24
};
static BOOL GetRegistrySysColors(COLORREF *, int); #endif
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 LRESULT tkWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM 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 long RealizePaletteNow( HDC Dc, HPALETTE Palette, BOOL bForceBackground ); static void ForceRedraw( HWND Window ); static BOOL FindPixelFormat(HDC hdc, GLenum type); static int FindBestPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd); static int FindExactPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd); static BOOL IsPixelFormatValid(HDC hdc, int ipfd, PIXELFORMATDESCRIPTOR *ppfd); 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 tkErrorPopups(GLboolean bEnable) { tkPopupEnable = bEnable; }
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 */
if (IdleFunc) { 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)(); } } else { if (GetMessage(&Message, NULL, 0, 0)) { TranslateMessage(&Message); DispatchMessage(&Message); } else { return; } } } }
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; }
void tkInitDisplayModePolicy(GLenum type) { windInfo.dmPolicy = type; }
GLenum tkInitDisplayModeID(GLint ipfd) { windInfo.ipfd = ipfd; return GL_TRUE; }
// 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; BOOL bGetVersionExRet;
hInstance = GetModuleHandle(NULL);
tkOSVerInfo.dwOSVersionInfoSize = sizeof(tkOSVerInfo); bGetVersionExRet = GetVersionEx(&tkOSVerInfo); TKASSERT(bGetVersionExRet); if ( tkOSVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && tkOSVerInfo.dwMajorVersion == 3 && (tkOSVerInfo.dwMinorVersion == 5 || tkOSVerInfo.dwMinorVersion == 51) ) tkNumStaticColors = COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1; else tkNumStaticColors = COLOR_INFOBK - COLOR_SCROLLBAR + 1;
// Must not define CS_PARENTDC style.
wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = (WNDPROC)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(BLACK_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 sends 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 )) ) { if ( tkUseStaticColors && ( index == 0 || index == 255 ) ) return;
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 = ( tkUseStaticColors ) ? PC_NOCOLLAPSE : 0;
// This is a workaround for a GDI palette "feature". If any of
// the static colors are repeated in the palette, those colors
// will map to the first occurance. So, for our case where there
// are only two static colors (black and white), if a white
// color appears anywhere in the palette other than in the last
// entry, the static white will remap to the first white. This
// destroys the nice one-to-one mapping we are trying to achieve.
//
// There are two ways to workaround this. The first is to
// simply not allow a pure white anywhere but in the last entry.
// Such requests are replaced with an attenuated white of
// (0xFE, 0xFE, 0xFE).
//
// The other way is to mark these extra whites with PC_RESERVED
// which will cause GDI to skip these entries when mapping colors.
// This way the app gets the actual colors requested, but can
// have side effects on other apps.
//
// Both solutions are included below. The PC_RESERVED solution is
// the one currently enabled. It may have side effects, but taking
// over the static colors as we are is a really big side effect that
// should swamp out the effects of using PC_RESERVED.
if ( tkUseStaticColors ) { if ( PalEntry.peRed == 0xFF && PalEntry.peGreen == 0xFF && PalEntry.peBlue == 0xFF ) { #define USE_PC_RESERVED_WORKAROUND 1
#if USE_PC_RESERVED_WORKAROUND
PalEntry.peFlags |= PC_RESERVED; #else
PalEntry.peRed = PalEntry.peGreen = PalEntry.peBlue = 0xFE; #endif
} }
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
//intensity = (intensity << 8) | intensity; ???
// This is a workaround for a GDI palette "feature". If any of
// the static colors are repeated in the palette, those colors
// will map to the first occurance. So, for our case where there
// are only two static colors (black and white), if a white
// color appears anywhere in the palette other than in the last
// entry, the static white will remap to the first white. This
// destroys the nice one-to-one mapping we are trying to achieve.
//
// There are two ways to workaround this. The first is to
// simply not allow a pure white anywhere but in the last entry.
// Such requests are replaced with an attenuated white of
// (0xFE, 0xFE, 0xFE).
//
// The other way is to mark these extra whites with PC_RESERVED
// which will cause GDI to skip these entries when mapping colors.
// This way the app gets the actual colors requested, but can
// have side effects on other apps.
//
// Both solutions are included below. The PC_RESERVED solution is
// the one currently enabled. It may have side effects, but taking
// over the static colors as we are is a really big side effect that
// should swamp out the effects of using PC_RESERVED.
#if USE_PC_RESERVED_WORKAROUND
if (intensity > 0xFF) intensity = 0xFF; #else
if (intensity >= 0xFF) intensity = ( tkUseStaticColors && k != 255) ? 0xFE : 0xFF; #endif
pPalEntry[k].peRed = pPalEntry[k].peGreen = pPalEntry[k].peBlue = (BYTE) intensity; pPalEntry[k].peFlags = ( tkUseStaticColors && k != 0 && k != 255 ) ? PC_NOCOLLAPSE : 0;
#if USE_PC_RESERVED_WORKAROUND
if (tkUseStaticColors && intensity == 0xFF && k != 0 && k!= 255) pPalEntry[k].peFlags |= PC_RESERVED; #endif
} }
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 = ( tkUseStaticColors && i != 0 && i != 255 ) ? PC_NOCOLLAPSE : 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, FALSE ); } } } }
/******************************************************************************/
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; }
GLenum tkGetDisplayModePolicy(void) { return windInfo.dmPolicy; }
GLint tkGetDisplayModeID(void) { return windInfo.ipfd; }
GLenum tkGetDisplayMode(void) { return windInfo.type; }
/***********************************************************************
* * * The Following functions are for our own use only. (ie static) * * * ***********************************************************************/
static LRESULT tkWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int key; PAINTSTRUCT paint; HDC hdc; PIXELFORMATDESCRIPTOR pfd;
switch (message) {
case WM_USER: if ( RealizePaletteNow( tkhdc, tkhpalette, FALSE ) > 0 ) { 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);
case WM_QUERYNEWPALETTE:
// We don't actually realize the palette here (we do it at WM_ACTIVATE
// time), but we need the system to think that we have so that a
// WM_PALETTECHANGED message is generated.
return (1);
case WM_PALETTECHANGED:
// Respond to this message only if the window that changed the palette
// is not this app's window.
// We are not the foreground window, so realize palette in the
// background. We cannot call RealizePaletteNow to do this because
// we should not do any of the tkUseStaticColors processing while
// in background.
if ( hWnd != (HWND) wParam ) { if ( !tkSystemColorsInUse && NULL != tkhpalette && NULL != SelectPalette( tkhdc, tkhpalette, TRUE ) ) RealizePalette( tkhdc ); }
return (0);
case WM_SYSCOLORCHANGE:
// If the system colors have changed and we have a palette
// for an RGB surface then we need to recompute the static
// color mapping because they might have been changed in
// the process of changing the system colors.
if (tkhdc != NULL && tkhpalette != NULL && PixelFormatDescriptorFromDc(tkhdc, &pfd) && (pfd.dwFlags & PFD_NEED_PALETTE) && pfd.iPixelType == PFD_TYPE_RGBA) { HPALETTE hpalTmp;
hpalTmp = tkhpalette; tkhpalette = NULL; if (CreateRGBPalette(tkhdc) != NULL) { DeleteObject(hpalTmp); ForceRedraw(hWnd); } else { tkhpalette = hpalTmp; } } break; case WM_ACTIVATE:
// If the window is going inactive, the palette must be realized to
// the background. Cannot depend on WM_PALETTECHANGED to be sent since
// the window that comes to the foreground may or may not be palette
// managed.
if ( LOWORD(wParam) == WA_INACTIVE ) { if ( NULL != tkhpalette ) { // Realize as a background palette. Need to call
// RealizePaletteNow rather than RealizePalette directly to
// because it may be necessary to release usage of the static
// system colors.
if ( RealizePaletteNow( tkhdc, tkhpalette, TRUE ) > 0 ) ForceRedraw( hWnd ); } }
// Window is going active. If we are not iconized, realize palette
// to the foreground. If management of the system static colors is
// needed, RealizePaletteNow will take care of it.
else if ( HIWORD(wParam) == 0 ) { if ( NULL != tkhpalette ) { if ( RealizePaletteNow( tkhdc, tkhpalette, FALSE ) > 0 ) ForceRedraw( hWnd );
return (1); } }
// Allow DefWindowProc() to finish the default processing (which includes
// changing the keyboard focus).
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 = (int)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)); }
#if RESTORE_FROM_REGISTRY
/******************************Public*Routine******************************\
* GetRegistrySysColors * * Reads the Control Panel's color settings from the registry and stores * those values in pcr. If we fail to get any value, then the corresponding * entry in pcr is not modified. * * History: * 12-Apr-1995 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
static BOOL GetRegistrySysColors(COLORREF *pcr, int nColors) { BOOL bRet = FALSE; long lRet; HKEY hkSysColors = (HKEY) NULL; int i; DWORD dwDataType; char achColor[64]; DWORD cjColor;
TKASSERT(nColors <= tkNumStaticColors);
// Open the key for the system color settings.
lRet = RegOpenKeyExA(HKEY_CURRENT_USER, "Control Panel\\Colors", 0, KEY_QUERY_VALUE, &hkSysColors);
if ( lRet != ERROR_SUCCESS ) { goto GetRegistrySysColors_exit; }
// Read each system color value. The names are stored in the global
// array of char *, gaszSysClrNames.
for (i = 0; i < nColors; i++) { cjColor = sizeof(achColor); lRet = RegQueryValueExA(hkSysColors, (LPSTR) gaszSysClrNames[i], (LPDWORD) NULL, &dwDataType, (LPBYTE) achColor, &cjColor);
TKASSERT(lRet != ERROR_MORE_DATA);
if ( lRet == ERROR_SUCCESS && dwDataType == REG_SZ ) { DWORD r, g, b;
sscanf(achColor, "%ld %ld %ld", &r, &g, &b); pcr[i] = RGB(r, g, b); } }
bRet = TRUE;
GetRegistrySysColors_exit: if (hkSysColors) RegCloseKey(hkSysColors);
return bRet; } #endif
/******************************Public*Routine******************************\
* GrabStaticEntries * * Support routine for RealizePaletteNow to manage the static system color * usage. * * This function will save the current static system color usage state. * It will fail if: * * 1. TK is not in "sys color in use state but system palette is in * SYSPAL_NOSTATIC mode. This means that another app still possesses * the static system colors. This this happens, GrabStaticEntries * will post a message to cause TK to try again (by calling * DelayPaletteRealization). * * Side effect: * If system colors are changed, then WM_SYSCOLORCHANGE message is * broadcast to all top level windows. * * DelayPaletteRealization may be called in case 2 above, resulting in * a WM_USER message being posted to our message queue. * * Returns: * TRUE if successful, FALSE otherwise (see above). * * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
static BOOL GrabStaticEntries(HDC hdc) { int i; BOOL bRet = FALSE;
// Do nothing if sys colors already in use.
if ( !tkSystemColorsInUse ) { // Take possession only if no other app has the static colors.
// How can we tell? If the return from SetSystemPaletteUse is
// SYSPAL_STATIC, then no other app has the statics. If it is
// SYSPAL_NOSTATIC, someone else has them and we must fail.
//
// SetSystemPaletteUse is properly synchronized internally
// so that it is atomic.
//
// Because we are relying on SetSystemPaletteUse to synchronize TK,
// it is important to observe the following order for grabbing and
// releasing:
//
// Grab call SetSystemPaletteUse and check for SYSPAL_STATIC
// save sys color settings
// set new sys color settings
//
// Release restore sys color settings
// call SetSystemPaletteUse
if ( SetSystemPaletteUse( hdc, SYSPAL_NOSTATIC ) == SYSPAL_STATIC ) { // Save current sys color settings.
for (i = COLOR_SCROLLBAR; i <= COLOR_BTNHIGHLIGHT; i++) gacrSave[i - COLOR_SCROLLBAR] = GetSysColor(i);
// Set b&w sys color settings. Put TK in "sys colors in use" state.
SetSysColors(tkNumStaticColors, gaiStaticIndex, gacrBlackAndWhite); tkSystemColorsInUse = TRUE;
// Inform all other top-level windows of the system color change.
PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
bRet = TRUE; }
// Sleep a little and then post message to try palette realization again
// later.
else { Sleep(0L); DelayPaletteRealization(); } } else bRet = TRUE;
return bRet; }
/******************************Public*Routine******************************\
* ReleaseStaticEntries * * Support routine for RealizePaletteNow to manage the static system color * usage. * * This function will reset the current static system color usage state. * It will fail if: * * 1. TK is not in a "sys colors in use" state. If we are in this case, * then the static system colors do not need to be released. * * Side effect: * If system colors are changed, then WM_SYSCOLORCHANGE message is * broadcast to all top level windows. * * Returns: * TRUE if successful, FALSE otherwise (see above). * * History: * 21-Jul-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
static BOOL ReleaseStaticEntries(HDC hdc) { BOOL bRet = FALSE;
// Do nothing if sys colors not in use.
if ( tkSystemColorsInUse ) { #if RESTORE_FROM_REGISTRY
// Replace saved system colors with registry values. We do it now
// rather than earlier because someone may have changed registry while
// TK app was running in the foreground (very unlikely, but it could
// happen).
//
// Also, we still try to save current setting in GrabStaticEntries so
// that if for some reason we fail to grab one or more of the colors
// from the registry, we can still fall back on what we grabbed via
// GetSysColors (even though there is a chance its the wrong color).
GetRegistrySysColors(gacrSave, tkNumStaticColors); #endif
// Restore the saved system color settings.
SetSysColors(tkNumStaticColors, gaiStaticIndex, gacrSave);
// Return the system palette to SYSPAL_STATIC.
SetSystemPaletteUse( hdc, SYSPAL_STATIC );
// Inform all other top-level windows of the system color change.
PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0);
// Reset the "sys colors in use" state and return success.
tkSystemColorsInUse = FALSE; bRet = TRUE; }
return bRet; }
// Default palette entry flags
#define PALETTE_FLAGS PC_NOCOLLAPSE
// Gamma correction factor * 10
#define GAMMA_CORRECTION 14
// Maximum color distance with 8-bit components
#define MAX_COL_DIST (3*256*256L)
// Number of static colors
#define STATIC_COLORS 20
// Flags used when matching colors
#define EXACT_MATCH 1
#define COLOR_USED 1
// Conversion tables for n bits to eight bits
#if GAMMA_CORRECTION == 10
// These tables are corrected for a gamma of 1.0
static unsigned char abThreeToEight[8] = { 0, 0111 >> 1, 0222 >> 1, 0333 >> 1, 0444 >> 1, 0555 >> 1, 0666 >> 1, 0377 }; static unsigned char abTwoToEight[4] = { 0, 0x55, 0xaa, 0xff }; static unsigned char abOneToEight[2] = { 0, 255 }; #else
// These tables are corrected for a gamma of 1.4
static unsigned char abThreeToEight[8] = { 0, 63, 104, 139, 171, 200, 229, 255 }; static unsigned char abTwoToEight[4] = { 0, 116, 191, 255 }; static unsigned char abOneToEight[2] = { 0, 255 }; #endif
// Table which indicates which colors in a 3-3-2 palette should be
// replaced with the system default colors
#if GAMMA_CORRECTION == 10
static int aiDefaultOverride[STATIC_COLORS] = { 0, 4, 32, 36, 128, 132, 160, 173, 181, 245, 247, 164, 156, 7, 56, 63, 192, 199, 248, 255 }; #else
static int aiDefaultOverride[STATIC_COLORS] = { 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91, 7, 56, 63, 192, 199, 248, 255 }; #endif
static unsigned char ComponentFromIndex(int i, int nbits, int shift) { unsigned char val;
TKASSERT(nbits >= 1 && nbits <= 3); val = i >> shift; switch (nbits) { case 1: return abOneToEight[val & 1];
case 2: return abTwoToEight[val & 3];
case 3: return abThreeToEight[val & 7]; } return 0; }
// System default colors
static PALETTEENTRY apeDefaultPalEntry[STATIC_COLORS] = { { 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 } };
/******************************Public*Routine******************************\
* * UpdateStaticMapping * * Computes the best match between the current system static colors * and a 3-3-2 palette * * History: * Tue Aug 01 18:18:12 1995 -by- Drew Bliss [drewb] * Created * \**************************************************************************/
static void UpdateStaticMapping(PALETTEENTRY *pe332Palette) { HPALETTE hpalStock; int iStatic, i332; int iMinDist, iDist; int iDelta; int iMinEntry; PALETTEENTRY *peStatic, *pe332;
hpalStock = GetStockObject(DEFAULT_PALETTE);
// The system should always have one of these
TKASSERT(hpalStock != NULL); // Make sure there's the correct number of entries
TKASSERT(GetPaletteEntries(hpalStock, 0, 0, NULL) == STATIC_COLORS);
// Get the current static colors
GetPaletteEntries(hpalStock, 0, STATIC_COLORS, apeDefaultPalEntry);
// Zero the flags in the static colors because they are used later
peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { peStatic->peFlags = 0; peStatic++; }
// Zero the flags in the incoming palette because they are used later
pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { pe332->peFlags = 0; pe332++; }
// Try to match each static color exactly
// This saves time by avoiding the least-squares match for each
// exact match
peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { if (peStatic->peRed == pe332->peRed && peStatic->peGreen == pe332->peGreen && peStatic->peBlue == pe332->peBlue) { TKASSERT(pe332->peFlags != COLOR_USED); peStatic->peFlags = EXACT_MATCH; pe332->peFlags = COLOR_USED; aiDefaultOverride[iStatic] = i332; break; }
pe332++; }
peStatic++; } // Match each static color as closely as possible to an entry
// in the 332 palette by minimized the square of the distance
peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { // Skip colors already matched exactly
if (peStatic->peFlags == EXACT_MATCH) { peStatic++; continue; } iMinDist = MAX_COL_DIST+1; #if DBG
iMinEntry = -1; #endif
pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { // Skip colors already used
if (pe332->peFlags == COLOR_USED) { pe332++; continue; } // Compute Euclidean distance squared
iDelta = pe332->peRed-peStatic->peRed; iDist = iDelta*iDelta; iDelta = pe332->peGreen-peStatic->peGreen; iDist += iDelta*iDelta; iDelta = pe332->peBlue-peStatic->peBlue; iDist += iDelta*iDelta;
if (iDist < iMinDist) { iMinDist = iDist; iMinEntry = i332; }
pe332++; }
TKASSERT(iMinEntry != -1);
// Remember the best match
aiDefaultOverride[iStatic] = iMinEntry; pe332Palette[iMinEntry].peFlags = COLOR_USED; peStatic++; }
// Zero the flags in the static colors because they may have been
// set. We want them to be zero so the colors can be remapped
peStatic = apeDefaultPalEntry; for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { peStatic->peFlags = 0; peStatic++; }
// Reset the 332 flags because we may have set them
pe332 = pe332Palette; for (i332 = 0; i332 < 256; i332++) { pe332->peFlags = PALETTE_FLAGS; pe332++; }
#if 0
for (iStatic = 0; iStatic < STATIC_COLORS; iStatic++) { PrintMessage("Static color %2d maps to %d\n", iStatic, aiDefaultOverride[iStatic]); } #endif
}
/******************************Public*Routine******************************\
* FillRgbPaletteEntries * * Fills a PALETTEENTRY array with values required for a logical rgb palette. * If tkSetStaticColorUsage has been called with TRUE, the static system * colors will be overridden. Otherwise, the PALETTEENTRY array will be * fixed up to contain the default static system colors. * * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
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 = PALETTE_FLAGS; }
if ( 256 == Count) { // If app set static system color usage for fixed palette support,
// setup to take over the static colors. Otherwise, fixup the
// static system colors.
if ( tkUseStaticColors ) { // Black and white already exist as the only remaining static
// colors. Let those remap. All others should be put into
// the palette (i.e., set PC_NOCOLLAPSE).
Entries[0].peFlags = 0; Entries[255].peFlags = 0; } else { // The defaultOverride array is computed assuming a 332
// palette where red has zero shift, etc.
if ( (3 == Pfd->cRedBits) && (0 == Pfd->cRedShift) && (3 == Pfd->cGreenBits) && (3 == Pfd->cGreenShift) && (2 == Pfd->cBlueBits) && (6 == Pfd->cBlueShift) ) { UpdateStaticMapping(Entries); for ( i = 0 ; i < STATIC_COLORS ; i++) { Entries[aiDefaultOverride[i]] = apeDefaultPalEntry[i]; } } } } } return( Entries ); }
/******************************Public*Routine******************************\
* FlushPalette * * Because of Win 3.1 compatibility, GDI palette mapping always starts * at zero and stops at the first exact match. So if there are duplicates, * the higher colors aren't mapped to--which is often a problem if we * are trying to make to any of the upper 10 static colors. To work around * this, we flush the palette to all black. * * This only needs to be done for the 8BPP (256 color) case. * \**************************************************************************/
static void FlushPalette(HDC hdc, int nColors) { LOGPALETTE *pPal; HPALETTE hpal, hpalOld; int i;
if (nColors == 256) { pPal = (LOGPALETTE *) LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, sizeof(LOGPALETTE) + nColors * sizeof(PALETTEENTRY));
if (pPal) { pPal->palVersion = 0x300; pPal->palNumEntries = (WORD)nColors;
// Mark everything PC_NOCOLLAPSE and PC_RESERVED to force every thing
// into the palette. Colors are already black because we zero initialized
// during memory allocation.
for (i = 0; i < nColors; i++) { pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE | PC_RESERVED; }
hpal = CreatePalette(pPal); LocalFree(pPal);
hpalOld = SelectPalette(hdc, hpal, FALSE); RealizePalette(hdc);
SelectPalette(hdc, hpalOld, FALSE); DeleteObject(hpal); } } }
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->iPixelType == PFD_TYPE_RGBA) && (pPfd->dwFlags & PFD_NEED_PALETTE) ) { /*
* Note how palette is to be realized. Take over the * system colors if either the pixel format requires it * or the app wants it. */ tkUseStaticColors = ( pPfd->dwFlags & PFD_NEED_SYSTEM_PALETTE ) || TK_USE_FIXED_332_PAL(windInfo.type);
Count = 1 << pPfd->cColorBits; LogPalette = AllocateMemory( sizeof(LOGPALETTE) + Count * sizeof(PALETTEENTRY));
if ( NULL != LogPalette ) { LogPalette->palVersion = 0x300; LogPalette->palNumEntries = (WORD)Count;
FillRgbPaletteEntries( pPfd, &LogPalette->palPalEntry[0], Count );
tkhpalette = CreatePalette(LogPalette); FreeMemory(LogPalette);
FlushPalette(Dc, Count); RealizePaletteNow( Dc, tkhpalette, FALSE ); } } } } return( tkhpalette ); }
static HPALETTE CreateCIPalette( HDC Dc ) { PIXELFORMATDESCRIPTOR Pfd; LOGPALETTE *LogicalPalette; HPALETTE StockPalette; UINT PaletteSize, StockPaletteSize, EntriesToCopy;
if ( (Dc != NULL) && (NULL == tkhpalette) ) { if ( PixelFormatDescriptorFromDc( Dc, &Pfd ) ) { if ( Pfd.iPixelType == PFD_TYPE_COLORINDEX ) { /*
* Note how palette is to be realized (Is this the correct place to do this?) */ tkUseStaticColors = ( Pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ) || TK_USE_FIXED_332_PAL(windInfo.type);
/*
* 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 = (WORD)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 );
/*
* If we are taking possession of the system colors, * must guarantee that 0 and 255 are black and white * (respectively). */
if ( tkUseStaticColors && PaletteSize == 256 ) { int i;
LogicalPalette->palPalEntry[0].peRed = LogicalPalette->palPalEntry[0].peGreen = LogicalPalette->palPalEntry[0].peBlue = 0x00;
LogicalPalette->palPalEntry[255].peRed = LogicalPalette->palPalEntry[255].peGreen = LogicalPalette->palPalEntry[255].peBlue = 0xFF;
LogicalPalette->palPalEntry[0].peFlags = LogicalPalette->palPalEntry[255].peFlags = 0;
/*
* All other entries should be remappable, * so mark them as PC_NOCOLLAPSE. */ for ( i = 1; i < 255; i++ ) LogicalPalette->palPalEntry[i].peFlags = PC_NOCOLLAPSE; }
tkhpalette = CreatePalette(LogicalPalette);
FreeMemory(LogicalPalette);
RealizePaletteNow( Dc, tkhpalette, FALSE ); } } } } return( tkhpalette ); }
static BOOL FindPixelFormat(HDC hdc, GLenum type) { PIXELFORMATDESCRIPTOR pfd; int PfdIndex; BOOL Result = FALSE;
if ( TK_MINIMUM_CRITERIA == windInfo.dmPolicy ) PfdIndex = FindBestPixelFormat(hdc, type, &pfd); else if ( TK_EXACT_MATCH == windInfo.dmPolicy ) PfdIndex = FindExactPixelFormat(hdc, type, &pfd); else if ( IsPixelFormatValid(hdc, windInfo.ipfd, &pfd) ) PfdIndex = windInfo.ipfd; else PfdIndex = 0;
if ( PfdIndex ) { if ( SetPixelFormat(hdc, PfdIndex, &pfd) ) { /*
* 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("Selecting a pixel format failed\n"); } return(Result); }
static int FindBestPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd) { PIXELFORMATDESCRIPTOR pfd;
pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
if (TK_IS_DOUBLE(type)) pfd.dwFlags |= PFD_DOUBLEBUFFER;
if (TK_IS_INDEX(type)) { pfd.iPixelType = PFD_TYPE_COLORINDEX; pfd.cColorBits = 8; } else { pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; }
if (TK_HAS_ALPHA(type)) pfd.cAlphaBits = 8; else pfd.cAlphaBits = 0;
if (TK_HAS_ACCUM(type)) pfd.cAccumBits = pfd.cColorBits + pfd.cAlphaBits; else pfd.cAccumBits = 0;
if (TK_HAS_DEPTH(type)) { if (TK_IS_DEPTH16(type)) pfd.cDepthBits = 16; else pfd.cDepthBits = 24; } else { pfd.cDepthBits = 0; }
if (TK_HAS_STENCIL(type)) pfd.cStencilBits = 4; else pfd.cStencilBits = 0;
pfd.cAuxBuffers = 0; pfd.iLayerType = PFD_MAIN_PLANE; *ppfd = pfd;
return ( ChoosePixelFormat(hdc, &pfd) ); }
static int FindExactPixelFormat(HDC hdc, GLenum type, PIXELFORMATDESCRIPTOR *ppfd) { int i, MaxPFDs, Score, BestScore, BestPFD; PIXELFORMATDESCRIPTOR pfd;
i = 1; BestPFD = BestScore = 0; do { MaxPFDs = DescribePixelFormat(hdc, i, sizeof(pfd), &pfd); if ( MaxPFDs <= 0 ) return ( 0 );
Score = 0; if ( !( ( pfd.dwFlags & PFD_DRAW_TO_WINDOW ) && ( pfd.dwFlags & PFD_SUPPORT_OPENGL ) ) ) continue; if ( pfd.iLayerType != PFD_MAIN_PLANE ) continue; if ( ( pfd.iPixelType == PFD_TYPE_RGBA ) && ( TK_IS_INDEX(type) ) ) continue; if ( ( pfd.iPixelType == PFD_TYPE_COLORINDEX ) && ( TK_IS_RGB(type) ) ) continue; if ( ( pfd.dwFlags & PFD_DOUBLEBUFFER ) && ( TK_IS_SINGLE(type) ) ) continue; if ( !( pfd.dwFlags & PFD_DOUBLEBUFFER ) && ( TK_IS_DOUBLE(type) ) ) continue;
/* If accum requested then accum rgb size must be > 0 */ /* If alpha requested then alpha size must be > 0 */ /* if accum & alpha requested then accum alpha size must be > 0 */ if ( TK_IS_RGB(type) ) { if ( TK_HAS_ACCUM(type) ) { if ( pfd.cAccumBits <= 0 ) continue; } else { if ( pfd.cAccumBits > 0 ) continue; }
if ( TK_HAS_ALPHA(type) ) { if ( pfd.cAlphaBits <= 0 ) continue; if ( TK_HAS_ACCUM(type) && pfd.cAccumAlphaBits <= 0 ) continue; } else { if ( pfd.cAlphaBits > 0 ) continue; } }
if ( TK_HAS_DEPTH(type) ) { if ( pfd.cDepthBits <= 0 ) continue; } else { if ( pfd.cDepthBits > 0 ) continue; }
if ( TK_HAS_STENCIL(type) ) { if ( pfd.cStencilBits <= 0 ) continue; } else { if ( pfd.cStencilBits > 0 ) continue; }
Score = pfd.cColorBits;
if (Score > BestScore) { BestScore = Score; BestPFD = i; *ppfd = pfd; } } while (++i <= MaxPFDs);
return ( BestPFD ); }
static BOOL IsPixelFormatValid(HDC hdc, int ipfd, PIXELFORMATDESCRIPTOR *ppfd) { if ( ipfd > 0 ) { if ( ipfd <= DescribePixelFormat(hdc, ipfd, sizeof(*ppfd), ppfd) ) { if ( ( ppfd->dwFlags & PFD_DRAW_TO_WINDOW ) && ( ppfd->dwFlags & PFD_SUPPORT_OPENGL ) ) { return ( TRUE ); } } } return ( FALSE ); }
static void PrintMessage( const char *Format, ... ) { va_list ArgList; char Buffer[256];
va_start(ArgList, Format); vsprintf(Buffer, Format, ArgList); va_end(ArgList);
MESSAGEBOX(GetFocus(), 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); } }
/******************************Public*Routine******************************\
* RealizePaletteNow * * Select the given palette in background or foreground mode (as specified * by the bForceBackground flag), and realize the palette. * * If static system color usage is set, the system colors are replaced. * * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
long RealizePaletteNow( HDC Dc, HPALETTE Palette, BOOL bForceBackground ) { long Result = -1; BOOL bHaveSysPal = TRUE;
TKASSERT( NULL!=Dc ); TKASSERT( NULL!=Palette );
// If static system color usage is set, prepare to take over the
// system palette.
if ( tkUseStaticColors ) { // If foreground, take over the static colors. If background, release
// the static colors.
if ( !bForceBackground ) { // If GrabStaticEntries succeeds, then it is OK to take over the
// static colors. If not, then GrabStaticEntries will have
// posted a WM_USER message for us to try again later.
bHaveSysPal = GrabStaticEntries( Dc ); } else { // If we are currently using the system colors (tkSystemColorsInUse)
// and RealizePaletteNow was called with bForceBackground set, we
// are being deactivated and must release the static system colors.
ReleaseStaticEntries( Dc ); }
// Rerealize the palette.
//
// If set to TRUE, bForceBackground will force the palette to be realized
// as a background palette, regardless of focus. This will happen anyway
// if the TK window does not have the keyboard focus.
if ( (bForceBackground || bHaveSysPal) && UnrealizeObject( Palette ) && NULL != SelectPalette( Dc, Palette, bForceBackground ) ) { Result = RealizePalette( Dc ); } } else { if ( NULL != SelectPalette( Dc, Palette, FALSE ) ) { Result = RealizePalette( Dc ); } }
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;
// Cleanup the palette.
if ( NULL != tkhpalette ) { // If static system color usage is set, restore the system colors.
if ( tkUseStaticColors ) { RealizePaletteNow( tkhdc, GetStockObject(DEFAULT_PALETTE), TRUE ); } else { if ( hStock = GetStockObject( DEFAULT_PALETTE ) ) SelectPalette( tkhdc, hStock, FALSE ); }
DeleteObject( tkhpalette ); }
// Cleanup the RC.
if ( NULL != tkhrc ) { wglMakeCurrent( tkhdc, NULL ); // Release first...
wglDeleteContext( tkhrc ); // then delete.
}
// Cleanup the DC.
if ( NULL != tkhdc ) { ReleaseDC( tkhwnd, tkhdc ); }
// Be really nice and reset global values.
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 "); if (ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE) DbgPrintf("PFD_NEED_SYSTEM_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 */
|