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.

938 lines
24 KiB

4 years ago
  1. /******************************Module*Header*******************************\
  2. * Module Name: glscrnsv.c
  3. *
  4. * Companion file to scrnsave.c. Hooks out any changes in functionality
  5. * defined as GL_SCRNSAVE in scrnsave.c, and does general intialization.
  6. *
  7. * Copyright (c) 1996 Microsoft Corporation
  8. *
  9. \**************************************************************************/
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include <stdlib.h>
  13. #include "scrnsave.h"
  14. #include "glscrnsv.h"
  15. #include "ssintrnl.hxx"
  16. #include "sswindow.hxx"
  17. #include "glscrnsv.hxx"
  18. #include "sswproc.hxx"
  19. static UINT (*KeyDownFunc)(int) = NULL;
  20. // Global ptr to screen saver instance
  21. SCRNSAVE *gpss = NULL;
  22. // Global strings.
  23. #define GEN_STRING_SIZE 64
  24. TCHAR szScreenSaverTitle[GEN_STRING_SIZE];
  25. extern TCHAR szClassName[]; // from sswindow.cxx
  26. LPCTSTR pszWindowClass = TEXT("WindowsScreenSaverClass"); // main class name
  27. TCHAR szClassName[] = TEXT("ScreenSaverClass"); // child class name
  28. // forward declarations of internal fns
  29. static BOOL RegisterMainClass( WNDPROC wndProc, HBRUSH hbrBg, HCURSOR hCursor );
  30. static BOOL RegisterChildClass();
  31. static BOOL AttemptResolutionSwitch( int width, int height, ISIZE *pNewSize );
  32. // externs
  33. extern void InitRealScreenSave(); // scrnsave.cxx
  34. extern LRESULT WINAPI
  35. RealScreenSaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  36. extern VOID UnloadPwdDLL(VOID);
  37. extern BOOL GLScreenSaverConfigureDialog( HWND hDlg, UINT msg, WPARAM wParam,
  38. LPARAM lParam ); // sswproc.cxx
  39. #ifdef SS_INITIAL_CLEAR
  40. static void InitialClear( PSSW *pssw );
  41. #endif
  42. #ifdef SS_WIN95
  43. #define SS_WIN95_MULTIWINDOW_WORKAROUND 1
  44. #define SS_WIN95_DESKTOP_REDRAW_FIX 1
  45. static BOOL bPowerSaveEnabled();
  46. #endif
  47. /**************************************************************************\
  48. * GLDoScreenSave
  49. *
  50. * Runs the screen saver in the specified mode
  51. *
  52. * GL version of DoScreenSave in scrnsave.c
  53. *
  54. * Does basic init, creates initial set of windows, and starts the message
  55. * loop, which runs until terminated by some event.
  56. *
  57. \**************************************************************************/
  58. static int
  59. GLDoScreenSave( int winType, LPARAM lParam )
  60. {
  61. MSG msg;
  62. // Create screen saver instance - this calls ss_Init()
  63. SCRNSAVE ss( winType, lParam );
  64. // Setup all the windows and start the message loop
  65. if( ss.SetupInitialWindows() )
  66. {
  67. // Send message to main window to start the drawing timer
  68. #ifdef SS_DELAYED_START_KLUGE
  69. // Kluge to work around 'window-not-ready' problem in child
  70. // preview mode - trigger off of WM_PAINT instead
  71. if( ! SS_DELAY_START(winType) )
  72. SendMessage( ss.psswMain->hwnd, SS_WM_START, 0, 0 );
  73. #else
  74. SendMessage( ss.psswMain->hwnd, SS_WM_START, 0, 0 );
  75. #endif // SS_DELAYED_START_KLUGE
  76. while( GetMessage( &msg, NULL, 0, 0 ) )
  77. {
  78. TranslateMessage( &msg );
  79. DispatchMessage( &msg );
  80. }
  81. }
  82. // We're done - screen saver exiting.
  83. // free password-handling DLL if loaded
  84. UnloadPwdDLL();
  85. return msg.wParam;
  86. }
  87. /**************************************************************************\
  88. * SCRNSAVE constructors
  89. *
  90. \**************************************************************************/
  91. SCRNSAVE::SCRNSAVE( int typeArg, LPARAM lParam )
  92. {
  93. type = typeArg;
  94. initParam = lParam;
  95. Init();
  96. }
  97. SCRNSAVE::SCRNSAVE( int typeArg )
  98. {
  99. type = typeArg;
  100. initParam = 0;
  101. Init();
  102. }
  103. void
  104. SCRNSAVE::Init()
  105. {
  106. psswMain = NULL;
  107. psswGL = NULL;
  108. bResSwitch = FALSE;
  109. pssc = NULL;
  110. pssPal = NULL;
  111. flags = 0;
  112. #ifdef SS_DEBUG
  113. bDoTiming = type == SS_TYPE_NORMAL ? TRUE : FALSE;
  114. #endif
  115. // Global ptr to the screen saver instance
  116. gpss = this;
  117. // Platform detections
  118. ss_QueryOSVersion();
  119. // Initialize randomizer
  120. ss_RandInit();
  121. // Disable message boxes in GLAUX
  122. tkErrorPopups(FALSE);
  123. // Create multi-purpose black bg brush
  124. hbrBg = (HBRUSH) GetStockObject( BLACK_BRUSH );
  125. // Call client ss's init function, to get ptr to its configuration
  126. // request
  127. if( type == SS_TYPE_CONFIG ) {
  128. // This case handled differently
  129. return;
  130. }
  131. pssc = ss_Init();
  132. SS_ASSERT( pssc, "SCRNSAVE constructor failure\n" );
  133. // Set GL config structure from pssc
  134. GLc.pfFlags = 0;
  135. GLc.hrc = 0;
  136. GLc.pStretch = NULL;
  137. switch( pssc->depthType ) {
  138. case SS_DEPTH16 :
  139. GLc.pfFlags |= SS_DEPTH16_BIT;
  140. break;
  141. case SS_DEPTH32 :
  142. GLc.pfFlags |= SS_DEPTH32_BIT;
  143. break;
  144. }
  145. if( pssc->bDoubleBuf )
  146. GLc.pfFlags |= SS_DOUBLEBUF_BIT;
  147. if( pssc->bStretch )
  148. GLc.pStretch = &pssc->stretchInfo;
  149. }
  150. /**************************************************************************\
  151. * SetupInitialWindows
  152. *
  153. * Create / Configure all required windows.
  154. *
  155. \**************************************************************************/
  156. BOOL
  157. SCRNSAVE::SetupInitialWindows()
  158. {
  159. // Create the windows
  160. if( ! CreateInitialWindows() ) {
  161. SS_WARNING( "SCRNSAVE:: Couldn't create windows\n" );
  162. return FALSE;
  163. }
  164. // Initial window clear
  165. //mf: doesn't seem to be necessary now...
  166. //#define SS_INITIAL_MAIN_WINDOW_CLEAR 1
  167. #ifdef SS_INITIAL_MAIN_WINDOW_CLEAR
  168. if( type == SS_TYPE_PREVIEW ) {
  169. // Make sure the screen is cleared to black before we start drawing
  170. // anything, as sometimes the background WM_PAINT doesn't get to us right
  171. // away. This is only a problem in preview mode
  172. psswMain->GdiClear();
  173. }
  174. #endif
  175. // Configure and Init the windows, if applicable
  176. #ifdef SS_DELAYED_START_KLUGE
  177. // delay start for some configurations
  178. if( ! SS_DELAY_START(type) ) {
  179. SendMessage( psswMain->hwnd, SS_WM_INITGL, 0, 0 );
  180. }
  181. #else
  182. SendMessage( psswMain->hwnd, SS_WM_INITGL, 0, 0 );
  183. #endif // SS_DELAYED_START_KLUGE
  184. return TRUE;
  185. }
  186. /**************************************************************************\
  187. * CreateInitialWindows
  188. *
  189. * Create the intitial set of windows.
  190. *
  191. \**************************************************************************/
  192. BOOL
  193. SCRNSAVE::CreateInitialWindows()
  194. {
  195. PSSW pssw;
  196. UINT uStyle;
  197. UINT uExStyle;
  198. LPCTSTR pszWindowTitle;
  199. if( !pssc )
  200. return FALSE;
  201. // Handle any request for resolution change
  202. #define SS_RESOLUTION_SWITCH 1
  203. #ifdef SS_RESOLUTION_SWITCH
  204. if( pssc->bStretch && (type == SS_TYPE_FULLSCREEN)
  205. && ss_fOnWin95() ) {
  206. STRETCH_INFO *pStretch = &pssc->stretchInfo;
  207. ISIZE newSize;
  208. // Try and change screen resolution to match stretch size
  209. bResSwitch = AttemptResolutionSwitch( pStretch->baseWidth,
  210. pStretch->baseHeight, &newSize );
  211. // Is stretching still necessary if resolution changed ?
  212. if( bResSwitch ) {
  213. if( (newSize.width == pStretch->baseWidth) &&
  214. (newSize.height == pStretch->baseHeight) )
  215. // exact match, no stretching now necessary
  216. pssc->bStretch = FALSE;
  217. }
  218. }
  219. #endif
  220. // Currently the bitmaps used in stretch mode don't support palette
  221. // messages, so disable any stretching when in PREVIEW mode (where we
  222. // need to support palette interaction).
  223. // mf: actually this is only a consideration in 8-bit mode...
  224. if( (type == SS_TYPE_PREVIEW) && pssc->bStretch )
  225. pssc->bStretch = FALSE;
  226. // Create the main ss window
  227. if( ! CreateMainWindow() )
  228. return FALSE;
  229. #ifdef SS_INITIAL_CLEAR
  230. // If main window is transparent, can do an initial clear here before
  231. // any other windows are created or palettes modified
  232. // This is bogus on NT, as system switches to secure desktop when screen
  233. // saver kicks in automatically.
  234. InitialClear( pssw );
  235. #endif
  236. // For now, simple window environment is described by pssc, so things
  237. // like bFloater and bStretch are mutually exclusive.
  238. SS_GL_CONFIG *pGLc = &gpss->GLc;
  239. if( pssc->bFloater ) {
  240. if( !(pssw = CreateChildWindow( &pssc->floaterInfo )) )
  241. return FALSE;
  242. pssw->pGLc = pGLc;
  243. psswGL = pssw; // support old-style
  244. } else {
  245. psswMain->pGLc = pGLc;
  246. psswGL = psswMain; // support old-style
  247. }
  248. return TRUE;
  249. }
  250. /**************************************************************************\
  251. * NormalWindowScreenSaverProc
  252. *
  253. * Highest level window proc, used only in normal window (/w) mode.
  254. *
  255. \**************************************************************************/
  256. LRESULT WINAPI
  257. NormalWindowScreenSaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  258. {
  259. switch( uMsg )
  260. {
  261. case WM_SETTEXT:
  262. // RealScreenSaverProc won't allow this - bypass it
  263. return ScreenSaverProc( hWnd, uMsg, wParam, lParam );
  264. case WM_CHAR:
  265. if( KeyDownFunc ) {
  266. int key = wParam;
  267. (*KeyDownFunc)(key);
  268. }
  269. break;
  270. case WM_KEYDOWN:
  271. if( wParam == VK_ESCAPE ) {
  272. PostMessage( hWnd, WM_CLOSE, 0, 0l );
  273. break;
  274. } else if( KeyDownFunc ) {
  275. (*KeyDownFunc)(wParam);
  276. return 0;
  277. }
  278. return 0; // ??
  279. default:
  280. break;
  281. }
  282. return RealScreenSaverProc( hWnd, uMsg, wParam, lParam );
  283. }
  284. /**************************************************************************\
  285. * DoScreenSave
  286. *
  287. * Hooked out version of DoScreenSave in standard scrnsave.c
  288. *
  289. \**************************************************************************/
  290. int
  291. DoScreenSave( HWND hwndParent )
  292. {
  293. return GLDoScreenSave( hwndParent ? SS_TYPE_PREVIEW : SS_TYPE_FULLSCREEN,
  294. (LPARAM) hwndParent );
  295. }
  296. /**************************************************************************\
  297. * DoWindowedScreenSave
  298. *
  299. * Called when screen saver invoked with /w (window mode) parameter
  300. *
  301. \**************************************************************************/
  302. int
  303. DoWindowedScreenSave( LPCTSTR szArgs )
  304. {
  305. return GLDoScreenSave( SS_TYPE_NORMAL, (LPARAM) szArgs );
  306. }
  307. /**************************************************************************\
  308. * DoConfigBox
  309. *
  310. * Hooked out version of DoConfigBox in standard scrnsave.c
  311. *
  312. \**************************************************************************/
  313. int
  314. DoConfigBox( HWND hwndParent )
  315. {
  316. // let the consumer register any special controls for the dialog
  317. if( !RegisterDialogClasses( hMainInstance ) )
  318. return FALSE;
  319. // Create screen saver instance
  320. SCRNSAVE ss( SS_TYPE_CONFIG );
  321. int retVal = DialogBox( hMainInstance,
  322. MAKEINTRESOURCE( DLG_SCRNSAVECONFIGURE ),
  323. hwndParent, (DLGPROC)GLScreenSaverConfigureDialog );
  324. return retVal;
  325. }
  326. /**************************************************************************\
  327. * CreateMainWindow
  328. *
  329. * Creates main screen saver window based on the window type
  330. *
  331. \**************************************************************************/
  332. BOOL
  333. SCRNSAVE::CreateMainWindow()
  334. {
  335. WNDPROC wndProc;
  336. int nCx, nCy;
  337. ISIZE size;
  338. UINT uStyle = 0;
  339. UINT uExStyle = 0;
  340. IPOINT2D pos;
  341. LPCTSTR pszWindowTitle;
  342. HCURSOR hCursor = NULL;
  343. HBRUSH hbrBgMain;
  344. PSSW pssw;
  345. BOOL bFailed;
  346. HWND hwndParent = NULL;
  347. wndProc = RealScreenSaverProc;
  348. switch( type ) {
  349. case SS_TYPE_FULLSCREEN:
  350. {
  351. HWND hOther;
  352. nCx = GetSystemMetrics( SM_CXSCREEN );
  353. nCy = GetSystemMetrics( SM_CYSCREEN );
  354. #ifdef SS_DEBUG
  355. //#define SS_FULLSCREEN_DEBUG 1
  356. #ifdef SS_FULLSCREEN_DEBUG
  357. // Reduce window size so we can see debugger
  358. nCx /= 2;
  359. nCy /= 2;
  360. #endif
  361. #endif
  362. uStyle = WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  363. uExStyle = WS_EX_TOPMOST;
  364. pszWindowTitle = TEXT("Screen Saver"); // MUST differ from preview
  365. // if there is another NORMAL screen save instance, switch to it
  366. hOther = FindWindow( szClassName, pszWindowTitle );
  367. if( hOther && IsWindow( hOther ) )
  368. {
  369. SetForegroundWindow( hOther );
  370. return FALSE;
  371. }
  372. InitRealScreenSave();
  373. }
  374. break;
  375. case SS_TYPE_PREVIEW:
  376. {
  377. RECT rcParent;
  378. hwndParent = (HWND) initParam;
  379. GetClientRect( hwndParent, &rcParent );
  380. fChildPreview = TRUE;
  381. nCx = rcParent.right;
  382. nCy = rcParent.bottom;
  383. uStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN;
  384. pszWindowTitle = TEXT("Preview"); // MUST differ from full screen
  385. }
  386. break;
  387. case SS_TYPE_NORMAL:
  388. {
  389. // We set fChildPreview even when we're running in a normal window,
  390. // as this flag is used in scrnsave.c to differentiate from full
  391. // screen.
  392. fChildPreview = TRUE;
  393. // init size to half screen by default
  394. nCx = GetSystemMetrics( SM_CXSCREEN ) >> 1;
  395. nCy = GetSystemMetrics( SM_CYSCREEN ) >> 1;
  396. if( initParam ) {
  397. // get size of window from args
  398. LPCTSTR szArgs = (LPCTSTR) initParam;
  399. //mf: not yet implemented
  400. }
  401. LoadString(hMainInstance, IDS_DESCRIPTION, szScreenSaverTitle,
  402. sizeof(szScreenSaverTitle) / sizeof(TCHAR));
  403. pszWindowTitle = szScreenSaverTitle; // MUST differ from preview
  404. uStyle = WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
  405. WS_CLIPSIBLINGS;
  406. hCursor = LoadCursor( NULL, IDC_ARROW );
  407. // Wrap RealScreenSaverProc
  408. wndProc = NormalWindowScreenSaverProc;
  409. }
  410. break;
  411. default:
  412. break;
  413. }
  414. size.width = nCx;
  415. size.height = nCy;
  416. #ifdef SS_INITIAL_CLEAR
  417. hbrBgMain = NULL;
  418. #else
  419. hbrBgMain = hbrBg;
  420. #endif
  421. pos.x = pos.y = 0;
  422. // Create SSW window wrapper
  423. pssw = new SSW( NULL, // parent
  424. &size,
  425. &pos,
  426. FALSE, // bMotion
  427. NULL // ChildSizeFunc
  428. );
  429. if( !pssw )
  430. return FALSE;
  431. // Initialize the window class and create the window
  432. if( !RegisterMainClass
  433. (
  434. wndProc,
  435. hbrBgMain,
  436. hCursor
  437. ) ||
  438. !pssw->CreateSSWindow
  439. (
  440. hMainInstance,
  441. uStyle,
  442. uExStyle,
  443. szScreenSaverTitle,
  444. wndProc,
  445. pszWindowClass,
  446. hwndParent // mf: ! hwndParentOverride
  447. ) )
  448. {
  449. delete pssw;
  450. return FALSE;
  451. }
  452. if( type != SS_TYPE_PREVIEW )
  453. #ifndef SS_DEBUG
  454. SetForegroundWindow( pssw->hwnd );
  455. #else
  456. {
  457. if( !SetForegroundWindow( pssw->hwnd ) )
  458. SS_DBGPRINT( "Main_Proc: SetForegroundWindow failed\n" );
  459. }
  460. #endif
  461. // Always configure the main window for gdi
  462. pssw->ConfigureForGdi();
  463. psswMain = pssw;
  464. return TRUE;
  465. }
  466. /**************************************************************************\
  467. * CreateChildWindow
  468. *
  469. * Creates a child window of the parent window
  470. *
  471. * This is a kind of wrapper-constructor
  472. \**************************************************************************/
  473. PSSW
  474. SCRNSAVE::CreateChildWindow( FLOATER_INFO *pFloater )
  475. {
  476. pFloater->bSubWindow = FALSE; // default is no logical subwin's
  477. #ifdef SS_WIN95_MULTIWINDOW_WORKAROUND
  478. if( ss_fOnWin95() && ss_fFullScreenMode() && bPowerSaveEnabled() ) {
  479. // Make the floater a logical sub-window of the main window, not a
  480. // separate window. This works around a USER bug where the power
  481. // save feature was not getting activated for multi-windowed screen
  482. // savers
  483. SS_DBGINFO( "SCRNSAVE::CreateChildWindow : Using logical sub-windows\n" );
  484. pFloater->bSubWindow = TRUE;
  485. }
  486. #endif // SS_WIN95_MULTIWINDOW_WORKAROUND
  487. // Register child window class
  488. // This only has to be done once, since so far, all child window
  489. // classes are the same
  490. if( !pFloater->bSubWindow && !RegisterChildClass() )
  491. return NULL;
  492. return CreateChildWindow( psswMain, pFloater );
  493. }
  494. PSSW
  495. SCRNSAVE::CreateChildWindow( PSSW psswParent, FLOATER_INFO *pFloater )
  496. {
  497. UINT uStyle = 0;
  498. UINT uExStyle = 0;
  499. PSSW pssw;
  500. uStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  501. // Size and position are NULL here, as the SSW will call the size
  502. // function callback in pFloater to get these and other values
  503. // Create the SSW window wrapper
  504. pssw = new SSW( psswParent, // parent
  505. NULL, // size
  506. NULL, // position
  507. pFloater->bMotion,
  508. pFloater->ChildSizeFunc
  509. );
  510. if( !pssw )
  511. return NULL;
  512. if( pFloater->bSubWindow )
  513. // Don't need to create win32 window
  514. return pssw;
  515. // Create a window
  516. if( !pssw->CreateSSWindow
  517. (
  518. hMainInstance,
  519. uStyle,
  520. 0, // uExStyle
  521. szScreenSaverTitle ,
  522. SS_ScreenSaverProc,
  523. szClassName,
  524. NULL // hwndParentOverride
  525. ) )
  526. {
  527. delete pssw;
  528. return NULL;
  529. }
  530. return pssw;
  531. }
  532. /**************************************************************************\
  533. * RegisterMainClass
  534. *
  535. * Registers class of the main SS window
  536. \**************************************************************************/
  537. static BOOL
  538. RegisterMainClass( WNDPROC wndProc, HBRUSH hbrBg, HCURSOR hCursor )
  539. {
  540. WNDCLASS cls;
  541. cls.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC;
  542. cls.lpfnWndProc = wndProc;
  543. cls.cbClsExtra = 0;
  544. cls.cbWndExtra = 0;
  545. cls.hInstance = hMainInstance;
  546. cls.hIcon = LoadIcon( hMainInstance, MAKEINTATOM( ID_APP ) );
  547. cls.hCursor = hCursor;
  548. cls.hbrBackground = hbrBg;
  549. cls.lpszMenuName = (LPTSTR)NULL;
  550. cls.lpszClassName = (LPTSTR)pszWindowClass;
  551. return RegisterClass(&cls);
  552. }
  553. /**************************************************************************\
  554. * RegisterChildClass
  555. *
  556. * Registers class of a standard child window
  557. \**************************************************************************/
  558. static BOOL
  559. RegisterChildClass()
  560. {
  561. static BOOL bRegistered = FALSE;
  562. if( bRegistered )
  563. return TRUE;
  564. WNDCLASS cls;
  565. cls.style = CS_VREDRAW | CS_HREDRAW;
  566. cls.lpfnWndProc = SS_ScreenSaverProc;
  567. cls.cbClsExtra = 0;
  568. cls.cbWndExtra = 0;
  569. cls.hInstance = hMainInstance;
  570. cls.hIcon = NULL;
  571. cls.hCursor = NULL;
  572. cls.hbrBackground = NULL;
  573. cls.lpszMenuName = (LPTSTR)NULL;
  574. cls.lpszClassName = (LPTSTR)szClassName;
  575. if( !RegisterClass(&cls) )
  576. return FALSE;
  577. // success
  578. bRegistered = TRUE;
  579. return TRUE;
  580. }
  581. /******************************Public*Routine******************************\
  582. * AttemptResolutionSwitch
  583. *
  584. * Try doing resolution switching to match or get close to the desired size.
  585. *
  586. \**************************************************************************/
  587. static BOOL
  588. AttemptResolutionSwitch( int width, int height, ISIZE *pNewSize )
  589. {
  590. BOOL bChanged = FALSE;
  591. // Try doing resolution switching to match or get close to the
  592. // desired width and height
  593. // Try switching to requested size
  594. #if 0
  595. //mf: not ready for prime time
  596. if( ss_ChangeDisplaySettings( width, height, 0 ) ) {
  597. #else
  598. if( 0 ) {
  599. // for now force failure of user request and try standard 640x480
  600. #endif
  601. bChanged = TRUE;
  602. } else {
  603. // Can't switch to requested size, try for best match
  604. // mf: !!! for now, let's play it safe and just try 640x480.
  605. width = 640;
  606. height = 480;
  607. // If screen already this size or less, leave be
  608. if( (GetSystemMetrics( SM_CXSCREEN ) <= width) &&
  609. (GetSystemMetrics( SM_CYSCREEN ) <= height) )
  610. return FALSE;
  611. //mf: use this when trying for best match
  612. // ss_QueryDisplaySettings();
  613. if( ss_ChangeDisplaySettings( width, height, 0 ) )
  614. bChanged = TRUE;
  615. }
  616. if( bChanged ) {
  617. pNewSize->width = width;
  618. pNewSize->height = height;
  619. }
  620. return bChanged;
  621. }
  622. #ifdef SS_INITIAL_CLEAR
  623. static void
  624. InitialClear( PSSW *pssw )
  625. {
  626. ss_GdiRectWipeClear( pssw->hwnd, pssw->size.width, pssw->size.height );
  627. }
  628. #endif // SS_INITIAL_CLEAR
  629. /**************************************************************************\
  630. * CloseWindows
  631. *
  632. * Close down any open windows.
  633. *
  634. * This sends a WM_CLOSE message to the top-level window if it is still open. If
  635. * the window has any children, they are also closed. For each window, the
  636. * SSW destructor is called.
  637. \**************************************************************************/
  638. void
  639. SCRNSAVE::CloseWindows()
  640. {
  641. if( psswMain ) {
  642. if( psswMain->bOwnWindow )
  643. DestroyWindow( psswMain->hwnd );
  644. else
  645. delete psswMain;
  646. }
  647. }
  648. /**************************************************************************\
  649. * SCRNSAVE destructor
  650. *
  651. \**************************************************************************/
  652. SCRNSAVE::~SCRNSAVE()
  653. {
  654. // Close any open windows (there might be some open if errors occurred)
  655. CloseWindows();
  656. #ifdef SS_WIN95_DESKTOP_REDRAW_FIX
  657. // On win95, sometimes the desktop is drawn incorrectly after we have
  658. // taken over the palette
  659. if( flags & SS_PALETTE_TAKEOVER ) {
  660. SS_DBGINFO( "SCRNSAVE destructor: Redrawing desktop\n" );
  661. ss_RedrawDesktop();
  662. }
  663. #endif
  664. if( bResSwitch ) {
  665. // Restore previous display settings
  666. ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
  667. }
  668. gpss = NULL;
  669. }
  670. #ifdef SS_WIN95_MULTIWINDOW_WORKAROUND
  671. // Macro to convert string to integer
  672. #ifdef UNICODE
  673. #define sztoi( pszStr ) _wtoi( (wchar_t *) (pszStr) )
  674. #else
  675. #define sztoi( pszStr ) atoi( (char *) (pszStr) )
  676. #endif
  677. /**************************************************************************\
  678. * GetRegValueBool
  679. *
  680. * Get registry value and convert to BOOL
  681. \**************************************************************************/
  682. #define SS_REG_BUF_SIZE 30
  683. static BOOL
  684. bGetRegValueBool( HKEY hKey, LPTSTR szValue, BOOL *pbEnabled )
  685. {
  686. TCHAR szBuf[SS_REG_BUF_SIZE];
  687. DWORD dataSize = SS_REG_BUF_SIZE;
  688. DWORD dwType;
  689. // Get the value
  690. if( ! ( RegQueryValueEx(
  691. hKey,
  692. szValue,
  693. (LPDWORD) NULL,
  694. (LPDWORD) &dwType,
  695. (LPBYTE) szBuf,
  696. (LPDWORD) &dataSize ) == ERROR_SUCCESS
  697. )
  698. )
  699. return FALSE;
  700. // Convert value to BOOL (the expected type is REG_SZ)
  701. switch( dwType ) {
  702. case REG_SZ :
  703. // Convert string to BOOL
  704. *pbEnabled = (BOOL) sztoi( szBuf );
  705. break;
  706. case REG_DWORD :
  707. // Handle numerical value
  708. *pbEnabled = (BOOL) *( (LPDWORD) szBuf );
  709. break;
  710. default:
  711. SS_WARNING( "GetRegValueBool : Unexpected type\n" );
  712. return FALSE;
  713. }
  714. return TRUE;
  715. }
  716. /**************************************************************************\
  717. * bPowerSaveEnabled
  718. *
  719. * Detect if power saving is enabled by checking registry values.
  720. *
  721. \**************************************************************************/
  722. static BOOL
  723. bPowerSaveEnabled()
  724. {
  725. BOOL bLowPowerActive;
  726. BOOL bPowerOffActive;
  727. HKEY hKey;
  728. // Open desktop key
  729. if( ! ( RegOpenKeyEx(
  730. HKEY_CURRENT_USER,
  731. (LPCTSTR) TEXT( "Control Panel\\desktop"),
  732. 0,
  733. KEY_QUERY_VALUE,
  734. &hKey ) == ERROR_SUCCESS
  735. )
  736. )
  737. {
  738. return FALSE; // Can't open desktop key
  739. }
  740. // Check values - power saving is enabled if either ScreenSaveLowPowerActive
  741. // or ScreenSavePowerOffActive is enabled.
  742. if( (
  743. bGetRegValueBool(
  744. hKey,
  745. (LPTSTR) TEXT("ScreenSaveLowPowerActive"),
  746. &bLowPowerActive )
  747. &&
  748. bLowPowerActive
  749. )
  750. ||
  751. (
  752. bGetRegValueBool(
  753. hKey,
  754. (LPTSTR) TEXT("ScreenSavePowerOffActive"),
  755. &bPowerOffActive )
  756. &&
  757. bPowerOffActive
  758. )
  759. )
  760. {
  761. return TRUE;
  762. }
  763. return FALSE;
  764. }
  765. #endif // SS_WIN95_MULTIWINDOW_WORKAROUND