Leaked source code of windows server 2003
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.

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