Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.0 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: pixelfmt.c
  3. *
  4. * Pixel format selection
  5. *
  6. * Copyright (c) 1994 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include "mtk.h"
  10. /******************************Public*Routine******************************\
  11. * SSU_ChoosePixelFormat
  12. *
  13. * Local implementation of ChoosePixelFormat
  14. *
  15. * Choose pixel format based on flags.
  16. * This allows us a little a more control than just calling ChoosePixelFormat
  17. \**************************************************************************/
  18. static int
  19. SSU_ChoosePixelFormat( HDC hdc, int flags )
  20. {
  21. int MaxPFDs;
  22. int iBest = 0;
  23. int i;
  24. PIXELFORMATDESCRIPTOR pfd;
  25. //mf: this don't handle alpha yet...
  26. // Always choose native pixel depth
  27. int cColorBits =
  28. GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
  29. BOOL bDoubleBuf = flags & SS_DOUBLEBUF_BIT;
  30. int cDepthBits = 0;
  31. if( SS_HAS_DEPTH16(flags) )
  32. cDepthBits = 16;
  33. else if( SS_HAS_DEPTH32(flags) )
  34. cDepthBits = 32;
  35. i = 1;
  36. do
  37. {
  38. MaxPFDs = DescribePixelFormat(hdc, i, sizeof(pfd), &pfd);
  39. if ( MaxPFDs <= 0 )
  40. return 0;
  41. if( ! (pfd.dwFlags & PFD_SUPPORT_OPENGL) )
  42. continue;
  43. if( flags & SS_BITMAP_BIT ) {
  44. // need bitmap pixel format
  45. if( ! (pfd.dwFlags & PFD_DRAW_TO_BITMAP) )
  46. continue;
  47. } else {
  48. // need window pixel format
  49. if( ! (pfd.dwFlags & PFD_DRAW_TO_WINDOW) )
  50. continue;
  51. // a window can be double buffered...
  52. if( ( bDoubleBuf && !(pfd.dwFlags & PFD_DOUBLEBUFFER) ) ||
  53. ( !bDoubleBuf && (pfd.dwFlags & PFD_DOUBLEBUFFER) ) )
  54. continue;
  55. }
  56. if ( pfd.iPixelType != PFD_TYPE_RGBA )
  57. continue;
  58. if( pfd.cColorBits != cColorBits )
  59. continue;
  60. if( (flags & SS_GENERIC_UNACCELERATED_BIT) &&
  61. ((pfd.dwFlags & (PFD_GENERIC_FORMAT|PFD_GENERIC_ACCELERATED))
  62. != PFD_GENERIC_FORMAT) )
  63. continue;
  64. if( (flags & SS_NO_SYSTEM_PALETTE_BIT) &&
  65. (pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE) )
  66. continue;
  67. if( cDepthBits ) {
  68. if( pfd.cDepthBits < cDepthBits )
  69. continue;
  70. } else {
  71. // No depth buffer required, but use it if nothing better
  72. if( pfd.cDepthBits ) {
  73. if( pfd.dwFlags & PFD_GENERIC_ACCELERATED )
  74. // Accelerated pixel format - we may as well use this, even
  75. // though we don't need depth. Otherwise if we keep going
  76. // to find a better match, we run the risk of overstepping
  77. // all the accelerated formats and picking a slower format.
  78. return i;
  79. iBest = i;
  80. continue;
  81. }
  82. }
  83. // We have found something useful
  84. return i;
  85. } while (++i <= MaxPFDs);
  86. if( iBest )
  87. // not an exact match, but good enough
  88. return iBest;
  89. // If we reach here, we have failed to find a suitable pixel format.
  90. // See if the system can find us one.
  91. memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) );
  92. pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
  93. pfd.cColorBits = cColorBits;
  94. pfd.cDepthBits = cDepthBits;
  95. pfd.iPixelType = PFD_TYPE_RGBA;
  96. pfd.dwFlags = PFD_SUPPORT_OPENGL;
  97. if( bDoubleBuf )
  98. pfd.dwFlags |= PFD_DOUBLEBUFFER;
  99. if( flags & SS_BITMAP_BIT )
  100. pfd.dwFlags |= PFD_DRAW_TO_BITMAP;
  101. else
  102. pfd.dwFlags |= PFD_DRAW_TO_WINDOW;
  103. if( (flags & SS_GENERIC_UNACCELERATED_BIT) ||
  104. (flags & SS_NO_SYSTEM_PALETTE_BIT) )
  105. // If either of these flags are set, we should be safe specifying a
  106. // 'slow' pixel format that supports bitmap drawing
  107. //mf: DRAW_TO_WINDOW seems to override this...
  108. pfd.dwFlags |= PFD_DRAW_TO_BITMAP;
  109. SS_WARNING( "SSU_ChoosePixelFormat failed, calling ChoosePIxelFormat\n" );
  110. return ChoosePixelFormat( hdc, &pfd );
  111. }
  112. /******************************Public*Routine******************************\
  113. * SSU_SetupPixelFormat
  114. *
  115. * Choose pixel format according to supplied flags. If ppfd is non-NULL,
  116. * call DescribePixelFormat with it.
  117. *
  118. \**************************************************************************/
  119. BOOL
  120. SSU_SetupPixelFormat(HDC hdc, int flags, PIXELFORMATDESCRIPTOR *ppfd )
  121. {
  122. int pixelFormat;
  123. int nTryAgain = 4;
  124. do{
  125. if( (pixelFormat = SSU_ChoosePixelFormat(hdc, flags)) &&
  126. SetPixelFormat(hdc, pixelFormat, NULL) ) {
  127. SS_DBGLEVEL1( SS_LEVEL_INFO,
  128. "SSU_SetupPixelFormat: Setting pixel format %d\n", pixelFormat );
  129. if( ppfd )
  130. DescribePixelFormat(hdc, pixelFormat,
  131. sizeof(PIXELFORMATDESCRIPTOR), ppfd);
  132. return TRUE; // Success
  133. }
  134. // Failed to set pixel format. Try again after waiting a bit (win95
  135. // bug with full screen dos box)
  136. Sleep( 1000 ); // Wait a second between attempts
  137. } while( nTryAgain-- );
  138. return FALSE;
  139. }
  140. /******************************Public*Routine******************************\
  141. * SSU_bNeedPalette
  142. *
  143. \**************************************************************************/
  144. BOOL
  145. SSU_bNeedPalette( PIXELFORMATDESCRIPTOR *ppfd )
  146. {
  147. if (ppfd->dwFlags & PFD_NEED_PALETTE)
  148. return TRUE;
  149. else
  150. return FALSE;
  151. }
  152. /******************************Public*Routine******************************\
  153. * SSU_PixelFormatDescriptorFromDc
  154. *
  155. \**************************************************************************/
  156. int
  157. SSU_PixelFormatDescriptorFromDc( HDC hdc, PIXELFORMATDESCRIPTOR *Pfd )
  158. {
  159. int PfdIndex;
  160. if ( 0 < (PfdIndex = GetPixelFormat( hdc )) )
  161. {
  162. if ( 0 < DescribePixelFormat( hdc, PfdIndex, sizeof(*Pfd), Pfd ) )
  163. {
  164. return(PfdIndex);
  165. }
  166. }
  167. return 0;
  168. }