|
|
/*
* (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 <stdarg.h>
#include <windows.h>
#include "ctk.h"
//#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 long NoOpExecFunc( TK_EventRec *pEvent );
static long (*ExecFunc)(TK_EventRec *pEvent ) = NoOpExecFunc;
static TK_EventRec tkEvent = { TK_EVENT_EXPOSE, { 0, 0, 0, 0 } };
static HWND tkhwnd = NULL; static HDC tkhdc = NULL; static HDC tkhmemdc = NULL; static HGLRC tkhrc = NULL; static HPALETTE tkhPalette = NULL; static char *lpszClassName = "ctkLibWClass";
static long tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam); static VOID StorePixelFormatsIDs( TK_VisualIDsRec *VisualID ); static void PrintMessage( const char *Format, ... ); static HGLRC CreateAndMakeContextCurrent( HDC Dc ); static void CleanUp( void ); static void DestroyThisWindow( HWND Window ); static short FindPixelFormat( HDC Dc, long FormatType ); static short GetPixelFormatInformation( HDC Dc, TK_WindowRec *tkWr, PIXELFORMATDESCRIPTOR *Pfd ); static TK_WindowRec *PIXELFORMATDESCRIPTOR_To_TK_WindowRec ( TK_WindowRec *WindowRec, PIXELFORMATDESCRIPTOR *Pfd );
HDC CreatePixelMapDC(HDC,TK_WindowRec *,UINT, int, LPPIXELFORMATDESCRIPTOR); BOOL DeletePixelMapDC(HDC);
// Fixed palette support.
#define BLACK PALETTERGB(0,0,0)
#define WHITE PALETTERGB(255,255,255)
#define NUM_STATIC_COLORS (COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1)
// 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.
static BOOL tkSystemColorsInUse = FALSE;
// TRUE if static colors have been saved
static BOOL tkStaticSaved = FALSE;
// saved system static colors
static COLORREF gacrSave[NUM_STATIC_COLORS];
// new B&W system static colors
static COLORREF gacrBlackAndWhite[NUM_STATIC_COLORS] = { 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
}; static INT gaiStaticIndex[NUM_STATIC_COLORS] = { 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 };
static VOID SaveStaticEntries(HDC); static VOID UseStaticEntries(HDC); static VOID RestoreStaticEntries(HDC);
/********************************************************************/
void tkCloseWindow(void) { DestroyThisWindow(tkhwnd); }
/********************************************************************/
long tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam) { PAINTSTRUCT Paint;
switch (message) { case WM_PAINT: BeginPaint( hWnd, &Paint );
if (!(*ExecFunc)(&tkEvent)) { tkCloseWindow(); }
EndPaint( hWnd, &Paint );
break;
case WM_GETMINMAXINFO: { LPMINMAXINFO lpmmi = (LPMINMAXINFO) lParam;
lpmmi->ptMinTrackSize.x = 1; lpmmi->ptMinTrackSize.y = 1;
} return 0;
case WM_DESTROY:
CleanUp(); PostQuitMessage(TRUE); return(DefWindowProc( hWnd, message, wParam, lParam)); } return(DefWindowProc( hWnd, message, wParam, lParam)); }
void tkExec( long (*Func)(TK_EventRec *pEvent) ) { MSG Message;
// WM_SIZE gets delivered before we get here!
if ( NULL != Func ) { ExecFunc = Func; /* save a pointer to the drawing function */ } else { ExecFunc = NoOpExecFunc; }
while (GL_TRUE) { if (GetMessage(&Message, NULL, 0, 0) ) { TranslateMessage(&Message); DispatchMessage(&Message); } else { break; } } }
static long NoOpExecFunc( TK_EventRec *pEvent ) { return(1); }
/********************************************************************/
// Default palette entry flags
#define PALETTE_FLAGS PC_NOCOLLAPSE
// Gamma correction factor * 10
#define GAMMA_CORRECTION 10
// 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]; } }
// 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
}
#define SwapPalE(i,j) { \
PALETTEENTRY palE; \ palE = pPal->palPalEntry[i]; \ pPal->palPalEntry[i] = pPal->palPalEntry[j]; \ pPal->palPalEntry[j] = palE; }
/******************************Public*Routine******************************\
* SaveStaticEntries * * Save the current static system color settings. This should be called * prior to UseStaticEntries() to initialize gacrSave. Once gacrSave is * called, RestoreStaticEntries() can be called to restore the static system * color settings. * * The colors can be saved only if the tk palette is the background palette. * This check is done so that we do not accidentally replace the saved * settings with the B&W settings used when static system color usage is set * and the fixed 332 rgb palette is realized in the foreground. * * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
static VOID SaveStaticEntries(HDC hdc) { int i;
if ( !tkSystemColorsInUse ) { for (i = COLOR_SCROLLBAR; i <= COLOR_BTNHIGHLIGHT; i++) gacrSave[i - COLOR_SCROLLBAR] = GetSysColor(i);
tkStaticSaved = TRUE; } }
/******************************Public*Routine******************************\
* UseStaticEntries * * Replace the static system color settings with black and white color * settings. This is used when taking over the system static colors to * realize a 332 rgb fixed palette. Realizing such a palette in the * foreground screws up the system colors (menus, titles, scrollbars, etc.). * Setting the system colors to B&W, while not perfect (some elements of * the UI are DIBs and will not be effected by this--for example, the * system menu (or "coin slot") button), is somewhat better. * * Side effect: * WM_SYSCOLORCHANGE message is broadcast to all top-level windows to * inform them of the system palette change. * * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
static VOID UseStaticEntries(HDC hdc) { SetSysColors(NUM_STATIC_COLORS, gaiStaticIndex, gacrBlackAndWhite); tkSystemColorsInUse = TRUE;
PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); }
/******************************Public*Routine******************************\
* RestoreStaticEntries * * Restores the static system colors to the settings that existed at the * time SaveStaticEntries was called. * * Side effect: * WM_SYSCOLORCHANGE message is broadcast to all top-level windows to * inform them of the system palette change. * * History: * 26-Apr-1994 -by- Gilman Wong [gilmanw] * Wrote it. \**************************************************************************/
static VOID RestoreStaticEntries(HDC hdc) { // Must check to see that SaveStaticEntries was called at least once.
// Otherwise, a bad tk app might mess up the system colors.
if ( tkStaticSaved ) { SetSysColors(NUM_STATIC_COLORS, gaiStaticIndex, gacrSave); tkSystemColorsInUse = FALSE;
PostMessage(HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0); } }
/******************************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 = 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 void CreateRGBPalette(HDC hdc, PIXELFORMATDESCRIPTOR *ppfd ) { LOGPALETTE *pPal; int n, i;
tkUseStaticColors = ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE;
// PFD_NEED_PALETTE should not be set if PFD_TYPE_COLORINDEX mode.
TKASSERT( (ppfd->iPixelType == PFD_TYPE_COLORINDEX) ? ((ppfd->dwFlags & PFD_NEED_PALETTE) == 0) : TRUE );
if (ppfd->dwFlags & PFD_NEED_PALETTE) { if (!tkhPalette) { n = 1 << ppfd->cColorBits; pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + n * sizeof(PALETTEENTRY)); pPal->palVersion = 0x300; pPal->palNumEntries = n; for (i=0; i<n; i++) { pPal->palPalEntry[i].peRed = ComponentFromIndex(i, ppfd->cRedBits, ppfd->cRedShift); pPal->palPalEntry[i].peGreen = ComponentFromIndex(i, ppfd->cGreenBits, ppfd->cGreenShift); pPal->palPalEntry[i].peBlue = ComponentFromIndex(i, ppfd->cBlueBits, ppfd->cBlueShift); pPal->palPalEntry[i].peFlags = PALETTE_FLAGS; }
if ( 256 == n ) { 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., peFlags == PC_NOCOLLAPSE).
pPal->palPalEntry[0].peFlags = 0; pPal->palPalEntry[255].peFlags = 0;
SaveStaticEntries(hdc); SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); } else { if ( (3 == ppfd->cRedBits) && (0 == ppfd->cRedShift) && (3 == ppfd->cGreenBits) && (3 == ppfd->cGreenShift) && (2 == ppfd->cBlueBits) && (6 == ppfd->cBlueShift) ) { UpdateStaticMapping(pPal->palPalEntry); for (i = 0; i < STATIC_COLORS; i++) { pPal->palPalEntry[aiDefaultOverride[i]] = apeDefaultPalEntry[i]; } } } } tkhPalette = CreatePalette(pPal); LocalFree(pPal); }
FlushPalette(hdc, n);
SelectPalette(hdc, tkhPalette, FALSE); n = RealizePalette(hdc);
if ( tkUseStaticColors ) UseStaticEntries(hdc); }
// set up logical indices for CI mode
else if( ppfd->iPixelType == PFD_TYPE_COLORINDEX ) { if (!tkhPalette) { if (ppfd->cColorBits == 4) {
// for 4-bit, create a logical palette with 16 entries
n = 16; pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + n * sizeof(PALETTEENTRY)); pPal->palVersion = 0x300; pPal->palNumEntries = n;
for( i = 0; i < 8; i ++) { pPal->palPalEntry[i] = apeDefaultPalEntry[i]; } for (i = 8; i < 16; i++) { pPal->palPalEntry[i] = apeDefaultPalEntry[i+4]; }
// conform expects indices 0..3 to be BLACK,RED,GREEN,BLUE, so
// we rearrange the table for now.
SwapPalE(1,9) SwapPalE(2,10) SwapPalE(3,12)
} else if (ppfd->cColorBits == 8) {
// for 8-bit, create a logical palette with 256 entries, making
// sure that the 20 system colors exist in the palette
n = 256; pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + n * sizeof(PALETTEENTRY)); pPal->palVersion = 0x300; pPal->palNumEntries = n;
tkhPalette = GetStockObject (DEFAULT_PALETTE);
// start by copying default palette into new one
GetPaletteEntries( tkhPalette, 0, 20, pPal->palPalEntry);
// conform expects indices 0..3 to be BLACK,RED,GREEN,BLUE, so
// we rearrange the table for now.
SwapPalE(1,13) SwapPalE(2,14) SwapPalE(3,16)
for( i = 20; i < n; i ++) { pPal->palPalEntry[i].peRed = (BYTE) (i - 1); pPal->palPalEntry[i].peGreen = (BYTE) (i - 2); pPal->palPalEntry[i].peBlue = (BYTE) (i - 3); pPal->palPalEntry[i].peFlags = (BYTE) 0; }
// If we are taking possession of the system colors,
// must guarantee that 0 and 255 are black and white
// (respectively), so that they can remap to the
// remaining two static colors. All other entries must
// be marked as PC_NOCOLLAPSE.
if ( tkUseStaticColors ) { pPal->palPalEntry[0].peRed = pPal->palPalEntry[0].peGreen = pPal->palPalEntry[0].peBlue = 0x00;
pPal->palPalEntry[255].peRed = pPal->palPalEntry[255].peGreen = pPal->palPalEntry[255].peBlue = 0xFF;
pPal->palPalEntry[0].peFlags = pPal->palPalEntry[255].peFlags = 0;
for ( i = 1 ; i < 255 ; i++ ) { pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
// 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.
if ( pPal->palPalEntry[i].peRed == 0xFF && pPal->palPalEntry[i].peGreen == 0xFF && pPal->palPalEntry[i].peBlue == 0xFF ) { pPal->palPalEntry[i].peFlags |= PC_RESERVED; } }
SaveStaticEntries(hdc); SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); }
} else { // for pixel formats > 8 bits deep, create a logical palette with
// 4096 entries
n = 4096; pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) + n * sizeof(PALETTEENTRY)); pPal->palVersion = 0x300; pPal->palNumEntries = n;
for( i = 0; i < n; i ++) { pPal->palPalEntry[i].peRed = (BYTE) ((i & 0x000f) << 4); pPal->palPalEntry[i].peGreen = (BYTE) (i & 0x00f0); pPal->palPalEntry[i].peBlue = (BYTE) ((i & 0x0f00) >> 4); pPal->palPalEntry[i].peFlags = (BYTE) 0; }
// conform expects indices 0..3 to be BLACK,RED,GREEN,BLUE, so
// we rearrange the table for now.
SwapPalE(1,0xf) SwapPalE(2,0xf0) SwapPalE(3,0xf00) }
tkhPalette = CreatePalette(pPal); LocalFree(pPal); }
FlushPalette(hdc, n);
TKASSERT(tkhPalette != NULL);
SelectPalette(hdc, tkhPalette, FALSE); n = RealizePalette(hdc);
if ( tkUseStaticColors ) UseStaticEntries(hdc); } }
void ShowPixelFormat(HDC hdc) { PIXELFORMATDESCRIPTOR pfd, *ppfd; int format;
ppfd = &pfd; format = GetPixelFormat(hdc); DescribePixelFormat(hdc, format, sizeof(PIXELFORMATDESCRIPTOR), ppfd);
printf("Pixel format %d\n", format); printf(" dwFlags - 0x%x", ppfd->dwFlags); if (ppfd->dwFlags & PFD_DOUBLEBUFFER) printf("PFD_DOUBLEBUFFER "); if (ppfd->dwFlags & PFD_STEREO) printf("PFD_STEREO "); if (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) printf("PFD_DRAW_TO_WINDOW "); if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) printf("PFD_DRAW_TO_BITMAP "); if (ppfd->dwFlags & PFD_SUPPORT_GDI) printf("PFD_SUPPORT_GDI "); if (ppfd->dwFlags & PFD_SUPPORT_OPENGL) printf("PFD_SUPPORT_OPENGL "); if (ppfd->dwFlags & PFD_GENERIC_FORMAT) printf("PFD_GENERIC_FORMAT "); if (ppfd->dwFlags & PFD_NEED_PALETTE) printf("PFD_NEED_PALETTE "); if (ppfd->dwFlags & PFD_NEED_SYSTEM_PALETTE) printf("PFD_NEED_SYSTEM_PALETTE "); printf("\n"); printf(" iPixelType - %d", ppfd->iPixelType); if (ppfd->iPixelType == PFD_TYPE_RGBA) printf("PGD_TYPE_RGBA\n"); if (ppfd->iPixelType == PFD_TYPE_COLORINDEX) printf("PGD_TYPE_COLORINDEX\n"); printf(" cColorBits - %d\n", ppfd->cColorBits); printf(" cRedBits - %d\n", ppfd->cRedBits); printf(" cRedShift - %d\n", ppfd->cRedShift); printf(" cGreenBits - %d\n", ppfd->cGreenBits); printf(" cGreenShift - %d\n", ppfd->cGreenShift); printf(" cBlueBits - %d\n", ppfd->cBlueBits); printf(" cBlueShift - %d\n", ppfd->cBlueShift); printf(" cAlphaBits - %d\n", ppfd->cAlphaBits); printf(" cAlphaShift - 0x%x\n", ppfd->cAlphaShift); printf(" cAccumBits - %d\n", ppfd->cAccumBits); printf(" cAccumRedBits - %d\n", ppfd->cAccumRedBits); printf(" cAccumGreenBits - %d\n", ppfd->cAccumGreenBits); printf(" cAccumBlueBits - %d\n", ppfd->cAccumBlueBits); printf(" cAccumAlphaBits - %d\n", ppfd->cAccumAlphaBits); printf(" cDepthBits - %d\n", ppfd->cDepthBits); printf(" cStencilBits - %d\n", ppfd->cStencilBits); printf(" cAuxBuffers - %d\n", ppfd->cAuxBuffers); printf(" iLayerType - %d\n", ppfd->iLayerType); printf(" bReserved - %d\n", ppfd->bReserved); printf(" dwLayerMask - 0x%x\n", ppfd->dwLayerMask); printf(" dwVisibleMask - 0x%x\n", ppfd->dwVisibleMask); printf(" dwDamageMask - 0x%x\n", ppfd->dwDamageMask); }
/*
* This function returns the pixel format index chosen * by choose pixel format. */
static short FindPixelFormat( HDC Dc, long FormatType ) { PIXELFORMATDESCRIPTOR Pfd; short PfdIndex;
Pfd.nSize = sizeof(Pfd); Pfd.nVersion = 1; Pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; Pfd.dwLayerMask = PFD_MAIN_PLANE;
if (TK_WIND_IS_DB(FormatType)) { Pfd.dwFlags |= PFD_DOUBLEBUFFER; }
if (TK_WIND_IS_CI(FormatType)) { Pfd.iPixelType = PFD_TYPE_COLORINDEX; Pfd.cColorBits = 8; }
if (TK_WIND_IS_RGB(FormatType)) { Pfd.iPixelType = PFD_TYPE_RGBA; Pfd.cColorBits = 24; }
if (TK_WIND_ACCUM & FormatType) { Pfd.cAccumBits = Pfd.cColorBits; } else { Pfd.cAccumBits = 0; }
if (TK_WIND_Z & FormatType) { Pfd.cDepthBits = 32; } else if (TK_WIND_Z16 & FormatType) { Pfd.cDepthBits = 16; } else { Pfd.cDepthBits = 0; }
if (TK_WIND_STENCIL & FormatType) { Pfd.cStencilBits = 8; } else { Pfd.cStencilBits = 0; }
PfdIndex = ChoosePixelFormat( Dc, &Pfd );
return( PfdIndex ); }
// Initialize a window, create a rendering context for that window
// only allow CI on palette devices, RGB on true color devices
// current server turns on Z, but no accum or stencil
// When SetPixelFormat is implemented, remove all of these restrictions
long tkNewWindow(TK_WindowRec *tkWr) { WNDCLASS wndclass; RECT WinRect; HANDLE hInstance; PIXELFORMATDESCRIPTOR Pfd; short PfdIndex; int nPixelFormats; BOOL Result = FALSE; HDC tmphdc = NULL;
TKASSERT(NULL==tkhwnd ); TKASSERT(NULL==tkhdc ); TKASSERT(NULL==tkhrc ); TKASSERT(NULL==tkhPalette ); TKASSERT(ExecFunc==NoOpExecFunc );
hInstance = GetModuleHandle(NULL);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 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(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = lpszClassName;
RegisterClass(&wndclass);
// Make window large enough to hold a client area as large as tkWr
WinRect.left = (tkWr->x == CW_USEDEFAULT) ? 0 : tkWr->x; WinRect.top = (tkWr->y == CW_USEDEFAULT) ? 0 : tkWr->y; WinRect.right = WinRect.left + tkWr->width; WinRect.bottom = WinRect.top + tkWr->height;
AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
tkhwnd = CreateWindowEx( WS_EX_TOPMOST, lpszClassName, tkWr->name, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, (tkWr->x == CW_USEDEFAULT ? CW_USEDEFAULT : WinRect.left), (tkWr->y == CW_USEDEFAULT ? CW_USEDEFAULT : WinRect.top), WinRect.right - WinRect.left, WinRect.bottom - WinRect.top, NULL, NULL, hInstance, NULL);
/*
* Fixup window size in case minimum tracking size did something. */ GetClientRect(tkhwnd, &WinRect); tkWr->width = WinRect.right; tkWr->height = WinRect.bottom;
if ( NULL != tkhwnd ) { tkhdc = GetDC(tkhwnd);
if (tkWr->type == TK_WIND_VISUAL) { nPixelFormats = DescribePixelFormat(tkhdc,abs(tkWr->info),sizeof(PIXELFORMATDESCRIPTOR),&Pfd);
// If tkWr->info is negative, this is a bitmap request
// Otherwise, it is a display request
if (tkWr->info < 0) { tkWr->info = -(tkWr->info);
if (!(Pfd.dwFlags & PFD_DRAW_TO_BITMAP)) goto tkNewWindow_exit;
tkhmemdc = CreatePixelMapDC(tkhdc, tkWr, DIB_RGB_COLORS, Pfd.cColorBits, &Pfd); tmphdc = tkhmemdc; } else { if (!(Pfd.dwFlags & PFD_DRAW_TO_WINDOW)) goto tkNewWindow_exit;
tmphdc = tkhdc; } } else tmphdc = tkhdc;
/*
* XXXX * I would like to delay the show window a little longer * but this causes an exception, during clears. New code * will fix this. */
ShowWindow(tkhwnd, SW_SHOWDEFAULT);
PfdIndex = GetPixelFormatInformation( tmphdc, tkWr, &Pfd );
if ( PfdIndex ) { if ( SetPixelFormat( tmphdc, PfdIndex, &Pfd ) ) { /*
* Would be nice to delay until then, alas, we have a bug */
ShowPixelFormat(tmphdc);
/*
* If the tmp DC is a memory DC, create and * realize the palette for the screen DC first. * Memory DC palettes are realized as background * palettes, so we must put the palette in the * foreground via the screen DC before we muck * around with the memory DC. */ if (tmphdc != tkhdc) CreateRGBPalette( tkhdc, &Pfd );
CreateRGBPalette( tmphdc, &Pfd ); tkhrc = CreateAndMakeContextCurrent( tmphdc );
if ( NULL != tkhrc ) { ShowWindow(tkhwnd, SW_SHOWDEFAULT);
/*
* Convert information in the pixel format descriptor * to the TK_WindowRec format */
PIXELFORMATDESCRIPTOR_To_TK_WindowRec ( tkWr, &Pfd );
Result = TRUE; } } } }
tkNewWindow_exit: if ( FALSE == Result ) { /*
* Something Failed, Destroy this window */
DestroyThisWindow(tkhwnd);
/*
* Process all the messages */
tkExec( (long (*)(TK_EventRec *pEvent))NULL ); } return( Result ); }
/*
* If a function fails, this function will clean itself up */
static HGLRC CreateAndMakeContextCurrent( HDC Dc ) { HGLRC Rc = NULL;
/* Create a Rendering Context */
Rc = wglCreateContext( Dc );
if ( NULL != Rc ) { /* Make it Current */
if ( FALSE == wglMakeCurrent( Dc, Rc ) ) { wglDeleteContext( Rc ); Rc = NULL; } } return( Rc ); }
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 ) { if ( NULL != tkhwnd ) { if ( NULL != tkhdc ) { if ( NULL != tkhPalette ) { DeleteObject( SelectObject( tkhdc, GetStockObject(DEFAULT_PALETTE) ));
if ( tkUseStaticColors ) { SetSystemPaletteUse( tkhdc, SYSPAL_STATIC ); RealizePalette( tkhdc ); RestoreStaticEntries( tkhdc ); }
tkhPalette = NULL; }
if ( NULL != tkhrc ) { wglMakeCurrent( tkhdc, NULL ); // No current context
wglDeleteContext(tkhrc); // Delete this context
tkhrc = NULL; } ReleaseDC( tkhwnd, tkhdc ); tkhdc = NULL; } tkhwnd = NULL; } ExecFunc = NoOpExecFunc; } /*******************************************************************/
void tkQuit(void) { TKASSERT(NULL==tkhwnd ); TKASSERT(NULL==tkhdc ); TKASSERT(NULL==tkhrc ); TKASSERT(NULL==tkhPalette );
ExitProcess(0); }
/*******************************************************************/
void tkSwapBuffers(void) { SwapBuffers(tkhdc); }
/*******************************************************************/
void tkGet(long item, void *data) { if (item == TK_SCREENIMAGE) { // XXXX We will need this the covglx and conformw
OutputDebugString("tkGet(TK_SCREENIMAGE) is not implemented\n"); } else if (item == TK_VISUALIDS) { StorePixelFormatsIDs( data ); } }
static VOID StorePixelFormatsIDs( TK_VisualIDsRec *VisualID ) { HDC hDc; int AvailableIds; int Id; PIXELFORMATDESCRIPTOR Pfd;
/*
* Get a DC for the display */
hDc = GetDC(NULL);
/*
* Get the total number of pixel formats */
AvailableIds = DescribePixelFormat( hDc, 0, 0, NULL );
/*
* Store the IDs in the structure. * The first Id starts at one. */
VisualID->count = 0;
for ( Id = 1 ; Id <= AvailableIds ; Id++ ) { /*
* Make sure you don't overrun the structure's buffer */
if ( Id <= ((sizeof(((TK_VisualIDsRec *)NULL)->IDs) / sizeof(((TK_VisualIDsRec *)NULL)->IDs[0]))) ) { if ( DescribePixelFormat( hDc, Id, sizeof(Pfd), &Pfd ) ) { /*
* Make sure the pixel format index supports OpenGL */
if ( PFD_SUPPORT_OPENGL & Pfd.dwFlags ) { VisualID->IDs[VisualID->count++] = Id; } } } else break; }
/*
* Don't need the DC anymore */
ReleaseDC( NULL, hDc ); }
static void PrintMessage( const char *Format, ... ) { va_list ArgList; char Buffer[256];
va_start(ArgList, Format); vsprintf(Buffer, Format, ArgList); va_end(ArgList);
fprintf( stderr, "libctk: %s", Buffer ); fflush(stdout); }
/********************************************************************/
/*
* This function returns the selected pixel format index and * the pixel format descriptor. */
static short GetPixelFormatInformation( HDC Dc, TK_WindowRec *tkWr, PIXELFORMATDESCRIPTOR *Pfd ) { short PfdIndex = 0; // Assume no pixel format matches
/*
* TK_WIND_REQUEST indicates that tkWr->info is a mask * describing the type of pixel format requested. */
if ( TK_WIND_REQUEST == tkWr->type ) { PfdIndex = FindPixelFormat( Dc, tkWr->info ); } else { /*
* Otherwise, tkWr->info contains the pixel format Id. */
PfdIndex = (short)tkWr->info; }
if ( DescribePixelFormat( Dc, PfdIndex, sizeof(*Pfd), Pfd) ) { if ( !(PFD_SUPPORT_OPENGL & Pfd->dwFlags) ) { PfdIndex = 0; // Does not support OpenGL, make it fail
} } return( PfdIndex ); }
/********************************************************************\
| CREATE PIXEL-MAP DC | | hWnd : WindowDC created via GetDC() | nFormat: must be in the range 21 - 40 | uUsage : DIB_RGB_COLORS (do this one) | DIB_PAL_COLORS | \********************************************************************/ HDC CreatePixelMapDC(HDC hDC, TK_WindowRec *tkWr, UINT uUsage, int nBpp, LPPIXELFORMATDESCRIPTOR lpPfd) { HDC hMemDC; HBITMAP hBitmap,hSave; int nWidth,nHeight,nColorTable,idx,nEntries; DWORD dwSize,dwBits,dwCompression; HANDLE hDib; PVOID pvBits; LPSTR lpDib,lpCT; DWORD dwRMask,dwBMask,dwGMask;
static COLORREF cr16Color[] = {0x00000000, 0x00000080, 0x00008000, 0x00008080, 0x00800000, 0x00800080, 0x00808000, 0x00808080, 0x00C0C0C0, 0x000000FF, 0x0000FF00, 0x0000FFFF, 0x00FF0000, 0x00FF00FF, 0x00FFFF00, 0x00FFFFFF};
if(hMemDC = CreateCompatibleDC(hDC)) { // Get device information for the surface
//
nWidth = tkWr->width; nHeight = tkWr->height;
#define USE_DFB 1
#if USE_DFB
// Use compatible bitmap (DFB if supported) if DC color
// depth matches requested color depth. Otherwise, use DIB.
if ( nBpp == (GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES)) ) { if(hBitmap = CreateCompatibleBitmap(hDC,nWidth,nHeight)) { if(hSave = SelectObject(hMemDC,hBitmap)) { return(hMemDC); }
DeleteObject(hBitmap); } } else { #endif
if(nBpp) { // Get the colortable size.
//
switch(nBpp) { case 32: case 16: nColorTable = 3 * sizeof(DWORD); dwCompression = BI_BITFIELDS; break;
case 24: nColorTable = 0; dwCompression = BI_RGB; break;
default: nColorTable = ((UINT)1 << nBpp) * sizeof(RGBQUAD); dwCompression = BI_RGB;
if(uUsage == DIB_PAL_COLORS) nColorTable >>= 1; break; }
// Calculate necessary size for dib.
//
dwBits = (DWORD)(((nWidth * nBpp) + 31) / 32) * nHeight * sizeof(DWORD); dwSize = (DWORD)dwBits + sizeof(BITMAPINFOHEADER) + nColorTable;
// Create the bitmap based upon the DIB specification.
//
if(hDib = GlobalAlloc(GHND,dwSize)) { if(lpDib = GlobalLock(hDib)) { // Initialize DIB specification.
//
((LPBITMAPINFOHEADER)lpDib)->biSize = sizeof(BITMAPINFOHEADER); ((LPBITMAPINFOHEADER)lpDib)->biWidth = nWidth; ((LPBITMAPINFOHEADER)lpDib)->biHeight = nHeight; ((LPBITMAPINFOHEADER)lpDib)->biPlanes = 1; ((LPBITMAPINFOHEADER)lpDib)->biBitCount = (UINT)nBpp; ((LPBITMAPINFOHEADER)lpDib)->biCompression = dwCompression; ((LPBITMAPINFOHEADER)lpDib)->biSizeImage = 0; ((LPBITMAPINFOHEADER)lpDib)->biXPelsPerMeter = 0; ((LPBITMAPINFOHEADER)lpDib)->biYPelsPerMeter = 0; ((LPBITMAPINFOHEADER)lpDib)->biClrUsed = 0; ((LPBITMAPINFOHEADER)lpDib)->biClrImportant = 0;
// Fill in colortable for appropriate bitmap-format.
//
lpCT = (LPSTR)((LPBITMAPINFO)lpDib)->bmiColors;
switch(nBpp) { case 32: case 16: // This creates the rough mask of bits for the
// number of color-bits.
//
dwRMask = (((DWORD)1 << lpPfd->cRedBits ) - 1); dwGMask = (((DWORD)1 << lpPfd->cGreenBits ) - 1); dwBMask = (((DWORD)1 << lpPfd->cBlueBits ) - 1);
// Shift the masks for the color-table.
//
*((LPDWORD)lpCT) = dwRMask << lpPfd->cRedShift; *(((LPDWORD)lpCT)+1) = dwGMask << lpPfd->cGreenShift; *(((LPDWORD)lpCT)+2) = dwBMask << lpPfd->cBlueShift; break;
case 24: break;
case 8: nEntries = ((UINT)1 << nBpp);
if(uUsage == DIB_PAL_COLORS) { for(idx=0; idx < nEntries; idx++) *(((LPWORD)lpCT)+idx) = idx; } else { for(idx=0; idx < nEntries; idx++) { ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbRed = ComponentFromIndex(idx,lpPfd->cRedBits ,lpPfd->cRedShift ); ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbGreen = ComponentFromIndex(idx,lpPfd->cGreenBits,lpPfd->cGreenShift); ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbBlue = ComponentFromIndex(idx,lpPfd->cBlueBits ,lpPfd->cBlueShift ); ((LPBITMAPINFO)lpDib)->bmiColors[idx].rgbReserved = 0; } } break;
case 4: nEntries = sizeof(cr16Color) / sizeof(cr16Color[0]);
if(uUsage == DIB_PAL_COLORS) { for(idx=0; idx < nEntries; idx++) *(((LPWORD)lpCT)+idx) = idx; } else { for(idx=0; idx < nEntries; idx++) *(((LPDWORD)lpCT)+idx) = cr16Color[idx]; } break;
case 1: if(uUsage == DIB_PAL_COLORS) { *((LPWORD)lpCT)++ = 0; *((LPWORD)lpCT) = 255; } else { ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbBlue = 0; ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbGreen = 0; ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbRed = 0; ((LPBITMAPINFO)lpDib)->bmiColors[0].rgbReserved = 0; ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbBlue = 255; ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbGreen = 255; ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbRed = 255; ((LPBITMAPINFO)lpDib)->bmiColors[1].rgbReserved = 0; } break; }
if (hBitmap = CreateDIBSection(hMemDC, (LPBITMAPINFO)lpDib, uUsage, &pvBits, NULL, 0)) { if(hSave = SelectObject(hMemDC,hBitmap)) { GlobalUnlock(hDib); GlobalFree(hDib);
return(hMemDC); } DeleteObject(hBitmap); }
GlobalUnlock(hDib); }
GlobalFree(hDib); } } #if USE_DFB
} #endif
}
return(NULL); }
BOOL DeletePixelMapDC(HDC hDC) { HBITMAP hFormat,hBitmap; BOOL bFree;
bFree = FALSE; if(hFormat = CreateCompatibleBitmap(hDC,1,1)) { if(hBitmap = SelectObject(hDC,hFormat)) { DeleteObject(hBitmap);
bFree = DeleteDC(hDC); }
DeleteObject(hFormat); }
return(bFree); }
/*
* This function updates a TK_WindowRec given a PIXELFORMATDESCRIPTOR */
static TK_WindowRec * PIXELFORMATDESCRIPTOR_To_TK_WindowRec ( TK_WindowRec *WindowRec, PIXELFORMATDESCRIPTOR *Pfd ) { WindowRec->type = TK_WIND_REQUEST; WindowRec->info = 0;
if ( PFD_DOUBLEBUFFER & Pfd->dwFlags ) { WindowRec->info |= TK_WIND_DB; } else { WindowRec->info |= TK_WIND_SB; }
if ( PFD_TYPE_COLORINDEX == Pfd->iPixelType ) { WindowRec->info |= TK_WIND_CI; } else { WindowRec->info |= TK_WIND_RGB; }
if ( Pfd->cAccumBits ) { WindowRec->info |= TK_WIND_ACCUM; }
if ( Pfd->cDepthBits > 16 ) { WindowRec->info |= TK_WIND_Z; } else if ( Pfd->cDepthBits > 0 ) { WindowRec->info |= TK_WIND_Z16; }
if ( Pfd->cStencilBits ) { WindowRec->info |= TK_WIND_STENCIL; }
if ( Pfd->cAuxBuffers ) { WindowRec->info |= TK_WIND_AUX; } return( WindowRec ); }
|