806 lines
21 KiB
C++
806 lines
21 KiB
C++
/******************************Module*Header*******************************\
|
|
* Module Name: glscrnsv.c
|
|
*
|
|
* Companion file to scrnsave.c. Hooks out any changes in functionality
|
|
* defined as GL_SCRNSAVE in scrnsave.c, and does general intialization.
|
|
*
|
|
* Copyright (c) 1996 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <stdlib.h>
|
|
#include "scrnsave.h"
|
|
|
|
#include "glscrnsv.h"
|
|
#include "ssintrnl.hxx"
|
|
#include "sswindow.hxx"
|
|
#include "glscrnsv.hxx"
|
|
#include "sswproc.hxx"
|
|
|
|
static UINT (*KeyDownFunc)(int) = NULL;
|
|
|
|
// Global ptr to screen saver instance
|
|
SCRNSAVE *gpss = NULL;
|
|
|
|
// Global strings.
|
|
#define GEN_STRING_SIZE 64
|
|
TCHAR szScreenSaverTitle[GEN_STRING_SIZE];
|
|
LPCTSTR pszWindowClass = TEXT("WindowsScreenSaverClass"); // main class name
|
|
LPCTSTR pszChildWindowClass = TEXT("ScreenSaverClass"); // child class name
|
|
|
|
// forward declarations of internal fns
|
|
static BOOL RegisterMainClass( WNDPROC wndProc, HBRUSH hbrBg, HCURSOR hCursor );
|
|
static BOOL RegisterChildClass();
|
|
static BOOL AttemptResolutionSwitch( int width, int height, ISIZE *pNewSize );
|
|
|
|
// externs
|
|
extern void InitRealScreenSave(); // scrnsave.cxx
|
|
extern LRESULT WINAPI
|
|
RealScreenSaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
|
extern VOID UnloadPwdDLL(VOID);
|
|
extern BOOL GLScreenSaverConfigureDialog( HWND hDlg, UINT msg, WPARAM wParam,
|
|
LPARAM lParam ); // sswproc.cxx
|
|
|
|
#ifdef SS_INITIAL_CLEAR
|
|
static void InitialClear( PSSW *pssw );
|
|
#endif
|
|
|
|
/**************************************************************************\
|
|
* GLDoScreenSave
|
|
*
|
|
* Runs the screen saver in the specified mode
|
|
*
|
|
* GL version of DoScreenSave in scrnsave.c
|
|
*
|
|
* Does basic init, creates initial set of windows, and starts the message
|
|
* loop, which runs until terminated by some event.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static INT_PTR
|
|
GLDoScreenSave( int winType, LPARAM lParam )
|
|
{
|
|
MSG msg;
|
|
|
|
// Create screen saver instance - this calls ss_Init()
|
|
SCRNSAVE ss( winType, lParam );
|
|
|
|
// Setup all the windows and start the message loop
|
|
|
|
if( ss.SetupInitialWindows() )
|
|
{
|
|
// Send message to main window to start the drawing timer
|
|
#ifdef SS_DELAYED_START_KLUGE
|
|
// Kluge to work around 'window-not-ready' problem in child
|
|
// preview mode - trigger off of WM_PAINT instead
|
|
if( ! SS_DELAY_START(winType) )
|
|
SendMessage( ss.psswMain->hwnd, SS_WM_START, 0, 0 );
|
|
#else
|
|
SendMessage( ss.psswMain->hwnd, SS_WM_START, 0, 0 );
|
|
#endif // SS_DELAYED_START_KLUGE
|
|
|
|
while( GetMessage( &msg, NULL, 0, 0 ) )
|
|
{
|
|
TranslateMessage( &msg );
|
|
DispatchMessage( &msg );
|
|
}
|
|
}
|
|
|
|
// We're done - screen saver exiting.
|
|
|
|
// free password-handling DLL if loaded
|
|
UnloadPwdDLL();
|
|
|
|
return msg.wParam;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* SCRNSAVE constructors
|
|
*
|
|
\**************************************************************************/
|
|
|
|
SCRNSAVE::SCRNSAVE( int typeArg, LPARAM lParam )
|
|
: type( typeArg ), initParam( lParam )
|
|
{
|
|
Init();
|
|
}
|
|
|
|
SCRNSAVE::SCRNSAVE( int typeArg )
|
|
: type(typeArg)
|
|
{
|
|
initParam = 0;
|
|
Init();
|
|
}
|
|
|
|
void
|
|
SCRNSAVE::Init()
|
|
{
|
|
psswMain = NULL;
|
|
psswGL = NULL;
|
|
bResSwitch = FALSE;
|
|
pssc = NULL;
|
|
pssPal = NULL;
|
|
flags = 0;
|
|
#ifdef SS_DEBUG
|
|
bDoTiming = type == SS_TYPE_NORMAL ? TRUE : FALSE;
|
|
#endif
|
|
|
|
// Global ptr to the screen saver instance
|
|
gpss = this;
|
|
|
|
// Platform detections
|
|
|
|
ss_QueryOSVersion();
|
|
|
|
// Initialize randomizer
|
|
|
|
ss_RandInit();
|
|
|
|
// Disable message boxes in GLAUX
|
|
|
|
tkErrorPopups(FALSE);
|
|
|
|
// Create multi-purpose black bg brush
|
|
|
|
hbrBg = (HBRUSH) GetStockObject( BLACK_BRUSH );
|
|
|
|
// Call client ss's init function, to get ptr to its configuration
|
|
// request
|
|
|
|
if( type == SS_TYPE_CONFIG ) {
|
|
// This case handled differently
|
|
return;
|
|
}
|
|
|
|
pssc = ss_Init();
|
|
SS_ASSERT( pssc, "SCRNSAVE constructor failure\n" );
|
|
|
|
// Set GL config structure from pssc
|
|
|
|
GLc.pfFlags = 0;
|
|
GLc.hrc = 0;
|
|
GLc.pStretch = NULL;
|
|
switch( pssc->depthType ) {
|
|
case SS_DEPTH16 :
|
|
GLc.pfFlags |= SS_DEPTH16_BIT;
|
|
break;
|
|
case SS_DEPTH32 :
|
|
GLc.pfFlags |= SS_DEPTH32_BIT;
|
|
break;
|
|
}
|
|
if( pssc->bDoubleBuf )
|
|
GLc.pfFlags |= SS_DOUBLEBUF_BIT;
|
|
if( pssc->bStretch )
|
|
GLc.pStretch = &pssc->stretchInfo;
|
|
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* SetupInitialWindows
|
|
*
|
|
* Create / Configure all required windows.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
SCRNSAVE::SetupInitialWindows()
|
|
{
|
|
// Create the windows
|
|
|
|
if( ! CreateInitialWindows() ) {
|
|
SS_WARNING( "SCRNSAVE:: Couldn't create windows\n" );
|
|
return FALSE;
|
|
}
|
|
|
|
// Initial window clear
|
|
|
|
//mf: doesn't seem to be necessary now...
|
|
//#define SS_INITIAL_MAIN_WINDOW_CLEAR 1
|
|
#ifdef SS_INITIAL_MAIN_WINDOW_CLEAR
|
|
if( type == SS_TYPE_PREVIEW ) {
|
|
// Make sure the screen is cleared to black before we start drawing
|
|
// anything, as sometimes the background WM_PAINT doesn't get to us right
|
|
// away. This is only a problem in preview mode
|
|
psswMain->GdiClear();
|
|
}
|
|
#endif
|
|
|
|
// Configure and Init the windows, if applicable
|
|
|
|
#ifdef SS_DELAYED_START_KLUGE
|
|
// delay start for some configurations
|
|
if( ! SS_DELAY_START(type) ) {
|
|
SendMessage( psswMain->hwnd, SS_WM_INITGL, 0, 0 );
|
|
}
|
|
#else
|
|
SendMessage( psswMain->hwnd, SS_WM_INITGL, 0, 0 );
|
|
#endif // SS_DELAYED_START_KLUGE
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************\
|
|
* CreateInitialWindows
|
|
*
|
|
* Create the intitial set of windows.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
SCRNSAVE::CreateInitialWindows()
|
|
{
|
|
PSSW pssw;
|
|
UINT uStyle;
|
|
UINT uExStyle;
|
|
LPCTSTR pszWindowTitle;
|
|
|
|
if( !pssc )
|
|
return FALSE;
|
|
|
|
// Handle any request for resolution change
|
|
|
|
#define SS_RESOLUTION_SWITCH 1
|
|
#ifdef SS_RESOLUTION_SWITCH
|
|
if( pssc->bStretch &&
|
|
(type == SS_TYPE_FULLSCREEN) &&
|
|
(GetSystemMetrics(SM_CMONITORS) == 1) )
|
|
{
|
|
|
|
STRETCH_INFO *pStretch = &pssc->stretchInfo;
|
|
ISIZE newSize;
|
|
|
|
// Try and change screen resolution to match stretch size
|
|
bResSwitch = AttemptResolutionSwitch( pStretch->baseWidth,
|
|
pStretch->baseHeight, &newSize );
|
|
// Is stretching still necessary if resolution changed ?
|
|
if( bResSwitch ) {
|
|
if( (newSize.width == pStretch->baseWidth) &&
|
|
(newSize.height == pStretch->baseHeight) )
|
|
// exact match, no stretching now necessary
|
|
pssc->bStretch = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Currently the bitmaps used in stretch mode don't support palette
|
|
// messages, so disable any stretching when in PREVIEW mode (where we
|
|
// need to support palette interaction).
|
|
// mf: actually this is only a consideration in 8-bit mode...
|
|
|
|
if( (type == SS_TYPE_PREVIEW) && pssc->bStretch )
|
|
pssc->bStretch = FALSE;
|
|
|
|
// Create the main ss window
|
|
|
|
if( ! CreateMainWindow() )
|
|
return FALSE;
|
|
|
|
#ifdef SS_INITIAL_CLEAR
|
|
// If main window is transparent, can do an initial clear here before
|
|
// any other windows are created or palettes modified
|
|
// This is bogus on NT, as system switches to secure desktop when screen
|
|
// saver kicks in automatically.
|
|
InitialClear( pssw );
|
|
#endif
|
|
|
|
// For now, simple window environment is described by pssc, so things
|
|
// like bFloater and bStretch are mutually exclusive.
|
|
|
|
SS_GL_CONFIG *pGLc = &gpss->GLc;
|
|
|
|
if( pssc->bFloater ) {
|
|
|
|
if( !(pssw = CreateChildWindow( &pssc->floaterInfo )) )
|
|
return FALSE;
|
|
|
|
pssw->pGLc = pGLc;
|
|
psswGL = pssw; // support old-style
|
|
} else {
|
|
psswMain->pGLc = pGLc;
|
|
psswGL = psswMain; // support old-style
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* NormalWindowScreenSaverProc
|
|
*
|
|
* Highest level window proc, used only in normal window (/w) mode.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
LRESULT WINAPI
|
|
NormalWindowScreenSaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
switch( uMsg )
|
|
{
|
|
case WM_SETTEXT:
|
|
// RealScreenSaverProc won't allow this - bypass it
|
|
return ScreenSaverProc( hWnd, uMsg, wParam, lParam );
|
|
|
|
case WM_CHAR:
|
|
if( KeyDownFunc ) {
|
|
int key = (int)wParam;
|
|
(*KeyDownFunc)(key);
|
|
}
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
if( wParam == VK_ESCAPE ) {
|
|
PostMessage( hWnd, WM_CLOSE, 0, 0l );
|
|
break;
|
|
} else if( KeyDownFunc ) {
|
|
(*KeyDownFunc)((int)wParam);
|
|
return 0;
|
|
}
|
|
return 0; // ??
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return RealScreenSaverProc( hWnd, uMsg, wParam, lParam );
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* DoScreenSave
|
|
*
|
|
* Hooked out version of DoScreenSave in standard scrnsave.c
|
|
*
|
|
\**************************************************************************/
|
|
|
|
INT_PTR
|
|
DoScreenSave( HWND hwndParent )
|
|
{
|
|
return GLDoScreenSave( hwndParent ? SS_TYPE_PREVIEW : SS_TYPE_FULLSCREEN,
|
|
(LPARAM) hwndParent );
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* DoWindowedScreenSave
|
|
*
|
|
* Called when screen saver invoked with /w (window mode) parameter
|
|
*
|
|
\**************************************************************************/
|
|
|
|
INT_PTR
|
|
DoWindowedScreenSave( LPCTSTR szArgs )
|
|
{
|
|
return GLDoScreenSave( SS_TYPE_NORMAL, (LPARAM) szArgs );
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* DoConfigBox
|
|
*
|
|
* Hooked out version of DoConfigBox in standard scrnsave.c
|
|
*
|
|
\**************************************************************************/
|
|
|
|
INT_PTR
|
|
DoConfigBox( HWND hwndParent )
|
|
{
|
|
// let the consumer register any special controls for the dialog
|
|
if( !RegisterDialogClasses( hMainInstance ) )
|
|
return FALSE;
|
|
|
|
// Create screen saver instance
|
|
SCRNSAVE ss( SS_TYPE_CONFIG );
|
|
|
|
int retVal = (int)DialogBox( hMainInstance,
|
|
MAKEINTRESOURCE( DLG_SCRNSAVECONFIGURE ),
|
|
hwndParent, (DLGPROC)GLScreenSaverConfigureDialog );
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CreateMainWindow
|
|
*
|
|
* Creates main screen saver window based on the window type
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
SCRNSAVE::CreateMainWindow()
|
|
{
|
|
WNDPROC wndProc;
|
|
ISIZE size;
|
|
UINT uStyle = 0;
|
|
UINT uExStyle = 0;
|
|
IPOINT2D pos;
|
|
LPCTSTR pszWindowTitle;
|
|
HCURSOR hCursor = NULL;
|
|
HBRUSH hbrBgMain;
|
|
PSSW pssw;
|
|
BOOL bFailed;
|
|
HWND hwndParent = NULL;
|
|
int nx, ny; // window origin
|
|
int ncx, ncy; // window size
|
|
|
|
wndProc = RealScreenSaverProc;
|
|
|
|
switch( type ) {
|
|
case SS_TYPE_FULLSCREEN:
|
|
{
|
|
HWND hOther;
|
|
|
|
// Get origin and size of virtual desktop
|
|
nx = GetSystemMetrics( SM_XVIRTUALSCREEN );
|
|
ny = GetSystemMetrics( SM_YVIRTUALSCREEN );
|
|
ncx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
|
|
ncy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
|
|
|
|
//#define SS_FULLSCREEN_DEBUG 1
|
|
#ifdef SS_FULLSCREEN_DEBUG
|
|
// Reduce window size so we can see debugger
|
|
ncx >>= 1;
|
|
ncy >>= 1;
|
|
#endif
|
|
uStyle = WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
uExStyle = WS_EX_TOPMOST;
|
|
|
|
pszWindowTitle = TEXT("Screen Saver"); // MUST differ from preview
|
|
|
|
// if there is another NORMAL screen save instance, switch to it
|
|
hOther = FindWindow( pszWindowClass, pszWindowTitle );
|
|
|
|
if( hOther && IsWindow( hOther ) )
|
|
{
|
|
SS_DBGINFO( "SCRNSAVE::CreateMainWindow : Switching to other ss instance\n" );
|
|
SetForegroundWindow( hOther );
|
|
return FALSE;
|
|
}
|
|
|
|
InitRealScreenSave();
|
|
}
|
|
break;
|
|
|
|
case SS_TYPE_PREVIEW:
|
|
{
|
|
RECT rcParent;
|
|
|
|
hwndParent = (HWND) initParam;
|
|
|
|
GetClientRect( hwndParent, &rcParent );
|
|
|
|
fChildPreview = TRUE;
|
|
ncx = rcParent.right;
|
|
ncy = rcParent.bottom;
|
|
nx = 0;
|
|
ny = 0;
|
|
uStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN;
|
|
|
|
pszWindowTitle = TEXT("Preview"); // MUST differ from full screen
|
|
}
|
|
break;
|
|
|
|
case SS_TYPE_NORMAL:
|
|
|
|
{
|
|
// We set fChildPreview even when we're running in a normal window,
|
|
// as this flag is used in scrnsave.c to differentiate from full
|
|
// screen.
|
|
fChildPreview = TRUE;
|
|
|
|
// init size to half of (primary) screen by default
|
|
ncx = GetSystemMetrics( SM_CXSCREEN ) >> 1;
|
|
ncy = GetSystemMetrics( SM_CYSCREEN ) >> 1;
|
|
nx = 0;
|
|
ny = 0;
|
|
|
|
if( initParam ) {
|
|
// get size of window from args
|
|
LPCTSTR szArgs = (LPCTSTR) initParam;
|
|
//mf: not yet implemented
|
|
}
|
|
|
|
LoadString(hMainInstance, IDS_DESCRIPTION, szScreenSaverTitle,
|
|
sizeof(szScreenSaverTitle) / sizeof(TCHAR));
|
|
pszWindowTitle = szScreenSaverTitle; // MUST differ from preview
|
|
|
|
uStyle = WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
|
|
WS_CLIPSIBLINGS;
|
|
|
|
hCursor = LoadCursor( NULL, IDC_ARROW );
|
|
|
|
// Wrap RealScreenSaverProc
|
|
wndProc = NormalWindowScreenSaverProc;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
size.width = ncx;
|
|
size.height = ncy;
|
|
pos.x = nx;
|
|
pos.y = ny;
|
|
|
|
// Create SSW window wrapper
|
|
|
|
pssw = new SSW( NULL, // parent
|
|
&size,
|
|
&pos,
|
|
FALSE, // bMotion
|
|
NULL // ChildSizeFunc
|
|
);
|
|
if( !pssw )
|
|
return FALSE;
|
|
|
|
// Initialize the window class and create the window
|
|
|
|
#ifdef SS_INITIAL_CLEAR
|
|
hbrBgMain = NULL;
|
|
#else
|
|
hbrBgMain = hbrBg;
|
|
#endif
|
|
|
|
if( !RegisterMainClass
|
|
(
|
|
wndProc,
|
|
hbrBgMain,
|
|
hCursor
|
|
) ||
|
|
|
|
!pssw->CreateSSWindow
|
|
(
|
|
hMainInstance,
|
|
uStyle,
|
|
uExStyle,
|
|
pszWindowTitle,
|
|
wndProc,
|
|
pszWindowClass,
|
|
hwndParent // mf: ! hwndParentOverride
|
|
) )
|
|
{
|
|
delete pssw;
|
|
return FALSE;
|
|
}
|
|
|
|
if( type != SS_TYPE_PREVIEW )
|
|
#ifndef SS_DEBUG
|
|
SetForegroundWindow( pssw->hwnd );
|
|
#else
|
|
{
|
|
if( !SetForegroundWindow( pssw->hwnd ) )
|
|
SS_DBGPRINT( "Main_Proc: SetForegroundWindow failed\n" );
|
|
}
|
|
#endif
|
|
|
|
// Always configure the main window for gdi
|
|
pssw->ConfigureForGdi();
|
|
|
|
psswMain = pssw;
|
|
return TRUE;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* CreateChildWindow
|
|
*
|
|
* Creates a child window of the parent window
|
|
*
|
|
* This is a kind of wrapper-constructor
|
|
\**************************************************************************/
|
|
|
|
PSSW
|
|
SCRNSAVE::CreateChildWindow( FLOATER_INFO *pFloater )
|
|
{
|
|
pFloater->bSubWindow = FALSE; // default is no logical subwin's
|
|
|
|
// Register child window class
|
|
// This only has to be done once, since so far, all child window
|
|
// classes are the same
|
|
if( !pFloater->bSubWindow && !RegisterChildClass() )
|
|
return NULL;
|
|
|
|
return CreateChildWindow( psswMain, pFloater );
|
|
}
|
|
|
|
PSSW
|
|
SCRNSAVE::CreateChildWindow( PSSW psswParent, FLOATER_INFO *pFloater )
|
|
{
|
|
UINT uStyle = 0;
|
|
UINT uExStyle = 0;
|
|
PSSW pssw;
|
|
|
|
uStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
|
|
// Size and position are NULL here, as the SSW will call the size
|
|
// function callback in pFloater to get these and other values
|
|
|
|
// Create the SSW window wrapper
|
|
|
|
pssw = new SSW( psswParent, // parent
|
|
NULL, // size
|
|
NULL, // position
|
|
pFloater->bMotion,
|
|
pFloater->ChildSizeFunc
|
|
);
|
|
if( !pssw )
|
|
return NULL;
|
|
|
|
if( pFloater->bSubWindow )
|
|
// Don't need to create win32 window
|
|
return pssw;
|
|
|
|
// Create a window
|
|
|
|
if( !pssw->CreateSSWindow
|
|
(
|
|
hMainInstance,
|
|
uStyle,
|
|
0, // uExStyle
|
|
szScreenSaverTitle ,
|
|
SS_ScreenSaverProc,
|
|
pszChildWindowClass,
|
|
NULL // hwndParentOverride
|
|
) )
|
|
{
|
|
delete pssw;
|
|
return NULL;
|
|
}
|
|
|
|
return pssw;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* RegisterMainClass
|
|
*
|
|
* Registers class of the main SS window
|
|
\**************************************************************************/
|
|
|
|
static BOOL
|
|
RegisterMainClass( WNDPROC wndProc, HBRUSH hbrBg, HCURSOR hCursor )
|
|
{
|
|
WNDCLASS cls;
|
|
|
|
cls.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_OWNDC;
|
|
cls.lpfnWndProc = wndProc;
|
|
cls.cbClsExtra = 0;
|
|
cls.cbWndExtra = 0;
|
|
cls.hInstance = hMainInstance;
|
|
cls.hIcon = LoadIcon( hMainInstance, MAKEINTATOM( ID_APP ) );
|
|
cls.hCursor = hCursor;
|
|
cls.hbrBackground = hbrBg;
|
|
cls.lpszMenuName = (LPTSTR)NULL;
|
|
cls.lpszClassName = (LPTSTR)pszWindowClass;
|
|
return RegisterClass(&cls);
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* RegisterChildClass
|
|
*
|
|
* Registers class of a standard child window
|
|
\**************************************************************************/
|
|
|
|
static BOOL
|
|
RegisterChildClass()
|
|
{
|
|
static BOOL bRegistered = FALSE;
|
|
|
|
if( bRegistered )
|
|
return TRUE;
|
|
|
|
WNDCLASS cls;
|
|
|
|
cls.style = CS_VREDRAW | CS_HREDRAW;
|
|
cls.lpfnWndProc = SS_ScreenSaverProc;
|
|
cls.cbClsExtra = 0;
|
|
cls.cbWndExtra = 0;
|
|
cls.hInstance = hMainInstance;
|
|
cls.hIcon = NULL;
|
|
cls.hCursor = NULL;
|
|
cls.hbrBackground = NULL;
|
|
cls.lpszMenuName = (LPTSTR)NULL;
|
|
cls.lpszClassName = pszChildWindowClass;
|
|
|
|
if( !RegisterClass(&cls) )
|
|
return FALSE;
|
|
|
|
// success
|
|
bRegistered = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* AttemptResolutionSwitch
|
|
*
|
|
* Try doing resolution switching to match or get close to the desired size.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static BOOL
|
|
AttemptResolutionSwitch( int width, int height, ISIZE *pNewSize )
|
|
{
|
|
BOOL bChanged = FALSE;
|
|
|
|
// Try doing resolution switching to match or get close to the
|
|
// desired width and height
|
|
|
|
// Try switching to requested size
|
|
#if 0
|
|
//mf: not ready for prime time
|
|
if( ss_ChangeDisplaySettings( width, height, 0 ) ) {
|
|
#else
|
|
if( 0 ) {
|
|
// for now force failure of user request and try standard 640x480
|
|
#endif
|
|
bChanged = TRUE;
|
|
} else {
|
|
// Can't switch to requested size, try for best match
|
|
// mf: !!! for now, let's play it safe and just try 640x480.
|
|
width = 640;
|
|
height = 480;
|
|
// If screen already this size or less, leave be
|
|
if( (GetSystemMetrics( SM_CXSCREEN ) <= width) &&
|
|
(GetSystemMetrics( SM_CYSCREEN ) <= height) )
|
|
return FALSE;
|
|
|
|
//mf: use this when trying for best match
|
|
// ss_QueryDisplaySettings();
|
|
|
|
if( ss_ChangeDisplaySettings( width, height, 0 ) )
|
|
bChanged = TRUE;
|
|
}
|
|
|
|
if( bChanged ) {
|
|
pNewSize->width = width;
|
|
pNewSize->height = height;
|
|
}
|
|
return bChanged;
|
|
}
|
|
|
|
#ifdef SS_INITIAL_CLEAR
|
|
static void
|
|
InitialClear( PSSW *pssw )
|
|
{
|
|
ss_GdiRectWipeClear( pssw->hwnd, pssw->size.width, pssw->size.height );
|
|
}
|
|
#endif // SS_INITIAL_CLEAR
|
|
|
|
/**************************************************************************\
|
|
* CloseWindows
|
|
*
|
|
* Close down any open windows.
|
|
*
|
|
* This sends a WM_CLOSE message to the top-level window if it is still open. If
|
|
* the window has any children, they are also closed. For each window, the
|
|
* SSW destructor is called.
|
|
\**************************************************************************/
|
|
|
|
void
|
|
SCRNSAVE::CloseWindows()
|
|
{
|
|
if( psswMain ) {
|
|
if( psswMain->bOwnWindow )
|
|
DestroyWindow( psswMain->hwnd );
|
|
else
|
|
delete psswMain;
|
|
}
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* SCRNSAVE destructor
|
|
*
|
|
\**************************************************************************/
|
|
|
|
SCRNSAVE::~SCRNSAVE()
|
|
{
|
|
// Close any open windows (there might be some open if errors occurred)
|
|
CloseWindows();
|
|
|
|
if( bResSwitch ) {
|
|
// Restore previous display settings
|
|
ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
|
|
}
|
|
|
|
gpss = NULL;
|
|
}
|