Windows NT 4.0 source code leak
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.

439 lines
11 KiB

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