1 /* 2 * PROJECT: ReactOS Power Configuration Applet 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/cpl/powercfg/advanced.c 5 * PURPOSE: advanced tab of applet 6 * PROGRAMMERS: Alexander Wurzinger (Lohnegrim at gmx dot net) 7 * Johannes Anderwald (johannes.anderwald@reactos.org) 8 * Martin Rottensteiner 9 * Dmitry Chapyshev (lentind@yandex.ru) 10 */ 11 12 #include "powercfg.h" 13 14 static POWER_ACTION g_SystemBatteries[3]; 15 static POWER_ACTION g_PowerButton[5]; 16 static POWER_ACTION g_SleepButton[5]; 17 18 19 static 20 VOID 21 SetSystrayPowerIconState(BOOL bEnabled) 22 { 23 HWND hwndTaskBar; 24 25 hwndTaskBar = FindWindowW(L"SystemTray_Main", NULL); 26 if (hwndTaskBar == NULL) 27 return; 28 29 SendMessageW(hwndTaskBar, WM_USER + 220, 1, bEnabled); 30 } 31 32 static 33 BOOL 34 GetSystrayPowerIconState(VOID) 35 { 36 HWND hwndTaskBar; 37 38 hwndTaskBar = FindWindowW(L"SystemTray_Main", NULL); 39 if (hwndTaskBar == NULL) 40 return FALSE; 41 42 return (BOOL)SendMessageW(hwndTaskBar, WM_USER + 221, 1, 0); 43 } 44 45 static VOID 46 AddItem(HWND hDlgCtrl, INT ResourceId, LPARAM lParam, POWER_ACTION * lpAction) 47 { 48 TCHAR szBuffer[MAX_PATH]; 49 LRESULT Index; 50 51 if (LoadString(hApplet, ResourceId, szBuffer, MAX_PATH) < MAX_PATH) 52 { 53 Index = SendMessage(hDlgCtrl, CB_INSERTSTRING, -1, (LPARAM)szBuffer); 54 if (Index != CB_ERR) 55 { 56 SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)Index, lParam); 57 lpAction[Index] = (POWER_ACTION)lParam; 58 } 59 } 60 } 61 62 static INT 63 FindActionIndex(POWER_ACTION * lpAction, DWORD dwActionSize, POWER_ACTION poAction) 64 { 65 INT Index; 66 67 for (Index = 0; Index < (INT)dwActionSize; Index++) 68 { 69 if (lpAction[Index] == poAction) 70 return Index; 71 } 72 73 return -1; 74 } 75 76 static BOOLEAN 77 IsBatteryUsed(VOID) 78 { 79 SYSTEM_BATTERY_STATE sbs; 80 81 if (CallNtPowerInformation(SystemBatteryState,NULL, (ULONG)0, &sbs, sizeof(SYSTEM_BATTERY_STATE)) == STATUS_SUCCESS) 82 { 83 if (sbs.BatteryPresent) 84 { 85 if (sbs.AcOnLine) 86 { 87 return FALSE; 88 } 89 return TRUE; 90 } 91 } 92 93 return FALSE; 94 } 95 96 POWER_ACTION 97 GetPowerActionFromPolicy( 98 POWER_ACTION_POLICY *Policy, 99 PSYSTEM_POWER_CAPABILITIES spc, 100 BOOL bIsLid) 101 { 102 POWER_ACTION poAction = PowerActionNone; 103 /* 104 105 TCHAR szBuffer[MAX_PATH]; 106 107 // Note: Windows XP SP2+ does not return the PowerAction code 108 // for PowerActionWarmEject + PowerActionShutdown but sets it 109 // to PowerActionNone and sets the Flags & EventCode 110 111 112 _stprintf(szBuffer, L"Action: %x EventCode %x Flags %x",Policy->Action, Policy->EventCode, Policy->Flags); 113 MessageBoxW(NULL, szBuffer, NULL, MB_OK); 114 115 */ 116 117 if (Policy->Action == PowerActionNone) 118 { 119 if (Policy->Flags == (POWER_ACTION_UI_ALLOWED | POWER_ACTION_QUERY_ALLOWED)) 120 { 121 if (Policy->EventCode == POWER_FORCE_TRIGGER_RESET) 122 { 123 poAction = PowerActionNone; 124 } 125 else if (Policy->EventCode == POWER_USER_NOTIFY_BUTTON) 126 { 127 poAction = PowerActionWarmEject; 128 } 129 else if (Policy->EventCode == POWER_USER_NOTIFY_SHUTDOWN) 130 { 131 poAction = PowerActionShutdown; 132 } 133 } 134 } 135 else 136 { 137 poAction = Policy->Action; 138 if ((poAction == PowerActionHibernate) && !(spc->SystemS4 && spc->HiberFilePresent)) 139 poAction = PowerActionSleep; 140 if ((poAction == PowerActionSleep) && !(spc->SystemS1 || spc->SystemS2 || spc->SystemS3)) 141 { 142 if (bIsLid) 143 poAction = PowerActionNone; 144 else 145 poAction = PowerActionShutdown; 146 } 147 } 148 149 return poAction; 150 } 151 152 VOID 153 ShowCurrentPowerActionPolicy(HWND hDlgCtrl, 154 POWER_ACTION *lpAction, 155 DWORD dwActionSize, 156 POWER_ACTION_POLICY *Policy, 157 PSYSTEM_POWER_CAPABILITIES spc, 158 BOOL bIsLid) 159 { 160 int poActionIndex; 161 POWER_ACTION poAction; 162 163 poAction = GetPowerActionFromPolicy(Policy, spc, bIsLid); 164 poActionIndex = FindActionIndex(lpAction, dwActionSize, poAction); 165 166 if (poActionIndex < 0) 167 { 168 return; 169 } 170 171 SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)poActionIndex, (LPARAM)0); 172 } 173 174 BOOLEAN 175 SaveCurrentPowerActionPolicy(IN HWND hDlgCtrl, 176 OUT POWER_ACTION_POLICY *Policy) 177 { 178 LRESULT Index; 179 LRESULT ItemData; 180 181 Index = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0); 182 if (Index == CB_ERR) 183 return FALSE; 184 185 ItemData = SendMessage(hDlgCtrl, CB_GETITEMDATA, (WPARAM)Index, 0); 186 if (ItemData == CB_ERR) 187 return FALSE; 188 189 switch(ItemData) 190 { 191 case PowerActionNone: 192 Policy->Action = PowerActionNone; 193 Policy->EventCode = POWER_FORCE_TRIGGER_RESET; 194 break; 195 196 case PowerActionWarmEject: 197 Policy->Action = PowerActionNone; 198 Policy->EventCode = POWER_USER_NOTIFY_BUTTON; 199 break; 200 201 case PowerActionShutdown: 202 Policy->Action = PowerActionNone; 203 Policy->EventCode = POWER_USER_NOTIFY_SHUTDOWN; 204 break; 205 206 case PowerActionSleep: 207 case PowerActionHibernate: 208 Policy->Action = (POWER_ACTION)ItemData; 209 Policy->EventCode = 0; 210 break; 211 212 default: 213 return FALSE; 214 } 215 216 Policy->Flags = (POWER_ACTION_UI_ALLOWED | POWER_ACTION_QUERY_ALLOWED); 217 218 return TRUE; 219 } 220 221 222 //------------------------------------------------------------------- 223 224 VOID 225 ShowCurrentPowerActionPolicies( 226 HWND hwndDlg, 227 PSYSTEM_POWER_CAPABILITIES spc) 228 { 229 if (!IsBatteryUsed()) 230 { 231 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_LIDCLOSE), 232 g_SystemBatteries, 233 sizeof(g_SystemBatteries) / sizeof(POWER_ACTION), 234 &gGPP.user.LidCloseAc, 235 spc, 236 TRUE); 237 238 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON), 239 g_PowerButton, 240 sizeof(g_PowerButton) / sizeof(POWER_ACTION), 241 &gGPP.user.PowerButtonAc, 242 spc, 243 FALSE); 244 245 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON), 246 g_SleepButton, 247 sizeof(g_SleepButton) / sizeof(POWER_ACTION), 248 &gGPP.user.SleepButtonAc, 249 spc, 250 FALSE); 251 } 252 else 253 { 254 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_LIDCLOSE), 255 g_SystemBatteries, 256 sizeof(g_SystemBatteries) / sizeof(POWER_ACTION), 257 &gGPP.user.LidCloseDc, 258 spc, 259 TRUE); 260 261 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON), 262 g_PowerButton, 263 sizeof(g_PowerButton) / sizeof(POWER_ACTION), 264 &gGPP.user.PowerButtonDc, 265 spc, 266 FALSE); 267 268 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON), 269 g_SleepButton, 270 sizeof(g_SleepButton) / sizeof(POWER_ACTION), 271 &gGPP.user.SleepButtonDc, 272 spc, 273 FALSE); 274 } 275 } 276 277 VOID 278 Adv_InitDialog( 279 HWND hwndDlg) 280 { 281 HWND hList1; 282 HWND hList2; 283 HWND hList3; 284 285 BOOLEAN bSuspend = FALSE; 286 BOOLEAN bHibernate; 287 BOOLEAN bShutdown; 288 BOOL bEnabled; 289 290 SYSTEM_POWER_CAPABILITIES spc; 291 292 bEnabled = GetSystrayPowerIconState(); 293 294 if (bEnabled) 295 gGPP.user.GlobalFlags |= EnableSysTrayBatteryMeter; 296 else 297 gGPP.user.GlobalFlags &= ~EnableSysTrayBatteryMeter; 298 299 CheckDlgButton(hwndDlg, 300 IDC_SYSTRAYBATTERYMETER, 301 bEnabled ? BST_CHECKED : BST_UNCHECKED); 302 CheckDlgButton(hwndDlg, 303 IDC_PASSWORDLOGON, 304 gGPP.user.GlobalFlags & EnablePasswordLogon ? BST_CHECKED : BST_UNCHECKED); 305 CheckDlgButton(hwndDlg, 306 IDC_VIDEODIMDISPLAY, 307 gGPP.user.GlobalFlags & EnableVideoDimDisplay ? BST_CHECKED : BST_UNCHECKED); 308 309 GetPwrCapabilities(&spc); 310 311 if (spc.SystemS1 || spc.SystemS2 || spc.SystemS3) 312 bSuspend=TRUE; 313 314 bHibernate = spc.HiberFilePresent; 315 bShutdown = spc.SystemS5; 316 317 hList1 = GetDlgItem(hwndDlg, IDC_LIDCLOSE); 318 SendMessage(hList1, CB_RESETCONTENT, 0, 0); 319 320 memset(g_SystemBatteries, 0x0, sizeof(g_SystemBatteries)); 321 if (spc.SystemBatteriesPresent) 322 { 323 AddItem(hList1, IDS_PowerActionNone1, (LPARAM)PowerActionNone, g_SystemBatteries); 324 325 if (bSuspend) 326 { 327 AddItem(hList1, IDS_PowerActionSleep, (LPARAM)PowerActionSleep, g_SystemBatteries); 328 } 329 330 if (bHibernate) 331 { 332 AddItem(hList1, IDS_PowerActionHibernate, (LPARAM)PowerActionHibernate, g_SystemBatteries); 333 } 334 } 335 else 336 { 337 ShowWindow(GetDlgItem(hwndDlg, IDC_VIDEODIMDISPLAY), FALSE); 338 ShowWindow(GetDlgItem(hwndDlg, IDC_SLIDCLOSE), FALSE); 339 ShowWindow(hList1, FALSE); 340 } 341 342 hList2 = GetDlgItem(hwndDlg, IDC_POWERBUTTON); 343 SendMessage(hList2, CB_RESETCONTENT, 0, 0); 344 345 memset(g_PowerButton, 0x0, sizeof(g_PowerButton)); 346 if (spc.PowerButtonPresent) 347 { 348 AddItem(hList2, IDS_PowerActionNone1, (LPARAM)PowerActionNone, g_PowerButton); 349 AddItem(hList2, IDS_PowerActionWarmEject, (LPARAM)PowerActionWarmEject, g_PowerButton); 350 351 if (bSuspend) 352 { 353 AddItem(hList2, IDS_PowerActionSleep, (LPARAM)PowerActionSleep, g_PowerButton); 354 } 355 356 if (bHibernate) 357 { 358 AddItem(hList2, IDS_PowerActionHibernate, (LPARAM)PowerActionHibernate, g_PowerButton); 359 } 360 361 if (bShutdown) 362 { 363 AddItem(hList2, IDS_PowerActionShutdown, (LPARAM)PowerActionShutdown, g_PowerButton); 364 } 365 } 366 else 367 { 368 ShowWindow(GetDlgItem(hwndDlg, IDC_SPOWERBUTTON), FALSE); 369 ShowWindow(hList2, FALSE); 370 } 371 372 hList3 = GetDlgItem(hwndDlg, IDC_SLEEPBUTTON); 373 SendMessage(hList3, CB_RESETCONTENT, 0, 0); 374 memset(g_SleepButton, 0x0, sizeof(g_SleepButton)); 375 376 if (spc.SleepButtonPresent) 377 { 378 AddItem(hList3, IDS_PowerActionNone1, (LPARAM)PowerActionNone, g_SleepButton); 379 AddItem(hList3, IDS_PowerActionWarmEject, (LPARAM)PowerActionWarmEject, g_SleepButton); 380 381 if (bSuspend) 382 { 383 AddItem(hList3, IDS_PowerActionSleep, (LPARAM)PowerActionSleep, g_SleepButton); 384 } 385 386 if (bHibernate) 387 { 388 AddItem(hList3, IDS_PowerActionHibernate, (LPARAM)PowerActionHibernate, g_SleepButton); 389 } 390 391 if (bShutdown) 392 { 393 AddItem(hList3, IDS_PowerActionShutdown, (LPARAM)PowerActionShutdown, g_SleepButton); 394 } 395 } 396 else 397 { 398 ShowWindow(GetDlgItem(hwndDlg, IDC_SSLEEPBUTTON), FALSE); 399 ShowWindow(hList3, FALSE); 400 } 401 402 if (ReadGlobalPwrPolicy(&gGPP)) 403 { 404 ShowCurrentPowerActionPolicies(hwndDlg, &spc); 405 } 406 } 407 408 static VOID 409 Adv_SaveData(HWND hwndDlg) 410 { 411 BOOL bSystrayBatteryMeter; 412 BOOL bPasswordLogon; 413 BOOL bVideoDimDisplay; 414 415 bSystrayBatteryMeter = 416 (IsDlgButtonChecked(hwndDlg, IDC_SYSTRAYBATTERYMETER) == BST_CHECKED); 417 418 bPasswordLogon = 419 (IsDlgButtonChecked(hwndDlg, IDC_PASSWORDLOGON) == BST_CHECKED); 420 421 bVideoDimDisplay = 422 (IsDlgButtonChecked(hwndDlg, IDC_VIDEODIMDISPLAY) == BST_CHECKED); 423 424 if (bSystrayBatteryMeter) 425 { 426 if (!(gGPP.user.GlobalFlags & EnableSysTrayBatteryMeter)) 427 { 428 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags + EnableSysTrayBatteryMeter; 429 } 430 } 431 else 432 { 433 if ((gGPP.user.GlobalFlags & EnableSysTrayBatteryMeter)) 434 { 435 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags - EnableSysTrayBatteryMeter; 436 } 437 } 438 439 if (bPasswordLogon) 440 { 441 if (!(gGPP.user.GlobalFlags & EnablePasswordLogon)) 442 { 443 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags + EnablePasswordLogon; 444 } 445 } 446 else 447 { 448 if ((gGPP.user.GlobalFlags & EnablePasswordLogon)) 449 { 450 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags - EnablePasswordLogon; 451 } 452 } 453 454 if (bVideoDimDisplay) 455 { 456 if (!(gGPP.user.GlobalFlags & EnableVideoDimDisplay)) 457 { 458 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags + EnableVideoDimDisplay; 459 } 460 } 461 else 462 { 463 if ((gGPP.user.GlobalFlags & EnableVideoDimDisplay)) 464 { 465 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags - EnableVideoDimDisplay; 466 } 467 } 468 469 if (!IsBatteryUsed()) 470 { 471 #if 0 472 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_LIDCLOSE), &gGPP.user.LidCloseAc); 473 #endif 474 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON), &gGPP.user.PowerButtonAc); 475 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON), &gGPP.user.SleepButtonAc); 476 } 477 else 478 { 479 #if 0 480 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_LIDCLOSE), &gGPP.user.LidCloseDc); 481 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON), &gGPP.user.PowerButtonDc); 482 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON), &gGPP.user.SleepButtonDc); 483 #endif 484 } 485 486 if (!WriteGlobalPwrPolicy(&gGPP)) 487 { 488 MessageBox(hwndDlg, L"WriteGlobalPwrPolicy failed", NULL, MB_OK); 489 } 490 491 SetSystrayPowerIconState(bSystrayBatteryMeter); 492 493 // Adv_InitDialog(hwndDlg); 494 } 495 496 /* Property page dialog callback */ 497 INT_PTR CALLBACK 498 AdvancedDlgProc(HWND hwndDlg, 499 UINT uMsg, 500 WPARAM wParam, 501 LPARAM lParam) 502 { 503 switch (uMsg) 504 { 505 case WM_INITDIALOG: 506 Adv_InitDialog(hwndDlg); 507 return TRUE; 508 509 case WM_COMMAND: 510 switch (LOWORD(wParam)) 511 { 512 case IDC_SYSTRAYBATTERYMETER: 513 case IDC_PASSWORDLOGON: 514 case IDC_VIDEODIMDISPLAY: 515 if (HIWORD(wParam) == BN_CLICKED) 516 { 517 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 518 } 519 break; 520 521 case IDC_LIDCLOSE: 522 case IDC_POWERBUTTON: 523 case IDC_SLEEPBUTTON: 524 if (HIWORD(wParam) == CBN_SELCHANGE) 525 { 526 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 527 } 528 break; 529 } 530 break; 531 532 case WM_NOTIFY: 533 switch (((LPNMHDR)lParam)->code) 534 { 535 case PSN_APPLY: 536 Adv_SaveData(hwndDlg); 537 return TRUE; 538 539 case PSN_SETACTIVE: 540 Adv_InitDialog(hwndDlg); 541 return TRUE; 542 } 543 break; 544 } 545 546 return FALSE; 547 } 548