2005-01-20 23:22:22 +00:00
// Berkeley Open Infrastructure for Network Computing
// http://boinc.berkeley.edu
// Copyright (C) 2005 University of California
2004-11-14 08:29:32 +00:00
//
2005-01-20 23:22:22 +00:00
// This 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 2.1 of the License, or (at your option) any later version.
2004-01-18 19:36:50 +00:00
//
2005-01-20 23:22:22 +00:00
// This software is distributed in the hope that it will be useful,
// 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.
//
// To view the GNU Lesser General Public License visit
// http://www.gnu.org/copyleft/lesser.html
// or write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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"
# include <windowsx.h>
# include <mmsystem.h>
# include <regstr.h>
# include <shlobj.h>
# define COMPILE_MULTIMON_STUBS
# include <multimon.h>
# include <strsafe.h>
2004-11-13 07:11:40 +00:00
# include "diagnostics.h"
# include "exception.h"
2004-11-15 06:44:50 +00:00
# include "boinc_ss.h"
# include "win_screensaver.h"
2004-11-13 07:11:40 +00:00
# include "win_util.h"
2004-03-04 11:41:43 +00:00
2005-07-07 22:26:49 +00:00
# ifdef _DEBUG
# define UNUSED(x)
# else
# define UNUSED(x) x
# endif
2002-11-14 00:49:24 +00:00
2006-04-12 02:28:50 +00:00
static MYGETLASTINPUTINFO gspfnMyGetLastInputInfo = NULL ;
static MYISHUNGAPPWINDOW gspfnMyIsHungAppWindow = NULL ;
static MYBROADCASTSYSTEMMESSAGE gspfnMyBroadcastSystemMessage = NULL ;
static CScreensaver * gspScreensaver = NULL ;
static HMODULE gshUser32 = NULL ;
2004-12-19 04:27:02 +00:00
2006-04-12 02:28:50 +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
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-12 02:28:50 +00:00
BOOL bIs95 = FALSE ;
2002-11-20 22:57:43 +00:00
2004-11-13 07:23:08 +00:00
# ifdef _DEBUG
// Initialize Diagnostics when compiled for debug
2004-12-19 04:27:02 +00:00
retval = boinc_init_diagnostics (
BOINC_DIAG_DUMPCALLSTACKENABLED |
BOINC_DIAG_HEAPCHECKENABLED |
BOINC_DIAG_MEMORYLEAKCHECKENABLED |
BOINC_DIAG_ARCHIVESTDERR |
2005-02-12 08:14:00 +00:00
BOINC_DIAG_REDIRECTSTDERR |
2004-12-19 04:27:02 +00:00
BOINC_DIAG_TRACETOSTDERR
2005-04-06 23:12:27 +00:00
) ;
2005-04-06 22:53:00 +00:00
if ( retval ) {
2005-02-12 08:14:00 +00:00
BOINCTRACE ( " WinMain - BOINC Screensaver Diagnostic Error '%d' \n " , retval ) ;
2004-12-19 04:27:02 +00:00
MessageBox ( NULL , NULL , " BOINC Screensaver Diagnostic Error " , MB_OK ) ;
2004-11-13 07:11:40 +00:00
}
2004-11-13 07:23:08 +00:00
# endif
2004-11-13 07:11:40 +00:00
2006-04-12 02:28:50 +00:00
// Figure out if we're on Win9x
OSVERSIONINFO osvi ;
osvi . dwOSVersionInfoSize = sizeof ( osvi ) ;
GetVersionEx ( & osvi ) ;
bIs95 = ( osvi . dwPlatformId = = VER_PLATFORM_WIN32_WINDOWS ) & &
( ( osvi . dwMajorVersion = = 4 ) & & ( osvi . dwMinorVersion = = 0 ) ) ;
// Load dynamically linked modules
gshUser32 = LoadLibrary ( _T ( " USER32.DLL " ) ) ;
// Map function pointers
if ( gshUser32 ) {
gspfnMyGetLastInputInfo = ( MYGETLASTINPUTINFO ) GetProcAddress ( gshUser32 , _T ( " GetLastInputInfo " ) ) ;
gspfnMyIsHungAppWindow = ( MYISHUNGAPPWINDOW ) GetProcAddress ( gshUser32 , _T ( " IsHungAppWindow " ) ) ;
if ( bIs95 ) {
gspfnMyBroadcastSystemMessage = ( MYBROADCASTSYSTEMMESSAGE ) GetProcAddress ( gshUser32 , _T ( " BroadcastSystemMessage " ) ) ;
} else {
gspfnMyBroadcastSystemMessage = ( MYBROADCASTSYSTEMMESSAGE ) GetProcAddress ( gshUser32 , _T ( " BroadcastSystemMessageA " ) ) ;
}
}
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 ;
}
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
2004-11-14 08:29:32 +00:00
retval = BOINCSS . Run ( ) ;
2006-04-12 02:28:50 +00:00
2004-11-14 08:29:32 +00:00
WSACleanup ( ) ;
2006-04-12 02:28:50 +00:00
// Clean up function pointers.
gspfnMyGetLastInputInfo = NULL ;
gspfnMyIsHungAppWindow = NULL ;
gspfnMyBroadcastSystemMessage = NULL ;
// Free modules
FreeLibrary ( gshUser32 ) ;
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_bCheckingSaverPassword = FALSE ;
m_bIs9x = FALSE ;
m_dwSaverMouseMoveCount = 0 ;
m_hWnd = NULL ;
m_hWndParent = NULL ;
m_hPasswordDLL = NULL ;
m_VerifySaverPassword = 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 ' ) ;
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
m_bPaintingInitialized = FALSE ;
2005-02-06 19:01:28 +00:00
m_bCoreNotified = FALSE ;
2005-02-06 09:34:38 +00:00
m_bResetCoreState = TRUE ;
m_iStatus = 0 ;
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
2004-12-03 19:47:54 +00:00
m_bBOINCConfigChecked = FALSE ;
m_bBOINCStartupConfigured = FALSE ;
2005-04-06 23:12: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 ;
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 ;
2005-02-03 19:11:35 +00:00
BOOL bReturnValue ;
2002-12-16 22:34:50 +00:00
2004-01-17 21:34:54 +00:00
m_hInstance = hInstance ;
// 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
2004-11-13 07:11:40 +00:00
// Figure out if we're on Win9x
OSVERSIONINFO osvi ;
osvi . dwOSVersionInfoSize = sizeof ( osvi ) ;
2005-04-06 23:12:27 +00:00
GetVersionEx ( & osvi ) ;
2004-11-13 07:11:40 +00:00
m_bIs9x = ( osvi . dwPlatformId = = VER_PLATFORM_WIN32_WINDOWS ) ;
2006-04-12 02:28:50 +00:00
// Store last input value if it exists
if ( gspfnMyGetLastInputInfo ) {
LASTINPUTINFO lii ;
lii . cbSize = sizeof ( LASTINPUTINFO ) ;
gspfnMyGetLastInputInfo ( & lii ) ;
m_dwLastInputTimeAtStartup = lii . dwTime ;
}
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
2005-02-09 21:54:04 +00:00
// Retrieve the blank screen flag so we can determine if we are
// suppose to actually blank the screen at some point.
2005-04-06 23:12:27 +00:00
bReturnValue = UtilGetRegKey ( REG_BLANK_NAME , m_dwBlankScreen ) ;
2005-02-12 08:14:00 +00:00
BOINCTRACE ( " CScreensaver::Create - Get Reg Key REG_BLANK_NAME return value '%d' \n " , bReturnValue ) ;
2005-04-06 23:12:27 +00:00
if ( bReturnValue ! = 0 ) m_dwBlankScreen = 0 ;
2005-02-09 21:54:04 +00:00
2005-02-03 19:11:35 +00:00
// Retrieve the blank screen timeout
// make sure you check return value of registry queries
// in case the item in question doesn't happen to exist.
2005-04-06 23:12:27 +00:00
bReturnValue = UtilGetRegKey ( REG_BLANK_TIME , m_dwBlankTime ) ;
2005-02-12 08:14:00 +00:00
BOINCTRACE ( " CScreensaver::Create - Get Reg Key REG_BLANK_TIME return value '%d' \n " , bReturnValue ) ;
2005-04-06 23:12:27 +00:00
if ( bReturnValue ! = 0 ) m_dwBlankTime = 5 ;
2005-02-03 19:11:35 +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.
2005-04-06 23:12:27 +00:00
bReturnValue = UtilSetRegKey ( REG_BLANK_NAME , m_dwBlankScreen ) ;
2005-02-12 08:14:00 +00:00
BOINCTRACE ( " CScreensaver::Create - Set Reg Key REG_BLANK_NAME return value '%d' \n " , bReturnValue ) ;
2005-04-06 23:12:27 +00:00
bReturnValue = UtilSetRegKey ( REG_BLANK_TIME , m_dwBlankTime ) ;
2005-02-12 08:14:00 +00:00
BOINCTRACE ( " CScreensaver::Create - Set Reg Key REG_BLANK_TIME return value '%d' \n " , bReturnValue ) ;
2005-02-04 02:54:25 +00:00
2005-02-04 17:29:59 +00:00
// Calculate the estimated blank time by adding the current time
// and and the user specified time which is in minutes
2005-07-06 09:14:43 +00:00
m_dwBlankTime = ( DWORD ) time ( 0 ) + ( m_dwBlankTime * 60 ) ;
2005-02-04 17:29:59 +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
2004-01-17 21:34:54 +00:00
// Create the screen saver window(s)
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_preview | |
2004-01-17 21:34:54 +00:00
m_SaverMode = = sm_test | |
2005-04-06 23:12:27 +00:00
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
2005-04-06 23:12:27 +00:00
PostMessage ( m_hWnd , WM_USER , 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.
//
INT CScreensaver : : Run ( ) {
2004-01-17 21:34:54 +00:00
HRESULT hr ;
2005-04-05 10:23:15 +00:00
// Create the data management thread to talk with the daemon
2005-04-06 23:12:27 +00:00
if ( ! CreateDataManagementThread ( ) ) {
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
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
switch ( m_SaverMode ) {
case sm_config :
if ( m_bErrorMode ) {
DisplayErrorMsg ( m_hrError ) ;
} else {
DoConfig ( ) ;
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
break ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
case sm_preview :
case sm_test :
case sm_full :
if ( FAILED ( hr = DoSaver ( ) ) ) {
DisplayErrorMsg ( hr ) ;
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
break ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
case sm_passwordchange :
ChangePassword ( ) ;
break ;
2004-01-17 21:34:54 +00:00
}
2005-02-09 21:54:04 +00:00
2005-04-05 10:23:15 +00:00
// Create the data management thread to talk with the daemon
2005-04-06 23:12:27 +00:00
//
if ( ! DestoryDataManagementThread ( ) ) {
2005-04-05 10:23:15 +00:00
return E_FAIL ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
2005-04-05 10:23:15 +00:00
return 0 ;
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 ] ;
2004-11-14 08:29:32 +00:00
2005-04-06 23:12:27 +00:00
GetTextForError ( hr , strMsg , 512 ) ;
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
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
m_hWndParent = HWND ( _atoi64 ( pstrCommandLine ) ) ;
# else
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
m_hWndParent = HWND ( _atoi64 ( pstrCommandLine ) ) ;
# else
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
m_hWndParent = HWND ( _atoi64 ( pstrCommandLine ) ) ;
# else
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 ) ) ;
StringCchCopy ( pMonitorInfoNew - > strDeviceName , 128 , dispdev . DeviceString ) ;
StringCchCopy ( pMonitorInfoNew - > strMonitorName , 128 , dispdev2 . DeviceString ) ;
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
2005-04-05 10:23:15 +00:00
// arguments: name: name of key, keyval: where to store value of key
// returns: int indicating error
// function: reads string value in specified key
2005-04-06 23:12:27 +00:00
//
int CScreensaver : : UtilSetRegKey ( LPCTSTR name , DWORD value ) {
2005-04-05 10:23:15 +00:00
LONG error ;
HKEY boinc_key ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
if ( m_bIs9x ) {
error = RegCreateKeyEx (
2005-04-05 10:23:15 +00:00
HKEY_LOCAL_MACHINE ,
_T ( " SOFTWARE \\ Space Sciences Laboratory, U.C. Berkeley \\ BOINC Screensaver " ) ,
0 ,
NULL ,
REG_OPTION_NON_VOLATILE ,
KEY_READ | KEY_WRITE ,
NULL ,
& boinc_key ,
NULL
) ;
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
2005-04-05 10:23:15 +00:00
} else {
2005-04-06 23:12:27 +00:00
error = RegCreateKeyEx (
2005-04-05 10:23:15 +00:00
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
) ;
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
2005-04-05 10:23:15 +00:00
}
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
error = RegSetValueEx ( boinc_key , name , 0 , REG_DWORD , ( CONST BYTE * ) & value , 4 ) ;
2004-11-14 08:29:32 +00:00
2005-04-06 23:12:27 +00:00
RegCloseKey ( boinc_key ) ;
2004-01-17 21:34:54 +00:00
2005-04-05 10:23:15 +00:00
return 0 ;
2002-12-16 22:34:50 +00:00
}
2004-01-17 21:34:54 +00:00
2005-04-05 10:23:15 +00:00
// arguments: name: name of key, keyval: where to store value of key
// returns: int indicating error
// function: reads string value in specified key
2005-04-06 23:12:27 +00:00
//
int 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 ;
2005-04-06 23:12:27 +00:00
if ( m_bIs9x ) {
error = RegOpenKeyEx (
2005-04-05 10:23:15 +00:00
HKEY_LOCAL_MACHINE ,
_T ( " SOFTWARE \\ Space Sciences Laboratory, U.C. Berkeley \\ BOINC Screensaver " ) ,
0 ,
KEY_ALL_ACCESS ,
& boinc_key
) ;
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
2005-04-05 10:23:15 +00:00
} else {
error = RegOpenKeyEx (
HKEY_CURRENT_USER ,
_T ( " SOFTWARE \\ Space Sciences Laboratory, U.C. Berkeley \\ BOINC Screensaver " ) ,
0 ,
KEY_ALL_ACCESS ,
& boinc_key
) ;
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
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
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
2005-04-05 10:23:15 +00:00
return 0 ;
}
// arguments: name: name of key, str: value of string to store
// if str is empty, attepts to delete the key
// returns: int indicating error
// function: sets string value in specified key in windows startup dir
2005-04-06 23:12:27 +00:00
//
int CScreensaver : : UtilGetRegStartupStr ( LPCTSTR name , LPTSTR str ) {
2005-04-05 10:23:15 +00:00
LONG error ;
DWORD type = REG_SZ ;
DWORD size = 128 ;
HKEY boinc_key ;
* str = 0 ;
2005-04-06 23:12:27 +00:00
if ( m_bIs9x ) {
error = RegOpenKeyEx (
2005-04-05 10:23:15 +00:00
HKEY_LOCAL_MACHINE ,
_T ( " Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Run " ) ,
0 ,
KEY_ALL_ACCESS ,
& boinc_key
) ;
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
2005-04-05 10:23:15 +00:00
} else {
2005-04-06 23:12:27 +00:00
error = RegOpenKeyEx (
2005-04-05 10:23:15 +00:00
HKEY_CURRENT_USER ,
_T ( " Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Run " ) ,
0 ,
KEY_ALL_ACCESS ,
& boinc_key
) ;
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
2005-04-05 10:23:15 +00:00
}
2005-04-06 23:12:27 +00:00
error = RegQueryValueEx ( boinc_key , name , NULL , & type , ( BYTE * ) str , & size ) ;
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
2005-04-06 23:12:27 +00:00
if ( error ! = ERROR_SUCCESS ) return - 1 ;
2005-04-05 10:23:15 +00:00
return ERROR_SUCCESS ;
}
2005-04-06 23:12:27 +00:00
// Determine if BOINC is configured to automatically start at logon/startup.
//
2005-04-05 10:23:15 +00:00
// Define dynamically linked to function
typedef HRESULT ( STDAPICALLTYPE * MYSHGETFOLDERPATH ) ( HWND hwnd , int csidl , HANDLE hToken , DWORD dwFlags , LPSTR pszPath ) ;
2005-04-06 23:12:27 +00:00
BOOL CScreensaver : : IsConfigStartupBOINC ( ) {
2005-04-05 10:23:15 +00:00
BOOL bRetVal ;
BOOL bCheckFileExists ;
TCHAR szBuffer [ MAX_PATH ] ;
2006-01-27 08:55:22 +00:00
TCHAR szShortcutBuffer [ MAX_PATH ] ;
2005-04-05 10:23:15 +00:00
HANDLE hFileHandle ;
HMODULE hShell32 ;
MYSHGETFOLDERPATH pfnMySHGetFolderPath = NULL ;
// Lets set the default value to FALSE
bRetVal = FALSE ;
2006-01-27 08:55:22 +00:00
// Load the shortcut filename into the shortcut buffer.
LoadString ( NULL , IDS_SHORTCUTNAME , szShortcutBuffer , sizeof ( szShortcutBuffer ) / sizeof ( TCHAR ) ) ;
2005-04-05 10:23:15 +00:00
// Attempt to link to dynamic function if it exists
hShell32 = LoadLibrary ( _T ( " SHELL32.DLL " ) ) ;
2005-04-06 23:12:27 +00:00
if ( NULL ! = hShell32 )
2005-04-05 10:23:15 +00:00
pfnMySHGetFolderPath = ( MYSHGETFOLDERPATH ) GetProcAddress ( hShell32 , _T ( " SHGetFolderPathA " ) ) ;
// Now lets begin looking in the registry
2005-04-06 23:12:27 +00:00
if ( ERROR_SUCCESS = = UtilGetRegStartupStr ( REG_STARTUP_NAME , szBuffer ) ) {
2005-04-05 10:23:15 +00:00
bRetVal = TRUE ;
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
// It could be in the global startup group
2005-04-06 23:12:27 +00:00
ZeroMemory ( szBuffer , sizeof ( szBuffer ) ) ;
2005-04-05 10:23:15 +00:00
bCheckFileExists = FALSE ;
2005-04-06 23:12:27 +00:00
if ( NULL ! = pfnMySHGetFolderPath ) {
if ( SUCCEEDED ( ( pfnMySHGetFolderPath ) ( NULL , CSIDL_STARTUP | CSIDL_FLAG_CREATE , NULL , SHGFP_TYPE_CURRENT , szBuffer ) ) ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: pfnMySHGetFolderPath - CSIDL_STARTUP - '%s' \n " ) , szBuffer ) ;
2006-01-27 08:55:22 +00:00
StringCchCatN ( szBuffer , sizeof ( szBuffer ) , _T ( " \\ " ) , sizeof ( _T ( " \\ " ) ) / sizeof ( TCHAR ) ) ;
if ( SUCCEEDED ( StringCchCatN ( szBuffer , sizeof ( szBuffer ) , szShortcutBuffer , sizeof ( szShortcutBuffer ) / sizeof ( TCHAR ) ) ) ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: Final pfnMySHGetFolderPath - CSIDL_STARTUP - '%s' \n " ) , szBuffer ) ;
bCheckFileExists = TRUE ;
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: FAILED pfnMySHGetFolderPath - CSIDL_STARTUP Append Operation \n " ) ) ;
}
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: FAILED pfnMySHGetFolderPath - CSIDL_STARTUP \n " ) ) ;
}
}
2005-04-06 23:12:27 +00:00
if ( bCheckFileExists ) {
2005-04-05 10:23:15 +00:00
hFileHandle = CreateFile (
szBuffer ,
GENERIC_READ ,
FILE_SHARE_READ ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL ,
NULL ) ;
2005-04-06 23:12:27 +00:00
if ( INVALID_HANDLE_VALUE ! = hFileHandle ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: CreateFile returned a valid handle '%d' \n " ) , hFileHandle ) ;
CloseHandle ( hFileHandle ) ;
bRetVal = TRUE ;
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: CreateFile returned INVALID_HANDLE_VALUE - GetLastError() '%d' \n " ) , GetLastError ( ) ) ;
// It could be in the global startup group
2005-04-06 23:12:27 +00:00
ZeroMemory ( szBuffer , sizeof ( szBuffer ) ) ;
2005-04-05 10:23:15 +00:00
bCheckFileExists = FALSE ;
2005-04-06 23:12:27 +00:00
if ( NULL ! = pfnMySHGetFolderPath ) {
if ( SUCCEEDED ( ( pfnMySHGetFolderPath ) ( NULL , CSIDL_COMMON_STARTUP | CSIDL_FLAG_CREATE , NULL , SHGFP_TYPE_CURRENT , szBuffer ) ) ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: pfnMySHGetFolderPath - CSIDL_COMMON_STARTUP - '%s' \n " ) , szBuffer ) ;
2006-01-27 08:55:22 +00:00
StringCchCatN ( szBuffer , sizeof ( szBuffer ) , _T ( " \\ " ) , sizeof ( _T ( " \\ " ) ) / sizeof ( TCHAR ) ) ;
if ( SUCCEEDED ( StringCchCatN ( szBuffer , sizeof ( szBuffer ) , szShortcutBuffer , sizeof ( szShortcutBuffer ) / sizeof ( TCHAR ) ) ) ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: Final pfnMySHGetFolderPath - CSIDL_COMMON_STARTUP - '%s' \n " ) , szBuffer ) ;
bCheckFileExists = TRUE ;
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: FAILED pfnMySHGetFolderPath - CSIDL_COMMON_STARTUP Append Operation \n " ) ) ;
}
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: FAILED pfnMySHGetFolderPath - CSIDL_COMMON_STARTUP \n " ) ) ;
}
}
2005-04-06 23:12:27 +00:00
if ( bCheckFileExists ) {
2005-04-05 10:23:15 +00:00
hFileHandle = CreateFile (
szBuffer ,
GENERIC_READ ,
FILE_SHARE_READ ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL ,
NULL ) ;
2005-04-06 23:12:27 +00:00
if ( INVALID_HANDLE_VALUE ! = hFileHandle ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: CreateFile returned a valid handle '%d' \n " ) , hFileHandle ) ;
CloseHandle ( hFileHandle ) ;
bRetVal = TRUE ;
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: CreateFile returned INVALID_HANDLE_VALUE - GetLastError() '%d' \n " ) , GetLastError ( ) ) ;
}
}
}
}
}
// Free the dynamically linked to library
FreeLibrary ( hShell32 ) ;
BOINCTRACE ( _T ( " CScreensaver::IsConfigStartupBOINC: Returning '%d' \n " ) , bRetVal ) ;
return bRetVal ;
}
// 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 ;
}
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 ) {
2005-04-05 10:23:15 +00:00
StringCbCopyN ( pszError , iErrorSize , m_szError , sizeof ( m_szError ) * sizeof ( TCHAR ) ) ;
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 ;
}
2005-04-06 23:12:27 +00:00
// Update the error message
//
VOID CScreensaver : : UpdateErrorBoxText ( ) {
2005-04-05 10:23:15 +00:00
RESULTS results ;
PROJECT * pProject ;
TCHAR szBuffer [ 256 ] ;
bool bIsActive = false ;
bool bIsExecuting = false ;
bool bIsDownloaded = false ;
int iResultCount = 0 ;
int iIndex = 0 ;
// Load error string
2005-04-06 23:12:27 +00:00
GetTextForError ( m_hrError , m_szError , sizeof ( m_szError ) / sizeof ( TCHAR ) ) ;
if ( SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING = = m_hrError ) {
if ( 0 = = rpc . get_results ( results ) ) {
2005-04-05 10:23:15 +00:00
iResultCount = results . results . size ( ) ;
2005-04-06 23:12:27 +00:00
for ( iIndex = 0 ; iIndex < iResultCount ; iIndex + + ) {
bIsDownloaded = ( RESULT_FILES_DOWNLOADED = = results . results . at ( iIndex ) - > state ) ;
bIsActive = ( results . results . at ( iIndex ) - > active_task ) ;
bIsExecuting = ( CPU_SCHED_SCHEDULED = = results . results . at ( iIndex ) - > scheduler_state ) ;
if ( ! ( bIsActive ) | | ! ( bIsDownloaded ) | | ! ( bIsExecuting ) ) continue ;
pProject = state . lookup_project ( results . results . at ( iIndex ) - > project_url ) ;
if ( NULL ! = pProject ) {
StringCbPrintf ( szBuffer , sizeof ( szBuffer ) / sizeof ( TCHAR ) ,
2005-04-05 10:23:15 +00:00
_T ( " %s: %.2f%% \n " ) ,
pProject - > project_name . c_str ( ) ,
results . results . at ( iIndex ) - > fraction_done * 100
) ;
2005-04-06 23:12:27 +00:00
StringCbCat ( m_szError , sizeof ( m_szError ) / sizeof ( TCHAR ) , szBuffer ) ;
} else {
2005-04-05 10:23:15 +00:00
m_bResetCoreState = TRUE ;
}
}
m_szError [ sizeof ( m_szError ) - 1 ] = ' \0 ' ;
}
}
BOINCTRACE ( _T ( " CScreensaver::UpdateErrorBoxText - Updated Text '%s' \n " ) , m_szError ) ;
}
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
E_FAIL , IDS_ERR_GENERIC ,
E_OUTOFMEMORY , IDS_ERR_OUTOFMEMORY ,
SCRAPPERR_BOINCNOTDETECTED , IDS_ERR_BOINCNOTDETECTED ,
SCRAPPERR_BOINCNOTDETECTEDSTARTUP , IDS_ERR_BOINCNOTDETECTEDSTARTUP ,
SCRAPPERR_BOINCSUSPENDED , IDS_ERR_BOINCSUSPENDED ,
SCRAPPERR_BOINCNOAPPSEXECUTING , IDS_ERR_BOINCNOAPPSEXECUTING ,
SCRAPPERR_BOINCNOPROJECTSDETECTED , IDS_ERR_BOINCNOAPPSEXECUTINGNOPROJECTSDETECTED ,
SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING , IDS_ERR_BOINCNOGRAPHICSAPPSEXECUTING ,
SCRAPPERR_BOINCSCREENSAVERLOADING , IDS_ERR_BOINCSCREENSAVERLOADING ,
2006-04-12 02:28:50 +00:00
SCRAPPERR_BOINCAPPFOUNDGRAPHICSLOADING , IDS_ERR_BOINCAPPFOUNDGRAPHICSLOADING ,
2005-04-05 10:23:15 +00:00
SCRAPPERR_NOPREVIEW , IDS_ERR_NOPREVIEW
} ;
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
}
2005-04-06 23:12:27 +00:00
// Create the thread that is used to talk to the daemon.
//
BOOL CScreensaver : : CreateDataManagementThread ( ) {
2005-05-05 06:07:14 +00:00
DWORD dwThreadID = 0 ;
2005-04-06 23:12:27 +00:00
m_hDataManagementThread = CreateThread (
2005-04-05 10:23:15 +00:00
NULL , // default security attributes
0 , // use default stack size
DataManagementProcStub , // thread function
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
2005-04-06 23:12:27 +00:00
if ( m_hDataManagementThread = = NULL ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::CreateDataManagementThread: Failed to create data management thread '%d' \n " ) , GetLastError ( ) ) ;
return FALSE ;
}
return TRUE ;
}
2005-04-06 23:12:27 +00:00
// Terminate the thread that is used to talk to the daemon.
//
BOOL CScreensaver : : DestoryDataManagementThread ( ) {
if ( ! TerminateThread ( m_hDataManagementThread , 0 ) ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::DestoryDataManagementThread: Failed to terminate data management thread '%d' \n " ) , GetLastError ( ) ) ;
return FALSE ;
}
return TRUE ;
}
2005-10-09 07:29:44 +00:00
// Do what needs to be done to update the text that is displayed
// to the user
2005-04-06 23:12:27 +00:00
//
DWORD WINAPI CScreensaver : : DataManagementProc ( ) {
2005-04-05 10:23:15 +00:00
BOOL bErrorMode ;
2006-04-06 03:46:16 +00:00
BOOL bForegroundWindowIsScreensaver ;
2005-04-05 10:23:15 +00:00
HRESULT hrError ;
HWND hwndBOINCGraphicsWindow = NULL ;
HWND hwndForegroundWindow = NULL ;
2006-04-06 03:46:16 +00:00
DWORD iMonitor = 0 ;
2005-04-05 10:23:15 +00:00
int iReturnValue = 0 ;
time_t tThreadCreateTime = 0 ;
2005-04-05 20:02:59 +00:00
bool bScreenSaverStarting = false ;
2006-04-06 03:46:16 +00:00
INTERNALMONITORINFO * pMonitorInfo = NULL ;
2005-04-05 10:23:15 +00:00
2005-04-05 20:02:59 +00:00
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - Display screen saver loading message \n " ) ) ;
2005-04-06 23:12:27 +00:00
SetError ( TRUE , SCRAPPERR_BOINCSCREENSAVERLOADING ) ;
2005-04-05 10:23:15 +00:00
tThreadCreateTime = time ( 0 ) ;
2005-04-06 23:12:27 +00:00
while ( 1 ) {
2005-04-05 20:02:59 +00:00
bScreenSaverStarting = ( 10 > = ( time ( 0 ) - tThreadCreateTime ) ) ;
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - Start Status = '%d', CoreNotified = '%d', ErrorMode = '%d', ErrorCode = '%x' \n " ) , m_iStatus , m_bCoreNotified , m_bErrorMode , m_hrError ) ;
2005-04-05 20:02:59 +00:00
// Lets try and get the current state of the CC
2005-04-06 23:12:27 +00:00
if ( m_bResetCoreState & & m_bCoreNotified ) {
iReturnValue = rpc . get_state ( state ) ;
if ( 0 = = iReturnValue ) {
2005-04-05 20:02:59 +00:00
m_bResetCoreState = FALSE ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 20:02:59 +00:00
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - get_state iReturnValue = '%d' \n " ) , iReturnValue ) ;
}
2005-04-06 23:12:27 +00:00
iReturnValue = rpc . get_screensaver_mode ( m_iStatus ) ;
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - get_screensaver_mode iReturnValue = '%d' \n " ) , iReturnValue ) ;
2005-04-06 23:12:27 +00:00
if ( 0 ! = iReturnValue ) {
2005-04-05 10:23:15 +00:00
// Attempt to reinitialize the RPC client and state
rpc . close ( ) ;
2005-04-06 23:12:27 +00:00
rpc . init ( NULL ) ;
2005-04-05 10:23:15 +00:00
m_bResetCoreState = TRUE ;
2006-04-06 08:03:27 +00:00
m_bCoreNotified = FALSE ;
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
if ( ! m_bBOINCConfigChecked ) {
2005-04-05 10:23:15 +00:00
m_bBOINCConfigChecked = TRUE ;
m_bBOINCStartupConfigured = IsConfigStartupBOINC ( ) ;
}
2005-04-06 23:12:27 +00:00
if ( ! bScreenSaverStarting ) {
if ( m_bBOINCStartupConfigured ) {
SetError ( TRUE , SCRAPPERR_BOINCNOTDETECTED ) ;
} else {
SetError ( TRUE , SCRAPPERR_BOINCNOTDETECTEDSTARTUP ) ;
}
2005-04-05 20:02:59 +00:00
}
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
// Reset the error flags.
2005-04-06 23:12:27 +00:00
SetError ( FALSE , 0 ) ;
2005-04-05 10:23:15 +00:00
2005-04-06 23:12:27 +00:00
if ( m_bCoreNotified ) {
switch ( m_iStatus ) {
2005-04-05 10:23:15 +00:00
case SS_STATUS_ENABLED :
2006-04-06 03:46:16 +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.
2005-04-06 23:12:27 +00:00
hwndBOINCGraphicsWindow = FindWindow ( BOINC_WINDOW_CLASS_NAME , NULL ) ;
2006-04-12 02:28:50 +00:00
if ( hwndBOINCGraphicsWindow ) {
2006-04-06 03:46:16 +00:00
// Graphics Application.
2005-04-05 10:23:15 +00:00
hwndForegroundWindow = GetForegroundWindow ( ) ;
2006-04-06 03:46:16 +00:00
// If the graphics application is not the top most window try and force it
// to the top.
2005-04-06 23:12:27 +00:00
if ( hwndForegroundWindow ! = hwndBOINCGraphicsWindow ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - Graphics Window Detected but NOT the foreground window, bringing window to foreground. \n " ) ) ;
2005-04-06 23:12:27 +00:00
SetForegroundWindow ( hwndBOINCGraphicsWindow ) ;
2005-04-05 10:23:15 +00:00
hwndForegroundWindow = GetForegroundWindow ( ) ;
2005-04-06 23:12:27 +00:00
if ( hwndForegroundWindow ! = hwndBOINCGraphicsWindow ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - Graphics Window Detected but NOT the foreground window, bringing window to foreground. (Final Try) \n " ) ) ;
2005-10-09 07:29:44 +00:00
2005-04-05 10:23:15 +00:00
// This may be needed on Windows 2000 or better machines
2006-04-12 02:28:50 +00:00
if ( gspfnMyBroadcastSystemMessage ) {
2005-10-09 07:29:44 +00:00
DWORD dwComponents = BSM_APPLICATIONS ;
2006-04-12 02:28:50 +00:00
gspfnMyBroadcastSystemMessage (
2005-10-09 07:29:44 +00:00
BSF_ALLOWSFW ,
& dwComponents ,
WM_BOINCSFW ,
NULL ,
NULL
) ;
}
2006-04-12 02:28:50 +00:00
}
} else {
// Science application has focus, and is visible.
//
// Some science application take a really long time to display something on their
// 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.
// In the science application case where the borders are hidden from view, the
// window just takes on the background of the previous window which happens to be
// the black screensaver window owned by this process.
//
// Here we need to plug into the operating systems heartbeat mechinism for windows
// and verify that their hasn't been any keyboard or mouse activity. If there has
// 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.
if ( gspfnMyIsHungAppWindow & & gspfnMyGetLastInputInfo ) {
if ( gspfnMyIsHungAppWindow ( hwndBOINCGraphicsWindow ) ) {
LASTINPUTINFO lii ;
lii . cbSize = sizeof ( LASTINPUTINFO ) ;
gspfnMyGetLastInputInfo ( & lii ) ;
if ( m_dwLastInputTimeAtStartup ! = lii . dwTime ) {
ShowWindow ( hwndBOINCGraphicsWindow , SW_MINIMIZE ) ;
ShowWindow ( hwndBOINCGraphicsWindow , SW_FORCEMINIMIZE ) ;
ShutdownSaver ( ) ;
}
}
2005-04-05 10:23:15 +00:00
}
}
2006-04-06 03:46: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 ;
hwndForegroundWindow = GetForegroundWindow ( ) ;
for ( iMonitor = 0 ; iMonitor < m_dwNumMonitors ; iMonitor + + ) {
pMonitorInfo = & m_Monitors [ iMonitor ] ;
if ( pMonitorInfo - > hWnd = = hwndForegroundWindow ) {
bForegroundWindowIsScreensaver = TRUE ;
}
}
if ( ! bForegroundWindowIsScreensaver ) {
2006-04-12 02:28:50 +00:00
// 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.
2006-04-06 03:46:16 +00:00
ShutdownSaver ( ) ;
2006-04-12 02:28:50 +00:00
} else {
// Application has been selected, and graphics should be up before too
// long.
SetError ( TRUE , SCRAPPERR_BOINCAPPFOUNDGRAPHICSLOADING ) ;
2006-04-06 03:46:16 +00:00
}
2005-04-05 10:23:15 +00:00
}
break ;
case SS_STATUS_BLANKED :
break ;
case SS_STATUS_BOINCSUSPENDED :
2005-04-06 23:12:27 +00:00
SetError ( TRUE , SCRAPPERR_BOINCSUSPENDED ) ;
2005-04-05 10:23:15 +00:00
break ;
case SS_STATUS_NOAPPSEXECUTING :
2005-04-06 23:12:27 +00:00
SetError ( TRUE , SCRAPPERR_BOINCNOAPPSEXECUTING ) ;
2005-04-05 10:23:15 +00:00
break ;
case SS_STATUS_NOPROJECTSDETECTED :
2005-04-06 23:12:27 +00:00
SetError ( TRUE , SCRAPPERR_BOINCNOPROJECTSDETECTED ) ;
2005-04-05 10:23:15 +00:00
break ;
case SS_STATUS_NOGRAPHICSAPPSEXECUTING :
2005-04-06 23:12:27 +00:00
SetError ( TRUE , SCRAPPERR_BOINCNOGRAPHICSAPPSEXECUTING ) ;
2005-04-05 10:23:15 +00:00
break ;
}
}
}
2005-04-06 23:12:27 +00:00
GetError ( bErrorMode , hrError , NULL , 0 ) ;
2005-05-20 20:28:00 +00:00
if ( SS_STATUS_QUIT = = m_iStatus & & m_bCoreNotified ) {
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - Shutdown BOINC Screensaver \n " ) ) ;
ShutdownSaver ( ) ;
2005-04-06 23:12:27 +00:00
} else {
2005-05-20 20:28:00 +00:00
if ( ! bErrorMode & & ! m_bCoreNotified ) {
BOINCTRACE ( _T ( " CScreensaver::DataManagementProc - Startup BOINC Screensaver \n " ) ) ;
StartupBOINC ( ) ;
2005-04-05 10:23:15 +00:00
}
}
BOINCTRACE ( _T ( " CScreensaver::SaverProc - End Status = '%d', CoreNotified = '%d', ErrorMode = '%d', ErrorCode = '%x' \n " ) , m_iStatus , m_bCoreNotified , m_bErrorMode , m_hrError ) ;
2006-04-04 04:39:40 +00:00
if ( bScreenSaverStarting | | ( SS_STATUS_ENABLED ! = m_iStatus ) ) {
2005-04-06 23:12:27 +00:00
Sleep ( 1000 ) ;
} else {
Sleep ( 10000 ) ;
}
2005-04-05 10:23:15 +00:00
}
}
2005-04-06 23:12:27 +00:00
// This function forwards to DataManagementProc, which has access to the
2005-04-05 10:23:15 +00:00
// "this" pointer.
2005-04-06 23:12:27 +00:00
//
2005-07-07 22:26:49 +00:00
DWORD WINAPI CScreensaver : : DataManagementProcStub ( LPVOID UNUSED ( lpParam ) ) {
2006-04-12 02:28:50 +00:00
return gspScreensaver - > DataManagementProc ( ) ;
2005-04-05 10:23:15 +00:00
}
2005-04-06 23:12:27 +00:00
// Notifies BOINC that it has to start the screensaver in full screen mode.
//
VOID CScreensaver : : StartupBOINC ( ) {
if ( m_SaverMode ! = sm_preview ) {
if ( ( NULL ! = m_Monitors [ 0 ] . hWnd ) & & ( m_bCoreNotified = = FALSE ) ) {
2005-04-05 10:23:15 +00:00
DISPLAY_INFO di ;
BOOL bReturnValue ;
int iReturnValue ;
2005-04-06 23:12:27 +00:00
if ( ! m_bIs9x ) {
2005-04-05 10:23:15 +00:00
// Retrieve the current window station and desktop names
2005-04-06 23:12:27 +00:00
bReturnValue = GetUserObjectInformation (
2005-04-05 10:23:15 +00:00
GetProcessWindowStation ( ) ,
UOI_NAME ,
di . window_station ,
sizeof ( di . window_station ) ,
NULL
) ;
2005-04-06 23:12:27 +00:00
if ( ! bReturnValue ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " Failed to retrieve the current window station. \n " ) ) ;
}
2005-04-06 23:12:27 +00:00
bReturnValue = GetUserObjectInformation (
2005-04-05 10:23:15 +00:00
GetThreadDesktop ( GetCurrentThreadId ( ) ) ,
UOI_NAME ,
di . desktop ,
sizeof ( di . desktop ) ,
NULL
) ;
2005-04-06 23:12:27 +00:00
if ( ! bReturnValue ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " Failed to retrieve the current desktop. \n " ) ) ;
}
}
// Tell the boinc client to start the screen saver
BOINCTRACE ( _T ( " CScreensaver::StartupBOINC - Calling set_screensaver_mode - WindowStation = '%s', Desktop = '%s', BlankScreen = '%d', BlankTime = '%d'. \n " ) , di . window_station , di . desktop , m_dwBlankScreen , m_dwBlankTime ) ;
2005-04-06 23:12:27 +00:00
if ( 0 = = m_dwBlankScreen ) {
2005-04-05 10:23:15 +00:00
iReturnValue = rpc . set_screensaver_mode ( true , 0 , di ) ;
2005-04-06 23:12:27 +00:00
} else {
2005-04-05 10:23:15 +00:00
iReturnValue = rpc . set_screensaver_mode ( true , m_dwBlankTime , di ) ;
2005-04-06 23:12:27 +00:00
}
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::StartupBOINC - set_screensaver_mode iReturnValue = '%d' \n " ) , iReturnValue ) ;
// We have now notified the boinc client
2005-04-06 23:12:27 +00:00
if ( 0 = = iReturnValue ) {
2005-04-05 10:23:15 +00:00
m_bCoreNotified = TRUE ;
2005-04-06 23:12:27 +00:00
} else {
SetError ( TRUE , SCRAPPERR_BOINCNOTDETECTED ) ;
}
2005-04-05 10:23:15 +00:00
}
}
}
2005-04-06 23:12:27 +00:00
// Notifies BOINC that it has to lose the screensaver.
//
VOID CScreensaver : : ShutdownBOINC ( ) {
if ( m_bCoreNotified ) {
2005-04-05 10:23:15 +00:00
DISPLAY_INFO di ;
// Tell the boinc client to stop the screen saver
rpc . set_screensaver_mode ( false , 0.0 , di ) ;
// We have now notified the boinc client
m_bCoreNotified = FALSE ;
}
}
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 ;
cls2 . lpfnWndProc = SaverProcStub ;
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 ) ;
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-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 ) ;
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-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 ) {
pMonitorInfo - > hWnd = CreateWindowEx ( WS_EX_TOPMOST , _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 {
pMonitorInfo - > hWnd = CreateWindowEx ( WS_EX_TOPMOST , _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
2005-04-05 20:02:59 +00:00
SetTimer ( pMonitorInfo - > hWnd , 2 , 2000 , 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 ;
}
2005-04-06 23:12:27 +00:00
// Run the screensaver graphics - may be preview, test or full-on mode
//
HRESULT CScreensaver : : DoSaver ( ) {
2005-04-05 10:23:15 +00:00
// If we're in full on mode, and on 9x, then need to load the password DLL
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_full & & m_bIs9x ) {
2005-04-05 10:23:15 +00:00
// Only do this if the password is set - check registry:
HKEY hKey ;
2005-04-06 23:12:27 +00:00
if ( RegOpenKey ( HKEY_CURRENT_USER , REGSTR_PATH_SCREENSAVE , & hKey ) = = ERROR_SUCCESS ) {
2005-04-05 10:23:15 +00:00
DWORD dwVal ;
DWORD dwSize = sizeof ( dwVal ) ;
2005-04-06 23:12:27 +00:00
if ( ( RegQueryValueEx (
hKey , REGSTR_VALUE_USESCRPASSWORD , NULL , NULL ,
( BYTE * ) & dwVal , & dwSize ) = = ERROR_SUCCESS ) & & dwVal
) {
m_hPasswordDLL = LoadLibrary ( _T ( " PASSWORD.CPL " ) ) ;
if ( m_hPasswordDLL )
m_VerifySaverPassword = ( VERIFYPWDPROC ) GetProcAddress ( m_hPasswordDLL , _T ( " VerifyScreenSavePwd " ) ) ;
RegCloseKey ( hKey ) ;
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
}
2005-04-06 23:12:27 +00:00
// Handle window messages for main screensaver windows.
//
LRESULT CScreensaver : : SaverProc (
HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam
) {
2005-03-23 00:16:58 +00:00
DWORD dwMonitor = 0 ;
# ifdef _DEBUG
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
}
}
2005-03-23 00:16:58 +00:00
# endif
2005-04-06 23:12:27 +00:00
switch ( uMsg ) {
2004-01-17 21:34:54 +00:00
case WM_USER :
// All initialization messages have gone through. Allow
// 500ms of idle time, then proceed with initialization.
2005-04-06 23:12:27 +00:00
SetTimer ( hWnd , 1 , 500 , NULL ) ;
2004-01-17 21:34:54 +00:00
break ;
case WM_TIMER :
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 ) ;
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
// Create a screen saver window on the primary display if
// the boinc client crashes
CreateSaverWindow ( ) ;
2005-02-03 01:55:34 +00:00
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 ( ) ;
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
{
2005-03-23 00:16:58 +00:00
// Show error message, if there is one
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-05 10:23:15 +00:00
BOOL bErrorMode ;
HRESULT hrError ;
2005-04-06 23:12:27 +00:00
GetError ( bErrorMode , hrError , NULL , 0 ) ;
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 {
DoPaint ( hWnd , ps . hdc ) ;
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 ;
INT xCur = GET_X_LPARAM ( lParam ) ;
INT yCur = GET_Y_LPARAM ( 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 + + ;
2005-04-06 23:12:27 +00:00
if ( m_dwSaverMouseMoveCount > 5 )
2004-01-17 21:34:54 +00:00
InterruptSaver ( ) ;
}
}
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 :
2005-04-06 23:12:27 +00:00
if ( m_SaverMode ! = sm_test ) {
2004-01-17 21:34:54 +00:00
InterruptSaver ( ) ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
return 0 ;
break ;
2005-03-23 00:16:58 +00:00
case WM_CLOSE :
case WM_DESTROY :
2005-04-02 18:08:55 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc Received WM_CLOSE or WM_DESTROY \n " ) ) ;
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_preview | | m_SaverMode = = sm_test ) {
2005-03-23 00:16:58 +00:00
ShutdownSaver ( ) ;
2005-04-06 23:12:27 +00:00
}
2005-03-23 00:16:58 +00:00
return 0 ;
2004-01-17 21:34:54 +00:00
break ;
case WM_SYSCOMMAND :
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 :
return FALSE ;
2005-04-06 23:12:27 +00:00
}
2004-01-17 21:34:54 +00:00
}
break ;
case WM_SETCURSOR :
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_full & & ! m_bCheckingSaverPassword ) {
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 :
2005-05-13 21:29:42 +00:00
if ( wParam = = PBT_APMQUERYSUSPEND & & m_VerifySaverPassword = = NULL )
2004-01-17 21:34:54 +00:00
InterruptSaver ( ) ;
break ;
}
2005-03-23 00:16:58 +00:00
BOINCTRACE ( _T ( " CScreensaver::SaverProc [%d] hWnd '%d' uMsg '%X' wParam '%d' lParam '%d' \n " ) , dwMonitor , hWnd , uMsg , wParam , lParam ) ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
return DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
2002-11-14 00:49:24 +00:00
}
2002-12-16 22:34:50 +00:00
2004-01-17 21:34:54 +00:00
2005-07-07 22:26:49 +00:00
INT_PTR CScreensaver : : ConfigureDialogProc ( HWND hwnd , UINT msg , WPARAM wParam , LPARAM UNUSED ( lParam ) ) {
2005-01-13 01:52:56 +00:00
DWORD screen_blank = 0 , blank_time = 0 ;
char buf [ 256 ] ;
int retval ;
switch ( msg ) {
case WM_INITDIALOG :
// make sure you check return value of registry queries
// in case the item in question doesn't happen to exist.
2005-04-06 23:12:27 +00:00
retval = UtilGetRegKey ( REG_BLANK_NAME , screen_blank ) ;
if ( retval < 0 ) {
screen_blank = 0 ;
}
CheckDlgButton ( hwnd , IDC_BLANK , screen_blank ) ;
2005-01-13 01:52:56 +00:00
2005-04-06 23:12:27 +00:00
retval = UtilGetRegKey ( REG_BLANK_TIME , blank_time ) ;
if ( retval < 0 ) { blank_time = 0 ; }
2005-01-13 01:52:56 +00:00
_ltot ( blank_time , buf , 10 ) ;
2005-04-06 23:12:27 +00:00
SetDlgItemText ( hwnd , IDC_BLANK_TIME , buf ) ;
2005-01-13 01:52:56 +00:00
return TRUE ;
case WM_COMMAND :
int id = LOWORD ( wParam ) ;
if ( id = = IDOK ) {
2005-04-06 23:12:27 +00:00
screen_blank = ( IsDlgButtonChecked ( hwnd , IDC_BLANK ) = = BST_CHECKED ) ;
UtilSetRegKey ( REG_BLANK_NAME , screen_blank ) ;
2005-01-13 01:52:56 +00:00
2005-04-06 23:12:27 +00:00
GetDlgItemText ( hwnd , IDC_BLANK_TIME , buf , 256 ) ;
blank_time = atoi ( buf ) ;
UtilSetRegKey ( REG_BLANK_TIME , blank_time ) ;
2005-01-13 01:52:56 +00:00
}
2005-04-06 23:12:27 +00:00
if ( id = = IDOK | | id = = IDCANCEL ) {
EndDialog ( hwnd , id ) ;
}
2005-01-13 01:52:56 +00:00
break ;
}
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
}
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 ( ) {
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
}
// Unload the password DLL (if we loaded it)
2005-04-06 23:12:27 +00:00
if ( m_hPasswordDLL ! = NULL ) {
FreeLibrary ( m_hPasswordDLL ) ;
2004-01-17 21:34:54 +00:00
m_hPasswordDLL = NULL ;
}
ShutdownBOINC ( ) ;
// Post message to drop out of message loop
2005-05-13 00:33:04 +00:00
// This can be called from the data management thread, so specifically
// lookup and post to the primary window instead of calling PostQuitMessage
// since PostQuitMessage posts to the current threads message pump if it
// exists.
if ( m_Monitors [ 0 ] . hWnd ) {
PostMessage ( m_Monitors [ 0 ] . hWnd , WM_QUIT , 0 , 0 ) ;
}
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
// A message was received (mouse move, keydown, etc.) that may mean
2004-01-17 21:34:54 +00:00
// the screen saver should show the password dialog and/or shut down.
2005-04-06 23:12:27 +00:00
//
VOID CScreensaver : : InterruptSaver ( ) {
2004-01-17 21:34:54 +00:00
BOOL bPasswordOkay = FALSE ;
2005-04-06 23:12:27 +00:00
if ( m_SaverMode = = sm_test | |
m_SaverMode = = sm_full & & ! m_bCheckingSaverPassword
) {
if ( m_bIs9x & & m_SaverMode = = sm_full ) {
2004-01-17 21:34:54 +00:00
// If no VerifyPassword function, then no password is set
// or we're not on 9x.
2005-04-06 23:12:27 +00:00
if ( m_VerifySaverPassword ! = NULL ) {
2004-01-17 21:34:54 +00:00
m_bCheckingSaverPassword = TRUE ;
2005-04-06 23:12:27 +00:00
bPasswordOkay = m_VerifySaverPassword ( m_hWnd ) ;
2004-01-17 21:34:54 +00:00
m_bCheckingSaverPassword = FALSE ;
2005-04-06 23:12:27 +00:00
if ( ! bPasswordOkay ) {
2004-01-17 21:34:54 +00:00
// Back to screen saving...
2005-04-06 23:12:27 +00:00
SetCursor ( NULL ) ;
2004-01-17 21:34:54 +00:00
m_dwSaverMouseMoveCount = 0 ;
return ;
}
}
}
ShutdownSaver ( ) ;
}
}
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
}
2004-01-17 21:34:54 +00:00
dwTimeNow = timeGetTime ( ) ;
fTimeDelta = ( FLOAT ) ( dwTimeNow - dwTimeLast ) / 1000.0f ;
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 {
2004-01-17 21:34:54 +00:00
pMonitorInfo - > widthError = 500 ;
2004-01-18 19:36:50 +00:00
pMonitorInfo - > heightError = 154 ;
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
2005-04-06 23:12:27 +00:00
if ( rcOld . left ! = rcNew . left | | rcOld . top ! = rcNew . top )
2005-04-05 10:23:15 +00:00
{
2005-04-06 23:12:27 +00:00
InvalidateRect ( hwnd , & rcOld , TRUE ) ;
InvalidateRect ( hwnd , & rcNew , TRUE ) ;
UpdateWindow ( hwnd ) ;
2005-04-05 10:23:15 +00:00
}
}
2004-01-17 21:34:54 +00:00
}
}
}
2005-04-06 23:12:27 +00:00
VOID CScreensaver : : DoPaint ( HWND hwnd , HDC hdc ) {
HMONITOR hMonitor = MonitorFromWindow ( hwnd , MONITOR_DEFAULTTONEAREST ) ;
2005-07-07 22:26:49 +00:00
INTERNALMONITORINFO * pMonitorInfo = NULL ;
2005-07-04 21:54:24 +00:00
DWORD iMonitor = 0 ;
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
// Draw the error message box
2005-04-05 10:23:15 +00:00
BOOL bErrorMode ;
HRESULT hrError ;
TCHAR szError [ 400 ] ;
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 ) ) ;
static HBITMAP hbmp = LoadBitmap ( m_hInstance , MAKEINTRESOURCE ( IDB_BOINCSPLAT ) ) ;
2004-01-17 21:34:54 +00:00
2005-04-05 10:23:15 +00:00
// Retrieve the latest piece of error information
2005-04-06 23:12:27 +00:00
GetError ( bErrorMode , hrError , szError , sizeof ( szError ) / sizeof ( TCHAR ) ) ;
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.
2005-04-06 23:12:27 +00:00
if ( ( SS_STATUS_BLANKED = = m_iStatus ) | | ! bErrorMode ) {
2005-04-05 10:23:15 +00:00
BOINCTRACE ( _T ( " CScreensaver::DoPaint - Blank Screen Detected \n " ) ) ;
2005-02-06 09:34:38 +00:00
rc = pMonitorInfo - > rcScreen ;
2005-04-06 23:12:27 +00:00
ScreenToClient ( hwnd , ( POINT * ) & rc . left ) ;
ScreenToClient ( hwnd , ( POINT * ) & rc . right ) ;
FillRect ( hdc , & rc , hbrushBlack ) ;
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 )
) ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
SetRect ( & rcOrginal , ( 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 )
) ;
2004-01-17 21:34:54 +00:00
2005-02-06 05:20:43 +00:00
// Draw the background as black.
2004-01-17 21:34:54 +00:00
FillRect ( hdc , & rc , hbrushBlack ) ;
2005-02-06 05:20:43 +00:00
// Draw a frame in red.
2005-04-06 22:53:00 +00:00
//FrameRect(hdc, &rc, hbrushRed);
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.
2005-12-23 04:51:52 +00:00
DrawTransparentBitmap ( hdc , hbmp , ( rc . left + 2 ) , ( rc . top + 2 ) , RGB ( 255 , 0 , 255 ) ) ;
2004-01-17 21:34:54 +00:00
rc . left + = 166 ;
// Draw text in the center of the frame
SetBkColor ( hdc , RGB ( 0 , 0 , 0 ) ) ; // Black
SetTextColor ( hdc , RGB ( 255 , 255 , 255 ) ) ; // Red
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 ;
rc2 . top = ( rc . bottom + rc . top - iTextHeight ) / 2 ;
2005-04-06 23:12:27 +00:00
DrawText ( hdc , szError , - 1 , & rc2 , DT_CENTER ) ;
2004-01-17 21:34:54 +00:00
// Erase everywhere except the error message box
2005-04-06 23:12:27 +00:00
ExcludeClipRect ( hdc , rcOrginal . left , rcOrginal . top , rcOrginal . right , rcOrginal . bottom ) ;
2004-01-17 21:34:54 +00:00
rc = pMonitorInfo - > rcScreen ;
2005-04-06 23:12:27 +00:00
ScreenToClient ( hwnd , ( POINT * ) & rc . left ) ;
ScreenToClient ( hwnd , ( POINT * ) & rc . right ) ;
FillRect ( hdc , & rc , hbrushBlack ) ;
2004-01-17 21:34:54 +00:00
}
2005-04-06 23:12:27 +00:00
VOID CScreensaver : : ChangePassword ( ) {
2004-01-17 21:34:54 +00:00
// Load the password change DLL
2005-04-06 23:12:27 +00:00
HINSTANCE mpr = LoadLibrary ( _T ( " MPR.DLL " ) ) ;
2004-01-17 21:34:54 +00:00
2005-04-06 23:12:27 +00:00
if ( mpr ! = NULL ) {
2004-01-17 21:34:54 +00:00
// Grab the password change function from it
2005-04-06 23:12:27 +00:00
typedef DWORD ( PASCAL * PWCHGPROC ) ( LPCSTR , HWND , DWORD , LPVOID ) ;
PWCHGPROC pwd = ( PWCHGPROC ) GetProcAddress ( mpr , " PwdChangePasswordA " ) ;
2004-01-17 21:34:54 +00:00
// Do the password change
2005-04-06 23:12:27 +00:00
if ( pwd ! = NULL ) {
pwd ( " SCRSAVE " , m_hWndParent , 0 , NULL ) ;
}
2004-01-17 21:34:54 +00:00
// Free the library
2005-04-06 23:12:27 +00:00
FreeLibrary ( mpr ) ;
2004-01-17 21:34:54 +00:00
}
}
2005-04-06 23:12:27 +00:00
// Draws a bitmap on the screen with a transparent background.
2004-01-18 19:36:50 +00:00
// Code orginally from Microsoft Knowledge Base Article - 79212
2005-04-06 23:12:27 +00:00
//
void CScreensaver : : DrawTransparentBitmap (
HDC hdc , HBITMAP hBitmap , LONG xStart , LONG yStart ,
COLORREF cTransparentColor
) {
BITMAP bm ;
COLORREF cColor ;
HBITMAP bmAndBack , bmAndObject , bmAndMem , bmSave ;
HBITMAP bmBackOld , bmObjectOld , bmMemOld , bmSaveOld ;
HDC hdcMem , hdcBack , hdcObject , hdcTemp , hdcSave ;
POINT ptSize ;
hdcTemp = CreateCompatibleDC ( hdc ) ;
SelectObject ( hdcTemp , hBitmap ) ; // Select the bitmap
GetObject ( hBitmap , sizeof ( BITMAP ) , ( LPSTR ) & bm ) ;
ptSize . x = bm . bmWidth ; // Get width of bitmap
ptSize . y = bm . bmHeight ; // Get height of bitmap
DPtoLP ( hdcTemp , & ptSize , 1 ) ; // Convert from device
2004-01-18 19:36:50 +00:00
// to logical points
2005-04-06 23:12:27 +00:00
// Create some DCs to hold temporary data.
hdcBack = CreateCompatibleDC ( hdc ) ;
hdcObject = CreateCompatibleDC ( hdc ) ;
hdcMem = CreateCompatibleDC ( hdc ) ;
hdcSave = CreateCompatibleDC ( hdc ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Create a bitmap for each DC. DCs are required for a number of
// GDI functions.
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Monochrome DC
bmAndBack = CreateBitmap ( ptSize . x , ptSize . y , 1 , 1 , NULL ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Monochrome DC
bmAndObject = CreateBitmap ( ptSize . x , ptSize . y , 1 , 1 , NULL ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
bmAndMem = CreateCompatibleBitmap ( hdc , ptSize . x , ptSize . y ) ;
bmSave = CreateCompatibleBitmap ( hdc , ptSize . x , ptSize . y ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Each DC must select a bitmap object to store pixel data.
bmBackOld = ( HBITMAP ) SelectObject ( hdcBack , bmAndBack ) ;
bmObjectOld = ( HBITMAP ) SelectObject ( hdcObject , bmAndObject ) ;
bmMemOld = ( HBITMAP ) SelectObject ( hdcMem , bmAndMem ) ;
bmSaveOld = ( HBITMAP ) SelectObject ( hdcSave , bmSave ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Set proper mapping mode.
SetMapMode ( hdcTemp , GetMapMode ( hdc ) ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Save the bitmap sent here, because it will be overwritten.
BitBlt ( hdcSave , 0 , 0 , ptSize . x , ptSize . y , hdcTemp , 0 , 0 , SRCCOPY ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Set the background color of the source DC to the color.
// contained in the parts of the bitmap that should be transparent
cColor = SetBkColor ( hdcTemp , cTransparentColor ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Create the object mask for the bitmap by performing a BitBlt
// from the source bitmap to a monochrome bitmap.
BitBlt ( hdcObject , 0 , 0 , ptSize . x , ptSize . y , hdcTemp , 0 , 0 , SRCCOPY ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Set the background color of the source DC back to the original
// color.
SetBkColor ( hdcTemp , cColor ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Create the inverse of the object mask.
BitBlt ( hdcBack , 0 , 0 , ptSize . x , ptSize . y , hdcObject , 0 , 0 , NOTSRCCOPY ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Copy the background of the main DC to the destination.
BitBlt ( hdcMem , 0 , 0 , ptSize . x , ptSize . y , hdc , xStart , yStart , SRCCOPY ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Mask out the places where the bitmap will be placed.
BitBlt ( hdcMem , 0 , 0 , ptSize . x , ptSize . y , hdcObject , 0 , 0 , SRCAND ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Mask out the transparent colored pixels on the bitmap.
BitBlt ( hdcTemp , 0 , 0 , ptSize . x , ptSize . y , hdcBack , 0 , 0 , SRCAND ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// XOR the bitmap with the background on the destination DC.
BitBlt ( hdcMem , 0 , 0 , ptSize . x , ptSize . y , hdcTemp , 0 , 0 , SRCPAINT ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Copy the destination to the screen.
BitBlt ( hdc , xStart , yStart , ptSize . x , ptSize . y , hdcMem , 0 , 0 , SRCCOPY ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Place the original bitmap back into the bitmap sent here.
BitBlt ( hdcTemp , 0 , 0 , ptSize . x , ptSize . y , hdcSave , 0 , 0 , SRCCOPY ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Delete the memory bitmaps.
DeleteObject ( SelectObject ( hdcBack , bmBackOld ) ) ;
DeleteObject ( SelectObject ( hdcObject , bmObjectOld ) ) ;
DeleteObject ( SelectObject ( hdcMem , bmMemOld ) ) ;
DeleteObject ( SelectObject ( hdcSave , bmSaveOld ) ) ;
2004-01-18 19:36:50 +00:00
2005-04-06 23:12:27 +00:00
// Delete the memory DCs.
DeleteDC ( hdcMem ) ;
DeleteDC ( hdcBack ) ;
DeleteDC ( hdcObject ) ;
DeleteDC ( hdcSave ) ;
DeleteDC ( hdcTemp ) ;
2004-01-18 19:36:50 +00:00
}
2004-01-19 19:45:52 +00:00
2005-01-02 18:29:53 +00:00
const char * BOINC_RCSID_116268c72f = " $Id$ " ;