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.

430 lines
11 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: ssutil.cxx
  3. *
  4. * Screen-saver utility functions
  5. *
  6. * Copyright (c) 1994 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include <nt.h>
  10. #include <ntrtl.h>
  11. #include <nturtl.h>
  12. #include <windows.h>
  13. #include <commdlg.h>
  14. #include <scrnsave.h>
  15. #include <GL\gl.h>
  16. #include <memory.h>
  17. #include <string.h>
  18. #include <stdarg.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <malloc.h>
  22. #include <time.h>
  23. #include "tk.h"
  24. #include "ssintrnl.hxx"
  25. #include "ssutil.hxx"
  26. static OSVERSIONINFO gosvi = {0};
  27. static BOOL gbGLv1_1 = FALSE; // GL version 1.1 boolean
  28. /******************************Public*Routine******************************\
  29. * SSU_ChoosePixelFormat
  30. *
  31. * Local implementation of ChoosePixelFormat
  32. *
  33. * Choose pixel format based on flags.
  34. * This allows us a little a more control than just calling ChoosePixelFormat
  35. \**************************************************************************/
  36. static int
  37. SSU_ChoosePixelFormat( HDC hdc, int flags )
  38. {
  39. int MaxPFDs;
  40. int iBest = 0;
  41. PIXELFORMATDESCRIPTOR pfd;
  42. // Always choose native pixel depth
  43. int cColorBits =
  44. GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
  45. BOOL bDoubleBuf = flags & SS_DOUBLEBUF_BIT;
  46. int cDepthBits = 0;
  47. if( SS_HAS_DEPTH16(flags) )
  48. cDepthBits = 16;
  49. else if( SS_HAS_DEPTH32(flags) )
  50. cDepthBits = 32;
  51. int i = 1;
  52. do
  53. {
  54. MaxPFDs = DescribePixelFormat(hdc, i, sizeof(pfd), &pfd);
  55. if ( MaxPFDs <= 0 )
  56. return 0;
  57. if( ! (pfd.dwFlags & PFD_SUPPORT_OPENGL) )
  58. continue;
  59. if( flags & SS_BITMAP_BIT ) {
  60. // need bitmap pixel format
  61. if( ! (pfd.dwFlags & PFD_DRAW_TO_BITMAP) )
  62. continue;
  63. } else {
  64. // need window pixel format
  65. if( ! (pfd.dwFlags & PFD_DRAW_TO_WINDOW) )
  66. continue;
  67. // a window can be double buffered...
  68. if( ( bDoubleBuf && !(pfd.dwFlags & PFD_DOUBLEBUFFER) ) ||
  69. ( !bDoubleBuf && (pfd.dwFlags & PFD_DOUBLEBUFFER) ) )
  70. continue;
  71. }
  72. if ( pfd.iPixelType != PFD_TYPE_RGBA )
  73. continue;
  74. if( pfd.cColorBits != cColorBits )
  75. continue;
  76. if( flags & SS_ALPHA_BIT ) {
  77. // We want alpha bit planes
  78. if( pfd.cAlphaBits == 0 )
  79. continue;
  80. } else {
  81. // We don't want alpha
  82. if( pfd.cAlphaBits )
  83. continue;
  84. }
  85. if( (flags & SS_GENERIC_UNACCELERATED_BIT) &&
  86. ((pfd.dwFlags & (PFD_GENERIC_FORMAT|PFD_GENERIC_ACCELERATED))
  87. != PFD_GENERIC_FORMAT) )
  88. continue;
  89. if( (flags & SS_NO_SYSTEM_PALETTE_BIT) &&
  90. (pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE) )
  91. continue;
  92. if( cDepthBits ) {
  93. if( pfd.cDepthBits < cDepthBits )
  94. continue;
  95. } else {
  96. // No depth buffer required, but use it if nothing better
  97. if( pfd.cDepthBits ) {
  98. if( pfd.dwFlags & PFD_GENERIC_ACCELERATED )
  99. // Accelerated pixel format - we may as well use this, even
  100. // though we don't need depth. Otherwise if we keep going
  101. // to find a better match, we run the risk of overstepping
  102. // all the accelerated formats and picking a slower format.
  103. return i;
  104. iBest = i;
  105. continue;
  106. }
  107. }
  108. // We have found something useful
  109. return i;
  110. } while (++i <= MaxPFDs);
  111. if( iBest )
  112. // not an exact match, but good enough
  113. return iBest;
  114. // If we reach here, we have failed to find a suitable pixel format.
  115. // See if the system can find us one.
  116. memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) );
  117. pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
  118. pfd.cColorBits = (BYTE)cColorBits;
  119. pfd.cDepthBits = (BYTE)cDepthBits;
  120. pfd.iPixelType = PFD_TYPE_RGBA;
  121. pfd.dwFlags = PFD_SUPPORT_OPENGL;
  122. if( bDoubleBuf )
  123. pfd.dwFlags |= PFD_DOUBLEBUFFER;
  124. if( flags & SS_BITMAP_BIT )
  125. pfd.dwFlags |= PFD_DRAW_TO_BITMAP;
  126. else
  127. pfd.dwFlags |= PFD_DRAW_TO_WINDOW;
  128. if( (flags & SS_GENERIC_UNACCELERATED_BIT) ||
  129. (flags & SS_NO_SYSTEM_PALETTE_BIT) )
  130. // If either of these flags are set, we should be safe specifying a
  131. // 'slow' pixel format that supports bitmap drawing
  132. //mf: DRAW_TO_WINDOW seems to override this...
  133. pfd.dwFlags |= PFD_DRAW_TO_BITMAP;
  134. SS_WARNING( "SSU_ChoosePixelFormat failed, calling ChoosePIxelFormat\n" );
  135. return ChoosePixelFormat( hdc, &pfd );
  136. }
  137. /******************************Public*Routine******************************\
  138. * SSU_SetupPixelFormat
  139. *
  140. * Choose pixel format according to supplied flags. If ppfd is non-NULL,
  141. * call DescribePixelFormat with it.
  142. *
  143. \**************************************************************************/
  144. BOOL
  145. SSU_SetupPixelFormat(HDC hdc, int flags, PIXELFORMATDESCRIPTOR *ppfd )
  146. {
  147. int pixelFormat;
  148. int nTryAgain = 4;
  149. do{
  150. if( (pixelFormat = SSU_ChoosePixelFormat(hdc, flags)) &&
  151. SetPixelFormat(hdc, pixelFormat, NULL) ) {
  152. SS_DBGLEVEL1( SS_LEVEL_INFO,
  153. "SSU_SetupPixelFormat: Setting pixel format %d\n", pixelFormat );
  154. if( ppfd )
  155. DescribePixelFormat(hdc, pixelFormat,
  156. sizeof(PIXELFORMATDESCRIPTOR), ppfd);
  157. return TRUE; // Success
  158. }
  159. // Failed to set pixel format. Try again after waiting a bit (win95
  160. // bug with full screen dos box)
  161. Sleep( 1000 ); // Wait a second between attempts
  162. } while( nTryAgain-- );
  163. return FALSE;
  164. }
  165. /******************************Public*Routine******************************\
  166. * SSU_bNeedPalette
  167. *
  168. \**************************************************************************/
  169. BOOL
  170. SSU_bNeedPalette( PIXELFORMATDESCRIPTOR *ppfd )
  171. {
  172. if (ppfd->dwFlags & PFD_NEED_PALETTE)
  173. return TRUE;
  174. else
  175. return FALSE;
  176. }
  177. /******************************Public*Routine******************************\
  178. * SSU_PixelFormatDescriptorFromDc
  179. *
  180. \**************************************************************************/
  181. int
  182. SSU_PixelFormatDescriptorFromDc( HDC hdc, PIXELFORMATDESCRIPTOR *Pfd )
  183. {
  184. int PfdIndex;
  185. if ( 0 < (PfdIndex = GetPixelFormat( hdc )) )
  186. {
  187. if ( 0 < DescribePixelFormat( hdc, PfdIndex, sizeof(*Pfd), Pfd ) )
  188. {
  189. return(PfdIndex);
  190. }
  191. }
  192. return 0;
  193. }
  194. /******************************Public*Routine******************************\
  195. * ss_ChangeDisplaySettings
  196. *
  197. * Try changing display settings.
  198. * If bitDepth is 0, use current bit depth
  199. *
  200. \**************************************************************************/
  201. BOOL
  202. ss_ChangeDisplaySettings( int width, int height, int bitDepth )
  203. {
  204. int change;
  205. DEVMODE dm = {0};
  206. dm.dmSize = sizeof(dm);
  207. dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
  208. dm.dmPelsWidth = width;
  209. dm.dmPelsHeight = height;
  210. if( bitDepth != 0 ) {
  211. dm.dmFields |= DM_BITSPERPEL;
  212. dm.dmBitsPerPel = bitDepth;
  213. }
  214. // change = ChangeDisplaySettings(&dm, CDS_TEST);
  215. change = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
  216. if( change == DISP_CHANGE_SUCCESSFUL )
  217. return TRUE;
  218. else
  219. return FALSE;
  220. }
  221. /******************************Public*Routine******************************\
  222. * ss_QueryDisplaySettings
  223. *
  224. * Find out what diplay resolutions are available.
  225. *
  226. \**************************************************************************/
  227. void
  228. ss_QueryDisplaySettings( void )
  229. {
  230. int i = 0;
  231. DEVMODE devMode = {0};
  232. while( EnumDisplaySettings( NULL, i, &devMode ) ) {
  233. i++;
  234. }
  235. }
  236. /******************************Public*Routine******************************\
  237. * ss_QueryGLVersion
  238. *
  239. * Find out what GL version is being loaded. If it's 1.1, set various
  240. * global capabilities.
  241. *
  242. \**************************************************************************/
  243. void
  244. ss_QueryGLVersion( void )
  245. {
  246. // Get GL version
  247. if( strstr( (char *) glGetString(GL_VERSION), "1.1") ) {
  248. gbGLv1_1 = TRUE;
  249. gbTextureObjects = TRUE;
  250. } else {
  251. gbGLv1_1 = FALSE;
  252. gbTextureObjects = FALSE;
  253. }
  254. if( !gbTextureObjects ) {
  255. SS_DBGINFO( "ss_QueryGLVersion: Texture Objects disabled\n" );
  256. }
  257. }
  258. /******************************Public*Routine******************************\
  259. * ss_fOnGL11
  260. *
  261. * True if running on OpenGL v.1.1x
  262. *
  263. \**************************************************************************/
  264. BOOL
  265. ss_fOnGL11( void )
  266. {
  267. return gbGLv1_1;
  268. }
  269. /******************************Public*Routine******************************\
  270. * ss_QueryOSVersion
  271. *
  272. * Query the OS version
  273. *
  274. \**************************************************************************/
  275. void
  276. ss_QueryOSVersion( void )
  277. {
  278. gosvi.dwOSVersionInfoSize = sizeof(gosvi);
  279. GetVersionEx(&gosvi);
  280. }
  281. /******************************Public*Routine******************************\
  282. * ss_fOnNT35
  283. *
  284. * True if running on NT version 3.51 or less
  285. *
  286. \**************************************************************************/
  287. BOOL
  288. ss_fOnNT35( void )
  289. {
  290. static fOnNT35;
  291. static bInited = FALSE;
  292. if( !bInited ) {
  293. if( !gosvi.dwOSVersionInfoSize )
  294. ss_QueryOSVersion();
  295. fOnNT35 =
  296. (
  297. (gosvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  298. (gosvi.dwMajorVersion == 3 && gosvi.dwMinorVersion <= 51)
  299. );
  300. bInited = TRUE;
  301. }
  302. return fOnNT35;
  303. }
  304. /******************************Public*Routine******************************\
  305. * ss_fOnWin95
  306. *
  307. * True if running on Windows 95
  308. *
  309. \**************************************************************************/
  310. BOOL
  311. ss_fOnWin95( void )
  312. {
  313. static fOnWin95;
  314. static bInited = FALSE;
  315. if( !bInited ) {
  316. if( !gosvi.dwOSVersionInfoSize )
  317. ss_QueryOSVersion();
  318. fOnWin95 = ( gosvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS );
  319. bInited = TRUE;
  320. }
  321. return fOnWin95;
  322. }
  323. /******************************Public*Routine******************************\
  324. * ss_fPreviewMode
  325. *
  326. * True if running in Display setting's child preview window
  327. *
  328. \**************************************************************************/
  329. BOOL
  330. ss_fPreviewMode( void )
  331. {
  332. return gpss->type == SS_TYPE_PREVIEW;
  333. }
  334. /******************************Public*Routine******************************\
  335. * ss_fFullScreenMode
  336. *
  337. * True if running full screen (/s option)
  338. *
  339. \**************************************************************************/
  340. BOOL
  341. ss_fFullScreenMode( void )
  342. {
  343. return gpss->type == SS_TYPE_FULLSCREEN;
  344. }
  345. BOOL
  346. ss_fConfigMode( void )
  347. {
  348. return gpss->type == SS_TYPE_CONFIG;
  349. }
  350. BOOL
  351. ss_fWindowMode( void )
  352. {
  353. return gpss->type == SS_TYPE_NORMAL;
  354. }
  355. /******************************Public*Routine******************************\
  356. * ss_RedrawDesktop
  357. *
  358. * Causes the entire desktop to be redrawn
  359. *
  360. \**************************************************************************/
  361. BOOL
  362. ss_RedrawDesktop( void )
  363. {
  364. return RedrawWindow( NULL, NULL, NULL, RDW_ERASE | RDW_INVALIDATE |
  365. RDW_ERASENOW | RDW_UPDATENOW | RDW_ALLCHILDREN );
  366. }