2008-08-06 18:36:30 +00:00
// This file is part of BOINC.
2005-01-20 23:22:22 +00:00
// http://boinc.berkeley.edu
2008-08-06 18:36:30 +00:00
// Copyright (C) 2008 University of California
2004-11-14 08:29:32 +00:00
//
2008-08-06 18:36:30 +00:00
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
2004-01-18 19:36:50 +00:00
//
2008-08-06 18:36:30 +00:00
// BOINC is distributed in the hope that it will be useful,
2005-01-20 23:22:22 +00:00
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
2008-08-06 18:36:30 +00:00
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
2005-03-23 00:16:58 +00:00
//
// Contributor(s):
// DirectX 8.1 Screen Saver Framework from Microsoft.
// Microsoft Knowledge Base Article - 79212
//
2003-06-15 20:28:30 +00:00
2004-06-16 23:29:48 +00:00
# include "boinc_win.h"
2004-11-15 06:44:50 +00:00
# include "boinc_ss.h"
2011-10-04 18:39:02 +00:00
# include "boinc_gl.h"
2006-06-14 07:14:09 +00:00
# include "diagnostics.h"
2006-09-01 21:38:18 +00:00
# include "common_defs.h"
2006-05-16 21:14:18 +00:00
# include "util.h"
2007-08-14 17:23:30 +00:00
# include "gui_rpc_client.h"
# include "screensaver.h"
2007-08-13 19:57:18 +00:00
# include "screensaver_win.h"
2004-03-04 11:41:43 +00:00
2009-12-16 19:55:09 +00:00
# ifndef UNUSED
2005-07-07 22:26:49 +00:00
# define UNUSED(x)
# endif
2009-12-16 19:55:09 +00:00
2006-04-12 02:28:50 +00:00
static CScreensaver * gspScreensaver = NULL ;
2004-12-19 04:27:02 +00:00
2006-12-28 18:31:32 +00:00
const UINT WM_SETTIMER = RegisterWindowMessage ( TEXT ( " BOINCSetTimer " ) ) ;
const UINT WM_INTERRUPTSAVER = RegisterWindowMessage ( TEXT ( " BOINCInterruptScreensaver " ) ) ;
2006-04-13 00:28:31 +00:00
const UINT WM_BOINCSFW = RegisterWindowMessage ( TEXT ( " BOINCSetForegroundWindow " ) ) ;
2004-12-19 04:27:02 +00:00
2002-12-16 22:34:50 +00:00
2009-12-16 19:55:09 +00:00
# define REG_ENABLE_BLANK _T("Blank")
# define REG_BLANK_TIME _T("Blank Time")
# define REG_DEFAULT_TIME _T("Default Time")
# define REG_RUN_TIME _T("Run Time")
# define REG_SWITCH_TIME _T("Switch Time")
# define MAXSLIDERTIC 8 // Zero indexed arrays
const DWORD dwTableSliderPositionToTime [ ] = { 1 , 2 , 5 , 10 , 15 , 30 , 45 , 60 , 0 } ;
2005-04-06 23:12:27 +00:00
INT WINAPI WinMain (
2005-07-07 22:26:49 +00:00
HINSTANCE hInstance , HINSTANCE UNUSED ( hPrevInstance ) , LPSTR UNUSED ( lpCmdLine ) , int UNUSED ( nCmdShow )
2005-04-06 23:12:27 +00:00
) {
2004-11-14 08:29:32 +00:00
HRESULT hr ;
2006-04-12 02:28:50 +00:00
CScreensaver BOINCSS ;
2004-11-14 08:29:32 +00:00
int retval ;
WSADATA wsdata ;
2006-04-13 00:28:31 +00:00
2009-02-23 06:09:16 +00:00
2007-08-28 18:54:31 +00:00
// Initialize the CRT random number generator.
srand ( ( unsigned int ) time ( 0 ) ) ;
2009-12-16 19:55:09 +00:00
// Initialize Windows Common Controls
INITCOMMONCONTROLSEX InitCtrls ;
InitCtrls . dwSize = sizeof ( InitCtrls ) ;
InitCtrls . dwICC = ICC_WIN95_CLASSES ;
InitCommonControlsEx ( & InitCtrls ) ;
2007-08-28 18:54:31 +00:00
// Initialize the Windows sockets interface.
2005-04-06 23:12:27 +00:00
retval = WSAStartup ( MAKEWORD ( 1 , 1 ) , & wsdata ) ;
if ( retval ) {
2005-02-12 08:14:00 +00:00
BOINCTRACE ( " WinMain - Winsock Initialization Failure '%d' \n " , retval ) ;
2004-11-14 08:29:32 +00:00
return retval ;
}
2011-03-31 19:56:47 +00:00
// Initialize Screensaver
2005-04-06 23:12:27 +00:00
if ( FAILED ( hr = BOINCSS . Create ( hInstance ) ) ) {
BOINCSS . DisplayErrorMsg ( hr ) ;
2004-11-14 08:29:32 +00:00
WSACleanup ( ) ;
2004-01-17 21:34:54 +00:00
return 0 ;
}
2006-04-12 02:28:50 +00:00
2011-03-31 19:56:47 +00:00
// Run Screensaver
2004-11-14 08:29:32 +00:00
retval = BOINCSS . Run ( ) ;
2011-03-14 18:58:04 +00:00
2009-02-23 06:09:16 +00:00
// Cleanup any existing screensaver objects and handles
2011-03-31 19:56:47 +00:00
BOINCTRACE ( " WinMain - Cleanup Screensaver Resources \n " ) ;
2009-02-23 06:09:16 +00:00
BOINCSS . Cleanup ( ) ;
2007-08-28 18:54:31 +00:00
// Cleanup the Windows sockets interface.
2011-03-31 19:56:47 +00:00
BOINCTRACE ( " WinMain - Cleanup Winsock Resources \n " ) ;
2004-11-14 08:29:32 +00:00
WSACleanup ( ) ;
2006-04-12 02:28:50 +00:00
2004-11-14 08:29:32 +00:00
return retval ;
2004-01-17 21:34:54 +00:00
}
2002-12-16 22:34:50 +00:00
2002-11-18 21:20:54 +00:00
2005-04-06 23:12:27 +00:00
CScreensaver : : CScreensaver ( ) {
2006-04-12 02:28:50 +00:00
gspScreensaver = this ;
2003-10-22 18:39:22 +00:00
2004-01-17 21:34:54 +00:00
m_dwSaverMouseMoveCount = 0 ;
m_hWnd = NULL ;
m_hWndParent = NULL ;
m_bAllScreensSame = FALSE ;
m_bWindowed = FALSE ;
m_bWaitForInputIdle = FALSE ;
m_bErrorMode = FALSE ;
m_hrError = S_OK ;
2004-11-16 08:06:11 +00:00
m_szError [ 0 ] = _T ( ' \0 ' ) ;
2009-02-23 06:09:16 +00:00
m_strBOINCInstallDirectory . clear ( ) ;
m_strBOINCDataDirectory . clear ( ) ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
LoadString ( NULL , IDS_DESCRIPTION , m_strWindowTitle , 200 ) ;
2004-01-17 21:34:54 +00:00
2007-10-09 10:01:27 +00:00
m_bPaintingInitialized = FALSE ;
2005-02-09 21:54:04 +00:00
m_dwBlankScreen = 0 ;
2005-02-03 19:11:35 +00:00
m_dwBlankTime = 0 ;
2004-01-17 21:34:54 +00:00
2007-10-09 10:01:27 +00:00
rpc = NULL ;
2009-02-20 11:49:49 +00:00
m_bConnected = false ;
2007-08-14 17:23:30 +00:00
m_hDataManagementThread = NULL ;
m_hGraphicsApplication = NULL ;
m_bResetCoreState = TRUE ;
2011-03-14 18:58:04 +00:00
m_bQuitDataManagementProc = FALSE ;
m_bDataManagementProcStopped = FALSE ;
2007-09-26 10:17:43 +00:00
memset ( & m_running_result , 0 , sizeof ( m_running_result ) ) ;
2004-12-03 19:47:54 +00:00
2007-10-09 10:01:27 +00:00
ZeroMemory ( m_Monitors , sizeof ( m_Monitors ) ) ;
2004-01-17 21:34:54 +00:00
m_dwNumMonitors = 0 ;
2006-04-12 02:28:50 +00:00
m_dwLastInputTimeAtStartup = 0 ;
2007-10-05 13:28:11 +00:00
m_tThreadCreateTime = 0 ;
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
// Have the client program call this function before calling Run().
//
HRESULT CScreensaver : : Create ( HINSTANCE hInstance ) {
2004-01-17 21:34:54 +00:00
HRESULT hr ;
2010-09-13 19:47:29 +00:00
int retval ;
struct ss_periods periods ;
2004-01-17 21:34:54 +00:00
m_hInstance = hInstance ;
2010-09-13 19:47:29 +00:00
// Retrieve the locations of the install directory and data directory
UtilGetRegDirectoryStr ( _T ( " DATADIR " ) , m_strBOINCDataDirectory ) ;
UtilGetRegDirectoryStr ( _T ( " INSTALLDIR " ) , m_strBOINCInstallDirectory ) ;
if ( ! m_strBOINCDataDirectory . empty ( ) ) {
SetCurrentDirectory ( m_strBOINCDataDirectory . c_str ( ) ) ;
}
// Initialize Diagnostics
retval = diagnostics_init (
# ifdef _DEBUG
BOINC_DIAG_HEAPCHECKENABLED |
BOINC_DIAG_MEMORYLEAKCHECKENABLED |
# endif
BOINC_DIAG_DUMPCALLSTACKENABLED |
BOINC_DIAG_ARCHIVESTDOUT |
BOINC_DIAG_REDIRECTSTDOUTOVERWRITE |
BOINC_DIAG_REDIRECTSTDERROVERWRITE |
BOINC_DIAG_TRACETOSTDOUT ,
" stdoutscr " ,
" stderrscr "
) ;
2011-07-07 14:37:18 +00:00
2010-09-13 19:47:29 +00:00
2004-01-17 21:34:54 +00:00
// Parse the command line and do the appropriate thing
2005-04-06 23:12:27 +00:00
m_SaverMode = ParseCommandLine ( GetCommandLine ( ) ) ;
2004-01-17 21:34:54 +00:00
2006-04-12 02:28:50 +00:00
// Store last input value if it exists
2009-07-25 03:53:25 +00:00
LASTINPUTINFO lii ;
lii . cbSize = sizeof ( LASTINPUTINFO ) ;
GetLastInputInfo ( & lii ) ;
2006-04-12 02:28:50 +00:00
2009-07-25 03:53:25 +00:00
m_dwLastInputTimeAtStartup = lii . dwTime ;
2006-04-12 02:28:50 +00:00
2002-12-16 22:34:50 +00:00
2004-11-14 08:29:32 +00:00
// Enumerate Monitors
EnumMonitors ( ) ;
2004-01-17 21:34:54 +00:00
2009-12-14 13:10:49 +00:00
// Get project-defined default values for GFXDefaultPeriod, GFXSciencePeriod, GFXChangePeriod
GetDefaultDisplayPeriods ( periods ) ;
m_bShow_default_ss_first = periods . Show_default_ss_first ;
2009-12-16 19:55:09 +00:00
// Get the last set of saved values, if not set
// use the configuration file, if not set, use defaults.
// Normalize on Seconds...
if ( ! UtilGetRegKey ( REG_ENABLE_BLANK , m_dwBlankScreen ) ) {
m_dwBlankScreen = 0 ;
}
if ( ! UtilGetRegKey ( REG_BLANK_TIME , m_dwBlankTime ) ) {
m_dwBlankTime = GFX_BLANK_PERIOD ;
} else {
// Registry stores minutes
m_dwBlankTime * = 60 ;
}
if ( ! UtilGetRegKey ( REG_DEFAULT_TIME , m_dwDefaultTime ) ) {
m_dwDefaultTime = ( DWORD ) periods . GFXDefaultPeriod ;
} else {
// Registry stores minutes
m_dwDefaultTime * = 60 ;
}
if ( ! UtilGetRegKey ( REG_RUN_TIME , m_dwRunTime ) ) {
m_dwRunTime = ( DWORD ) periods . GFXSciencePeriod ;
} else {
// Registry stores minutes
m_dwRunTime * = 60 ;
}
if ( ! UtilGetRegKey ( REG_SWITCH_TIME , m_dwSwitchTime ) ) {
m_dwSwitchTime = ( DWORD ) periods . GFXChangePeriod ;
} else {
// Registry stores minutes
m_dwSwitchTime * = 60 ;
}
2005-02-09 21:54:04 +00:00
2009-12-16 19:55:09 +00:00
// Set the legacy value if needed
if ( ! m_dwBlankScreen ) {
m_dwBlankTime = 0 ;
}
2005-02-03 19:11:35 +00:00
2009-12-16 19:55:09 +00:00
// Convert values as stored into floating point values to be used
// at runtime
m_fGFXDefaultPeriod = ( double ) m_dwDefaultTime ;
m_fGFXSciencePeriod = ( double ) m_dwRunTime ;
m_fGFXChangePeriod = ( double ) m_dwSwitchTime ;
2009-12-14 13:10:49 +00:00
2005-02-04 02:54:25 +00:00
// Save the value back to the registry in case this is the first
// execution and so we need the default value later.
2009-12-16 19:55:09 +00:00
// Store in minutes
UtilSetRegKey ( REG_ENABLE_BLANK , m_dwBlankScreen ) ;
UtilSetRegKey ( REG_BLANK_TIME , m_dwBlankTime ? m_dwBlankTime / 60 : 0 ) ;
UtilSetRegKey ( REG_DEFAULT_TIME , m_dwDefaultTime ? m_dwDefaultTime / 60 : 0 ) ;
UtilSetRegKey ( REG_RUN_TIME , m_dwRunTime ? m_dwRunTime / 60 : 0 ) ;
UtilSetRegKey ( REG_SWITCH_TIME , m_dwSwitchTime ? m_dwSwitchTime / 60 : 0 ) ;
2005-02-04 02:54:25 +00:00
2009-02-23 06:09:16 +00:00
2005-02-04 17:29:59 +00:00
// Calculate the estimated blank time by adding the current time
2009-12-16 19:55:09 +00:00
// and and the user specified time.
2009-12-14 13:10:49 +00:00
if ( m_dwBlankTime > 0 ) {
2009-12-16 19:55:09 +00:00
m_dwBlankTime = ( DWORD ) time ( 0 ) + m_dwBlankTime ;
2009-12-14 13:10:49 +00:00
}
2005-04-05 10:23:15 +00:00
// Create the infrastructure mutexes so we can properly aquire them to report
// errors
2005-04-06 23:12:27 +00:00
if ( ! CreateInfrastructureMutexes ( ) ) {
2005-04-05 10:23:15 +00:00
return E_FAIL ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 10:23:15 +00:00
2007-10-05 13:28:11 +00:00
if ( rpc = = NULL ) rpc = new RPC_CLIENT ;
2011-03-14 18:58:04 +00:00
// Create the screen saver window(s)
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_preview | |
m_SaverMode = = sm_full
) {
if ( FAILED ( hr = CreateSaverWindow ( ) ) ) {
SetError ( TRUE , hr ) ;
}
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_preview ) {
2004-01-17 21:34:54 +00:00
// In preview mode, "pause" (enter a limited message loop) briefly
// before proceeding, so the display control panel knows to update itself.
m_bWaitForInputIdle = TRUE ;
// Post a message to mark the end of the initial group of window messages
2006-04-13 04:21:23 +00:00
PostMessage ( m_hWnd , WM_SETTIMER , 0 , 0 ) ;
2004-01-17 21:34:54 +00:00
MSG msg ;
2005-04-06 23:12:27 +00:00
while ( m_bWaitForInputIdle ) {
2004-01-17 21:34:54 +00:00
// If GetMessage returns FALSE, it's quitting time.
2005-04-06 23:12:27 +00:00
if ( ! GetMessage ( & msg , m_hWnd , 0 , 0 ) ) {
2004-01-17 21:34:54 +00:00
// Post the quit message to handle it later
PostQuitMessage ( 0 ) ;
break ;
}
2005-04-06 23:12:27 +00:00
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
2004-01-17 21:34:54 +00:00
}
}
return S_OK ;
}
2005-04-06 23:12:27 +00:00
// Starts main execution of the screen saver.
//
2009-02-23 06:09:16 +00:00
HRESULT CScreensaver : : Run ( ) {
2007-12-14 19:38:42 +00:00
HOST_INFO hostinfo ;
2004-01-17 21:34:54 +00:00
HRESULT hr ;
// Parse the command line and do the appropriate thing
2005-04-06 23:12:27 +00:00
switch ( m_SaverMode ) {
2009-02-23 06:09:16 +00:00
case sm_config :
if ( m_bErrorMode ) {
DisplayErrorMsg ( m_hrError ) ;
} else {
DoConfig ( ) ;
}
break ;
case sm_test :
rpc - > init ( NULL ) ;
rpc - > get_host_info ( hostinfo ) ;
rpc - > close ( ) ;
break ;
case sm_preview :
// In Windows, preview mode is for the mini-view of the screensaver.
// For BOINC we just display the icon, so there is no need to
// startup the data management thread which in turn will
// launch a graphics application.
if ( FAILED ( hr = DoSaver ( ) ) ) {
DisplayErrorMsg ( hr ) ;
}
break ;
case sm_full :
// Create the various required threads
if ( ! CreateInputActivityThread ( ) ) return E_FAIL ;
2009-02-24 20:00:02 +00:00
if ( ! CreateGraphicsWindowPromotionThread ( ) ) {
DestroyDataManagementThread ( ) ;
return E_FAIL ;
}
if ( ! CreateDataManagementThread ( ) ) {
DestroyDataManagementThread ( ) ;
DestroyGraphicsWindowPromotionThread ( ) ;
return E_FAIL ;
}
2009-02-23 06:09:16 +00:00
if ( FAILED ( hr = DoSaver ( ) ) ) {
DisplayErrorMsg ( hr ) ;
}
2006-04-13 08:37:25 +00:00
2009-02-23 06:09:16 +00:00
// Destroy the various required threads
//
2009-02-24 20:00:02 +00:00
DestroyDataManagementThread ( ) ;
DestroyGraphicsWindowPromotionThread ( ) ;
DestroyInputActivityThread ( ) ;
2011-10-13 14:41:24 +00:00
2009-02-23 06:09:16 +00:00
break ;
}
return S_OK ;
}
2006-04-13 08:37:25 +00:00
2009-02-23 06:09:16 +00:00
// Cleanup anything that needs cleaning.
//
HRESULT CScreensaver : : Cleanup ( ) {
2011-03-31 19:56:47 +00:00
BOINCTRACE ( " CScreensaver::Cleanup - Cleanup graphics application if running \n " ) ;
2009-02-23 06:09:16 +00:00
if ( m_hGraphicsApplication ) {
TerminateProcess ( m_hGraphicsApplication , 0 ) ;
m_hGraphicsApplication = NULL ;
2004-01-17 21:34:54 +00:00
}
2011-04-25 17:17:42 +00:00
BOINCTRACE ( " CScreensaver::Cleanup - Cleanup RPC client \n " ) ;
2009-02-23 06:09:16 +00:00
if ( rpc ) {
2011-03-14 18:58:04 +00:00
rpc - > close ( ) ;
2009-02-23 06:09:16 +00:00
delete rpc ;
rpc = NULL ;
}
return S_OK ;
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
// Displays error messages in a message box
//
HRESULT CScreensaver : : DisplayErrorMsg ( HRESULT hr ) {
2005-04-05 10:23:15 +00:00
TCHAR strMsg [ 512 ] ;
2005-04-06 23:12:27 +00:00
GetTextForError ( hr , strMsg , 512 ) ;
MessageBox ( m_hWnd , strMsg , m_strWindowTitle , MB_ICONERROR | MB_OK ) ;
2005-04-05 10:23:15 +00:00
return hr ;
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
// Interpret command-line parameters passed to this app.
//
SaverMode CScreensaver : : ParseCommandLine ( TCHAR * pstrCommandLine ) {
2004-01-17 21:34:54 +00:00
m_hWndParent = NULL ;
2004-11-13 07:11:40 +00:00
BOINCTRACE ( " ParseCommandLine: '%s' \n " , pstrCommandLine ) ;
2004-01-17 21:34:54 +00:00
// Skip the first part of the command line, which is the full path
// to the exe. If it contains spaces, it will be contained in quotes.
2005-04-06 23:12:27 +00:00
if ( * pstrCommandLine = = _T ( ' \" ' ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
while ( * pstrCommandLine ! = _T ( ' \0 ' ) & & * pstrCommandLine ! = _T ( ' \" ' ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
if ( * pstrCommandLine = = _T ( ' \" ' ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
} else {
while ( * pstrCommandLine ! = _T ( ' \0 ' ) & & * pstrCommandLine ! = _T ( ' ' ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
if ( * pstrCommandLine = = _T ( ' ' ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
}
// Skip along to the first option delimiter "/" or "-"
2005-04-06 23:12:27 +00:00
while ( * pstrCommandLine ! = _T ( ' \0 ' ) & & * pstrCommandLine ! = _T ( ' / ' ) & & * pstrCommandLine ! = _T ( ' - ' ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
2003-01-24 01:43:16 +00:00
2004-01-17 21:34:54 +00:00
// If there wasn't one, then must be config mode
2005-04-06 23:12:27 +00:00
if ( * pstrCommandLine = = _T ( ' \0 ' ) ) {
2004-01-17 21:34:54 +00:00
return sm_config ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
// Otherwise see what the option was
2005-04-06 23:12:27 +00:00
switch ( * ( + + pstrCommandLine ) ) {
2004-01-17 21:34:54 +00:00
case ' c ' :
case ' C ' :
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
while ( * pstrCommandLine & & ! isdigit ( * pstrCommandLine ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
if ( isdigit ( * pstrCommandLine ) ) {
2004-01-17 21:34:54 +00:00
# ifdef _WIN64
2007-08-14 17:23:30 +00:00
m_hWndParent = ( HWND ) _atoi64 ( pstrCommandLine ) ;
2004-01-17 21:34:54 +00:00
# else
2007-08-14 17:23:30 +00:00
m_hWndParent = ( HWND ) _ttol ( pstrCommandLine ) ;
2003-10-22 18:39:22 +00:00
# endif
2005-04-06 23:12:27 +00:00
} else {
2004-01-17 21:34:54 +00:00
m_hWndParent = NULL ;
}
return sm_config ;
case ' t ' :
case ' T ' :
return sm_test ;
case ' p ' :
case ' P ' :
// Preview-mode, so option is followed by the parent HWND in decimal
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
while ( * pstrCommandLine & & ! isdigit ( * pstrCommandLine ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
if ( isdigit ( * pstrCommandLine ) ) {
2004-01-17 21:34:54 +00:00
# ifdef _WIN64
2007-08-14 17:23:30 +00:00
m_hWndParent = ( HWND ) _atoi64 ( pstrCommandLine ) ;
2004-01-17 21:34:54 +00:00
# else
2007-08-14 17:23:30 +00:00
m_hWndParent = ( HWND ) _ttol ( pstrCommandLine ) ;
2003-10-22 18:39:22 +00:00
# endif
2004-01-17 21:34:54 +00:00
}
return sm_preview ;
case ' a ' :
case ' A ' :
// Password change mode, so option is followed by parent HWND in decimal
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
while ( * pstrCommandLine & & ! isdigit ( * pstrCommandLine ) ) {
2004-01-17 21:34:54 +00:00
pstrCommandLine + + ;
2005-04-06 23:12:27 +00:00
}
if ( isdigit ( * pstrCommandLine ) ) {
2004-01-17 21:34:54 +00:00
# ifdef _WIN64
2007-08-14 17:23:30 +00:00
m_hWndParent = ( HWND ) _atoi64 ( pstrCommandLine ) ;
2004-01-17 21:34:54 +00:00
# else
2007-08-14 17:23:30 +00:00
m_hWndParent = ( HWND ) _ttol ( pstrCommandLine ) ;
2003-10-22 18:39:22 +00:00
# endif
2004-01-17 21:34:54 +00:00
}
return sm_passwordchange ;
default :
// All other options => run the screensaver (typically this is "/s")
return sm_full ;
}
}
2005-04-06 23:12:27 +00:00
// Determine HMONITOR, desktop rect, and other info for each monitor.
2004-01-17 21:34:54 +00:00
// Note that EnumDisplayDevices enumerates monitors in the order
// indicated on the Settings page of the Display control panel, which
// is the order we want to list monitors in, as opposed to the order
// used by D3D's GetAdapterInfo.
2005-04-06 23:12:27 +00:00
//
VOID CScreensaver : : EnumMonitors ( VOID ) {
2004-01-17 21:34:54 +00:00
DWORD iDevice = 0 ;
DISPLAY_DEVICE_FULL dispdev ;
DISPLAY_DEVICE_FULL dispdev2 ;
DEVMODE devmode ;
dispdev . cb = sizeof ( dispdev ) ;
dispdev2 . cb = sizeof ( dispdev2 ) ;
devmode . dmSize = sizeof ( devmode ) ;
devmode . dmDriverExtra = 0 ;
INTERNALMONITORINFO * pMonitorInfoNew ;
2005-04-06 23:12:27 +00:00
while ( EnumDisplayDevices ( NULL , iDevice , ( DISPLAY_DEVICE * ) & dispdev , 0 ) ) {
2004-01-17 21:34:54 +00:00
// Ignore NetMeeting's mirrored displays
2005-04-06 23:12:27 +00:00
if ( ( dispdev . StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) = = 0 ) {
2004-01-17 21:34:54 +00:00
// To get monitor info for a display device, call EnumDisplayDevices
// a second time, passing dispdev.DeviceName (from the first call) as
// the first parameter.
EnumDisplayDevices ( dispdev . DeviceName , 0 , ( DISPLAY_DEVICE * ) & dispdev2 , 0 ) ;
pMonitorInfoNew = & m_Monitors [ m_dwNumMonitors ] ;
2005-04-06 23:12:27 +00:00
ZeroMemory ( pMonitorInfoNew , sizeof ( INTERNALMONITORINFO ) ) ;
2009-12-16 19:55:09 +00:00
strncpy (
pMonitorInfoNew - > strDeviceName ,
dispdev . DeviceString ,
sizeof ( pMonitorInfoNew - > strDeviceName ) * sizeof ( TCHAR )
) ;
strncpy (
pMonitorInfoNew - > strMonitorName ,
dispdev2 . DeviceString ,
sizeof ( pMonitorInfoNew - > strMonitorName ) * sizeof ( TCHAR )
) ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
if ( dispdev . StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP ) {
EnumDisplaySettings ( dispdev . DeviceName , ENUM_CURRENT_SETTINGS , & devmode ) ;
if ( dispdev . StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE ) {
2004-01-17 21:34:54 +00:00
// For some reason devmode.dmPosition is not always (0, 0)
// for the primary display, so force it.
pMonitorInfoNew - > rcScreen . left = 0 ;
pMonitorInfoNew - > rcScreen . top = 0 ;
2005-04-06 23:12:27 +00:00
} else {
2004-01-17 21:34:54 +00:00
pMonitorInfoNew - > rcScreen . left = devmode . dmPosition . x ;
pMonitorInfoNew - > rcScreen . top = devmode . dmPosition . y ;
}
pMonitorInfoNew - > rcScreen . right = pMonitorInfoNew - > rcScreen . left + devmode . dmPelsWidth ;
pMonitorInfoNew - > rcScreen . bottom = pMonitorInfoNew - > rcScreen . top + devmode . dmPelsHeight ;
2005-04-06 23:12:27 +00:00
pMonitorInfoNew - > hMonitor = MonitorFromRect ( & pMonitorInfoNew - > rcScreen , MONITOR_DEFAULTTONULL ) ;
2004-01-17 21:34:54 +00:00
}
m_dwNumMonitors + + ;
2005-04-06 23:12:27 +00:00
if ( m_dwNumMonitors = = MAX_DISPLAYS ) {
2004-01-17 21:34:54 +00:00
break ;
2005-04-06 23:12:27 +00:00
}
2003-10-22 18:39:22 +00:00
}
2004-01-17 21:34:54 +00:00
iDevice + + ;
2003-10-22 18:39:22 +00:00
}
2002-12-16 22:34:50 +00:00
}
2002-11-18 21:20:54 +00:00
2004-01-17 21:34:54 +00:00
2009-02-23 06:09:16 +00:00
BOOL CScreensaver : : UtilGetRegKey ( LPCTSTR name , DWORD & keyval ) {
2005-04-05 10:23:15 +00:00
LONG error ;
DWORD type = REG_DWORD ;
2005-04-06 23:12:27 +00:00
DWORD size = sizeof ( DWORD ) ;
2005-04-05 10:23:15 +00:00
DWORD value ;
HKEY boinc_key ;
2009-07-25 03:53:25 +00:00
error = RegOpenKeyEx (
HKEY_CURRENT_USER ,
_T ( " SOFTWARE \\ Space Sciences Laboratory, U.C. Berkeley \\ BOINC Screensaver " ) ,
0 ,
KEY_ALL_ACCESS ,
& boinc_key
) ;
if ( error ! = ERROR_SUCCESS ) return FALSE ;
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
error = RegQueryValueEx ( boinc_key , name , NULL , & type , ( BYTE * ) & value , & size ) ;
2005-04-05 10:23:15 +00:00
keyval = value ;
2005-04-06 23:12:27 +00:00
RegCloseKey ( boinc_key ) ;
2005-04-05 10:23:15 +00:00
2009-02-23 06:09:16 +00:00
if ( error ! = ERROR_SUCCESS ) return FALSE ;
2005-04-05 10:23:15 +00:00
2009-02-23 06:09:16 +00:00
return TRUE ;
2005-04-05 10:23:15 +00:00
}
2009-02-23 06:09:16 +00:00
BOOL CScreensaver : : UtilSetRegKey ( LPCTSTR name , DWORD value ) {
2005-04-05 10:23:15 +00:00
LONG error ;
HKEY boinc_key ;
2009-07-25 03:53:25 +00:00
error = RegCreateKeyEx (
HKEY_CURRENT_USER ,
_T ( " SOFTWARE \\ Space Sciences Laboratory, U.C. Berkeley \\ BOINC Screensaver " ) ,
0 ,
NULL ,
REG_OPTION_NON_VOLATILE ,
KEY_READ | KEY_WRITE ,
NULL ,
& boinc_key ,
NULL
) ;
if ( error ! = ERROR_SUCCESS ) return FALSE ;
2005-04-05 10:23:15 +00:00
2009-02-23 06:09:16 +00:00
error = RegSetValueEx ( boinc_key , name , 0 , REG_DWORD , ( CONST BYTE * ) & value , 4 ) ;
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
RegCloseKey ( boinc_key ) ;
2005-04-05 10:23:15 +00:00
2009-02-23 06:09:16 +00:00
return TRUE ;
2005-04-05 10:23:15 +00:00
}
2009-02-23 06:09:16 +00:00
BOOL CScreensaver : : UtilGetRegDirectoryStr ( LPCTSTR szTargetName , std : : string & strDirectory ) {
2009-02-13 11:08:32 +00:00
LONG lReturnValue ;
HKEY hkSetupHive ;
LPTSTR lpszRegistryValue = NULL ;
DWORD dwSize = 0 ;
// change the current directory to the boinc data directory if it exists
lReturnValue = RegOpenKeyEx (
HKEY_LOCAL_MACHINE ,
_T ( " SOFTWARE \\ Space Sciences Laboratory, U.C. Berkeley \\ BOINC Setup " ) ,
0 ,
KEY_READ ,
& hkSetupHive
) ;
if ( lReturnValue = = ERROR_SUCCESS ) {
// How large does our buffer need to be?
lReturnValue = RegQueryValueEx (
hkSetupHive ,
2009-02-23 06:09:16 +00:00
szTargetName ,
2009-02-13 11:08:32 +00:00
NULL ,
NULL ,
NULL ,
& dwSize
) ;
if ( lReturnValue ! = ERROR_FILE_NOT_FOUND ) {
// Allocate the buffer space.
lpszRegistryValue = ( LPTSTR ) malloc ( dwSize ) ;
( * lpszRegistryValue ) = NULL ;
// Now get the data
lReturnValue = RegQueryValueEx (
hkSetupHive ,
2009-02-23 06:09:16 +00:00
szTargetName ,
2009-02-13 11:08:32 +00:00
NULL ,
NULL ,
( LPBYTE ) lpszRegistryValue ,
& dwSize
) ;
2009-02-23 06:09:16 +00:00
// Store the directory for later use.
strDirectory = lpszRegistryValue ;
} else {
return FALSE ;
2009-02-13 11:08:32 +00:00
}
2009-02-23 06:09:16 +00:00
} else {
return FALSE ;
2009-02-13 11:08:32 +00:00
}
// Cleanup
if ( hkSetupHive ) RegCloseKey ( hkSetupHive ) ;
2009-02-23 06:09:16 +00:00
return TRUE ;
2009-02-13 11:08:32 +00:00
}
2005-04-05 10:23:15 +00:00
// Desc: Create the infrastructure for thread safe acccess to the infrastructure
// layer of the screen saver.
2005-04-06 23:12:27 +00:00
//
BOOL CScreensaver : : CreateInfrastructureMutexes ( ) {
m_hErrorManagementMutex = CreateMutex ( NULL , FALSE , NULL ) ;
if ( NULL = = m_hErrorManagementMutex ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::CreateInfrastructureMutexes: Failed to create m_hErrorManagementMutex '%d' \n " ) , GetLastError ( ) ) ;
return FALSE ;
}
return TRUE ;
}
2006-04-13 00:28:31 +00:00
2005-04-06 23:12:27 +00:00
// Provide a thread-safe implementation for retrieving the current
2005-04-05 10:23:15 +00:00
// error condition.
2005-04-06 23:12:27 +00:00
//
BOOL CScreensaver : : GetError (
BOOL & bErrorMode , HRESULT & hrError , TCHAR * pszError , size_t iErrorSize
) {
2005-04-05 10:23:15 +00:00
DWORD dwWaitResult ;
BOOL bRetVal = FALSE ;
// Request ownership of mutex.
2005-04-06 23:12:27 +00:00
dwWaitResult = WaitForSingleObject (
2005-04-05 10:23:15 +00:00
m_hErrorManagementMutex , // handle to mutex
5000L ) ; // five-second time-out interval
2005-04-06 23:12:27 +00:00
switch ( dwWaitResult ) {
2005-04-05 10:23:15 +00:00
// WAIT_OBJECT_0 - The thread got mutex ownership.
case WAIT_OBJECT_0 :
bErrorMode = m_bErrorMode ;
hrError = m_hrError ;
2005-04-06 23:12:27 +00:00
if ( NULL ! = pszError ) {
2009-12-16 19:55:09 +00:00
strncpy ( pszError , m_szError , iErrorSize ) ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 10:23:15 +00:00
bRetVal = TRUE ;
break ;
// WAIT_TIMEOUT - Cannot get mutex ownership due to time-out.
// WAIT_ABANDONED - Got ownership of the abandoned mutex object.
case WAIT_TIMEOUT :
case WAIT_ABANDONED :
break ;
}
2005-04-06 23:12:27 +00:00
ReleaseMutex ( m_hErrorManagementMutex ) ;
2005-04-05 10:23:15 +00:00
return bRetVal ;
}
2005-04-06 23:12:27 +00:00
// Provide a thread-safe implementation for setting the current
2005-04-05 10:23:15 +00:00
// error condition. This API should only be called in the data management
// thread, any other thread may cause a race condition.
2005-04-06 23:12:27 +00:00
//
BOOL CScreensaver : : SetError ( BOOL bErrorMode , HRESULT hrError ) {
2005-04-05 10:23:15 +00:00
DWORD dwWaitResult ;
BOOL bRetVal = FALSE ;
// Request ownership of mutex.
2005-04-06 23:12:27 +00:00
dwWaitResult = WaitForSingleObject (
2005-04-05 10:23:15 +00:00
m_hErrorManagementMutex , // handle to mutex
2005-04-06 23:12:27 +00:00
5000L // five-second time-out interval
) ;
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
switch ( dwWaitResult ) {
2005-04-05 10:23:15 +00:00
// WAIT_OBJECT_0 - The thread got mutex ownership.
case WAIT_OBJECT_0 :
m_bErrorMode = bErrorMode ;
m_hrError = hrError ;
// Update the error text, including a possible RPC call
// to the daemon.
UpdateErrorBoxText ( ) ;
bRetVal = TRUE ;
break ;
// WAIT_TIMEOUT - Cannot get mutex ownership due to time-out.
// WAIT_ABANDONED - Got ownership of the abandoned mutex object.
case WAIT_TIMEOUT :
case WAIT_ABANDONED :
break ;
}
2005-04-06 23:12:27 +00:00
ReleaseMutex ( m_hErrorManagementMutex ) ;
2005-04-05 10:23:15 +00:00
return bRetVal ;
}
2006-04-13 00:28:31 +00:00
2005-04-06 23:12:27 +00:00
// Update the error message
//
VOID CScreensaver : : UpdateErrorBoxText ( ) {
2009-02-24 20:00:02 +00:00
// Load error string
GetTextForError ( m_hrError , m_szError , sizeof ( m_szError ) / sizeof ( TCHAR ) ) ;
2011-11-09 00:22:10 +00:00
BOINCTRACE ( _T ( " CScreensaver::UpdateErrorBoxText - HRESULT '%d' Updated Text '%s' \n " ) , m_hrError , m_szError ) ;
2005-04-05 10:23:15 +00:00
}
2006-04-13 00:28:31 +00:00
2005-04-06 23:12:27 +00:00
// Translate an HRESULT error code into a string that can be displayed
2005-04-05 10:23:15 +00:00
// to explain the error. A class derived from CD3DScreensaver can
// provide its own version of this function that provides app-specific
// error translation instead of or in addition to calling this function.
// This function returns TRUE if a specific error was translated, or
// FALSE if no specific translation for the HRESULT was found (though
// it still puts a generic string into pszError).
2005-04-06 23:12:27 +00:00
//
BOOL CScreensaver : : GetTextForError (
HRESULT hr , TCHAR * pszError , DWORD dwNumChars
) {
const DWORD dwErrorMap [ ] [ 2 ] = {
2005-04-05 10:23:15 +00:00
// HRESULT, stringID
2009-12-16 19:55:09 +00:00
( const DWORD ) E_FAIL , IDS_ERR_GENERIC ,
( const DWORD ) E_OUTOFMEMORY , IDS_ERR_OUTOFMEMORY ,
2009-02-24 20:00:02 +00:00
SCRAPPERR_NOPREVIEW , IDS_ERR_NOPREVIEW ,
SCRAPPERR_BOINCSCREENSAVERLOADING , IDS_ERR_BOINCSCREENSAVERLOADING ,
SCRAPPERR_BOINCSHUTDOWNEVENT , IDS_ERR_BOINCSHUTDOWNEVENT ,
SCRAPPERR_BOINCAPPFOUNDGRAPHICSLOADING , IDS_ERR_BOINCAPPFOUNDGRAPHICSLOADING ,
SCRAPPERR_BOINCNOTDETECTED , IDS_ERR_BOINCNOTDETECTED ,
2011-11-10 01:14:04 +00:00
SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING , IDS_ERR_BOINCSCREENSAVERLOADING
2005-04-05 10:23:15 +00:00
} ;
const DWORD dwErrorMapSize = sizeof ( dwErrorMap ) / sizeof ( DWORD [ 2 ] ) ;
DWORD iError ;
DWORD resid = 0 ;
2005-12-23 04:51:52 +00:00
for ( iError = 0 ; iError < dwErrorMapSize ; iError + + ) {
if ( hr = = ( HRESULT ) dwErrorMap [ iError ] [ 0 ] ) {
resid = dwErrorMap [ iError ] [ 1 ] ;
2005-04-05 10:23:15 +00:00
}
}
2005-04-06 23:12:27 +00:00
if ( resid = = 0 ) {
2005-04-05 10:23:15 +00:00
resid = IDS_ERR_GENERIC ;
}
2005-04-06 23:12:27 +00:00
LoadString ( NULL , resid , pszError , dwNumChars ) ;
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
if ( resid = = IDS_ERR_GENERIC ) {
2005-04-05 10:23:15 +00:00
return FALSE ;
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
return TRUE ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 10:23:15 +00:00
}
2009-02-23 06:09:16 +00:00
// Create the thread that is used to monitor input activity.
2005-04-06 23:12:27 +00:00
//
2009-02-23 06:09:16 +00:00
BOOL CScreensaver : : CreateInputActivityThread ( ) {
2005-05-05 06:07:14 +00:00
DWORD dwThreadID = 0 ;
2011-03-29 20:59:09 +00:00
2009-02-23 06:09:16 +00:00
BOINCTRACE ( _T ( " CScreensaver::CreateInputActivityThread Start \n " ) ) ;
2011-03-29 20:59:09 +00:00
2009-02-23 06:09:16 +00:00
m_hInputActivityThread = CreateThread (
2005-04-05 10:23:15 +00:00
NULL , // default security attributes
0 , // use default stack size
2009-02-23 06:09:16 +00:00
InputActivityProcStub , // thread function
2005-04-05 10:23:15 +00:00
NULL , // argument to thread function
0 , // use default creation flags
2005-05-05 06:07:14 +00:00
& dwThreadID ) ; // returns the thread identifier
2005-04-05 10:23:15 +00:00
2009-02-23 06:09:16 +00:00
if ( m_hInputActivityThread = = NULL ) {
BOINCTRACE ( _T ( " CScreensaver::CreateInputActivityThread: Failed to create input activity thread '%d' \n " ) , GetLastError ( ) ) ;
2005-04-05 10:23:15 +00:00
return FALSE ;
}
2009-02-20 11:49:49 +00:00
m_tThreadCreateTime = time ( 0 ) ;
2005-04-05 10:23:15 +00:00
return TRUE ;
}
2009-02-23 06:09:16 +00:00
// Terminate the thread that is used to monitor input activity.
2005-04-06 23:12:27 +00:00
//
2009-02-23 06:09:16 +00:00
BOOL CScreensaver : : DestroyInputActivityThread ( ) {
2011-03-29 20:59:09 +00:00
BOINCTRACE ( _T ( " CScreensaver::DestroyInputActivityThread: Shutting Down... \n " ) ) ;
2009-02-23 06:09:16 +00:00
if ( ! TerminateThread ( m_hInputActivityThread , 0 ) ) {
BOINCTRACE ( _T ( " CScreensaver::DestroyInputActivityThread: Failed to terminate input activity thread '%d' \n " ) , GetLastError ( ) ) ;
return FALSE ;
2005-04-05 10:23:15 +00:00
}
2011-03-29 20:59:09 +00:00
2005-04-05 10:23:15 +00:00
return TRUE ;
}
2006-04-13 00:28:31 +00:00
2009-02-23 06:09:16 +00:00
// This function forwards to InputActivityProc, which has access to the
// "this" pointer.
2005-04-06 23:12:27 +00:00
//
2009-02-23 06:09:16 +00:00
DWORD WINAPI CScreensaver : : InputActivityProcStub ( LPVOID UNUSED ( lpParam ) ) {
return gspScreensaver - > InputActivityProc ( ) ;
2007-10-05 13:28:11 +00:00
}
2005-04-05 20:02:59 +00:00
2005-04-05 10:23:15 +00:00
2008-08-17 17:27:24 +00:00
// Some graphics applications take a really long time to display something on their
2008-08-14 19:09:01 +00:00
// window, during this time the window will appear to eat keyboard and mouse event
// messages and not respond to other system events. These windows are considered
// ghost windows, normally they have an outline and can be moved around and resized.
2008-08-17 17:27:24 +00:00
// In the graphic applications case where the borders are hidden from view, the
2008-08-14 19:09:01 +00:00
// window just takes on the background of the previous window which happens to be
// the black screensaver window owned by this process.
//
2008-08-17 17:27:24 +00:00
// Verify that their hasn't been any keyboard or mouse activity. If there has,
2008-08-14 19:09:01 +00:00
// we should hide the window from this process and exit out of the screensaver to
// return control back to the user as quickly as possible.
//
2009-02-23 06:09:16 +00:00
DWORD WINAPI CScreensaver : : InputActivityProc ( ) {
LASTINPUTINFO lii ;
2011-04-25 17:17:42 +00:00
bool bAutoBreak = false ;
2010-09-13 19:47:29 +00:00
DWORD dwCounter = 0 ;
2011-04-25 17:17:42 +00:00
2009-02-23 06:09:16 +00:00
lii . cbSize = sizeof ( LASTINPUTINFO ) ;
2010-09-13 19:47:29 +00:00
BOINCTRACE ( _T ( " CScreensaver::InputActivityProc - Last Input Activity '%d'. \n " ) , m_dwLastInputTimeAtStartup ) ;
2011-04-25 17:17:42 +00:00
while ( ! bAutoBreak ) {
2010-09-13 19:47:29 +00:00
if ( GetLastInputInfo ( & lii ) ) {
if ( dwCounter > 4 ) {
BOINCTRACE ( _T ( " CScreensaver::InputActivityProc - Heartbeat. \n " ) ) ;
dwCounter = 0 ;
}
if ( m_dwLastInputTimeAtStartup ! = lii . dwTime ) {
BOINCTRACE ( _T ( " CScreensaver::InputActivityProc - Activity Detected. \n " ) ) ;
SetError ( TRUE , SCRAPPERR_BOINCSHUTDOWNEVENT ) ;
FireInterruptSaverEvent ( ) ;
2011-04-25 17:17:42 +00:00
bAutoBreak = true ;
2010-09-13 19:47:29 +00:00
}
} else {
BOINCTRACE ( _T ( " CScreensaver::InputActivityProc - Failed to detect input activity. \n " ) ) ;
fprintf ( stdout , _T ( " Screen saver shutdown due to not being able to detect input activity. \n " ) ) ;
fprintf ( stdout , _T ( " Try rebooting, if the problem persists contact the BOINC. \n " ) ) ;
fprintf ( stdout , _T ( " development team. \n \n " ) ) ;
2009-07-25 03:53:25 +00:00
SetError ( TRUE , SCRAPPERR_BOINCSHUTDOWNEVENT ) ;
FireInterruptSaverEvent ( ) ;
2011-04-25 17:21:16 +00:00
bAutoBreak = true ;
2012-05-11 18:54:15 +00:00
}
2010-09-13 19:47:29 +00:00
dwCounter + + ;
2009-02-23 06:09:16 +00:00
boinc_sleep ( 0.25 ) ;
}
2011-04-25 17:17:42 +00:00
return 0 ;
2009-02-23 06:09:16 +00:00
}
2008-08-13 20:44:08 +00:00
2009-02-23 06:09:16 +00:00
// Create the thread that is used to promote the graphics window.
//
BOOL CScreensaver : : CreateGraphicsWindowPromotionThread ( ) {
DWORD dwThreadID = 0 ;
BOINCTRACE ( _T ( " CScreensaver::CreateGraphicsWindowPromotionThread Start \n " ) ) ;
m_hGraphicsWindowPromotionThread = CreateThread (
NULL , // default security attributes
0 , // use default stack size
GraphicsWindowPromotionProcStub , // thread function
NULL , // argument to thread function
0 , // use default creation flags
& dwThreadID ) ; // returns the thread identifier
if ( m_hGraphicsWindowPromotionThread = = NULL ) {
BOINCTRACE ( _T ( " CScreensaver::CreateGraphicsWindowPromotionThread: Failed to create graphics window promotion thread '%d' \n " ) , GetLastError ( ) ) ;
return FALSE ;
}
return TRUE ;
}
// Terminate the thread that is used to promote the graphics window.
//
BOOL CScreensaver : : DestroyGraphicsWindowPromotionThread ( ) {
2011-03-29 20:59:09 +00:00
BOINCTRACE ( _T ( " CScreensaver::DestroyGraphicsWindowPromotionThread: Shutting Down... \n " ) ) ;
2009-02-23 06:09:16 +00:00
if ( ! TerminateThread ( m_hGraphicsWindowPromotionThread , 0 ) ) {
BOINCTRACE ( _T ( " CScreensaver::DestroyGraphicsWindowPromotionThread: Failed to terminate graphics window promotion thread '%d' \n " ) , GetLastError ( ) ) ;
return FALSE ;
2008-08-13 20:44:08 +00:00
}
2011-03-29 20:59:09 +00:00
2009-02-23 06:09:16 +00:00
return TRUE ;
}
// This function forwards to GraphicsWindowPromotionProc, which has access to the
// "this" pointer.
//
DWORD WINAPI CScreensaver : : GraphicsWindowPromotionProcStub ( LPVOID UNUSED ( lpParam ) ) {
return gspScreensaver - > GraphicsWindowPromotionProc ( ) ;
2008-08-13 20:44:08 +00:00
}
2008-08-14 19:09:01 +00:00
// When running in screensaver mode the only two valid conditions for z-order
// is that either the screensaver or graphics application is the foreground
// application. If this is not true, then blow out of the screensaver.
//
2009-02-23 06:09:16 +00:00
DWORD WINAPI CScreensaver : : GraphicsWindowPromotionProc ( ) {
2007-10-05 13:28:11 +00:00
HWND hwndBOINCGraphicsWindow = NULL ;
HWND hwndForeWindow = NULL ;
HWND hwndForeParent = NULL ;
DWORD iMonitor = 0 ;
INTERNALMONITORINFO * pMonitorInfo = NULL ;
2009-02-23 06:09:16 +00:00
BOOL bForegroundWindowIsScreensaver ;
while ( true ) {
hwndBOINCGraphicsWindow = FindWindow ( BOINC_WINDOW_CLASS_NAME , NULL ) ;
if ( hwndBOINCGraphicsWindow ) {
// Graphics Application found.
2005-04-05 10:23:15 +00:00
2009-02-23 06:09:16 +00:00
// If the graphics application is not the top most window try and force it
// to the top.
hwndForeWindow = GetForegroundWindow ( ) ;
if ( hwndForeWindow ! = hwndBOINCGraphicsWindow ) {
BOINCTRACE ( _T ( " CScreensaver::GraphicsWindowPromotionProc - Graphics Window Detected but NOT the foreground window, bringing window to foreground. \n " ) ) ;
SetForegroundWindow ( hwndBOINCGraphicsWindow ) ;
hwndForeWindow = GetForegroundWindow ( ) ;
if ( hwndForeWindow ! = hwndBOINCGraphicsWindow ) {
BOINCTRACE ( _T ( " CScreensaver::GraphicsWindowPromotionProc - Graphics Window Detected but NOT the foreground window, bringing window to foreground. (Final Try) \n " ) ) ;
// This may be needed on Windows 2000 or better machines
//
// NOTE: This API appears to be a SendMessage() variant and as such
// can lock up this thread if a graphics application deadlocks.
//
2009-07-25 03:53:25 +00:00
DWORD dwComponents = BSM_APPLICATIONS ;
BroadcastSystemMessage (
BSF_ALLOWSFW ,
& dwComponents ,
WM_BOINCSFW ,
NULL ,
NULL
) ;
2009-02-23 06:09:16 +00:00
}
}
} else {
// Graphics application does not exist. So check that one of the windows
// assigned to each monitor is the foreground window.
bForegroundWindowIsScreensaver = FALSE ;
hwndForeWindow = GetForegroundWindow ( ) ;
hwndForeParent = GetParent ( hwndForeWindow ) ;
for ( iMonitor = 0 ; iMonitor < m_dwNumMonitors ; iMonitor + + ) {
pMonitorInfo = & m_Monitors [ iMonitor ] ;
if ( ( pMonitorInfo - > hWnd = = hwndForeWindow ) | | ( pMonitorInfo - > hWnd = = hwndForeParent ) )
{
bForegroundWindowIsScreensaver = TRUE ;
}
}
if ( ! bForegroundWindowIsScreensaver ) {
// This can happen because of a personal firewall notifications or some
// funky IM client that thinks it has to notify the user even when in
// screensaver mode.
BOINCTRACE ( _T ( " CScreensaver::CheckForNotificationWindow - Unknown window detected \n " ) ) ;
SetError ( TRUE , SCRAPPERR_BOINCSHUTDOWNEVENT ) ;
2009-04-02 19:04:10 +00:00
FireInterruptSaverEvent ( ) ;
2008-08-14 19:09:01 +00:00
}
}
2009-02-23 06:09:16 +00:00
boinc_sleep ( 1.0 ) ;
2008-08-14 19:09:01 +00:00
}
}
2009-02-23 06:09:16 +00:00
// Create the thread that is used to talk to the daemon.
2008-08-14 19:09:01 +00:00
//
2009-02-23 06:09:16 +00:00
BOOL CScreensaver : : CreateDataManagementThread ( ) {
DWORD dwThreadID = 0 ;
2011-03-29 20:59:09 +00:00
2009-02-23 06:09:16 +00:00
BOINCTRACE ( _T ( " CScreensaver::CreateDataManagementThread Start \n " ) ) ;
2011-03-29 20:59:09 +00:00
2009-02-23 06:09:16 +00:00
m_hDataManagementThread = CreateThread (
NULL , // default security attributes
0 , // use default stack size
DataManagementProcStub , // thread function
NULL , // argument to thread function
0 , // use default creation flags
& dwThreadID ) ; // returns the thread identifier
if ( m_hDataManagementThread = = NULL ) {
BOINCTRACE ( _T ( " CScreensaver::CreateDataManagementThread: Failed to create data management thread '%d' \n " ) , GetLastError ( ) ) ;
return FALSE ;
}
2011-03-29 20:59:09 +00:00
2009-02-23 06:09:16 +00:00
return TRUE ;
}
// Terminate the thread that is used to talk to the daemon.
//
BOOL CScreensaver : : DestroyDataManagementThread ( ) {
2011-03-29 20:59:09 +00:00
BOINCTRACE ( _T ( " CScreensaver::DestoryDataManagementThread: Shutting down... \n " ) ) ;
m_bQuitDataManagementProc = true ;
for ( int i = 0 ; i < 50 ; i + + ) {
if ( m_bDataManagementProcStopped ) {
BOINCTRACE ( _T ( " CScreensaver::DestoryDataManagementThread: Thread gracefully shutdown \n " ) ) ;
return TRUE ;
}
2011-03-14 18:58:04 +00:00
boinc_sleep ( 0.1 ) ;
}
2011-03-29 20:59:09 +00:00
BOINCTRACE ( _T ( " CScreensaver::DestoryDataManagementThread: Terminating thread... \n " ) ) ;
2009-02-23 06:09:16 +00:00
if ( ! TerminateThread ( m_hDataManagementThread , 0 ) ) {
2011-03-29 20:59:09 +00:00
BOINCTRACE ( _T ( " CScreensaver::DestoryDataManagementThread: Failed to terminate thread '%d' \n " ) , GetLastError ( ) ) ;
2009-02-23 06:09:16 +00:00
return FALSE ;
}
2011-03-29 20:59:09 +00:00
2009-02-23 06:09:16 +00:00
return TRUE ;
}
// This function forwards to DataManagementProc, which has access to the
// "this" pointer.
//
DWORD WINAPI CScreensaver : : DataManagementProcStub ( LPVOID UNUSED ( lpParam ) ) {
return gspScreensaver - > DataManagementProc ( ) ;
}
void CScreensaver : : HandleRPCError ( )
2008-08-14 19:09:01 +00:00
{
2009-02-23 06:09:16 +00:00
rpc - > close ( ) ;
m_bConnected = false ;
// Attempt to reinitialize the RPC client and state
if ( ! rpc - > init ( NULL ) ) {
m_bConnected = true ;
m_bResetCoreState = TRUE ;
return ;
}
2009-03-03 12:08:49 +00:00
if ( ( time ( 0 ) - m_tThreadCreateTime ) > 3 ) {
2009-02-23 06:09:16 +00:00
SetError ( TRUE , SCRAPPERR_BOINCNOTDETECTED ) ;
}
2005-04-05 10:23:15 +00:00
}
2006-04-13 00:28:31 +00:00
2009-02-23 06:09:16 +00:00
2005-04-06 23:12:27 +00:00
// Register and create the appropriate window(s)
//
HRESULT CScreensaver : : CreateSaverWindow ( ) {
2005-04-05 10:23:15 +00:00
// Register an appropriate window class for the primary display
WNDCLASS cls ;
2005-04-06 23:12:27 +00:00
cls . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
cls . hIcon = LoadIcon ( m_hInstance , MAKEINTRESOURCE ( IDI_MAIN_ICON ) ) ;
2005-04-05 10:23:15 +00:00
cls . lpszMenuName = NULL ;
cls . lpszClassName = _T ( " BOINCPrimarySaverWndClass " ) ;
cls . hbrBackground = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;
cls . hInstance = m_hInstance ;
cls . style = CS_VREDRAW | CS_HREDRAW ;
cls . lpfnWndProc = SaverProcStub ;
cls . cbWndExtra = 0 ;
cls . cbClsExtra = 0 ;
2005-04-06 23:12:27 +00:00
RegisterClass ( & cls ) ;
2005-04-05 10:23:15 +00:00
// Register an appropriate window class for the secondary display(s)
WNDCLASS cls2 ;
2005-04-06 23:12:27 +00:00
cls2 . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
cls2 . hIcon = LoadIcon ( m_hInstance , MAKEINTRESOURCE ( IDI_MAIN_ICON ) ) ;
2005-04-05 10:23:15 +00:00
cls2 . lpszMenuName = NULL ;
cls2 . lpszClassName = _T ( " BOINCGenericSaverWndClass " ) ;
cls2 . hbrBackground = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;
cls2 . hInstance = m_hInstance ;
cls2 . style = CS_VREDRAW | CS_HREDRAW ;
2011-03-29 20:59:09 +00:00
cls2 . lpfnWndProc = GenericSaverProcStub ;
2005-04-05 10:23:15 +00:00
cls2 . cbWndExtra = 0 ;
cls2 . cbClsExtra = 0 ;
2005-04-06 23:12:27 +00:00
RegisterClass ( & cls2 ) ;
2005-04-05 10:23:15 +00:00
// Create the window
RECT rc ;
DWORD dwStyle ;
2005-04-06 23:12:27 +00:00
switch ( m_SaverMode ) {
2005-04-05 10:23:15 +00:00
case sm_preview :
2005-04-06 23:12:27 +00:00
GetClientRect ( m_hWndParent , & rc ) ;
2005-04-05 10:23:15 +00:00
dwStyle = WS_VISIBLE | WS_CHILD ;
2005-04-06 23:12:27 +00:00
AdjustWindowRect ( & rc , dwStyle , FALSE ) ;
2006-04-13 08:37:25 +00:00
m_hWnd = CreateWindow ( _T ( " BOINCPrimarySaverWndClass " ) ,
m_strWindowTitle , dwStyle , rc . left , rc . top , rc . right - rc . left ,
rc . bottom - rc . top , m_hWndParent , NULL , m_hInstance , this
2005-04-06 23:12:27 +00:00
) ;
2005-04-05 10:23:15 +00:00
m_Monitors [ 0 ] . hWnd = m_hWnd ;
2005-04-06 23:12:27 +00:00
GetClientRect ( m_hWnd , & m_rcRenderTotal ) ;
GetClientRect ( m_hWnd , & m_rcRenderCurDevice ) ;
2005-04-05 10:23:15 +00:00
break ;
case sm_test :
rc . left = rc . top = 50 ;
rc . right = rc . left + 600 ;
rc . bottom = rc . top + 400 ;
dwStyle = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU ;
2005-04-06 23:12:27 +00:00
AdjustWindowRect ( & rc , dwStyle , FALSE ) ;
2006-04-13 08:37:25 +00:00
m_hWnd = CreateWindow ( _T ( " BOINCPrimarySaverWndClass " ) ,
m_strWindowTitle , dwStyle , rc . left , rc . top , rc . right - rc . left ,
rc . bottom - rc . top , NULL , NULL , m_hInstance , this
2005-04-06 23:12:27 +00:00
) ;
2005-04-05 10:23:15 +00:00
m_Monitors [ 0 ] . hWnd = m_hWnd ;
2005-04-06 23:12:27 +00:00
GetClientRect ( m_hWnd , & m_rcRenderTotal ) ;
GetClientRect ( m_hWnd , & m_rcRenderCurDevice ) ;
2005-04-05 10:23:15 +00:00
SetTimer ( m_hWnd , 2 , 60000 , NULL ) ;
break ;
case sm_full :
dwStyle = WS_VISIBLE | WS_POPUP ;
m_hWnd = NULL ;
2005-04-06 23:12:27 +00:00
for ( DWORD iMonitor = 0 ; iMonitor < m_dwNumMonitors ; iMonitor + + ) {
2005-04-05 10:23:15 +00:00
INTERNALMONITORINFO * pMonitorInfo ;
pMonitorInfo = & m_Monitors [ iMonitor ] ;
2005-04-06 23:12:27 +00:00
if ( pMonitorInfo - > hWnd = = NULL ) {
if ( pMonitorInfo - > hMonitor = = NULL )
2005-04-05 10:23:15 +00:00
continue ;
rc = pMonitorInfo - > rcScreen ;
2005-04-06 23:12:27 +00:00
if ( 0 = = iMonitor ) {
2006-04-13 08:37:25 +00:00
pMonitorInfo - > hWnd = CreateWindowEx ( NULL , _T ( " BOINCPrimarySaverWndClass " ) ,
2005-04-05 10:23:15 +00:00
m_strWindowTitle , dwStyle , rc . left , rc . top , rc . right - rc . left ,
2005-04-06 23:12:27 +00:00
rc . bottom - rc . top , NULL , NULL , m_hInstance , this ) ;
} else {
2006-04-13 08:37:25 +00:00
pMonitorInfo - > hWnd = CreateWindowEx ( NULL , _T ( " BOINCGenericSaverWndClass " ) ,
2005-04-05 10:23:15 +00:00
m_strWindowTitle , dwStyle , rc . left , rc . top , rc . right - rc . left ,
2005-04-06 23:12:27 +00:00
rc . bottom - rc . top , NULL , NULL , m_hInstance , this ) ;
2005-04-05 10:23:15 +00:00
}
2005-04-06 23:12:27 +00:00
if ( pMonitorInfo - > hWnd = = NULL ) {
2005-04-05 10:23:15 +00:00
return E_FAIL ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
if ( m_hWnd = = NULL ) {
2005-04-05 10:23:15 +00:00
m_hWnd = pMonitorInfo - > hWnd ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 10:23:15 +00:00
2006-07-25 10:19:27 +00:00
SetTimer ( pMonitorInfo - > hWnd , 2 , 250 , NULL ) ;
2005-04-05 10:23:15 +00:00
}
}
}
2005-04-06 23:12:27 +00:00
if ( m_hWnd = = NULL ) {
2005-04-05 10:23:15 +00:00
return E_FAIL ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 10:23:15 +00:00
return S_OK ;
}
2011-08-18 09:56:11 +00:00
2005-04-06 23:12:27 +00:00
// Run the screensaver graphics - may be preview, test or full-on mode
//
HRESULT CScreensaver : : DoSaver ( ) {
2004-01-17 21:34:54 +00:00
// Flag as screensaver running if in full on mode
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_full ) {
2004-01-17 21:34:54 +00:00
BOOL bUnused ;
2005-04-06 23:12:27 +00:00
SystemParametersInfo ( SPI_SCREENSAVERRUNNING , TRUE , & bUnused , 0 ) ;
2004-01-17 21:34:54 +00:00
}
// Message pump
BOOL bGotMsg ;
MSG msg ;
msg . message = WM_NULL ;
2005-04-06 23:12:27 +00:00
while ( msg . message ! = WM_QUIT ) {
bGotMsg = PeekMessage ( & msg , NULL , 0 , 0 , PM_REMOVE ) ;
if ( bGotMsg ) {
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
} else {
2004-01-17 21:34:54 +00:00
Sleep ( 10 ) ;
}
}
return S_OK ;
}
2005-04-06 23:12:27 +00:00
VOID CScreensaver : : DoConfig ( ) {
DialogBox ( NULL , MAKEINTRESOURCE ( DLG_CONFIG ) , m_hWndParent , ConfigureDialogProcStub ) ;
2004-01-17 21:34:54 +00:00
}
2011-03-29 20:59:09 +00:00
// Handle window messages for main screensaver window.
2005-04-06 23:12:27 +00:00
//
LRESULT CScreensaver : : SaverProc (
HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam
) {
2005-03-23 00:16:58 +00:00
# ifdef _DEBUG
2011-09-02 16:54:46 +00:00
DWORD dwMonitor = 0 ;
2005-04-06 23:12:27 +00:00
for ( DWORD iIndex = 0 ; iIndex < m_dwNumMonitors ; iIndex + + ) {
if ( hWnd = = m_Monitors [ iIndex ] . hWnd ) {
2005-03-23 00:16:58 +00:00
dwMonitor = iIndex ;
2005-04-06 23:12:27 +00:00
}
}
2006-04-13 08:37:25 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc [%d] hWnd '%d' uMsg '%X' wParam '%d' lParam '%d' \n " ) , dwMonitor , hWnd , uMsg , wParam , lParam ) ;
2011-03-29 20:59:09 +00:00
# endif
2006-04-13 08:37:25 +00:00
2005-04-06 23:12:27 +00:00
switch ( uMsg ) {
2004-01-17 21:34:54 +00:00
case WM_TIMER :
2006-04-13 04:21:23 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_TIMER \n " ) ) ;
2005-04-06 23:12:27 +00:00
switch ( wParam ) {
2004-01-17 21:34:54 +00:00
case 1 :
// Initial idle time is done, proceed with initialization.
m_bWaitForInputIdle = FALSE ;
2005-04-06 23:12:27 +00:00
KillTimer ( hWnd , 1 ) ;
2006-04-13 08:37:25 +00:00
return 0 ;
2005-02-03 01:55:34 +00:00
break ;
2004-11-17 09:27:06 +00:00
case 2 :
2005-04-05 10:23:15 +00:00
// Update the position of the box every second so that it
// does not end up off the visible area of the screen.
UpdateErrorBox ( ) ;
2006-04-13 08:37:25 +00:00
return 0 ;
2005-04-05 10:23:15 +00:00
break ;
2005-02-03 01:55:34 +00:00
}
2004-01-17 21:34:54 +00:00
break ;
2005-03-23 00:16:58 +00:00
case WM_PAINT :
2004-01-17 21:34:54 +00:00
{
2006-07-25 10:19:27 +00:00
BOOL bErrorMode ;
HRESULT hrError ;
TCHAR szError [ 400 ] ;
GetError ( bErrorMode , hrError , szError , sizeof ( szError ) / sizeof ( TCHAR ) ) ;
// Show error message, if there is one
2005-03-23 00:16:58 +00:00
PAINTSTRUCT ps ;
2005-04-06 23:12:27 +00:00
BeginPaint ( hWnd , & ps ) ;
2004-01-17 21:34:54 +00:00
2005-03-23 00:16:58 +00:00
// In preview mode, just fill
// the preview window with black, and the BOINC icon.
2005-04-06 23:12:27 +00:00
if ( ! bErrorMode & & m_SaverMode = = sm_preview ) {
2005-03-23 00:16:58 +00:00
RECT rc ;
GetClientRect ( hWnd , & rc ) ;
2005-04-06 23:12:27 +00:00
FillRect ( ps . hdc , & rc , ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ) ;
2005-03-23 00:16:58 +00:00
DrawIcon ( ps . hdc , ( rc . right / 2 ) - 16 , ( rc . bottom / 2 ) - 16 ,
2005-04-06 23:12:27 +00:00
LoadIcon ( m_hInstance , MAKEINTRESOURCE ( IDI_MAIN_ICON ) ) ) ;
} else {
2006-07-26 05:39:09 +00:00
DoPaint ( hWnd , ps . hdc , & ps ) ;
2005-03-23 00:16:58 +00:00
}
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
EndPaint ( hWnd , & ps ) ;
2004-01-17 21:34:54 +00:00
}
return 0 ;
2005-03-23 00:16:58 +00:00
break ;
2004-01-17 21:34:54 +00:00
case WM_MOUSEMOVE :
2005-04-06 23:12:27 +00:00
if ( m_SaverMode ! = sm_test ) {
2004-01-17 21:34:54 +00:00
static INT xPrev = - 1 ;
static INT yPrev = - 1 ;
2009-12-16 19:55:09 +00:00
INT xCur = LOWORD ( lParam ) ;
INT yCur = HIWORD ( lParam ) ;
2005-04-06 23:12:27 +00:00
if ( xCur ! = xPrev | | yCur ! = yPrev ) {
2004-01-17 21:34:54 +00:00
xPrev = xCur ;
yPrev = yCur ;
m_dwSaverMouseMoveCount + + ;
2006-04-13 08:37:25 +00:00
if ( m_dwSaverMouseMoveCount > 5 ) {
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_MOUSEMOVE and time to InterruptSaver() \n " ) ) ;
2011-03-29 20:59:09 +00:00
FireInterruptSaverEvent ( ) ;
2006-04-13 08:37:25 +00:00
}
2004-01-17 21:34:54 +00:00
}
}
2005-03-23 00:16:58 +00:00
return 0 ;
2004-01-17 21:34:54 +00:00
break ;
case WM_KEYDOWN :
case WM_LBUTTONDOWN :
case WM_RBUTTONDOWN :
case WM_MBUTTONDOWN :
2006-04-13 04:21:23 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_KEYDOWN | WM_LBUTTONDOWN | WM_RBUTTONDOWN | WM_MBUTTONDOWN \n " ) ) ;
2005-04-06 23:12:27 +00:00
if ( m_SaverMode ! = sm_test ) {
2011-03-29 20:59:09 +00:00
FireInterruptSaverEvent ( ) ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
return 0 ;
break ;
2012-08-07 21:43:30 +00:00
case WM_CLOSE :
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_CLOSE \n " ) ) ;
DestroyWindow ( hWnd ) ;
return 0 ;
break ;
case WM_DESTROY :
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_DESTROY \n " ) ) ;
if ( m_SaverMode = = sm_preview | | m_SaverMode = = sm_test ) {
ShutdownSaver ( ) ;
}
PostQuitMessage ( 0 ) ;
return 0 ;
break ;
2004-01-17 21:34:54 +00:00
case WM_SYSCOMMAND :
2006-04-13 04:23:49 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_SYSCOMMAND \n " ) ) ;
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_full ) {
switch ( wParam ) {
2004-01-17 21:34:54 +00:00
case SC_NEXTWINDOW :
case SC_PREVWINDOW :
case SC_SCREENSAVE :
case SC_CLOSE :
2006-04-13 08:37:25 +00:00
return 0 ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
}
break ;
case WM_SETCURSOR :
2006-04-13 04:21:23 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_SETCURSOR \n " ) ) ;
2009-07-25 03:53:25 +00:00
if ( m_SaverMode = = sm_full ) {
2004-01-17 21:34:54 +00:00
// Hide cursor
2005-04-06 23:12:27 +00:00
SetCursor ( NULL ) ;
2004-01-17 21:34:54 +00:00
return TRUE ;
}
break ;
case WM_POWERBROADCAST :
2006-04-13 04:21:23 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_POWERBROADCAST \n " ) ) ;
2009-07-25 03:53:25 +00:00
if ( wParam = = PBT_APMQUERYSUSPEND )
2011-03-29 20:59:09 +00:00
FireInterruptSaverEvent ( ) ;
2004-01-17 21:34:54 +00:00
break ;
2006-12-29 16:35:33 +00:00
}
2006-04-13 04:21:23 +00:00
2006-12-29 16:35:33 +00:00
if ( WM_SETTIMER = = uMsg ) {
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_SETTIMER \n " ) ) ;
// All initialization messages have gone through. Allow
// 500ms of idle time, then proceed with initialization.
SetTimer ( hWnd , 1 , 500 , NULL ) ;
2012-08-07 21:43:30 +00:00
return 0 ;
2006-12-29 16:35:33 +00:00
} else if ( WM_INTERRUPTSAVER = = uMsg ) {
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_INTERRUPTSAVER \n " ) ) ;
2012-04-27 20:50:27 +00:00
CloseWindow ( hWnd ) ;
2012-08-07 21:43:30 +00:00
ShutdownSaver ( ) ;
2012-04-27 20:50:27 +00:00
PostQuitMessage ( 0 ) ;
2012-08-07 21:43:30 +00:00
return 0 ;
2011-03-29 20:59:09 +00:00
}
return DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
}
// Handle window messages for secondary screensaver windows.
//
LRESULT CScreensaver : : GenericSaverProc (
HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam
) {
# ifdef _DEBUG
2011-09-02 16:54:46 +00:00
DWORD dwMonitor = 0 ;
2011-03-29 20:59:09 +00:00
for ( DWORD iIndex = 0 ; iIndex < m_dwNumMonitors ; iIndex + + ) {
if ( hWnd = = m_Monitors [ iIndex ] . hWnd ) {
dwMonitor = iIndex ;
}
}
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc [%d] hWnd '%d' uMsg '%X' wParam '%d' lParam '%d' \n " ) , dwMonitor , hWnd , uMsg , wParam , lParam ) ;
# endif
switch ( uMsg ) {
case WM_TIMER :
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_TIMER \n " ) ) ;
switch ( wParam ) {
case 1 :
// Initial idle time is done, proceed with initialization.
m_bWaitForInputIdle = FALSE ;
KillTimer ( hWnd , 1 ) ;
return 0 ;
break ;
case 2 :
// Update the position of the box every second so that it
// does not end up off the visible area of the screen.
UpdateErrorBox ( ) ;
return 0 ;
break ;
}
break ;
case WM_PAINT :
{
BOOL bErrorMode ;
HRESULT hrError ;
TCHAR szError [ 400 ] ;
GetError ( bErrorMode , hrError , szError , sizeof ( szError ) / sizeof ( TCHAR ) ) ;
// Show error message, if there is one
PAINTSTRUCT ps ;
BeginPaint ( hWnd , & ps ) ;
// In preview mode, just fill
// the preview window with black, and the BOINC icon.
if ( ! bErrorMode & & m_SaverMode = = sm_preview ) {
RECT rc ;
GetClientRect ( hWnd , & rc ) ;
FillRect ( ps . hdc , & rc , ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ) ;
DrawIcon ( ps . hdc , ( rc . right / 2 ) - 16 , ( rc . bottom / 2 ) - 16 ,
LoadIcon ( m_hInstance , MAKEINTRESOURCE ( IDI_MAIN_ICON ) ) ) ;
} else {
DoPaint ( hWnd , ps . hdc , & ps ) ;
}
EndPaint ( hWnd , & ps ) ;
}
return 0 ;
break ;
case WM_MOUSEMOVE :
if ( m_SaverMode ! = sm_test ) {
static INT xPrev = - 1 ;
static INT yPrev = - 1 ;
INT xCur = LOWORD ( lParam ) ;
INT yCur = HIWORD ( lParam ) ;
if ( xCur ! = xPrev | | yCur ! = yPrev ) {
xPrev = xCur ;
yPrev = yCur ;
m_dwSaverMouseMoveCount + + ;
if ( m_dwSaverMouseMoveCount > 5 ) {
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_MOUSEMOVE and time to InterruptSaver() \n " ) ) ;
FireInterruptSaverEvent ( ) ;
}
}
}
return 0 ;
break ;
case WM_KEYDOWN :
case WM_LBUTTONDOWN :
case WM_RBUTTONDOWN :
case WM_MBUTTONDOWN :
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_KEYDOWN | WM_LBUTTONDOWN | WM_RBUTTONDOWN | WM_MBUTTONDOWN \n " ) ) ;
if ( m_SaverMode ! = sm_test ) {
FireInterruptSaverEvent ( ) ;
}
return 0 ;
break ;
case WM_SYSCOMMAND :
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_SYSCOMMAND \n " ) ) ;
if ( m_SaverMode = = sm_full ) {
switch ( wParam ) {
case SC_NEXTWINDOW :
case SC_PREVWINDOW :
case SC_SCREENSAVE :
case SC_CLOSE :
return 0 ;
}
}
break ;
case WM_SETCURSOR :
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_SETCURSOR \n " ) ) ;
if ( m_SaverMode = = sm_full ) {
// Hide cursor
SetCursor ( NULL ) ;
return TRUE ;
}
break ;
case WM_POWERBROADCAST :
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_POWERBROADCAST \n " ) ) ;
if ( wParam = = PBT_APMQUERYSUSPEND )
FireInterruptSaverEvent ( ) ;
break ;
}
if ( WM_SETTIMER = = uMsg ) {
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_SETTIMER \n " ) ) ;
// All initialization messages have gone through. Allow
// 500ms of idle time, then proceed with initialization.
SetTimer ( hWnd , 1 , 500 , NULL ) ;
2012-08-07 21:43:30 +00:00
return 0 ;
2006-04-13 04:21:23 +00:00
2012-04-27 20:50:27 +00:00
} else if ( WM_INTERRUPTSAVER = = uMsg ) {
2004-01-17 21:34:54 +00:00
2012-04-27 20:50:27 +00:00
BOINCTRACE ( _T ( " CScreensaver::GenericSaverProc Received WM_INTERRUPTSAVER \n " ) ) ;
CloseWindow ( hWnd ) ;
2012-08-07 21:43:30 +00:00
return 0 ;
2004-01-17 21:34:54 +00:00
2011-08-18 09:56:11 +00:00
}
return DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
}
2009-12-16 19:55:09 +00:00
DWORD CScreensaver : : ConvertSliderPositionToTime ( DWORD dwPosition ) {
return dwTableSliderPositionToTime [ dwPosition ] ;
}
2005-01-13 01:52:56 +00:00
2009-12-16 19:55:09 +00:00
DWORD CScreensaver : : ConvertTimeToSliderPosition ( DWORD dwMinutes ) {
DWORD dwPosition = 0 ;
if ( 0 > = dwMinutes ) {
dwPosition = MAXSLIDERTIC ; // Never
} else {
for ( unsigned int i = 0 ; i < = MAXSLIDERTIC - 1 ; i + + ) {
if ( dwTableSliderPositionToTime [ i ] < = dwMinutes ) {
dwPosition = i ;
2005-04-06 23:12:27 +00:00
}
2009-12-16 19:55:09 +00:00
}
}
return dwPosition ;
}
2005-01-13 01:52:56 +00:00
2009-12-16 19:55:09 +00:00
VOID CScreensaver : : InitializeDefaultSlider ( HWND hwndDlg , UINT uControl ) {
HWND hwndSlider = GetDlgItem ( hwndDlg , uControl ) ;
if ( hwndSlider ) {
SendMessage ( hwndSlider , TBM_SETRANGE , TRUE , MAKELONG ( 0 , MAXSLIDERTIC ) ) ;
SendMessage ( hwndSlider , TBM_SETLINESIZE , 0 , 1 ) ;
SendMessage ( hwndSlider , TBM_SETPAGESIZE , 0 , 1 ) ;
}
}
2005-01-13 01:52:56 +00:00
2009-12-16 19:55:09 +00:00
DWORD CScreensaver : : GetSliderPosition ( HWND hwndDlg , UINT uControl ) {
HWND hwndSlider = GetDlgItem ( hwndDlg , uControl ) ;
if ( hwndSlider ) {
return SendMessage ( hwndSlider , TBM_GETPOS , 0 , 0 ) ;
}
return 0 ;
}
VOID CScreensaver : : SetSliderPosition ( HWND hwndDlg , UINT uControl , DWORD dwPosition ) {
HWND hwndSlider = GetDlgItem ( hwndDlg , uControl ) ;
if ( hwndSlider ) {
SendMessage ( hwndSlider , TBM_SETPOS , TRUE , dwPosition ) ;
}
}
INT_PTR CScreensaver : : ConfigureDialogProc (
HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM UNUSED ( lParam )
) {
DWORD dwEnableBlankTime = 0 ;
DWORD dwBlankTime = 0 ;
DWORD dwDefaultTime = 0 ;
DWORD dwRunTime = 0 ;
DWORD dwSwitchTime = 0 ;
switch ( uMsg ) {
case WM_INITDIALOG :
// Initialize slider controls
InitializeDefaultSlider ( hWnd , IDC_SLIDER_BLANKTIME ) ;
InitializeDefaultSlider ( hWnd , IDC_SLIDER_DEFAULTTIME ) ;
InitializeDefaultSlider ( hWnd , IDC_SLIDER_RUNTIME ) ;
InitializeDefaultSlider ( hWnd , IDC_SLIDER_SWITCHTIME ) ;
// Get the last set of saved values, if nothing is set
// use defaults.
if ( ! UtilGetRegKey ( REG_ENABLE_BLANK , dwEnableBlankTime ) ) {
dwEnableBlankTime = 0 ;
}
if ( ! UtilGetRegKey ( REG_BLANK_TIME , dwBlankTime ) ) {
dwBlankTime = GFX_BLANK_PERIOD ? GFX_BLANK_PERIOD / 60 : 0 ;
}
if ( ! UtilGetRegKey ( REG_DEFAULT_TIME , dwDefaultTime ) ) {
dwDefaultTime = GFX_DEFAULT_PERIOD ? GFX_DEFAULT_PERIOD / 60 : 0 ;
}
if ( ! UtilGetRegKey ( REG_RUN_TIME , dwRunTime ) ) {
dwRunTime = GFX_SCIENCE_PERIOD ? GFX_SCIENCE_PERIOD / 60 : 0 ;
}
if ( ! UtilGetRegKey ( REG_SWITCH_TIME , dwSwitchTime ) ) {
dwSwitchTime = GFX_CHANGE_PERIOD ? GFX_CHANGE_PERIOD / 60 : 0 ;
}
// Set the legacy value if needed
if ( ! dwEnableBlankTime ) {
dwBlankTime = 0 ;
}
// Update Slider Controls with previously saved values
SetSliderPosition ( hWnd , IDC_SLIDER_BLANKTIME , ConvertTimeToSliderPosition ( dwBlankTime ) ) ;
SetSliderPosition ( hWnd , IDC_SLIDER_DEFAULTTIME , ConvertTimeToSliderPosition ( dwDefaultTime ) ) ;
SetSliderPosition ( hWnd , IDC_SLIDER_RUNTIME , ConvertTimeToSliderPosition ( dwRunTime ) ) ;
SetSliderPosition ( hWnd , IDC_SLIDER_SWITCHTIME , ConvertTimeToSliderPosition ( dwSwitchTime ) ) ;
return TRUE ;
case WM_COMMAND :
switch ( LOWORD ( wParam ) )
{
case IDOK :
dwBlankTime = ConvertSliderPositionToTime ( GetSliderPosition ( hWnd , IDC_SLIDER_BLANKTIME ) ) ;
dwDefaultTime = ConvertSliderPositionToTime ( GetSliderPosition ( hWnd , IDC_SLIDER_DEFAULTTIME ) ) ;
dwRunTime = ConvertSliderPositionToTime ( GetSliderPosition ( hWnd , IDC_SLIDER_RUNTIME ) ) ;
dwSwitchTime = ConvertSliderPositionToTime ( GetSliderPosition ( hWnd , IDC_SLIDER_SWITCHTIME ) ) ;
// Set the legacy value if needed
if ( dwBlankTime ) {
dwEnableBlankTime = 1 ;
2005-04-06 23:12:27 +00:00
}
2009-12-16 19:55:09 +00:00
UtilSetRegKey ( REG_ENABLE_BLANK , dwEnableBlankTime ) ;
UtilSetRegKey ( REG_BLANK_TIME , dwBlankTime ) ;
UtilSetRegKey ( REG_DEFAULT_TIME , dwDefaultTime ) ;
UtilSetRegKey ( REG_RUN_TIME , dwRunTime ) ;
UtilSetRegKey ( REG_SWITCH_TIME , dwSwitchTime ) ;
// Fall Through
case IDCANCEL :
EndDialog ( hWnd , wParam ) ;
return TRUE ;
}
2005-01-13 01:52:56 +00:00
}
return FALSE ;
}
2005-04-06 23:12:27 +00:00
// This function forwards all window messages to SaverProc, which has
2005-01-13 01:52:56 +00:00
// access to the "this" pointer.
2005-04-06 23:12:27 +00:00
//
LRESULT CALLBACK CScreensaver : : SaverProcStub (
HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam
) {
2006-04-12 02:28:50 +00:00
return gspScreensaver - > SaverProc ( hWnd , uMsg , wParam , lParam ) ;
2005-01-13 01:52:56 +00:00
}
2011-03-29 20:59:09 +00:00
// This function forwards all window messages to GenericSaverProc, which has
// access to the "this" pointer.
//
LRESULT CALLBACK CScreensaver : : GenericSaverProcStub (
HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam
) {
return gspScreensaver - > GenericSaverProc ( hWnd , uMsg , wParam , lParam ) ;
}
2005-04-06 23:12:27 +00:00
INT_PTR CALLBACK CScreensaver : : ConfigureDialogProcStub (
HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam
) {
2006-04-12 02:28:50 +00:00
return gspScreensaver - > ConfigureDialogProc ( hwndDlg , uMsg , wParam , lParam ) ;
2005-01-13 01:52:56 +00:00
}
2005-04-06 23:12:27 +00:00
VOID CScreensaver : : ShutdownSaver ( ) {
2009-04-02 19:04:10 +00:00
BOINCTRACE ( _T ( " CScreensaver::ShutdownSaver Function Begin \n " ) ) ;
2004-01-17 21:34:54 +00:00
// Unflag screensaver running if in full on mode
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_full ) {
2004-01-17 21:34:54 +00:00
BOOL bUnused ;
2005-04-06 23:12:27 +00:00
SystemParametersInfo ( SPI_SCREENSAVERRUNNING , FALSE , & bUnused , 0 ) ;
2004-01-17 21:34:54 +00:00
}
2007-08-16 23:09:03 +00:00
// Kill the currently executing graphics application
2007-10-05 13:28:11 +00:00
terminate_screensaver ( m_hGraphicsApplication , & m_running_result ) ;
2007-08-16 23:09:03 +00:00
2009-04-02 19:04:10 +00:00
BOINCTRACE ( _T ( " CScreensaver::ShutdownSaver Function End \n " ) ) ;
}
VOID CScreensaver : : FireInterruptSaverEvent ( ) {
BOINCTRACE ( _T ( " CScreensaver::FireInterruptSaverEvent Function Begin \n " ) ) ;
2012-04-27 20:50:27 +00:00
// Handle secondary curtains first
for ( DWORD iIndex = 1 ; iIndex < m_dwNumMonitors ; iIndex + + ) {
2009-04-02 19:04:10 +00:00
if ( m_Monitors [ iIndex ] . hWnd ) {
PostMessage ( m_Monitors [ iIndex ] . hWnd , WM_INTERRUPTSAVER , NULL , NULL ) ;
}
2005-05-13 00:33:04 +00:00
}
2009-04-02 19:04:10 +00:00
2012-04-27 20:50:27 +00:00
// Handle primary curtain
PostMessage ( m_Monitors [ 0 ] . hWnd , WM_INTERRUPTSAVER , NULL , NULL ) ;
2009-04-02 19:04:10 +00:00
BOINCTRACE ( _T ( " CScreensaver::FireInterruptSaverEvent Function End \n " ) ) ;
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
// Update the box that shows the error message
//
VOID CScreensaver : : UpdateErrorBox ( ) {
2004-01-17 21:34:54 +00:00
INTERNALMONITORINFO * pMonitorInfo ;
HWND hwnd ;
RECT rcBounds ;
static DWORD dwTimeLast = 0 ;
DWORD dwTimeNow ;
FLOAT fTimeDelta ;
2004-11-17 09:27:06 +00:00
2004-01-17 21:34:54 +00:00
// Update timing to determine how much to move error box
2005-04-06 23:12:27 +00:00
if ( dwTimeLast = = 0 ) {
2004-01-17 21:34:54 +00:00
dwTimeLast = timeGetTime ( ) ;
2005-04-06 23:12:27 +00:00
}
2007-08-20 19:54:42 +00:00
2004-01-17 21:34:54 +00:00
dwTimeNow = timeGetTime ( ) ;
2006-07-25 10:19:27 +00:00
fTimeDelta = ( FLOAT ) ( dwTimeNow - dwTimeLast ) / 10000.0f ;
2004-01-17 21:34:54 +00:00
dwTimeLast = dwTimeNow ;
2005-04-06 23:12:27 +00:00
for ( DWORD iMonitor = 0 ; iMonitor < m_dwNumMonitors ; iMonitor + + ) {
2004-01-17 21:34:54 +00:00
pMonitorInfo = & m_Monitors [ iMonitor ] ;
hwnd = pMonitorInfo - > hWnd ;
2005-04-06 23:12:27 +00:00
if ( hwnd = = NULL )
2004-01-17 21:34:54 +00:00
continue ;
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_full ) {
2004-01-17 21:34:54 +00:00
rcBounds = pMonitorInfo - > rcScreen ;
2005-04-06 23:12:27 +00:00
ScreenToClient ( hwnd , ( POINT * ) & rcBounds . left ) ;
ScreenToClient ( hwnd , ( POINT * ) & rcBounds . right ) ;
} else {
2004-01-17 21:34:54 +00:00
rcBounds = m_rcRenderTotal ;
}
2005-04-06 23:12:27 +00:00
if ( pMonitorInfo - > widthError = = 0 ) {
if ( m_SaverMode = = sm_preview ) {
2004-01-17 21:34:54 +00:00
pMonitorInfo - > widthError = ( float ) ( rcBounds . right - rcBounds . left ) ;
pMonitorInfo - > heightError = ( float ) ( rcBounds . bottom - rcBounds . top ) ;
pMonitorInfo - > xError = 0.0f ;
pMonitorInfo - > yError = 0.0f ;
pMonitorInfo - > xVelError = 0.0f ;
pMonitorInfo - > yVelError = 0.0f ;
2005-04-06 23:12:27 +00:00
InvalidateRect ( hwnd , NULL , FALSE ) ; // Invalidate the hwnd so it gets drawn
UpdateWindow ( hwnd ) ;
} else {
2007-10-02 21:44:14 +00:00
pMonitorInfo - > widthError = 454 ;
pMonitorInfo - > heightError = 320 ;
2004-01-17 21:34:54 +00:00
pMonitorInfo - > xError = ( rcBounds . right + rcBounds . left - pMonitorInfo - > widthError ) / 2.0f ;
pMonitorInfo - > yError = ( rcBounds . bottom + rcBounds . top - pMonitorInfo - > heightError ) / 2.0f ;
pMonitorInfo - > xVelError = ( rcBounds . right - rcBounds . left ) / 10.0f ;
2005-04-05 10:23:15 +00:00
pMonitorInfo - > yVelError = ( rcBounds . bottom - rcBounds . top ) / 20.0f ;
}
2005-04-06 23:12:27 +00:00
} else {
if ( m_SaverMode ! = sm_preview ) {
2005-04-05 10:23:15 +00:00
RECT rcOld ;
RECT rcNew ;
2005-02-03 01:55:34 +00:00
2005-04-06 23:12:27 +00:00
SetRect ( & rcOld , ( INT ) pMonitorInfo - > xError , ( INT ) pMonitorInfo - > yError ,
2005-04-05 10:23:15 +00:00
( INT ) ( pMonitorInfo - > xError + pMonitorInfo - > widthError ) ,
2005-04-06 23:12:27 +00:00
( INT ) ( pMonitorInfo - > yError + pMonitorInfo - > heightError ) ) ;
2005-02-03 01:55:34 +00:00
2005-04-05 10:23:15 +00:00
// Update rect velocity
2005-04-06 23:12:27 +00:00
if ( ( pMonitorInfo - > xError + pMonitorInfo - > xVelError * fTimeDelta +
2005-04-05 10:23:15 +00:00
pMonitorInfo - > widthError > rcBounds . right & & pMonitorInfo - > xVelError > 0.0f ) | |
( pMonitorInfo - > xError + pMonitorInfo - > xVelError * fTimeDelta <
2005-04-06 23:12:27 +00:00
rcBounds . left & & pMonitorInfo - > xVelError < 0.0f )
) {
2005-04-05 10:23:15 +00:00
pMonitorInfo - > xVelError = - pMonitorInfo - > xVelError ;
2005-02-03 01:55:34 +00:00
}
2005-04-06 23:12:27 +00:00
if ( ( pMonitorInfo - > yError + pMonitorInfo - > yVelError * fTimeDelta +
2005-04-05 10:23:15 +00:00
pMonitorInfo - > heightError > rcBounds . bottom & & pMonitorInfo - > yVelError > 0.0f ) | |
( pMonitorInfo - > yError + pMonitorInfo - > yVelError * fTimeDelta <
2005-04-06 23:12:27 +00:00
rcBounds . top & & pMonitorInfo - > yVelError < 0.0f )
) {
2005-04-05 10:23:15 +00:00
pMonitorInfo - > yVelError = - pMonitorInfo - > yVelError ;
2005-02-03 01:55:34 +00:00
}
2005-04-05 10:23:15 +00:00
// Update rect position
pMonitorInfo - > xError + = pMonitorInfo - > xVelError * fTimeDelta ;
pMonitorInfo - > yError + = pMonitorInfo - > yVelError * fTimeDelta ;
2005-04-06 23:12:27 +00:00
SetRect ( & rcNew , ( INT ) pMonitorInfo - > xError , ( INT ) pMonitorInfo - > yError ,
2005-04-05 10:23:15 +00:00
( INT ) ( pMonitorInfo - > xError + pMonitorInfo - > widthError ) ,
2005-04-06 23:12:27 +00:00
( INT ) ( pMonitorInfo - > yError + pMonitorInfo - > heightError ) ) ;
2004-01-17 21:34:54 +00:00
2007-08-20 19:54:42 +00:00
if ( ( dwTimeNow - pMonitorInfo - > dwTimeLastUpdate ) > 1000 )
2006-07-25 10:19:27 +00:00
{
pMonitorInfo - > dwTimeLastUpdate = dwTimeNow ;
InvalidateRect ( hwnd , NULL , TRUE ) ;
2005-04-06 23:12:27 +00:00
UpdateWindow ( hwnd ) ;
2006-07-25 10:19:27 +00:00
}
2005-04-05 10:23:15 +00:00
}
2004-01-17 21:34:54 +00:00
}
}
}
2006-07-25 10:19:27 +00:00
VOID CScreensaver : : DoPaint ( HWND hwnd , HDC hdc , LPPAINTSTRUCT lpps ) {
2005-07-04 21:54:24 +00:00
DWORD iMonitor = 0 ;
2006-07-25 10:19:27 +00:00
INTERNALMONITORINFO * pMonitorInfo = NULL ;
HMONITOR hMonitor = MonitorFromWindow ( hwnd , MONITOR_DEFAULTTONEAREST ) ;
2005-07-04 21:54:24 +00:00
for ( iMonitor = 0 ; iMonitor < m_dwNumMonitors ; iMonitor + + ) {
2004-01-17 21:34:54 +00:00
pMonitorInfo = & m_Monitors [ iMonitor ] ;
2005-04-06 23:12:27 +00:00
if ( pMonitorInfo - > hMonitor = = hMonitor )
2004-01-17 21:34:54 +00:00
break ;
}
2005-04-06 23:12:27 +00:00
if ( iMonitor = = m_dwNumMonitors ) {
2004-01-17 21:34:54 +00:00
return ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
2006-07-25 10:19:27 +00:00
// Retrieve the latest piece of error information
2005-04-05 10:23:15 +00:00
BOOL bErrorMode ;
HRESULT hrError ;
TCHAR szError [ 400 ] ;
2006-07-25 10:19:27 +00:00
GetError ( bErrorMode , hrError , szError , sizeof ( szError ) / sizeof ( TCHAR ) ) ;
// Start drawing the goods
2004-01-17 21:34:54 +00:00
RECT rc ;
RECT rc2 ;
RECT rcOrginal ;
int iTextHeight ;
2005-04-06 23:12:27 +00:00
static HBRUSH hbrushBlack = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;
static HBRUSH hbrushRed = ( HBRUSH ) CreateSolidBrush ( RGB ( 255 , 0 , 0 ) ) ;
2009-12-16 19:55:09 +00:00
static HBITMAP hbmp = LoadBitmap ( m_hInstance , MAKEINTRESOURCE ( IDB_BOINC ) ) ;
2004-01-17 21:34:54 +00:00
2006-07-25 10:19:27 +00:00
// Start off with a black screen and then draw on top of it.
FillRect ( hdc , & lpps - > rcPaint , hbrushBlack ) ;
2005-04-05 10:23:15 +00:00
2005-02-06 09:34:38 +00:00
// If the screensaver has switched to a blanked state or not in an error mode,
// we should exit here so the screen has been erased to black.
2007-08-14 17:23:30 +00:00
if ( ! bErrorMode ) {
2005-02-06 09:34:38 +00:00
return ;
}
2005-04-06 23:12:27 +00:00
SetRect ( & rc , ( INT ) pMonitorInfo - > xError , ( INT ) pMonitorInfo - > yError ,
2004-01-17 21:34:54 +00:00
( INT ) ( pMonitorInfo - > xError + pMonitorInfo - > widthError ) ,
2005-04-06 23:12:27 +00:00
( INT ) ( pMonitorInfo - > yError + pMonitorInfo - > heightError )
) ;
2008-09-16 01:14:30 +00:00
// This fill rect is useful when testing
//FillRect(hdc, &rc, hbrushRed);
rcOrginal = rc ;
2004-01-17 21:34:54 +00:00
// Draw the bitmap rectangle and copy the bitmap into
// it. the bitmap is centered in the rectangle by adding 2
// to the left and top coordinates of the bitmap rectangle,
// and subtracting 4 from the right and bottom coordinates.
2009-12-16 19:55:09 +00:00
BITMAP bm ;
2007-10-02 21:44:14 +00:00
GetObject ( hbmp , sizeof ( BITMAP ) , ( LPSTR ) & bm ) ;
2009-12-19 22:10:46 +00:00
HDC hdcTemp = CreateCompatibleDC ( hdc ) ;
SelectObject ( hdcTemp , hbmp ) ;
2007-10-02 21:44:14 +00:00
long left = rc . left + ( pMonitorInfo - > widthError - 4 - bm . bmWidth ) / 2 ;
long top = rc . top + 2 ;
2009-12-19 22:10:46 +00:00
POINT pt ;
pt . x = bm . bmWidth ;
pt . y = bm . bmHeight ;
DPtoLP ( hdcTemp , & pt , 1 ) ;
TransparentBlt (
hdc , left , top , pt . x , pt . y , hdcTemp , 0 , 0 , pt . x , pt . y , RGB ( 255 , 0 , 255 )
) ;
DeleteDC ( hdcTemp ) ;
2004-01-17 21:34:54 +00:00
// Draw text in the center of the frame
SetBkColor ( hdc , RGB ( 0 , 0 , 0 ) ) ; // Black
2009-12-19 22:10:46 +00:00
SetTextColor ( hdc , RGB ( 255 , 255 , 255 ) ) ; // White
2007-10-02 21:44:14 +00:00
// Set font
2009-12-16 19:55:09 +00:00
HFONT hFont ;
hFont = CreateFont (
0 ,
0 ,
0 ,
0 ,
FW_DONTCARE ,
FALSE ,
FALSE ,
0 ,
ANSI_CHARSET ,
OUT_DEFAULT_PRECIS ,
CLIP_DEFAULT_PRECIS ,
DEFAULT_QUALITY ,
DEFAULT_PITCH | FF_SWISS ,
" Arial Narrow "
) ;
2007-10-02 21:44:14 +00:00
2009-12-16 19:55:09 +00:00
if ( hFont ) SelectObject ( hdc , hFont ) ;
2008-09-16 01:14:30 +00:00
// Try using the "Arial Narrow" font, if that fails use whatever
// the system default font is. Something is better than nothing.
rc2 = rc ;
2005-04-06 23:12:27 +00:00
iTextHeight = DrawText ( hdc , szError , - 1 , & rc , DT_CENTER | DT_CALCRECT ) ;
2004-01-17 21:34:54 +00:00
rc = rc2 ;
2008-09-16 01:14:30 +00:00
rc2 . top + = bm . bmHeight + 20 ;
2005-04-06 23:12:27 +00:00
DrawText ( hdc , szError , - 1 , & rc2 , DT_CENTER ) ;
2008-09-16 01:14:30 +00:00
2009-12-16 19:55:09 +00:00
if ( hFont ) DeleteObject ( hFont ) ;
2004-01-17 21:34:54 +00:00
}