Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1422 lines
46 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1996
  4. *
  5. * TITLE: PWRSCHEM.C
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: ReedB
  10. *
  11. * DATE: 17 Oct, 1996
  12. *
  13. * DESCRIPTION:
  14. * Support for power scheme page (front page) of PowerCfg.Cpl.
  15. *
  16. *******************************************************************************/
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <windows.h>
  21. #include <commctrl.h>
  22. #include <regstr.h>
  23. #include <help.h>
  24. #include <powercfp.h>
  25. #include "powercfg.h"
  26. #include "pwrresid.h"
  27. #include "PwrMn_cs.h"
  28. #include <shfusion.h>
  29. // Structure to manage the scheme list information.
  30. typedef struct _SCHEME_LIST
  31. {
  32. LIST_ENTRY leSchemeList;
  33. UINT uiID;
  34. LPTSTR lpszName;
  35. LPTSTR lpszDesc;
  36. PPOWER_POLICY ppp;
  37. } SCHEME_LIST, *PSCHEME_LIST;
  38. // Structure to manage the power scheme dialog proc info.
  39. typedef struct _POWER_SCHEME_DLG_INFO
  40. {
  41. HWND hwndSchemeList;
  42. } POWER_SCHEME_DLG_INFO, *PPOWER_SCHEME_DLG_INFO;
  43. // Private functions implemented in PWRSCHEM.C:
  44. UINT StripBlanks(LPTSTR);
  45. UINT RangeLimitHiberTimeOuts(UINT uiIdleTimeout, UINT *uiHiberToIDs);
  46. VOID RefreshSchemes(HWND, PSCHEME_LIST);
  47. VOID HandleIdleTimeOutChanged(HWND hWnd, UINT uMsg, WPARAM wParam, BOOL *pbDirty);
  48. LONG MsgBoxId(HWND, UINT, UINT, LPTSTR, UINT);
  49. BOOLEAN DoDeleteScheme(HWND, LPTSTR);
  50. BOOLEAN DoSaveScheme(HWND);
  51. BOOLEAN ClearSchemeList(VOID);
  52. BOOLEAN RemoveScheme(PSCHEME_LIST, LPTSTR);
  53. BOOLEAN PowerSchemeDlgInit(HWND, PPOWER_SCHEME_DLG_INFO);
  54. BOOLEAN CALLBACK PowerSchemeEnumProc(UINT, DWORD, LPTSTR, DWORD, LPTSTR, PPOWER_POLICY, LPARAM);
  55. BOOLEAN HandleCurSchemeChanged(HWND hWnd);
  56. BOOLEAN MapHiberTimer(PPOWER_POLICY ppp, BOOLEAN Get);
  57. PSCHEME_LIST GetCurSchemeFromCombo(HWND hWnd);
  58. PSCHEME_LIST FindScheme(LPTSTR, BOOLEAN);
  59. PSCHEME_LIST AddScheme(UINT, LPTSTR, UINT, LPTSTR, UINT, PPOWER_POLICY);
  60. PSCHEME_LIST FindNextScheme(LPTSTR);
  61. /*******************************************************************************
  62. *
  63. * G L O B A L D A T A
  64. *
  65. *******************************************************************************/
  66. extern HINSTANCE g_hInstance; // Global instance handle of this DLL.
  67. // This structure is filled in by the Power Policy Manager at CPL_INIT time.
  68. extern SYSTEM_POWER_CAPABILITIES g_SysPwrCapabilities;
  69. extern BOOLEAN g_bVideoLowPowerSupported;
  70. extern DWORD g_dwNumSleepStates;
  71. extern UINT g_uiSpindownMaxMin;
  72. extern BOOL g_bRunningUnderNT;
  73. UINT g_uiTimeoutIDs[] = // Timeout string ID's.
  74. {
  75. IDS_01_MIN, 60 * 1, // 1 Min.
  76. IDS_02_MIN, 60 * 2,
  77. IDS_03_MIN, 60 * 3,
  78. IDS_05_MIN, 60 * 5,
  79. IDS_10_MIN, 60 * 10,
  80. IDS_15_MIN, 60 * 15,
  81. IDS_20_MIN, 60 * 20,
  82. IDS_25_MIN, 60 * 25,
  83. IDS_30_MIN, 60 * 30,
  84. IDS_45_MIN, 60 * 45,
  85. IDS_01_HOUR, 60 * 60 * 1, // 1 Hour
  86. IDS_02_HOUR, 60 * 60 * 2,
  87. IDS_03_HOUR, 60 * 60 * 3,
  88. IDS_04_HOUR, 60 * 60 * 4,
  89. IDS_05_HOUR, 60 * 60 * 5,
  90. IDS_NEVER, 0,
  91. 0, 0
  92. };
  93. UINT g_uiHiberToIDs[] = // Hiber timeout string ID's.
  94. {
  95. IDS_01_MIN, 60 * 1, // 1 Min.
  96. IDS_02_MIN, 60 * 2,
  97. IDS_03_MIN, 60 * 3,
  98. IDS_05_MIN, 60 * 5,
  99. IDS_10_MIN, 60 * 10,
  100. IDS_15_MIN, 60 * 15,
  101. IDS_20_MIN, 60 * 20,
  102. IDS_25_MIN, 60 * 25,
  103. IDS_30_MIN, 60 * 30,
  104. IDS_45_MIN, 60 * 45,
  105. IDS_01_HOUR, 60 * 60 * 1, // 1 Hour
  106. IDS_02_HOUR, 60 * 60 * 2,
  107. IDS_03_HOUR, 60 * 60 * 3,
  108. IDS_04_HOUR, 60 * 60 * 4,
  109. IDS_05_HOUR, 60 * 60 * 5,
  110. IDS_06_HOUR, 60 * 60 * 6,
  111. IDS_NEVER, 0,
  112. 0, 0
  113. };
  114. UINT g_uiHiberToAcIDs[sizeof(g_uiHiberToIDs)]; // Hibernate AC timeout string ID's.
  115. UINT g_uiHiberToDcIDs[sizeof(g_uiHiberToIDs)]; // Hibernate DC timeout string ID's.
  116. UINT g_uiSpinDownIDs[] = // Disk spin down timeout string ID's.
  117. {
  118. IDS_01_MIN, 60 * 1, // 1 Min.
  119. IDS_02_MIN, 60 * 2,
  120. IDS_03_MIN, 60 * 3,
  121. IDS_05_MIN, 60 * 5,
  122. IDS_10_MIN, 60 * 10,
  123. IDS_15_MIN, 60 * 15,
  124. IDS_20_MIN, 60 * 20,
  125. IDS_25_MIN, 60 * 25,
  126. IDS_30_MIN, 60 * 30,
  127. IDS_45_MIN, 60 * 45,
  128. IDS_01_HOUR, 60 * 60 * 1, // 1 Hour
  129. IDS_02_HOUR, 60 * 60 * 2,
  130. IDS_03_HOUR, 60 * 60 * 3,
  131. IDS_04_HOUR, 60 * 60 * 4,
  132. IDS_05_HOUR, 60 * 60 * 5,
  133. IDS_NEVER, 0,
  134. 0, 0
  135. };
  136. // Show/hide UI state variables for power schemes dialog.
  137. UINT g_uiWhenComputerIsState;
  138. UINT g_uiStandbyState;
  139. UINT g_uiMonitorState;
  140. UINT g_uiDiskState;
  141. UINT g_uiHiberState;
  142. UINT g_uiHiberTimeoutAc;
  143. UINT g_uiHiberTimeoutDc;
  144. UINT g_uiIdleTimeoutAc;
  145. UINT g_uiIdleTimeoutDc;
  146. // Power schemes dialog controls descriptions:
  147. UINT g_uiNumPwrSchemeCntrls;
  148. #define NUM_POWER_SCHEME_CONTROLS 17
  149. #define NUM_POWER_SCHEME_CONTROLS_NOBAT 8
  150. // Handy indicies into our g_pcPowerScheme control array
  151. #define ID_GOONSTANDBY 0
  152. #define ID_STANDBYACCOMBO 1
  153. #define ID_TURNOFFMONITOR 2
  154. #define ID_MONITORACCOMBO 3
  155. #define ID_TURNOFFHARDDISKS 4
  156. #define ID_DISKACCOMBO 5
  157. #define ID_SYSTEMHIBERNATES 6
  158. #define ID_HIBERACCOMBO 7
  159. #define ID_STANDBYDCCOMBO 8
  160. #define ID_MONITORDCCOMBO 9
  161. #define ID_DISKDCCOMBO 10
  162. #define ID_HIBERDCCOMBO 11
  163. #define ID_WHENCOMPUTERIS 12
  164. #define ID_PLUGGEDIN 13
  165. #define ID_RUNNINGONBAT 14
  166. #define ID_PLUG 15
  167. #define ID_BATTERY 16
  168. POWER_CONTROLS g_pcPowerScheme[NUM_POWER_SCHEME_CONTROLS] =
  169. {// Control ID Control Type Data Address Data Size Parameter Pointer EnableVisible State Pointer
  170. IDC_GOONSTANDBY, STATIC_TEXT, NULL, 0, NULL, &g_uiStandbyState,
  171. IDC_STANDBYACCOMBO, COMBO_BOX, &g_uiTimeoutIDs, sizeof(DWORD), &g_uiIdleTimeoutAc, &g_uiStandbyState,
  172. IDC_TURNOFFMONITOR, STATIC_TEXT, NULL, 0, NULL, &g_uiMonitorState,
  173. IDC_MONITORACCOMBO, COMBO_BOX, &g_uiTimeoutIDs, sizeof(DWORD), NULL, &g_uiMonitorState,
  174. IDC_TURNOFFHARDDISKS, STATIC_TEXT, NULL, 0, NULL, &g_uiDiskState,
  175. IDC_DISKACCOMBO, COMBO_BOX, &g_uiSpinDownIDs, sizeof(DWORD), NULL, &g_uiDiskState,
  176. IDC_SYSTEMHIBERNATES, STATIC_TEXT, NULL, 0, NULL, &g_uiHiberState,
  177. IDC_HIBERACCOMBO, COMBO_BOX, &g_uiHiberToAcIDs, sizeof(DWORD), &g_uiHiberTimeoutAc, &g_uiHiberState,
  178. IDC_STANDBYDCCOMBO, COMBO_BOX, &g_uiTimeoutIDs, sizeof(DWORD), &g_uiIdleTimeoutDc, &g_uiStandbyState,
  179. IDC_MONITORDCCOMBO, COMBO_BOX, &g_uiTimeoutIDs, sizeof(DWORD), NULL, &g_uiMonitorState,
  180. IDC_DISKDCCOMBO, COMBO_BOX, &g_uiSpinDownIDs, sizeof(DWORD), NULL, &g_uiDiskState,
  181. IDC_HIBERDCCOMBO, COMBO_BOX, &g_uiHiberToDcIDs, sizeof(DWORD), &g_uiHiberTimeoutDc, &g_uiHiberState,
  182. IDC_WHENCOMPUTERIS, STATIC_TEXT, NULL, 0, NULL, &g_uiWhenComputerIsState,
  183. IDC_PLUGGEDIN, STATIC_TEXT, NULL, 0, NULL, &g_uiWhenComputerIsState,
  184. IDC_RUNNINGONBAT, STATIC_TEXT, NULL, 0, NULL, &g_uiWhenComputerIsState,
  185. IDI_PLUG, STATIC_TEXT, NULL, 0, NULL, &g_uiWhenComputerIsState,
  186. IDI_BATTERY, STATIC_TEXT, NULL, 0, NULL, &g_uiWhenComputerIsState,
  187. };
  188. // Show/hide UI state variables for advanced power schemes dialog.
  189. UINT g_uiAdvWhenComputerIsState;
  190. UINT g_uiOptimizeState;
  191. // Globals to manage the power schemes list:
  192. SCHEME_LIST g_sl; // Head of the power schemes list.
  193. PSCHEME_LIST g_pslCurActive; // Currently active power scheme.
  194. PSCHEME_LIST g_pslCurSel; // Currently selected power scheme.
  195. PSCHEME_LIST g_pslValid; // A valid scheme for error recovery.
  196. UINT g_uiSchemeCount; // Number of power schemes.
  197. LIST_ENTRY g_leSchemeList; // Head of the power schemes list.
  198. BOOL g_bSystrayChange; // A systary change requires PowerSchemeDlgProc re-init.
  199. // "Power Schemes" Dialog Box (IDD_POWERSCHEME == 100) help arrays:
  200. const DWORD g_PowerSchemeHelpIDs[]=
  201. {
  202. IDC_SCHEMECOMBO, IDH_100_1000, // Power Schemes: "Power schemes" (ComboBox)
  203. IDC_POWERSCHEMESTEXT, IDH_COMM_GROUPBOX,
  204. IDC_SAVEAS, IDH_100_1001, // Power Schemes: "&Save As..." (Button)
  205. IDC_DELETE, IDH_100_1002, // Power Schemes: "&Delete" (Button)
  206. IDC_SETTINGSFOR, IDH_COMM_GROUPBOX, // Power Schemes: "Settings for groupbox" (Button)
  207. IDC_GOONSTANDBY, IDH_100_1009, // Power Schemes: "Go on s&tandby:" (Static)
  208. IDC_STANDBYACCOMBO, IDH_100_1005, // Power Schemes: "Standby AC time" (ComboBox)
  209. IDC_STANDBYDCCOMBO, IDH_100_1006, // Power Schemes: "Standby DC time" (ComboBox)
  210. IDC_SYSTEMHIBERNATES, IDH_SYSTEMHIBERNATES,
  211. IDC_HIBERACCOMBO, IDH_HIBERACCOMBO,
  212. IDC_HIBERDCCOMBO, IDH_HIBERDCCOMBO,
  213. IDC_TURNOFFMONITOR, IDH_100_1010, // Power Schemes: "Turn off &monitor:" (Static)
  214. IDC_MONITORACCOMBO, IDH_100_1007, // Power Schemes: "Monitor AC time" (ComboBox)
  215. IDC_MONITORDCCOMBO, IDH_100_1008, // Power Schemes: "Monitor DC time" (ComboBox)
  216. IDC_TURNOFFHARDDISKS, IDH_107_1509, // Advanced Power Scheme Settings: "Turn off hard &disks:" (Static)
  217. IDC_DISKACCOMBO, IDH_107_1505, // Advanced Power Scheme Settings: "Disk off time AC" (ComboBox)
  218. IDC_DISKDCCOMBO, IDH_107_1506, // Advanced Power Scheme Settings: "Disk off time DC" (ComboBox)
  219. IDC_PLUGGEDIN, NO_HELP,
  220. IDC_NO_HELP_0, NO_HELP,
  221. IDC_NO_HELP_7, NO_HELP,
  222. IDI_PWRMNG, NO_HELP,
  223. IDI_PLUG, NO_HELP,
  224. IDI_BATTERY, NO_HELP,
  225. IDC_WHENCOMPUTERIS, NO_HELP,
  226. IDC_PLUGGEDIN, NO_HELP,
  227. IDC_RUNNINGONBAT, NO_HELP,
  228. 0, 0
  229. };
  230. // "Save Scheme" Dialog Box (IDD_SAVE == 109) help ID's:
  231. #define IDH_109_1700 111411309 // Save Scheme: "Save name power scheme" (Edit)
  232. // "Save Scheme" Dialog Box (IDD_SAVE == 109) help array:
  233. const DWORD g_SaveAsHelpIDs[]=
  234. {
  235. IDC_SAVENAMEEDIT, IDH_109_1700, // Save Scheme: "Save name power scheme" (Edit)
  236. IDC_SAVETEXT, IDH_109_1700,
  237. 0, 0
  238. };
  239. /*******************************************************************************
  240. *
  241. * P U B L I C E N T R Y P O I N T S
  242. *
  243. *******************************************************************************/
  244. /*******************************************************************************
  245. *
  246. * InitSchemesList
  247. *
  248. * DESCRIPTION:
  249. * Called once at DLL initialization time.
  250. *
  251. * PARAMETERS:
  252. *
  253. *******************************************************************************/
  254. VOID InitSchemesList(VOID)
  255. {
  256. InitializeListHead(&g_leSchemeList);
  257. }
  258. /*******************************************************************************
  259. *
  260. * SaveAsDlgProc
  261. *
  262. * DESCRIPTION:
  263. *
  264. * PARAMETERS:
  265. * Dialog procedure for the advanced power scheme dialog.
  266. *
  267. *******************************************************************************/
  268. INT_PTR CALLBACK SaveAsDlgProc(
  269. HWND hWnd,
  270. UINT uMsg,
  271. WPARAM wParam,
  272. LPARAM lParam
  273. )
  274. {
  275. TCHAR szBuf[2 * MAX_FRIENDLY_NAME_LEN]; // Leave room for DBCS
  276. PSCHEME_LIST pslNew;
  277. static PBOOLEAN pbSavedCurrent;
  278. switch (uMsg) {
  279. case WM_INITDIALOG:
  280. SetDlgItemText(hWnd, IDC_SAVENAMEEDIT, g_pslCurSel->lpszName);
  281. SendDlgItemMessage(hWnd, IDC_SAVENAMEEDIT, EM_SETSEL, 0, -1);
  282. SendDlgItemMessage(hWnd, IDC_SAVENAMEEDIT, EM_LIMITTEXT, MAX_FRIENDLY_NAME_LEN-2, 0L);
  283. EnableWindow(GetDlgItem(hWnd, IDOK), (g_pslCurSel->lpszName[0] != TEXT('\0')));
  284. pbSavedCurrent = (PBOOLEAN) lParam;
  285. *pbSavedCurrent = FALSE;
  286. return TRUE;
  287. case WM_COMMAND:
  288. switch (LOWORD(wParam)) {
  289. case IDC_SAVENAMEEDIT:
  290. if (HIWORD(wParam) == EN_CHANGE) {
  291. GetDlgItemText(hWnd, IDC_SAVENAMEEDIT, szBuf, 2);
  292. if (*szBuf) {
  293. EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
  294. }
  295. }
  296. break;
  297. case IDOK:
  298. GetDlgItemText(hWnd, IDC_SAVENAMEEDIT, szBuf, MAX_FRIENDLY_NAME_LEN-1);
  299. // Strip trailing blanks, don't allow blank scheme name.
  300. if (!StripBlanks(szBuf)) {
  301. MsgBoxId(hWnd, IDS_SAVESCHEME, IDS_BLANKNAME,
  302. NULL, MB_OK | MB_ICONEXCLAMATION);
  303. return TRUE;
  304. }
  305. // Insert a new policies element in the policies list.
  306. pslNew = AddScheme(NEWSCHEME, szBuf, STRSIZE(szBuf),
  307. TEXT(""), sizeof(TCHAR), g_pslCurSel->ppp);
  308. // Write out the Scheme.
  309. if (pslNew) {
  310. if ( WritePwrSchemeReport(hWnd,
  311. &(pslNew->uiID),
  312. pslNew->lpszName,
  313. pslNew->lpszDesc,
  314. pslNew->ppp) )
  315. {
  316. if ( g_pslCurSel == pslNew )
  317. {
  318. *pbSavedCurrent = TRUE;
  319. }
  320. else
  321. {
  322. g_pslCurSel = pslNew;
  323. }
  324. }
  325. }
  326. // fall thru to IDCANCEL
  327. case IDCANCEL:
  328. EndDialog(hWnd, wParam);
  329. break;
  330. }
  331. break;
  332. case WM_HELP: // F1
  333. WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_SaveAsHelpIDs);
  334. return TRUE;
  335. case WM_CONTEXTMENU: // right mouse click
  336. WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_SaveAsHelpIDs);
  337. return TRUE;
  338. }
  339. return FALSE;
  340. }
  341. /*******************************************************************************
  342. *
  343. * PowerSchemeDlgProc
  344. *
  345. * DESCRIPTION:
  346. * Dialog procedure for power scheme page.
  347. *
  348. * PARAMETERS:
  349. *
  350. *******************************************************************************/
  351. INT_PTR CALLBACK PowerSchemeDlgProc(
  352. HWND hWnd,
  353. UINT uMsg,
  354. WPARAM wParam,
  355. LPARAM lParam
  356. )
  357. {
  358. NMHDR FAR *lpnm;
  359. UINT uiNewSel, uiNewState;
  360. LPTSTR pszUPS;
  361. static POWER_SCHEME_DLG_INFO psdi;
  362. static BOOL bDirty = FALSE;
  363. static BOOL bInitFailed = FALSE;
  364. if (bInitFailed) {
  365. return FALSE;
  366. }
  367. switch (uMsg) {
  368. case WM_INITDIALOG:
  369. // Set the control count to match the dialog template we're using.
  370. if (g_SysPwrCapabilities.SystemBatteriesPresent) {
  371. g_uiNumPwrSchemeCntrls = NUM_POWER_SCHEME_CONTROLS;
  372. if (g_SysPwrCapabilities.BatteriesAreShortTerm) {
  373. pszUPS = LoadDynamicString(IDS_POWEREDBYUPS);
  374. DisplayFreeStr(hWnd, IDC_RUNNINGONBAT, pszUPS, FREE_STR);
  375. }
  376. }
  377. else {
  378. g_uiNumPwrSchemeCntrls = NUM_POWER_SCHEME_CONTROLS_NOBAT;
  379. }
  380. if (!PowerSchemeDlgInit(hWnd, &psdi)) {
  381. bInitFailed = TRUE;
  382. }
  383. return TRUE;
  384. case WM_CHILDACTIVATE:
  385. // If Systray changed something while another property page (dialog)
  386. // had the focus reinitialize the dialog.
  387. if (g_bSystrayChange) {
  388. PowerSchemeDlgInit(hWnd, &psdi);
  389. g_bSystrayChange = FALSE;
  390. }
  391. // Reinitialize hibernate timer since the hibernate tab
  392. // may have changed it's state.
  393. if (GetPwrCapabilities(&g_SysPwrCapabilities)) {
  394. if (g_bRunningUnderNT &&
  395. g_SysPwrCapabilities.SystemS4 &&
  396. g_SysPwrCapabilities.SystemS5 &&
  397. g_SysPwrCapabilities.HiberFilePresent) {
  398. uiNewState = CONTROL_ENABLE;
  399. } else {
  400. uiNewState = CONTROL_HIDE;
  401. }
  402. if (g_bRunningUnderNT && (g_uiStandbyState == CONTROL_HIDE) &&
  403. (g_SysPwrCapabilities.SystemS1 ||
  404. g_SysPwrCapabilities.SystemS2 ||
  405. g_SysPwrCapabilities.SystemS3)) {
  406. g_uiStandbyState = CONTROL_ENABLE;
  407. }
  408. }
  409. if (g_uiHiberState != uiNewState) {
  410. g_uiHiberState = uiNewState;
  411. MapHiberTimer(g_pslCurSel->ppp, FALSE);
  412. SetControls(hWnd, g_uiNumPwrSchemeCntrls, g_pcPowerScheme);
  413. }
  414. break;
  415. case WM_NOTIFY:
  416. lpnm = (NMHDR FAR *)lParam;
  417. switch(lpnm->code) {
  418. case PSN_APPLY:
  419. if (bDirty) {
  420. // Do the hibernate PSN_APPLY since the
  421. // PowerSchemeDlgProc PSN_APPLY logic depends
  422. // on hibernate state.
  423. DoHibernateApply();
  424. GetControls(hWnd, g_uiNumPwrSchemeCntrls,
  425. g_pcPowerScheme);
  426. MapHiberTimer(g_pslCurSel->ppp, TRUE);
  427. // Set active scheme.
  428. if (SetActivePwrSchemeReport(hWnd,
  429. g_pslCurSel->uiID,
  430. NULL,
  431. g_pslCurSel->ppp)) {
  432. if (g_pslCurSel != g_pslCurActive) {
  433. g_pslCurActive = g_pslCurSel;
  434. RefreshSchemes(hWnd, g_pslCurSel);
  435. }
  436. }
  437. bDirty = FALSE;
  438. // The Power Policy Manager may have changed
  439. // the scheme during validation.
  440. MapHiberTimer(g_pslCurSel->ppp, FALSE);
  441. SetControls(hWnd, g_uiNumPwrSchemeCntrls,
  442. g_pcPowerScheme);
  443. }
  444. break;
  445. }
  446. break;
  447. case WM_COMMAND:
  448. switch (LOWORD(wParam)) {
  449. case IDC_SCHEMECOMBO:
  450. if (HIWORD(wParam) == CBN_SELCHANGE) {
  451. if (g_pslCurSel = GetCurSchemeFromCombo(hWnd)) {
  452. HandleCurSchemeChanged(hWnd);
  453. MarkSheetDirty(hWnd, &bDirty);
  454. }
  455. }
  456. break;
  457. case IDC_STANDBYACCOMBO:
  458. case IDC_STANDBYDCCOMBO:
  459. HandleIdleTimeOutChanged(hWnd, uMsg, wParam, &bDirty);
  460. break;
  461. case IDC_MONITORACCOMBO:
  462. case IDC_MONITORDCCOMBO:
  463. case IDC_DISKACCOMBO:
  464. case IDC_DISKDCCOMBO:
  465. case IDC_HIBERACCOMBO:
  466. case IDC_HIBERDCCOMBO:
  467. if (HIWORD(wParam) == CBN_SELCHANGE) {
  468. MarkSheetDirty(hWnd, &bDirty);
  469. }
  470. break;
  471. case IDC_SAVEAS:
  472. if (DoSaveScheme(hWnd)) {
  473. HandleCurSchemeChanged(hWnd);
  474. MarkSheetDirty(hWnd, &bDirty);
  475. }
  476. break;
  477. case IDC_DELETE:
  478. if (DoDeleteScheme(hWnd, g_pslCurSel->lpszName)) {
  479. HandleCurSchemeChanged(hWnd);
  480. }
  481. break;
  482. default:
  483. return FALSE;
  484. }
  485. break;
  486. case PCWM_NOTIFYPOWER:
  487. // Notification from systray, user has changed a PM UI setting.
  488. PowerSchemeDlgInit(hWnd, &psdi);
  489. break;
  490. case WM_HELP: // F1
  491. WinHelp(((LPHELPINFO)lParam)->hItemHandle, PWRMANHLP, HELP_WM_HELP, (ULONG_PTR)(LPTSTR)g_PowerSchemeHelpIDs);
  492. return TRUE;
  493. case WM_CONTEXTMENU: // right mouse click
  494. WinHelp((HWND)wParam, PWRMANHLP, HELP_CONTEXTMENU, (ULONG_PTR)(LPTSTR)g_PowerSchemeHelpIDs);
  495. return TRUE;
  496. }
  497. return FALSE;
  498. }
  499. /*******************************************************************************
  500. *
  501. * P R I V A T E F U N C T I O N S
  502. *
  503. *******************************************************************************/
  504. /*******************************************************************************
  505. *
  506. * HandleIdleTimeOutChanged
  507. *
  508. * DESCRIPTION:
  509. * Range limit the hibernate timeout combo boxes based on the value of the
  510. * idle timeouts.
  511. *
  512. * PARAMETERS:
  513. *
  514. *******************************************************************************/
  515. VOID HandleIdleTimeOutChanged(HWND hWnd, UINT uMsg, WPARAM wParam, BOOL *pbDirty)
  516. {
  517. UINT uiIdleTo, uiLimitedTo;
  518. if (HIWORD(wParam) == CBN_SELCHANGE) {
  519. MarkSheetDirty(hWnd, pbDirty);
  520. if (LOWORD(wParam) == IDC_STANDBYACCOMBO) {
  521. GetControls(hWnd, 1, &g_pcPowerScheme[ID_STANDBYACCOMBO]);
  522. GetControls(hWnd, 1, &g_pcPowerScheme[ID_HIBERACCOMBO]);
  523. uiIdleTo = g_uiIdleTimeoutAc;
  524. uiLimitedTo = RangeLimitHiberTimeOuts(uiIdleTo, g_uiHiberToAcIDs);
  525. if (g_uiHiberTimeoutAc && (uiIdleTo >= g_uiHiberTimeoutAc)) {
  526. g_uiHiberTimeoutAc = uiLimitedTo;
  527. }
  528. SetControls(hWnd, 1, &g_pcPowerScheme[ID_HIBERACCOMBO]);
  529. }
  530. else {
  531. GetControls(hWnd, 1, &g_pcPowerScheme[ID_STANDBYDCCOMBO]);
  532. GetControls(hWnd, 1, &g_pcPowerScheme[ID_HIBERDCCOMBO]);
  533. uiIdleTo = g_uiIdleTimeoutDc;
  534. uiLimitedTo = RangeLimitHiberTimeOuts(uiIdleTo, g_uiHiberToDcIDs);
  535. if (g_uiHiberTimeoutDc && (uiIdleTo >= g_uiHiberTimeoutDc)) {
  536. g_uiHiberTimeoutDc = uiLimitedTo;
  537. }
  538. SetControls(hWnd, 1, &g_pcPowerScheme[ID_HIBERDCCOMBO]);
  539. }
  540. }
  541. }
  542. /*******************************************************************************
  543. *
  544. * RangeLimitHiberTimeOuts
  545. *
  546. * DESCRIPTION:
  547. *
  548. * PARAMETERS:
  549. *
  550. *******************************************************************************/
  551. UINT RangeLimitHiberTimeOuts(UINT uiIdleTimeout, UINT *uiHiberToIDs)
  552. {
  553. UINT i, uiNewMin;
  554. // Initialize the hiber timout ID's to full range.
  555. memcpy(uiHiberToIDs, g_uiHiberToIDs, sizeof(g_uiHiberToIDs));
  556. if (uiIdleTimeout) {
  557. i = 0;
  558. while (uiHiberToIDs[i++]) {
  559. if (uiHiberToIDs[i] >= uiIdleTimeout) {
  560. i += 2;
  561. uiNewMin = uiHiberToIDs[i];
  562. RangeLimitIDarray(uiHiberToIDs, uiNewMin, (UINT) -1);
  563. return uiNewMin;
  564. }
  565. i++;
  566. }
  567. DebugPrint( "RangeLimitHiberTimeOuts: couldn't find value larger than: %d", uiIdleTimeout);
  568. }
  569. return (UINT) -1;
  570. }
  571. /*******************************************************************************
  572. *
  573. * MapHiberTimer
  574. *
  575. * DESCRIPTION:
  576. * Displayed hibernate timeout may never be less than the idle timeout. This
  577. * function handles the mapping. The following table (per KenR) specifies the
  578. * Idle action to be set by the UI for different combinations of Idle and
  579. * Hibernate timeouts. It is understood that the Hibernate timeout UI only
  580. * appears when HiberFilePresent is TRUE. For case E, the HiberTimeout will be
  581. * set in the IdleTimeout member. For case F, the UI will adjust the
  582. * DozeS4Timeout member to be the displayed HiberTimeout plus the IdleTimeout.
  583. *
  584. * Case HiberFilePresent UiHiberTimeout UiIdleTimeout IdleAction DozeS4Timeout IdleTimeout
  585. * ---------------------------------------------------------------------------------------------------------------
  586. * A. FALSE N/A 0 (Never) PowerActionNone 0 0
  587. * B. FALSE N/A !0 PowerActionSleep 0 UiIdleTimeout
  588. * C. TRUE 0 (Never) 0 (Never) PowerActionNone 0 0
  589. * D. TRUE 0 (Never) !0 PowerActionSleep 0 UiIdleTimeout
  590. * E. TRUE !0 0 (Never) PowerActionHibernate 0 UiHiberTimeout
  591. * F. TRUE !0 !0 PowerActionSleep UiHiber-UiIdle UiIdleTimeout
  592. *
  593. * PARAMETERS:
  594. *
  595. *******************************************************************************/
  596. BOOLEAN MapHiberTimer(PPOWER_POLICY ppp, BOOLEAN Get)
  597. {
  598. if (Get) {
  599. // Get values from the UI. AC.
  600. ppp->mach.DozeS4TimeoutAc = 0;
  601. ppp->user.IdleTimeoutAc = g_uiIdleTimeoutAc;
  602. if (g_uiHiberTimeoutAc) {
  603. if (g_uiIdleTimeoutAc) {
  604. ppp->mach.DozeS4TimeoutAc = g_uiHiberTimeoutAc - g_uiIdleTimeoutAc;
  605. }
  606. else {
  607. ppp->user.IdleTimeoutAc = g_uiHiberTimeoutAc;
  608. }
  609. }
  610. // DC.
  611. ppp->mach.DozeS4TimeoutDc = 0;
  612. ppp->user.IdleTimeoutDc = g_uiIdleTimeoutDc;
  613. if (g_uiHiberTimeoutDc) {
  614. if (g_uiIdleTimeoutDc) {
  615. ppp->mach.DozeS4TimeoutDc = g_uiHiberTimeoutDc - g_uiIdleTimeoutDc;
  616. }
  617. else {
  618. ppp->user.IdleTimeoutDc = g_uiHiberTimeoutDc;
  619. }
  620. }
  621. // Set the correct idle action. AC.
  622. ppp->user.IdleAc.Action = PowerActionNone;
  623. if (g_uiIdleTimeoutAc) {
  624. ppp->user.IdleAc.Action = PowerActionSleep;
  625. }
  626. else {
  627. if (g_SysPwrCapabilities.HiberFilePresent) {
  628. if (g_uiHiberTimeoutAc) {
  629. ppp->user.IdleAc.Action = PowerActionHibernate;
  630. }
  631. }
  632. }
  633. // DC.
  634. ppp->user.IdleDc.Action = PowerActionNone;
  635. if (g_uiIdleTimeoutDc) {
  636. ppp->user.IdleDc.Action = PowerActionSleep;
  637. }
  638. else {
  639. if (g_SysPwrCapabilities.HiberFilePresent) {
  640. if (g_uiHiberTimeoutDc) {
  641. ppp->user.IdleDc.Action = PowerActionHibernate;
  642. }
  643. }
  644. }
  645. }
  646. else {
  647. // Set values to the UI. AC.
  648. if (ppp->user.IdleAc.Action == PowerActionHibernate) {
  649. g_uiHiberTimeoutAc = ppp->user.IdleTimeoutAc;
  650. g_uiIdleTimeoutAc = 0;
  651. }
  652. else {
  653. g_uiIdleTimeoutAc = ppp->user.IdleTimeoutAc;
  654. if (ppp->mach.DozeS4TimeoutAc && g_SysPwrCapabilities.HiberFilePresent) {
  655. g_uiHiberTimeoutAc = ppp->user.IdleTimeoutAc +
  656. ppp->mach.DozeS4TimeoutAc;
  657. }
  658. else {
  659. g_uiHiberTimeoutAc = 0;
  660. }
  661. }
  662. // DC.
  663. if (ppp->user.IdleDc.Action == PowerActionHibernate) {
  664. g_uiHiberTimeoutDc = ppp->user.IdleTimeoutDc;
  665. g_uiIdleTimeoutDc = 0;
  666. }
  667. else {
  668. g_uiIdleTimeoutDc = ppp->user.IdleTimeoutDc;
  669. if (ppp->mach.DozeS4TimeoutDc && g_SysPwrCapabilities.HiberFilePresent) {
  670. g_uiHiberTimeoutDc = ppp->user.IdleTimeoutDc +
  671. ppp->mach.DozeS4TimeoutDc;
  672. }
  673. else {
  674. g_uiHiberTimeoutDc = 0;
  675. }
  676. }
  677. // Range limit the hibernate timeout combo boxes based
  678. // on the value of the idle timeouts.
  679. RangeLimitHiberTimeOuts(g_uiIdleTimeoutAc, g_uiHiberToAcIDs);
  680. RangeLimitHiberTimeOuts(g_uiIdleTimeoutDc, g_uiHiberToDcIDs);
  681. }
  682. return TRUE;
  683. }
  684. /*******************************************************************************
  685. *
  686. * HandleCurSchemeChanged
  687. *
  688. * DESCRIPTION:
  689. *
  690. * PARAMETERS:
  691. *
  692. *******************************************************************************/
  693. BOOLEAN HandleCurSchemeChanged(HWND hWnd)
  694. {
  695. LPTSTR pString;
  696. BOOL bEnable;
  697. // Update the group box text if enabled.
  698. if ((g_uiStandbyState != CONTROL_HIDE) ||
  699. (g_uiMonitorState != CONTROL_HIDE) ||
  700. (g_uiDiskState != CONTROL_HIDE) ||
  701. (g_uiHiberState != CONTROL_HIDE)) {
  702. pString = LoadDynamicString(IDS_SETTINGSFORMAT, g_pslCurSel->lpszName);
  703. DisplayFreeStr(hWnd, IDC_SETTINGSFOR, pString, FREE_STR);
  704. }
  705. else {
  706. ShowWindow(GetDlgItem(hWnd, IDC_SETTINGSFOR), SW_HIDE);
  707. }
  708. // Update the power schemes combobox list.
  709. RefreshSchemes(hWnd, g_pslCurSel);
  710. // Setup the data pointers in the g_pcPowerScheme array.
  711. g_pcPowerScheme[ID_MONITORACCOMBO].lpdwParam =
  712. &(g_pslCurSel->ppp->user.VideoTimeoutAc);
  713. g_pcPowerScheme[ID_MONITORDCCOMBO].lpdwParam =
  714. &(g_pslCurSel->ppp->user.VideoTimeoutDc);
  715. g_pcPowerScheme[ID_DISKACCOMBO].lpdwParam =
  716. &(g_pslCurSel->ppp->user.SpindownTimeoutAc);
  717. g_pcPowerScheme[ID_DISKDCCOMBO].lpdwParam =
  718. &(g_pslCurSel->ppp->user.SpindownTimeoutDc);
  719. // Update the rest of the controls.
  720. MapHiberTimer(g_pslCurSel->ppp, FALSE);
  721. SetControls(hWnd, g_uiNumPwrSchemeCntrls, g_pcPowerScheme);
  722. // Set the delete push button state.
  723. if (g_uiSchemeCount < 2) {
  724. bEnable = FALSE;
  725. }
  726. else {
  727. bEnable = TRUE;
  728. }
  729. EnableWindow(GetDlgItem(hWnd, IDC_DELETE), bEnable);
  730. return TRUE;
  731. }
  732. /*******************************************************************************
  733. *
  734. * GetCurSchemeFromCombo
  735. *
  736. * DESCRIPTION:
  737. * Get the current selection from the power schemes combobox list.
  738. *
  739. * PARAMETERS:
  740. *
  741. *******************************************************************************/
  742. PSCHEME_LIST GetCurSchemeFromCombo(HWND hWnd)
  743. {
  744. UINT uiCBRet;
  745. PSCHEME_LIST psl;
  746. uiCBRet = (UINT) SendDlgItemMessage(hWnd, IDC_SCHEMECOMBO, CB_GETCURSEL, 0, 0);
  747. if (uiCBRet != CB_ERR) {
  748. psl = (PSCHEME_LIST) SendDlgItemMessage(hWnd, IDC_SCHEMECOMBO,
  749. CB_GETITEMDATA, uiCBRet, 0);
  750. if (psl != (PSCHEME_LIST) CB_ERR) {
  751. return FindScheme(psl->lpszName, TRUE);
  752. }
  753. }
  754. DebugPrint( "GetCurSchemeFromCombo, CB_GETITEMDATA or CB_GETCURSEL failed");
  755. return FALSE;
  756. }
  757. /*******************************************************************************
  758. *
  759. * ClearSchemeList
  760. *
  761. * DESCRIPTION:
  762. * Clear the scheme list if it's not already empty. Return TRUE if there's
  763. * a change to the contents of power scheme list.
  764. *
  765. * PARAMETERS:
  766. *
  767. *******************************************************************************/
  768. BOOLEAN ClearSchemeList(VOID)
  769. {
  770. PSCHEME_LIST psl, pslNext;
  771. if (IsListEmpty(&g_leSchemeList)) {
  772. return FALSE;
  773. }
  774. for (psl = (PSCHEME_LIST)g_leSchemeList.Flink;
  775. psl != (PSCHEME_LIST)&g_leSchemeList; psl = pslNext) {
  776. pslNext = (PSCHEME_LIST) psl->leSchemeList.Flink;
  777. RemoveScheme(psl, NULL);
  778. }
  779. g_pslCurActive = NULL;
  780. g_pslCurSel = NULL;
  781. g_uiSchemeCount = 0;
  782. return TRUE;
  783. }
  784. /*******************************************************************************
  785. *
  786. * RemoveScheme
  787. *
  788. * DESCRIPTION:
  789. *
  790. * PARAMETERS:
  791. *
  792. *******************************************************************************/
  793. BOOLEAN RemoveScheme(PSCHEME_LIST psl, LPTSTR lpszName)
  794. {
  795. if (lpszName) {
  796. psl = FindScheme(lpszName, TRUE);
  797. }
  798. if (psl == &g_sl) {
  799. DebugPrint( "RemoveScheme, Attempted to delete head!");
  800. return FALSE;
  801. }
  802. if (psl) {
  803. LocalFree(psl->lpszName);
  804. LocalFree(psl->lpszDesc);
  805. RemoveEntryList(&psl->leSchemeList);
  806. LocalFree(psl);
  807. g_uiSchemeCount--;
  808. return TRUE;
  809. }
  810. return FALSE;
  811. }
  812. /*******************************************************************************
  813. *
  814. * FindScheme
  815. *
  816. * DESCRIPTION:
  817. *
  818. * PARAMETERS:
  819. *
  820. *******************************************************************************/
  821. PSCHEME_LIST FindScheme(LPTSTR lpszName, BOOLEAN bShouldExist)
  822. {
  823. PSCHEME_LIST psl, pslNext;
  824. if (!lpszName) {
  825. DebugPrint( "FindScheme, invalid parameters");
  826. return NULL;
  827. }
  828. // Search by name.
  829. for (psl = (PSCHEME_LIST)g_leSchemeList.Flink;
  830. psl != (PSCHEME_LIST)&g_leSchemeList; psl = pslNext) {
  831. pslNext = (PSCHEME_LIST) psl->leSchemeList.Flink;
  832. if (!lstrcmpi(lpszName, psl->lpszName)) {
  833. return psl;
  834. }
  835. }
  836. if (bShouldExist) {
  837. DebugPrint( "FindScheme, couldn't find: %s", lpszName);
  838. }
  839. return NULL;
  840. }
  841. /*******************************************************************************
  842. *
  843. * AddScheme
  844. *
  845. * DESCRIPTION:
  846. *
  847. * PARAMETERS:
  848. *
  849. *******************************************************************************/
  850. PSCHEME_LIST AddScheme(
  851. UINT uiID,
  852. LPTSTR lpszName,
  853. UINT uiNameSize,
  854. LPTSTR lpszDesc,
  855. UINT uiDescSize,
  856. PPOWER_POLICY ppp
  857. )
  858. {
  859. PSCHEME_LIST psl;
  860. if (!lpszName || !lpszDesc) {
  861. DebugPrint( "AddScheme, invalid parameters");
  862. return NULL;
  863. }
  864. // If a scheme of this name already exists just return a pointer to it.
  865. psl = FindScheme(lpszName, FALSE);
  866. if ( NULL == psl )
  867. {
  868. // Allocate and initalize a Scheme element for the scheme list.
  869. psl = LocalAlloc(0, sizeof(SCHEME_LIST) );
  870. if ( NULL == psl )
  871. return psl; // out of memory
  872. }
  873. else
  874. {
  875. // remove the entry from the list and free allocated memory
  876. RemoveEntryList(&psl->leSchemeList);
  877. g_uiSchemeCount --;
  878. LocalFree( psl->lpszName );
  879. LocalFree( psl->lpszDesc );
  880. LocalFree( psl->ppp );
  881. }
  882. // Update the Scheme
  883. psl->uiID = uiID;
  884. psl->lpszName = LocalAlloc(0, uiNameSize);
  885. psl->lpszDesc = LocalAlloc(0, uiDescSize);
  886. psl->ppp = LocalAlloc(0, sizeof(POWER_POLICY));
  887. if (psl->lpszName && psl->lpszDesc && psl->ppp) {
  888. lstrcpy(psl->lpszName, lpszName);
  889. lstrcpy(psl->lpszDesc, lpszDesc);
  890. memcpy(psl->ppp, ppp, sizeof(POWER_POLICY));
  891. InsertTailList(&g_leSchemeList, &psl->leSchemeList);
  892. g_uiSchemeCount++;
  893. return psl;
  894. }
  895. LocalFree(psl->lpszName);
  896. LocalFree(psl->lpszDesc);
  897. LocalFree(psl->ppp);
  898. LocalFree(psl);
  899. psl = NULL;
  900. return psl;
  901. }
  902. /*******************************************************************************
  903. *
  904. * PowerSchemeEnumProc
  905. * Builds the policies list.
  906. *
  907. * DESCRIPTION:
  908. *
  909. * PARAMETERS:
  910. * lParam - Is the ID of the currently active power scheme.
  911. *
  912. *******************************************************************************/
  913. BOOLEAN CALLBACK PowerSchemeEnumProc(
  914. UINT uiID,
  915. DWORD dwNameSize,
  916. LPTSTR lpszName,
  917. DWORD dwDescSize,
  918. LPTSTR lpszDesc,
  919. PPOWER_POLICY ppp,
  920. LPARAM lParam
  921. )
  922. {
  923. PSCHEME_LIST psl;
  924. // Validate the new scheme.
  925. if (ValidateUISchemeFields(ppp)) {
  926. // Allocate and initalize a policies element.
  927. if ((psl = AddScheme(uiID, lpszName, dwNameSize, lpszDesc,
  928. dwDescSize, ppp)) != NULL) {
  929. // Save a valid entry for error recovery.
  930. g_pslValid = psl;
  931. // Setup currently active policies pointer.
  932. if ((UINT)lParam == uiID) {
  933. g_pslCurActive = psl;
  934. }
  935. return TRUE;
  936. }
  937. }
  938. return FALSE;
  939. }
  940. /*******************************************************************************
  941. *
  942. * PowerSchemeDlgInit
  943. *
  944. * DESCRIPTION:
  945. * Initialize the power scheme dialog.
  946. *
  947. * PARAMETERS:
  948. *
  949. *******************************************************************************/
  950. BOOLEAN PowerSchemeDlgInit(
  951. HWND hWnd,
  952. PPOWER_SCHEME_DLG_INFO ppsdi
  953. )
  954. {
  955. UINT uiCurrentSchemeID;
  956. UINT i;
  957. // On WINNT, only power users may add new power schemes.
  958. if (CanUserWritePwrScheme()) {
  959. ShowWindow(GetDlgItem(hWnd, IDC_SAVEAS), SW_SHOW);
  960. ShowWindow(GetDlgItem(hWnd, IDC_DELETE), SW_SHOW);
  961. }
  962. else {
  963. ShowWindow(GetDlgItem(hWnd, IDC_SAVEAS), SW_HIDE);
  964. ShowWindow(GetDlgItem(hWnd, IDC_DELETE), SW_HIDE);
  965. }
  966. ppsdi->hwndSchemeList = GetDlgItem(hWnd, IDC_SCHEMECOMBO);
  967. ClearSchemeList();
  968. // Get the currently active power scheme.
  969. if (GetActivePwrScheme(&uiCurrentSchemeID)) {
  970. // Get the Policies list from PowrProf.
  971. for (i = 0; i < 2; i++) {
  972. if (EnumPwrSchemes(PowerSchemeEnumProc, (LPARAM)uiCurrentSchemeID) &&
  973. g_pslCurActive) {
  974. g_pslCurSel = g_pslCurActive;
  975. // Setup UI show/hide state variables.
  976. g_uiWhenComputerIsState = CONTROL_HIDE;
  977. if (g_SysPwrCapabilities.SystemS1 ||
  978. g_SysPwrCapabilities.SystemS2 ||
  979. g_SysPwrCapabilities.SystemS3) {
  980. g_uiStandbyState = CONTROL_ENABLE;
  981. g_uiWhenComputerIsState = CONTROL_ENABLE;
  982. }
  983. else {
  984. g_uiStandbyState = CONTROL_HIDE;
  985. }
  986. if (g_bVideoLowPowerSupported) {
  987. g_uiMonitorState = CONTROL_ENABLE;
  988. g_uiWhenComputerIsState = CONTROL_ENABLE;
  989. }
  990. else {
  991. g_uiMonitorState = CONTROL_HIDE;
  992. }
  993. if (g_SysPwrCapabilities.DiskSpinDown) {
  994. g_uiDiskState = CONTROL_ENABLE;
  995. RangeLimitIDarray(g_uiSpinDownIDs,
  996. HIWORD(g_uiSpindownMaxMin)*60,
  997. LOWORD(g_uiSpindownMaxMin)*60);
  998. }
  999. else {
  1000. g_uiDiskState = CONTROL_HIDE;
  1001. }
  1002. if (g_bRunningUnderNT &&
  1003. g_SysPwrCapabilities.SystemS4 &&
  1004. g_SysPwrCapabilities.SystemS5 &&
  1005. g_SysPwrCapabilities.HiberFilePresent) {
  1006. g_uiHiberState = CONTROL_ENABLE;
  1007. }
  1008. else {
  1009. g_uiHiberState = CONTROL_HIDE;
  1010. }
  1011. // Update the UI.
  1012. HandleCurSchemeChanged(hWnd);
  1013. return TRUE;
  1014. }
  1015. else {
  1016. DebugPrint( "PowerSchemeDlgInit, failure enumerating schemes. g_pslCurActive: %X", g_pslCurActive);
  1017. if (g_pslValid) {
  1018. if (SetActivePwrScheme(g_pslValid->uiID, NULL, g_pslValid->ppp)) {
  1019. uiCurrentSchemeID = g_pslValid->uiID;
  1020. ClearSchemeList();
  1021. }
  1022. else {
  1023. DebugPrint( "PowerSchemeDlgInit, unable to set valid scheme");
  1024. }
  1025. }
  1026. else {
  1027. DebugPrint( "PowerSchemeDlgInit, no valid schemes");
  1028. break;
  1029. }
  1030. }
  1031. }
  1032. }
  1033. DisableControls(hWnd, g_uiNumPwrSchemeCntrls, g_pcPowerScheme);
  1034. return FALSE;
  1035. }
  1036. /*******************************************************************************
  1037. *
  1038. * RefreshSchemes
  1039. *
  1040. * DESCRIPTION:
  1041. * Update the power schemes combobox list.
  1042. *
  1043. * PARAMETERS:
  1044. * hWnd - Power schemes dialog hWnd.
  1045. * pslSel - Power scheme to leave selected on exit.
  1046. *
  1047. *******************************************************************************/
  1048. VOID RefreshSchemes(
  1049. HWND hWnd,
  1050. PSCHEME_LIST pslSel
  1051. )
  1052. {
  1053. PSCHEME_LIST psl, pslNext;
  1054. UINT uiIndex;
  1055. SendDlgItemMessage(hWnd, IDC_SCHEMECOMBO, CB_RESETCONTENT, FALSE, 0L);
  1056. for (psl = (PSCHEME_LIST)g_leSchemeList.Flink;
  1057. psl != (PSCHEME_LIST)&g_leSchemeList; psl = pslNext) {
  1058. pslNext = (PSCHEME_LIST) psl->leSchemeList.Flink;
  1059. // Add the schemes to the combo list box.
  1060. uiIndex = (UINT) SendDlgItemMessage(hWnd, IDC_SCHEMECOMBO, CB_ADDSTRING,
  1061. 0, (LPARAM) psl->lpszName);
  1062. if (uiIndex != CB_ERR) {
  1063. SendDlgItemMessage(hWnd, IDC_SCHEMECOMBO, CB_SETITEMDATA,
  1064. uiIndex, (LPARAM) psl);
  1065. }
  1066. else {
  1067. DebugPrint( "RefreshSchemes, CB_ADDSTRING failed: %s", psl->lpszName);
  1068. }
  1069. }
  1070. // Select the passed entry.
  1071. if (pslSel) {
  1072. uiIndex = (UINT) SendDlgItemMessage(hWnd, IDC_SCHEMECOMBO, CB_FINDSTRINGEXACT,
  1073. (WPARAM)-1, (LPARAM)pslSel->lpszName);
  1074. if (uiIndex != CB_ERR) {
  1075. uiIndex = (UINT) SendDlgItemMessage(hWnd, IDC_SCHEMECOMBO, CB_SETCURSEL,
  1076. (WPARAM)uiIndex, 0);
  1077. if (uiIndex == CB_ERR) {
  1078. DebugPrint( "RefreshSchemes, CB_SETCURSEL failed: %s, index: %d", psl->lpszName, uiIndex);
  1079. }
  1080. }
  1081. else {
  1082. DebugPrint( "RefreshSchemes, CB_FINDSTRINGEXACT failed: %s", psl->lpszName);
  1083. }
  1084. }
  1085. }
  1086. /*******************************************************************************
  1087. *
  1088. * StripBlanks
  1089. *
  1090. * DESCRIPTION:
  1091. *
  1092. * PARAMETERS:
  1093. *
  1094. *******************************************************************************/
  1095. UINT StripBlanks(LPTSTR lpszString)
  1096. {
  1097. LPTSTR lpszPosn, lpszSrc;
  1098. /* strip leading blanks */
  1099. lpszPosn = lpszString;
  1100. while(*lpszPosn == TEXT(' ')) {
  1101. lpszPosn++;
  1102. }
  1103. if (lpszPosn != lpszString)
  1104. lstrcpy(lpszString, lpszPosn);
  1105. /* strip trailing blanks */
  1106. if ((lpszPosn=lpszString+lstrlen(lpszString)) != lpszString) {
  1107. lpszPosn = CharPrev(lpszString, lpszPosn);
  1108. while(*lpszPosn == TEXT(' '))
  1109. lpszPosn = CharPrev(lpszString, lpszPosn);
  1110. lpszPosn = CharNext(lpszPosn);
  1111. *lpszPosn = TEXT('\0');
  1112. }
  1113. return lstrlen(lpszString);
  1114. }
  1115. /*******************************************************************************
  1116. *
  1117. * MsgBoxId
  1118. *
  1119. * DESCRIPTION:
  1120. *
  1121. * PARAMETERS:
  1122. *
  1123. *******************************************************************************/
  1124. LONG MsgBoxId(
  1125. HWND hWnd,
  1126. UINT uiCaption,
  1127. UINT uiFormat,
  1128. LPTSTR lpszParam,
  1129. UINT uiFlags
  1130. )
  1131. {
  1132. LPTSTR lpszCaption;
  1133. LPTSTR lpszText;
  1134. LONG lRet = 0;
  1135. lpszCaption = LoadDynamicString(uiCaption);
  1136. if (lpszCaption) {
  1137. lpszText = LoadDynamicString(uiFormat, lpszParam);
  1138. if (lpszText) {
  1139. lRet = MessageBox(hWnd, lpszText, lpszCaption, uiFlags);
  1140. LocalFree(lpszText);
  1141. }
  1142. LocalFree(lpszCaption);
  1143. }
  1144. return lRet;
  1145. }
  1146. /*******************************************************************************
  1147. *
  1148. * DoDeleteScheme
  1149. *
  1150. * DESCRIPTION:
  1151. *
  1152. * PARAMETERS:
  1153. *
  1154. *******************************************************************************/
  1155. BOOLEAN DoDeleteScheme(HWND hWnd, LPTSTR lpszName)
  1156. {
  1157. LPTSTR lpszCaption;
  1158. LPTSTR lpszText;
  1159. PSCHEME_LIST psl, pslDelete;
  1160. // Dont't allow delete unless we have at least two schemes.
  1161. if ((g_uiSchemeCount < 2) || !(pslDelete = FindScheme(lpszName, TRUE))) {
  1162. return FALSE;
  1163. }
  1164. // Get confirmation from the user.
  1165. if (IDYES == MsgBoxId(hWnd, IDS_CONFIRMDELETECAPTION, IDS_CONFIRMDELETE,
  1166. lpszName, MB_YESNO | MB_ICONQUESTION)) {
  1167. // If we deleted the currently active scheme set the next scheme active.
  1168. if (pslDelete == g_pslCurActive) {
  1169. if ((psl = FindNextScheme(lpszName)) &&
  1170. (SetActivePwrSchemeReport(hWnd, psl->uiID, NULL, psl->ppp))) {
  1171. g_pslCurActive = psl;
  1172. }
  1173. else {
  1174. return FALSE;
  1175. }
  1176. }
  1177. // Remove requested scheme.
  1178. if (DeletePwrScheme(pslDelete->uiID)) {
  1179. RemoveScheme(NULL, lpszName);
  1180. g_pslCurSel = g_pslCurActive;
  1181. return TRUE;
  1182. }
  1183. }
  1184. return FALSE;
  1185. }
  1186. /*******************************************************************************
  1187. *
  1188. * FindNextScheme
  1189. *
  1190. * DESCRIPTION:
  1191. *
  1192. * PARAMETERS:
  1193. *
  1194. *******************************************************************************/
  1195. PSCHEME_LIST FindNextScheme(LPTSTR lpszName)
  1196. {
  1197. PSCHEME_LIST psl, pslFirst, pslNext;
  1198. for (pslFirst = psl = (PSCHEME_LIST)g_leSchemeList.Flink;
  1199. psl != (PSCHEME_LIST)&g_leSchemeList; psl = pslNext) {
  1200. pslNext = (PSCHEME_LIST) psl->leSchemeList.Flink;
  1201. if (!lstrcmpi(lpszName, psl->lpszName)) {
  1202. if (pslNext != (PSCHEME_LIST)&g_leSchemeList) {
  1203. return pslNext;
  1204. }
  1205. else {
  1206. return pslFirst;
  1207. }
  1208. }
  1209. }
  1210. DebugPrint( "FindNextScheme, unable to find: %s", lpszName);
  1211. return NULL;
  1212. }
  1213. /*******************************************************************************
  1214. *
  1215. * DoSaveScheme
  1216. *
  1217. * DESCRIPTION:
  1218. *
  1219. * PARAMETERS:
  1220. *
  1221. *******************************************************************************/
  1222. BOOLEAN DoSaveScheme(HWND hWnd)
  1223. {
  1224. POWER_POLICY ppSave;
  1225. BOOLEAN bSavedCurrent;
  1226. PSCHEME_LIST pslTemplateScheme = g_pslCurSel;
  1227. // Make a copy of the template scheme to restore after the save.
  1228. memcpy(&ppSave, pslTemplateScheme->ppp, sizeof(ppSave));
  1229. // Get any changes the user might have made for the new scheme.
  1230. GetControls(hWnd, g_uiNumPwrSchemeCntrls, g_pcPowerScheme);
  1231. MapHiberTimer(g_pslCurSel->ppp, TRUE);
  1232. if (IDOK != DialogBoxParam(g_hInstance,
  1233. MAKEINTRESOURCE(IDD_SAVE),
  1234. hWnd,
  1235. SaveAsDlgProc,
  1236. (LPARAM)&bSavedCurrent)) {
  1237. return FALSE;
  1238. }
  1239. // Restore the template scheme if we didn't save the current scheme.
  1240. if (!bSavedCurrent) {
  1241. memcpy(pslTemplateScheme->ppp, &ppSave, sizeof(ppSave));
  1242. return TRUE;
  1243. }
  1244. return TRUE;
  1245. }