b311480e |
1 | // Copyright (c) 1996-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
7fd59977 |
19 | /*********************************************************************** |
20 | FONCTION : |
21 | ---------- |
22 | Classe WNT_GraphicDevice.cxx : |
23 | |
24 | HISTORIQUE DES MODIFICATIONS : |
25 | -------------------------------- |
26 | 03-01-95 : EUG -> Creation. |
27 | 20-11-97 : FMN -> Portage WIN95 |
28 | MAR-98 : EUG -> Porting Win95 |
29 | JUN-98 : EUG -> Modifications to provide access to this class |
30 | from CCL (second constructor + Init () method) |
31 | SEP-98 : DCB -> Avoid memory crash when color indices do not follow |
32 | each other or do not begin with '1' |
33 | JAN-99 : EUG -> Modifications to provide treating display window |
34 | as graphic device |
35 | ************************************************************************/ |
36 | |
37 | /*----------------------------------------------------------------------*/ |
38 | /* |
39 | * Includes |
40 | */ |
41 | |
42 | // include windows.h first to have all definitions available |
43 | #include <windows.h> |
44 | |
45 | #include <WNT.h> |
46 | #include <WNT_GraphicDevice.ixx> |
47 | #include <Aspect_ColorMapEntry.hxx> |
48 | #include <Aspect_GraphicDriver.hxx> |
49 | #include <Aspect_Units.hxx> |
50 | |
51 | #include <stdio.h> |
52 | |
53 | /*----------------------------------------------------------------------*/ |
54 | /* |
55 | * Constantes |
56 | */ |
57 | |
58 | #define PAL ((PLOGPALETTE)myLogPal) |
59 | #define MAX_PAL_ERROR (3*256*256L) |
60 | #define DEFAULT_GAMMA 1.4 |
61 | |
62 | static int __fastcall _createColorRamp ( HPALETTE* ); |
63 | static BOOL s_SysPalInUse; |
64 | |
65 | extern HWINSTA ( WINAPI *NTOpenWindowStation ) ( LPTSTR, BOOL, DWORD ); |
66 | extern BOOL ( WINAPI *NTSetProcessWindowStation ) ( HWINSTA ); |
67 | extern HDESK ( WINAPI *NTOpenDesktop ) ( LPTSTR, DWORD, BOOL, DWORD ); |
68 | extern BOOL ( WINAPI *NTSetThreadDesktop ) ( HDESK ); |
69 | extern BOOL ( WINAPI *NTCloseDesktop ) ( HDESK ); |
70 | extern BOOL ( WINAPI *NTCloseWindowStation ) ( HWINSTA ); |
71 | |
72 | extern OSVERSIONINFO WNT_osVer; |
73 | |
74 | //======================================================================= |
75 | //function : WNT_GraphicDevice |
76 | //purpose : |
77 | //======================================================================= |
78 | |
79 | WNT_GraphicDevice::WNT_GraphicDevice ( |
80 | const Standard_Boolean aColorCube, |
81 | const Aspect_Handle aDevContext |
82 | ) |
83 | { |
84 | |
85 | Init ( aColorCube, aDevContext ); |
86 | |
87 | } // end constructor ( 1 ) |
88 | |
89 | //======================================================================= |
90 | //function : WNT_GraphicDevice |
91 | //purpose : |
92 | //======================================================================= |
93 | |
94 | WNT_GraphicDevice::WNT_GraphicDevice ( |
95 | const Standard_Boolean aColorCube, |
96 | const Standard_Integer aDevContext |
97 | ) |
98 | { |
99 | |
100 | Init ( aColorCube, ( Aspect_Handle )aDevContext ); |
101 | |
102 | } // end constructor ( 2 ) |
103 | |
104 | //======================================================================= |
105 | //function : Init |
106 | //purpose : |
107 | //======================================================================= |
108 | |
109 | void WNT_GraphicDevice::Init ( |
110 | const Standard_Boolean aColorCube, |
111 | const Aspect_Handle aDevContext |
112 | ) |
113 | { |
114 | |
115 | HDC hDC; |
116 | BOOL palDev; |
117 | HWND hwnd = NULL; |
118 | HBITMAP hBmp = NULL; |
119 | int numRes, palSize, nPlanes, nBits; |
120 | |
121 | hDC = ( aDevContext == NULL ) ? GetDC ( NULL ) : |
122 | ( HDC )aDevContext, hwnd = WindowFromDC ( ( HDC )aDevContext ); |
123 | |
124 | // It is found that the error occurs in the place in the source code that is |
125 | // responsible for connecting to the desktop and window pointed by the environment |
126 | // variable CSF_DISPLAY. |
127 | // For the moment it is unclear at all what this code is needed for. Therefore it |
128 | // is removed from the sources in order to fix this bug. This allowed to run the |
129 | // code without problems on both win32 and win64 platforms. |
130 | // It is needed to carry out special investigations about this subject. Probably it |
131 | // can be used to connect to a virtual desktop in order to make snapshots on the |
132 | // Windows station on which no user is logged in. |
133 | // |
134 | // if ( aDevContext == 0 && WNT_osVer.dwPlatformId == VER_PLATFORM_WIN32_NT ) { |
135 | |
136 | // HWINSTA hWst = NULL; |
137 | // HDESK hDsk = NULL; |
138 | // DWORD dwLen, dwLenOrig; |
139 | // LPTSTR buff = NULL; |
140 | // LPTSTR sNam = NULL; |
141 | // LPTSTR dNam = NULL; |
142 | // BOOL fSts = FALSE; |
143 | |
144 | // dwLenOrig = GetEnvironmentVariable( TEXT( "CSF_DISPLAY" ), NULL, 0 ); |
145 | |
146 | // if ( dwLenOrig == 0 ) |
147 | |
148 | // dwLen = sizeof ( TEXT( "WinSta0\\Default" ) ); |
149 | |
150 | // else |
151 | |
152 | // dwLen = dwLenOrig + sizeof ( TCHAR ); |
153 | |
154 | // buff = ( LPTSTR )HeapAlloc ( |
155 | // GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, dwLen |
156 | // ); |
157 | |
158 | // if ( dwLenOrig != 0 ) |
159 | |
160 | // GetEnvironmentVariable ( TEXT( "CSF_DISPLAY" ), buff, dwLen ); |
161 | |
162 | // else |
163 | |
164 | // lstrcpy ( buff, TEXT( "WinSta0\\Default" ) ); |
165 | |
166 | // dwLen = 0; |
167 | |
168 | // while ( buff[ dwLen ] != TEXT( '\\' ) && buff[ dwLen ] != TEXT( '\x00' ) ) ++dwLen; |
169 | |
170 | // sNam = ( LPTSTR )HeapAlloc ( |
171 | // GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS, |
172 | // dwLen * sizeof ( TCHAR ) + sizeof ( TCHAR ) |
173 | // ); |
174 | |
175 | // dwLenOrig = 0; |
176 | |
177 | // while ( dwLenOrig != dwLen ) { |
178 | |
179 | // sNam[ dwLenOrig ] = buff[ dwLenOrig ]; |
180 | // ++dwLenOrig; |
181 | |
182 | // } // end while |
183 | |
184 | // sNam[ dwLenOrig ] = TEXT( '\x00' ); |
185 | |
186 | // if ( buff[ dwLen ] == TEXT( '\x00' ) ) goto leave; |
187 | |
188 | // lstrcpy ( buff, &buff[ dwLen + 1 ] ); |
189 | |
190 | // dNam = ( LPTSTR )HeapAlloc ( |
191 | // GetProcessHeap (), HEAP_GENERATE_EXCEPTIONS, |
192 | // lstrlen ( buff ) * sizeof ( TCHAR ) + sizeof ( TCHAR ) |
193 | // ); |
194 | |
195 | // lstrcpy ( dNam, buff ); |
196 | |
197 | // if ( ( hWst = ( *NTOpenWindowStation ) ( sNam, FALSE, MAXIMUM_ALLOWED ) ) == NULL || |
198 | // !( *NTSetProcessWindowStation ) ( hWst ) |
199 | // ) goto leave; |
200 | |
201 | // if ( ( hDsk = ( *NTOpenDesktop ) ( dNam, 0, FALSE, MAXIMUM_ALLOWED ) ) == NULL || |
202 | // !( *NTSetThreadDesktop ) ( hDsk ) |
203 | // ) |
204 | |
205 | // if ( GetLastError () == ERROR_BUSY ) { |
206 | |
207 | // if ( hDsk != NULL ) ( *NTCloseDesktop ) ( hDsk ); |
208 | // if ( hWst != NULL ) ( *NTCloseWindowStation ) ( hWst ); |
209 | |
210 | // } else goto leave; |
211 | |
212 | // fSts = TRUE; |
213 | //leave: |
214 | // if ( sNam != NULL ) HeapFree ( GetProcessHeap (), 0, ( LPVOID )sNam ); |
215 | // if ( dNam != NULL ) HeapFree ( GetProcessHeap (), 0, ( LPVOID )dNam ); |
216 | // if ( buff != NULL ) HeapFree ( GetProcessHeap (), 0, ( LPVOID )buff ); |
217 | |
218 | // if ( !fSts ) { |
219 | |
220 | // if ( hDsk != NULL ) ( *NTCloseDesktop ) ( hDsk ); |
221 | // if ( hWst != NULL ) ( *NTCloseWindowStation ) ( hWst ); |
222 | |
223 | // Aspect_GraphicDeviceDefinitionError :: Raise ( "Access to station is denied" ); |
224 | |
225 | // } // end if |
226 | |
227 | // } // end if |
228 | |
229 | palDev = ( GetDeviceCaps ( hDC, RASTERCAPS ) & RC_PALETTE ) ? TRUE : FALSE; |
230 | numRes = GetDeviceCaps ( hDC, NUMRESERVED ); |
231 | palSize = ( palDev ) ? GetDeviceCaps ( hDC, SIZEPALETTE ) : 0; |
232 | nPlanes = GetDeviceCaps ( hDC, PLANES ); |
233 | nBits = GetDeviceCaps ( hDC, BITSPIXEL ); |
234 | myWidth = GetDeviceCaps ( hDC, HORZRES ); |
235 | myHeight = GetDeviceCaps ( hDC, VERTRES ); |
236 | myMWidth = ( float )GetDeviceCaps ( hDC, HORZSIZE ) / ( 1. MILLIMETER ); |
237 | myMHeight = ( float )GetDeviceCaps ( hDC, VERTSIZE ) / ( 1. MILLIMETER ); |
238 | |
239 | if ( aDevContext != NULL && hwnd != NULL ) { |
240 | |
241 | RECT r; |
242 | |
243 | GetClientRect ( hwnd, &r ); |
244 | |
245 | myMWidth = myMWidth * r.right / myWidth; |
246 | myMHeight = myMHeight * r.bottom / myHeight; |
247 | myWidth = r.right; |
248 | myHeight = r.bottom; |
249 | |
250 | } else { |
251 | |
252 | BITMAP bm; |
253 | |
254 | hBmp = ( HBITMAP )GetCurrentObject ( hDC, OBJ_BITMAP ); |
255 | |
256 | if ( GetObject ( hBmp, sizeof ( BITMAP ), &bm ) ) { |
257 | |
258 | myMWidth = myMWidth * bm.bmWidth / myWidth; |
259 | myMHeight = myMHeight * bm.bmHeight / myHeight; |
260 | // Tempory correction for Windows 98 |
261 | if ( WNT_osVer.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS ) { |
262 | // |
263 | myWidth = bm.bmWidth; |
264 | myHeight = bm.bmHeight; |
265 | |
266 | } else hBmp = NULL; |
267 | // Tempory correction for Windows 98 |
268 | } |
269 | // |
270 | |
271 | } // end else |
272 | |
273 | if ( aDevContext == NULL ) ReleaseDC ( NULL, hDC ); |
274 | |
275 | myNumColors = ( 1 << ( nBits * nPlanes ) ); |
276 | |
277 | if ( palDev ) myNumColors -= numRes; |
278 | |
279 | myFreeIndex = 0; |
280 | myOpenGLPalette = aColorCube; |
281 | |
282 | if ( palDev ) { |
283 | |
284 | if ( hwnd == NULL && hBmp == NULL ) { |
285 | |
286 | myLogPal = HeapAlloc ( |
287 | GetProcessHeap (), HEAP_ZERO_MEMORY, |
288 | sizeof( LOGPALETTE ) + |
289 | sizeof( PALETTEENTRY ) * myNumColors |
290 | ); |
291 | |
292 | if ( !myLogPal ) |
293 | |
294 | Aspect_GraphicDeviceDefinitionError :: Raise ( "Out of memory" ); |
295 | |
296 | PAL -> palVersion = 0x300; |
297 | PAL -> palNumEntries = 1; |
298 | |
299 | myPalette = CreatePalette ( PAL ); |
300 | |
301 | if ( !myPalette ) { |
302 | |
303 | HeapFree ( GetProcessHeap (), 0, myLogPal ); |
304 | Aspect_GraphicDeviceDefinitionError :: Raise ( "Unable to create user palette" ); |
305 | |
306 | } // end if |
307 | |
308 | myFreeIndex = 0; |
309 | |
310 | if ( myOpenGLPalette && !_createColorRamp ( ( HPALETTE* )&myPalette ) ) |
311 | |
312 | Aspect_GraphicDeviceDefinitionError :: Raise ( "Colorcube creation failed" ); |
313 | |
314 | } else { |
315 | |
316 | myPalette = GetCurrentObject ( hDC, OBJ_PAL ); |
317 | myLogPal = NULL; |
318 | |
319 | } // end else |
320 | |
321 | } else { // not a palette device |
322 | |
323 | myPalette = 0; |
324 | myLogPal = NULL; |
325 | |
326 | } // end else ( palDev . . . ) |
327 | |
328 | myHighlightColor = RGB( 255, 255, 255 ); |
329 | |
330 | } // end WNT_GraphicDevice :: Init |
331 | |
332 | void WNT_GraphicDevice :: Destroy () { |
333 | |
334 | if ( myPalette && myLogPal != NULL ) { |
335 | |
336 | DeletePalette ( myPalette ); |
337 | HeapFree ( GetProcessHeap (), 0, myLogPal ); |
338 | |
339 | } // end if |
340 | |
341 | } // end WNT_GraphicDevice :: Destroy |
342 | |
343 | WNT_ColorRef WNT_GraphicDevice :: SetColor ( |
344 | const Quantity_Color& aColor, |
345 | const Standard_Boolean aHighlight |
346 | ) { |
347 | |
348 | Standard_Real r, g, b; |
349 | Standard_Integer red, green, blue; |
350 | |
351 | aColor.Values ( r, g, b, Quantity_TOC_RGB ); |
352 | |
353 | red = ( Standard_Integer )( 255. * r ); |
354 | green = ( Standard_Integer )( 255. * g ); |
355 | blue = ( Standard_Integer )( 255. * b ); |
356 | |
357 | return SetColor ( red, green, blue, aHighlight ); |
358 | |
359 | } // end WNT_GraphicDevice :: SetColor( 1 ) |
360 | |
361 | WNT_ColorRef WNT_GraphicDevice :: SetColor ( |
362 | const Standard_Integer aRed, |
363 | const Standard_Integer aGreen, |
364 | const Standard_Integer aBlue, |
365 | const Standard_Boolean aHighlight |
366 | ) { |
367 | |
368 | int i; |
369 | WNT_ColorRef retVal; |
370 | BYTE red, green, blue; |
371 | |
372 | red = ( BYTE )aRed; |
373 | green = ( BYTE )aGreen; |
374 | blue = ( BYTE )aBlue; |
375 | |
376 | if ( !myPalette ) |
377 | |
378 | retVal = RGB( red, green, blue ); |
379 | |
380 | else if ( myOpenGLPalette ) |
381 | |
382 | retVal = PALETTEINDEX( |
383 | GetNearestPaletteIndex ( |
384 | ( HPALETTE )myPalette, RGB( red, green, blue ) |
385 | ) |
386 | ); |
387 | |
388 | else { |
389 | |
390 | if ( myFreeIndex < myNumColors ) { |
391 | |
392 | for ( i = 0; i < myFreeIndex; ++i ) // avoid color duplication |
393 | |
394 | if ( PAL -> palPalEntry[ i ].peRed == red && |
395 | PAL -> palPalEntry[ i ].peGreen == green && |
396 | PAL -> palPalEntry[ i ].peBlue == blue |
397 | ) |
398 | |
399 | break; |
400 | |
401 | if ( i == myFreeIndex ) { // add new color entry |
402 | |
403 | PAL -> palPalEntry[ i ].peRed = red; |
404 | PAL -> palPalEntry[ i ].peGreen = green; |
405 | PAL -> palPalEntry[ i ].peBlue = blue; |
406 | PAL -> palPalEntry[ i ].peFlags = 0; |
407 | ++myFreeIndex; |
408 | ResizePalette ( ( HPALETTE )myPalette, myFreeIndex ); |
409 | SetPaletteEntries ( ( HPALETTE )myPalette, i, 1, &PAL -> palPalEntry[ i ] ); |
410 | |
411 | } // end if |
412 | |
413 | retVal = PALETTEINDEX( i ); |
414 | |
415 | } else // get closest color |
416 | |
417 | retVal = PALETTEINDEX( |
418 | GetNearestPaletteIndex ( |
419 | ( HPALETTE )myPalette, RGB( red, green, blue ) |
420 | ) |
421 | ); |
422 | |
423 | } // end else ( !myPalette . . . ) |
424 | |
425 | if ( aHighlight ) |
426 | |
427 | myHighlightColor = retVal; |
428 | |
429 | return retVal; |
430 | |
431 | } // end WNT_GraphicDevice :: SetColor(2) |
432 | |
433 | void WNT_GraphicDevice :: SetColor ( const WNT_Long& aPixel ) { |
434 | |
435 | if ( myPalette && !myOpenGLPalette && myFreeIndex < myNumColors ) { |
436 | |
437 | int idx; |
438 | BYTE red, green, blue; |
439 | |
440 | blue = (BYTE) (aPixel & 0xFF); |
441 | green = (BYTE) (( aPixel >> 8 ) & 0xFF); |
442 | red = (BYTE) (( aPixel >> 16 ) & 0xFF); |
443 | |
444 | idx = myFreeIndex; |
445 | |
446 | for ( int i = 2; i < myFreeIndex; ++i ) // avoid color duplication |
447 | |
448 | if ( PAL -> palPalEntry[ i ].peRed == red && |
449 | PAL -> palPalEntry[ i ].peGreen == green && |
450 | PAL -> palPalEntry[ i ].peBlue == blue |
451 | ) |
452 | |
453 | return; |
454 | |
455 | PAL -> palPalEntry[ idx ].peRed = red; |
456 | PAL -> palPalEntry[ idx ].peGreen = green; |
457 | PAL -> palPalEntry[ idx ].peBlue = blue; |
458 | PAL -> palPalEntry[ idx ].peFlags = 0; |
459 | ++myFreeIndex; |
460 | ResizePalette ( ( HPALETTE )myPalette, myFreeIndex ); |
461 | SetPaletteEntries ( ( HPALETTE )myPalette, idx, 1, &PAL -> palPalEntry[ idx ] ); |
462 | |
463 | } // end if ( myPalette . . . ) |
464 | |
465 | } // end WNT_GraphicDevice :: SetColor(3) |
466 | |
467 | void WNT_GraphicDevice :: MapColors ( |
468 | const Handle( Aspect_ColorMap )& aColorMap, |
469 | Handle( WNT_HColorTable )& aColorTable |
470 | ) { |
471 | |
472 | Aspect_ColorMapEntry entry; |
473 | Quantity_Color color; |
474 | COLORREF dwColor; |
475 | Standard_Real r, g, b; |
476 | int i, index; |
477 | |
478 | if ( myOpenGLPalette || !IsPaletteDevice () ) // readonly palette or no palette |
479 | |
480 | for ( i = 1; i <= aColorMap -> Size (); ++i ) { |
481 | |
482 | entry = aColorMap -> Entry ( i ); |
483 | color = entry.Color (); |
484 | aColorTable -> SetValue ( entry.Index (), SetColor ( color ) ); |
485 | |
486 | } // end for |
487 | |
488 | else { // writable palette |
489 | |
490 | for ( i = 1; i <= aColorMap -> Size (); ++i ) { |
491 | |
492 | entry = aColorMap -> Entry ( i ); |
493 | color = entry.Color (); |
494 | dwColor = aColorTable -> Value ( i ); |
495 | index = dwColor & 0x01000000 ? dwColor & 0x00FFFFFF : 0xFFFFFFFF; |
496 | |
497 | if ( index != 0xFFFFFFFF && index < myFreeIndex ) { |
498 | |
499 | color.Values ( r, g, b, Quantity_TOC_RGB ); |
500 | PAL -> palPalEntry[ index ].peRed = ( BYTE )( 255. * r ); |
501 | PAL -> palPalEntry[ index ].peGreen = ( BYTE )( 255. * g ); |
502 | PAL -> palPalEntry[ index ].peBlue = ( BYTE )( 255. * b ); |
503 | |
504 | } else |
505 | |
506 | aColorTable -> SetValue ( i, SetColor ( color ) ); |
507 | |
508 | } // end for |
509 | |
510 | SetPaletteEntries ( |
511 | ( HPALETTE )myPalette, 0, myFreeIndex, &PAL -> palPalEntry[ 0 ] |
512 | ); |
513 | |
514 | } // end else |
515 | |
516 | } // WNT_GraphicDevice :: MapColors |
517 | |
518 | Handle( Aspect_GraphicDriver ) WNT_GraphicDevice :: GraphicDriver () const { |
519 | |
520 | Handle( Aspect_GraphicDriver ) dummy; |
521 | |
522 | return dummy; |
523 | |
524 | } // WNT_GraphicDevice :: GraphicDriver |
525 | //***// |
526 | //*** Function to create RGB color map for use with OpenGL. ***// |
527 | //*** For OpenGL RGB rendering we need to know red, green, & blue ***// |
528 | //*** component bit sizes and positions. This program creates an RGB color ***// |
529 | //*** cube with a default gamma of 1.4. ***// |
530 | //*** Unfortunately, because the standard 20 colors in the system palette ***// |
531 | //*** cannot be changed, if we select this palette into a display DC, ***// |
532 | //*** we will not realize all of the logical palette. The function ***// |
533 | //*** changes some of the entries in the logical palette to match enties in ***// |
534 | //*** the system palette using a least-squares calculation to find which ***// |
535 | //*** entries to replace. ***// |
536 | //***// |
537 | static int __fastcall _createColorRamp ( HPALETTE* pal ) { |
538 | |
539 | int i, j; |
540 | int sysPalSize, logPalSize; |
541 | int red_max, green_max, blue_max, |
542 | red_mask, green_mask, blue_mask; |
543 | int iPf; |
544 | HDC hDC; |
545 | PIXELFORMATDESCRIPTOR pfd; |
546 | PPALETTEENTRY sysPal, colorRamp; |
547 | PBYTE gRed, gGreen, gBlue; |
548 | BYTE inc; |
549 | LONG error, min_error, error_index, delta; |
550 | double dv, gamma; |
551 | char buff[ 32 ]; |
552 | |
553 | ZeroMemory ( ( PVOID )&pfd, sizeof ( PIXELFORMATDESCRIPTOR ) ); |
554 | |
555 | pfd.nSize = sizeof ( PIXELFORMATDESCRIPTOR ); |
556 | pfd.nVersion = 1; |
557 | pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | |
558 | PFD_DOUBLEBUFFER; |
559 | pfd.iPixelType = PFD_TYPE_RGBA; |
560 | pfd.cColorBits = 24; |
561 | pfd.cDepthBits = 32; |
562 | pfd.iLayerType = PFD_MAIN_PLANE; |
563 | |
564 | hDC = GetDC ( NULL ); |
565 | |
566 | iPf = ChoosePixelFormat ( hDC, &pfd ); |
567 | i = DescribePixelFormat ( |
568 | hDC, iPf, sizeof ( PIXELFORMATDESCRIPTOR ), &pfd |
569 | ); |
570 | |
571 | if ( !i ) { |
572 | |
573 | ReleaseDC ( NULL, hDC ); |
574 | |
575 | return 0; |
576 | |
577 | } // end if |
578 | |
579 | sysPalSize = GetDeviceCaps ( hDC, NUMCOLORS ); |
580 | logPalSize = 1 << pfd.cColorBits; |
581 | sysPal = new PALETTEENTRY[ sysPalSize + logPalSize ]; |
582 | colorRamp = sysPal + sysPalSize; |
583 | GetSystemPaletteEntries ( hDC, 0, sysPalSize, sysPal ); |
584 | |
585 | ReleaseDC ( NULL, hDC ); |
586 | |
587 | red_max = 1 << pfd.cRedBits; |
588 | green_max = 1 << pfd.cGreenBits; |
589 | blue_max = 1 << pfd.cBlueBits; |
590 | |
591 | red_mask = red_max - 1; |
592 | green_mask = green_max - 1; |
593 | blue_mask = blue_max - 1; |
594 | |
595 | gRed = new BYTE[ red_max + green_max + blue_max ]; |
596 | gGreen = gRed + red_max; |
597 | gBlue = gGreen + green_max; |
598 | |
599 | inc = ( BYTE )( 255.0F / ( float )red_mask ); |
600 | |
601 | if ( GetEnvironmentVariable ( "CSF_GammaValue", buff, 32 ) ) { |
602 | |
91322f44 |
603 | gamma = Atof ( buff ); |
7fd59977 |
604 | |
605 | if ( gamma == 0.0 ) |
606 | |
607 | gamma = DEFAULT_GAMMA; |
608 | |
609 | } else |
610 | |
611 | gamma = DEFAULT_GAMMA; |
612 | |
613 | for ( i = 0; i < red_max; ++i ) { |
614 | |
615 | gRed[ i ] = ( i * inc ) & 0xFF; |
616 | dv = ( 255. * pow ( gRed[ i ] / 255., 1. / gamma ) ) + 0.5; |
617 | gRed[ i ] = ( BYTE )dv; |
618 | |
619 | } // end for |
620 | |
621 | inc = ( BYTE )( 255.0F / ( float )green_mask ); |
622 | |
623 | for ( i = 0; i < green_max; ++i ) { |
624 | |
625 | gGreen[ i ] = ( i * inc ) & 0xFF; |
626 | dv = ( 255. * pow ( gGreen[ i ] / 255., 1. / gamma ) ) + 0.5; |
627 | gGreen[ i ] = ( BYTE )dv; |
628 | |
629 | } // end for |
630 | |
631 | inc = ( BYTE )( 255.0F / ( float )blue_mask ); |
632 | |
633 | for ( i = 0; i < blue_max; ++i ) { |
634 | |
635 | gBlue[ i ] = ( i * inc ) & 0xFF; |
636 | dv = ( 255. * pow ( gBlue[ i ] / 255., 1. / gamma ) ) + 0.5; |
637 | gBlue[ i ] = ( BYTE )dv; |
638 | |
639 | } // end for |
640 | |
641 | for ( i = 0; i < logPalSize; ++i ) { |
642 | |
643 | colorRamp[ i ].peRed = |
644 | gRed[ ( i >> pfd.cRedShift ) & red_mask ]; |
645 | colorRamp[ i ].peGreen = |
646 | gGreen[ ( i >> pfd.cGreenShift ) & green_mask ]; |
647 | colorRamp[ i ].peBlue = |
648 | gBlue[ ( i >> pfd.cBlueShift ) & blue_mask ]; |
649 | colorRamp[ i ].peFlags = 0; |
650 | |
651 | } // end for |
652 | |
653 | if ( pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ) { |
654 | |
655 | s_SysPalInUse = TRUE; |
656 | |
657 | for ( i = 1; i < logPalSize - 1; ++i ) colorRamp[ i ].peFlags = PC_NOCOLLAPSE; |
658 | |
659 | } else { |
660 | |
661 | for ( i = 0; i < sysPalSize; ++i ) |
662 | |
663 | for ( j = 0; j < logPalSize; ++j ) |
664 | |
665 | if ( sysPal[ i ].peRed == colorRamp[ j ].peRed && |
666 | sysPal[ i ].peGreen == colorRamp[ j ].peRed && |
667 | sysPal[ i ].peBlue == colorRamp[ j ].peRed |
668 | ) |
669 | |
670 | sysPal[ i ].peFlags = colorRamp[ i ].peFlags = 1; |
671 | |
672 | else |
673 | |
674 | sysPal[ i ].peFlags = colorRamp[ i ].peFlags = 0; |
675 | |
676 | for ( i = 0; i < sysPalSize; ++i ) { |
677 | |
678 | if ( sysPal[ i ].peFlags ) continue; |
679 | |
680 | min_error = MAX_PAL_ERROR; |
681 | |
682 | for ( j = 0; j < logPalSize; ++j ) { |
683 | |
684 | if ( colorRamp[ j ].peFlags ) continue; |
685 | |
686 | delta = colorRamp[ j ].peRed - sysPal[ i ].peRed; |
687 | error = delta * delta; |
688 | delta = colorRamp[ j ].peGreen - sysPal[ i ].peGreen; |
689 | error += delta * delta; |
690 | delta = colorRamp[ j ].peBlue - sysPal[ i ].peBlue; |
691 | error += delta * delta; |
692 | |
693 | if ( error < min_error ) { |
694 | |
695 | error_index = j; |
696 | min_error = error; |
697 | |
698 | } // end if |
699 | |
700 | } // end for ( j . . . ) |
701 | |
702 | colorRamp[ error_index ].peRed = sysPal[ i ].peRed; |
703 | colorRamp[ error_index ].peGreen = sysPal[ i ].peGreen; |
704 | colorRamp[ error_index ].peBlue = sysPal[ i ].peBlue; |
705 | colorRamp[ error_index ].peFlags = PC_EXPLICIT; |
706 | |
707 | } // end for ( i . . . ) |
708 | |
709 | } // end else |
710 | |
711 | ResizePalette ( *pal, logPalSize ); |
712 | SetPaletteEntries ( *pal, 0, logPalSize, colorRamp ); |
713 | |
714 | delete [] gRed; |
715 | delete [] sysPal; |
716 | |
717 | return 1; |
718 | |
719 | } // end createColorRamp |
720 | |
721 | int WNT_SysPalInUse ( void ) { |
722 | |
723 | return s_SysPalInUse; |
724 | |
725 | } // end WNT_SysPalInUse |