|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 1996 * * TITLE: PWRSWTCH.C * * VERSION: 2.0 * * AUTHOR: ReedB * * DATE: 17 Oct, 1996 * * DESCRIPTION: * Support for Advanced page of PowerCfg.Cpl. * *******************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <commctrl.h>
#include <systrayp.h>
#include <help.h>
#include <powercfp.h>
#include "powercfg.h"
#include "pwrresid.h"
#include "PwrMn_cs.h"
/*******************************************************************************
* * G L O B A L D A T A * *******************************************************************************/
// This structure is filled in by the Power Policy Manager at CPL_INIT time.
extern SYSTEM_POWER_CAPABILITIES g_SysPwrCapabilities; extern BOOL g_bRunningUnderNT;
// Machine is currently capable of hibernate, managed by code in hibernat.c.
extern UINT g_uiPwrActIDs[]; extern UINT g_uiLidActIDs[];
// A systary change requires PowerSchemeDlgProc re-init.
extern BOOL g_bSystrayChange;
// Persistant storage of this data is managed by POWRPROF.DLL API's.
GLOBAL_POWER_POLICY g_gpp;
// Show/hide UI state variables.
DWORD g_dwShowPowerButtonUI; DWORD g_dwShowSleepButtonUI; DWORD g_dwShowLidUI; DWORD g_dwShowPwrButGrpUI; DWORD g_dwShowEnableSysTray; DWORD g_uiPasswordState; DWORD g_uiVideoDimState;
// Static flags:
UINT g_uiEnableSysTrayFlag = EnableSysTrayBatteryMeter; UINT g_uiEnablePWLogonFlag = EnablePasswordLogon; UINT g_uiEnableVideoDimDisplay = EnableVideoDimDisplay;
// Indicies into combobox selections
UINT g_uiDoNothing; UINT g_uiAskMeWhatToDo; UINT g_uiShutdown;
// Global marking whether sheet is dirty
BOOL g_bDirty;
// Button policies dialog controls descriptions:
#define NUM_BUTTON_POL_CONTROLS 10
// Handy indicies into our g_pcButtonPol control array:
#define ID_LIDCLOSETEXT 0
#define ID_LIDCLOSEACTION 1
#define ID_PWRBUTTONTEXT 2
#define ID_PWRBUTACTION 3
#define ID_SLPBUTTONTEXT 4
#define ID_SLPBUTACTION 5
#define ID_ENABLEMETER 6
#define ID_PASSWORD 7
#define ID_VIDEODIM 8
#define ID_POWERBUTGROUP 9
POWER_CONTROLS g_pcButtonPol[NUM_BUTTON_POL_CONTROLS] = {// Control ID Control Type Data Address Data Size Parameter Pointer Enable/Visible State Pointer
IDC_LIDCLOSETEXT, STATIC_TEXT, NULL, 0, NULL, &g_dwShowLidUI, IDC_LIDCLOSEACTION, COMBO_BOX, NULL, sizeof(g_gpp.user.LidCloseDc.Action), (LPDWORD)&g_gpp.user.LidCloseDc.Action, &g_dwShowLidUI, IDC_PWRBUTTONTEXT, STATIC_TEXT, NULL, 0, NULL, &g_dwShowPowerButtonUI, IDC_PWRBUTACTION, COMBO_BOX, NULL, sizeof(g_gpp.user.PowerButtonDc.Action), (LPDWORD)&g_gpp.user.PowerButtonDc.Action, &g_dwShowPowerButtonUI, IDC_SLPBUTTONTEXT, STATIC_TEXT, NULL, 0, NULL, &g_dwShowSleepButtonUI, IDC_SLPBUTACTION, COMBO_BOX, NULL, sizeof(g_gpp.user.SleepButtonDc.Action), (LPDWORD)&g_gpp.user.SleepButtonDc.Action, &g_dwShowSleepButtonUI, IDC_ENABLEMETER, CHECK_BOX, &g_gpp.user.GlobalFlags, sizeof(g_gpp.user.GlobalFlags), &g_uiEnableSysTrayFlag, &g_dwShowEnableSysTray, IDC_PASSWORD, CHECK_BOX, &g_gpp.user.GlobalFlags, sizeof(g_gpp.user.GlobalFlags), &g_uiEnablePWLogonFlag, &g_uiPasswordState, IDC_VIDEODIM, CHECK_BOX, &g_gpp.user.GlobalFlags, sizeof(g_gpp.user.GlobalFlags), &g_uiEnableVideoDimDisplay, &g_uiVideoDimState, IDC_POWERBUTGROUP, STATIC_TEXT, NULL, 0, NULL, &g_dwShowPwrButGrpUI, };
// "Power Switches" Dialog Box (IDD_BUTTONPOLICY == 104) help array:
const DWORD g_PowerSwitchHelpIDs[]= { IDC_OPTIONSGROUPBOX,IDH_COMM_GROUPBOX, IDC_POWERBUTGROUP, IDH_COMM_GROUPBOX, IDC_LIDCLOSEACTION, IDH_104_1301, // "Lid close action dropdown" (ComboBox)
IDC_LIDCLOSETEXT, IDH_104_1301, IDC_PWRBUTACTION, IDH_104_1303, // "Power button action dropdown" (ComboBox)
IDC_PWRBUTTONTEXT, IDH_104_1303, IDC_SLPBUTACTION, IDH_104_1304, // "Sleep button action dropdown" (ComboBox)
IDC_SLPBUTTONTEXT, IDH_104_1304, IDC_ENABLEMETER, IDH_102_1203, // "&Show meter on taskbar." (Button)
IDC_PASSWORD, IDH_107_1500, // "Prompt for &password when bringing computer out of standby." (Button)
IDC_VIDEODIM, IDH_108_1503, // "&Dim display when running on batteries." (Button)
IDI_PWRMNG, NO_HELP, IDC_NO_HELP_5, NO_HELP, 0, 0 };
void ActionEventCodeToSelection (HWND hwnd, int iDlgItem, const POWER_ACTION_POLICY *pPAP)
{ ULONG ulEventCode; DWORD dwSelection;
// Special case PowerActionNone. This could be:
// "Shut Down"
// "Ask me what to do"
// "Do nothing"
if (pPAP->Action == PowerActionNone) { ulEventCode = pPAP->EventCode & (POWER_USER_NOTIFY_BUTTON | POWER_USER_NOTIFY_SHUTDOWN); if ((ulEventCode & POWER_USER_NOTIFY_SHUTDOWN) != 0) { dwSelection = g_uiShutdown; } else if ((ulEventCode & POWER_USER_NOTIFY_BUTTON) != 0) { dwSelection = g_uiAskMeWhatToDo; } else { dwSelection = g_uiDoNothing; } (LRESULT)SendDlgItemMessage(hwnd, iDlgItem, CB_SETCURSEL, dwSelection, 0); } }
void SelectionToActionEventCode (HWND hwnd, int iDlgItem, DWORD dwMissingItems, POWER_ACTION_POLICY *pPAP)
{ ULONG ulEventCode; DWORD dwSelection;
// Special case the "Power Switch" UI. Always turn off the POWER_USER_NOTIFY_POWER_BUTTON
// and POWER_USER_NOTIFY_SLEEP_BUTTON flag because it doesn't mean anything for action
// other than PowerActionNone. Turn it on for PowerActionNone otherwise the SAS
// window will not get the message posted. The SAS window has the logic to check
// the registry setting.
pPAP->EventCode &= ~(POWER_USER_NOTIFY_BUTTON | POWER_USER_NOTIFY_SHUTDOWN | POWER_FORCE_TRIGGER_RESET); if (pPAP->Action == PowerActionNone) { dwSelection = (DWORD)SendDlgItemMessage(hwnd, iDlgItem, CB_GETCURSEL, 0, 0);
// dwMissingItems is a special variable that's used SOLELY for the purpose of
// getting the lid switch to work. The other switches have 5 options available:
//
// Do nothing
// Ask me what to do
// Sleep
// Hibernate
// Shut Down
//
// The lid switch doesn't allow "Ask me what to do" so all of the items get
// shifted by one and the comparisons are wrong. What the lid switch selection
// extractor passes in to this function is the "fudge factor" to get this right.
// Note because "Do nothing" is always available there's no need to compromise
// for it. Just keep doing the same old same old.
if (dwSelection == g_uiDoNothing) { ulEventCode = POWER_FORCE_TRIGGER_RESET; } else if ((dwSelection + dwMissingItems) == g_uiAskMeWhatToDo) { ulEventCode = POWER_USER_NOTIFY_BUTTON; } else if ((dwSelection + dwMissingItems) == g_uiShutdown) { ulEventCode = POWER_USER_NOTIFY_SHUTDOWN; } else { ulEventCode = 0; } pPAP->EventCode |= ulEventCode; } }
/*******************************************************************************
* * SetAdvancedDlgProcData * * DESCRIPTION: * Set up the data pointers in g_pcButtonPol depending on hibernate state. * Set the data to the controls. If bPreserve is TRUE get the current * values UI values and restore them after updating the listboxes. * * PARAMETERS: * *******************************************************************************/
VOID SetAdvancedDlgProcData(HWND hWnd, BOOL bRestoreCurrent) { UINT ii; UINT jj;
// Set the state of the show/hide UI state variables.
if (g_SysPwrCapabilities.SystemS1 || g_SysPwrCapabilities.SystemS2 || g_SysPwrCapabilities.SystemS3 || (g_SysPwrCapabilities.SystemS4 && g_SysPwrCapabilities.HiberFilePresent)) { int err; HKEY hPowerPolicy; DWORD Value; DWORD dwType ; DWORD dwSize ;
g_uiPasswordState = CONTROL_ENABLE;
//
// Check for policy forcing the password always on
//
err = RegOpenKeyEx( HKEY_CURRENT_USER, POWER_POLICY_KEY, 0, KEY_READ, &hPowerPolicy ); if (err == 0) { dwSize = sizeof(Value); err = RegQueryValueEx(hPowerPolicy, LOCK_ON_RESUME, NULL, &dwType, (LPBYTE)&Value, &dwSize); if ( (err == 0) && (dwType == REG_DWORD) && (Value != 0)) { g_uiPasswordState = CONTROL_DISABLE; g_gpp.user.GlobalFlags |= EnablePasswordLogon; }
RegCloseKey( hPowerPolicy );
} } else { g_uiPasswordState = CONTROL_HIDE; }
if (bRestoreCurrent) { GetControls(hWnd, NUM_BUTTON_POL_CONTROLS, g_pcButtonPol); }
//
// Build the Action ID's for the Lid, Power Button and/or Sleep Button
//
ii=0; jj=0;
g_uiLidActIDs[jj++] = IDS_DONOTHING; g_uiLidActIDs[jj++] = PowerActionNone;
g_uiDoNothing = ii / 2; g_uiPwrActIDs[ii++] = IDS_DONOTHING; g_uiPwrActIDs[ii++] = PowerActionNone; g_uiAskMeWhatToDo = ii / 2; g_uiPwrActIDs[ii++] = IDS_PROMPT; g_uiPwrActIDs[ii++] = PowerActionNone;
if (g_SysPwrCapabilities.SystemS1 || g_SysPwrCapabilities.SystemS2 || g_SysPwrCapabilities.SystemS3) { g_uiPwrActIDs[ii++] = IDS_STANDBY; g_uiPwrActIDs[ii++] = PowerActionSleep;
g_uiLidActIDs[jj++] = IDS_STANDBY; g_uiLidActIDs[jj++] = PowerActionSleep; }
if (g_SysPwrCapabilities.HiberFilePresent) { g_uiPwrActIDs[ii++] = IDS_HIBERNATE; g_uiPwrActIDs[ii++] = PowerActionHibernate;
g_uiLidActIDs[jj++] = IDS_HIBERNATE; g_uiLidActIDs[jj++] = PowerActionHibernate; }
g_uiShutdown = ii / 2; g_uiPwrActIDs[ii++] = IDS_POWEROFF; g_uiPwrActIDs[ii++] = PowerActionNone; //g_uiLidActIDs[jj++] = IDS_POWEROFF; WinBug 5.1 #352752 - "Shutdown" isn't valid for
//g_uiLidActIDs[jj++] = PowerActionNone; closing the lid.
g_uiPwrActIDs[ii++] = 0; g_uiPwrActIDs[ii++] = 0; g_uiLidActIDs[jj++] = 0; g_uiLidActIDs[jj++] = 0;
g_pcButtonPol[ID_LIDCLOSEACTION].lpvData = g_uiLidActIDs; g_pcButtonPol[ID_PWRBUTACTION].lpvData = g_uiPwrActIDs; g_pcButtonPol[ID_SLPBUTACTION].lpvData = g_uiPwrActIDs;
// Special case PowerActionShutdownOff. This is no longer
// supported in the UI. Convert this to "Shut Down".
if (g_gpp.user.PowerButtonDc.Action == PowerActionShutdownOff) { g_gpp.user.PowerButtonDc.Action = PowerActionNone; g_gpp.user.PowerButtonDc.EventCode = POWER_USER_NOTIFY_SHUTDOWN; g_bDirty = TRUE; } if (g_gpp.user.SleepButtonDc.Action == PowerActionShutdownOff) { g_gpp.user.SleepButtonDc.Action = PowerActionNone; g_gpp.user.SleepButtonDc.EventCode = POWER_USER_NOTIFY_SHUTDOWN; g_bDirty = TRUE; }
// Map power actions to allowed UI values.
MapPwrAct(&g_gpp.user.LidCloseDc.Action, TRUE); MapPwrAct(&g_gpp.user.PowerButtonDc.Action, TRUE); MapPwrAct(&g_gpp.user.SleepButtonDc.Action, TRUE);
// Only update the list boxes.
SetControls(hWnd, NUM_BUTTON_POL_CONTROLS, g_pcButtonPol);
// Map action and event code group to combobox selection.
ActionEventCodeToSelection(hWnd, IDC_PWRBUTACTION, &g_gpp.user.PowerButtonDc); ActionEventCodeToSelection(hWnd, IDC_SLPBUTACTION, &g_gpp.user.SleepButtonDc); ActionEventCodeToSelection(hWnd, IDC_LIDCLOSEACTION, &g_gpp.user.LidCloseDc); }
/*******************************************************************************
* * InitAdvancedDlg * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
BOOLEAN InitAdvancedDlg(HWND hWnd) { // Start off with the page not dirty.
g_bDirty = FALSE;
// If we can't read the global power policies hide
// the controls on this page.
if (!GetGlobalPwrPolicy(&g_gpp)) { HideControls(hWnd, NUM_BUTTON_POL_CONTROLS, g_pcButtonPol); return TRUE; }
// Get the enable systray icon mask based on AC online/offline.
g_uiEnableSysTrayFlag = EnableSysTrayBatteryMeter;
if (g_SysPwrCapabilities.VideoDimPresent) { g_uiVideoDimState = CONTROL_ENABLE; } else { g_uiVideoDimState = CONTROL_HIDE; }
g_dwShowEnableSysTray = CONTROL_ENABLE; g_dwShowPwrButGrpUI = CONTROL_HIDE; if (g_SysPwrCapabilities.LidPresent) { g_dwShowLidUI = CONTROL_ENABLE; g_dwShowPwrButGrpUI = CONTROL_ENABLE; } else { g_dwShowLidUI = CONTROL_HIDE; }
//
// Don't show the Power Button if S5 is not supported on the system
//
if (g_SysPwrCapabilities.PowerButtonPresent && g_SysPwrCapabilities.SystemS5) { g_dwShowPowerButtonUI = CONTROL_ENABLE; g_dwShowPwrButGrpUI = CONTROL_ENABLE; } else { g_dwShowPowerButtonUI = CONTROL_HIDE; }
//
// Sleep Button - Don't show the sleep button if there are not any actions.
//
if (g_SysPwrCapabilities.SleepButtonPresent && (g_SysPwrCapabilities.SystemS1 || g_SysPwrCapabilities.SystemS2 || g_SysPwrCapabilities.SystemS3 || (g_SysPwrCapabilities.SystemS4 && g_SysPwrCapabilities.HiberFilePresent))) { g_dwShowSleepButtonUI = CONTROL_ENABLE; g_dwShowPwrButGrpUI = CONTROL_ENABLE; } else { g_dwShowSleepButtonUI = CONTROL_HIDE; }
SetAdvancedDlgProcData(hWnd, FALSE);
// If we can't write the global power policies disable
// the controls this page.
if (!WriteGlobalPwrPolicyReport(hWnd, &g_gpp, FALSE)) { DisableControls(hWnd, NUM_BUTTON_POL_CONTROLS, g_pcButtonPol); } return TRUE; }
/*******************************************************************************
* * P U B L I C E N T R Y P O I N T S * *******************************************************************************/
/*******************************************************************************
* * AdvancedDlgProc * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
INT_PTR CALLBACK AdvancedDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { NMHDR FAR *lpnm; UINT uiID;
switch (uMsg) { case WM_INITDIALOG: return InitAdvancedDlg(hWnd);
#ifdef WINNT
case WM_CHILDACTIVATE: // Reinitialize since the hibernate tab may have changed
// the hibernate state, NT only.
SetAdvancedDlgProcData(hWnd, TRUE); break; #endif
case WM_NOTIFY: lpnm = (NMHDR FAR *)lParam; switch(lpnm->code) { case PSN_APPLY: // Fetch data from dialog controls.
if (g_bDirty) { GetControls(hWnd, NUM_BUTTON_POL_CONTROLS, g_pcButtonPol);
// Map combobox selection to action and event code group.
SelectionToActionEventCode(hWnd, IDC_PWRBUTACTION, 0, &g_gpp.user.PowerButtonDc); SelectionToActionEventCode(hWnd, IDC_SLPBUTACTION, 0, &g_gpp.user.SleepButtonDc); SelectionToActionEventCode(hWnd, IDC_LIDCLOSEACTION, 1, &g_gpp.user.LidCloseDc);
g_gpp.user.LidCloseAc.Action = g_gpp.user.LidCloseDc.Action; g_gpp.user.LidCloseAc.EventCode = g_gpp.user.LidCloseDc.EventCode; g_gpp.user.PowerButtonAc.Action = g_gpp.user.PowerButtonDc.Action; g_gpp.user.PowerButtonAc.EventCode = g_gpp.user.PowerButtonDc.EventCode; g_gpp.user.SleepButtonAc.Action = g_gpp.user.SleepButtonDc.Action; g_gpp.user.SleepButtonAc.EventCode = g_gpp.user.SleepButtonDc.EventCode;
if (WriteGlobalPwrPolicyReport(hWnd, &g_gpp, TRUE)) { GetActivePwrScheme(&uiID); SetActivePwrSchemeReport(hWnd, uiID, &g_gpp, NULL);
// Enable or disable battery meter service on systray.
SysTray_EnableService(STSERVICE_POWER, g_gpp.user.GlobalFlags & g_uiEnableSysTrayFlag); g_bDirty = FALSE; } } break;
case PSN_SETACTIVE: // Hibernate page may have changed the hibernate state,
// reinitialize the dependent part of Advanced page.
SetAdvancedDlgProcData(hWnd, TRUE); break; } break;
case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_SLPBUTACTION: case IDC_PWRBUTACTION: case IDC_LIDCLOSEACTION: if (HIWORD(wParam) == LBN_SELCHANGE) { // Let parent know something changed.
MarkSheetDirty(hWnd, &g_bDirty); } break;
case IDC_VIDEODIM: case IDC_PASSWORD: case IDC_ENABLEMETER: // Enable the parent dialog Apply button on change.
MarkSheetDirty(hWnd, &g_bDirty); break;
} break;
case PCWM_NOTIFYPOWER: // Notification from systray, user has changed a PM UI setting.
g_bSystrayChange = TRUE; break;
case WM_HELP: // F1
WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_PowerSwitchHelpIDs); return TRUE;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_PowerSwitchHelpIDs); return TRUE; } return FALSE; }
|