[POWERCFG] Do not re-initialize all paged directly when the hibernate file setting...
[reactos.git] / dll / cpl / powercfg / advanced.c
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(POWER_ACTION_POLICY *Policy)
98 {
99 POWER_ACTION poAction = PowerActionNone;
100 /*
101
102 TCHAR szBuffer[MAX_PATH];
103
104 // Note: Windows XP SP2+ does not return the PowerAction code
105 // for PowerActionWarmEject + PowerActionShutdown but sets it
106 // to PowerActionNone and sets the Flags & EventCode
107
108
109 _stprintf(szBuffer, L"Action: %x EventCode %x Flags %x",Policy->Action, Policy->EventCode, Policy->Flags);
110 MessageBoxW(NULL, szBuffer, NULL, MB_OK);
111
112 */
113
114 if (Policy->Action == PowerActionNone)
115 {
116 if (Policy->Flags == (POWER_ACTION_UI_ALLOWED | POWER_ACTION_QUERY_ALLOWED))
117 {
118 if (Policy->EventCode == POWER_FORCE_TRIGGER_RESET)
119 {
120 poAction = PowerActionNone;
121 }
122 else if (Policy->EventCode == POWER_USER_NOTIFY_BUTTON)
123 {
124 poAction = PowerActionWarmEject;
125 }
126 else if (Policy->EventCode == POWER_USER_NOTIFY_SHUTDOWN)
127 {
128 poAction = PowerActionShutdown;
129 }
130 }
131 }
132 else
133 {
134 poAction = Policy->Action;
135 }
136
137 return poAction;
138 }
139
140 VOID
141 ShowCurrentPowerActionPolicy(HWND hDlgCtrl,
142 POWER_ACTION *lpAction,
143 DWORD dwActionSize,
144 POWER_ACTION_POLICY *Policy)
145 {
146 int poActionIndex;
147 POWER_ACTION poAction;
148
149 poAction = GetPowerActionFromPolicy(Policy);
150 poActionIndex = FindActionIndex(lpAction, dwActionSize, poAction);
151
152 if (poActionIndex < 0)
153 {
154 return;
155 }
156
157 SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)poActionIndex, (LPARAM)0);
158 }
159
160 BOOLEAN
161 SaveCurrentPowerActionPolicy(IN HWND hDlgCtrl,
162 OUT POWER_ACTION_POLICY *Policy)
163 {
164 LRESULT Index;
165 LRESULT ItemData;
166
167 Index = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
168 if (Index == CB_ERR)
169 return FALSE;
170
171 ItemData = SendMessage(hDlgCtrl, CB_GETITEMDATA, (WPARAM)Index, 0);
172 if (ItemData == CB_ERR)
173 return FALSE;
174
175 switch(ItemData)
176 {
177 case PowerActionNone:
178 Policy->Action = PowerActionNone;
179 Policy->EventCode = POWER_FORCE_TRIGGER_RESET;
180 break;
181
182 case PowerActionWarmEject:
183 Policy->Action = PowerActionNone;
184 Policy->EventCode = POWER_USER_NOTIFY_BUTTON;
185 break;
186
187 case PowerActionShutdown:
188 Policy->Action = PowerActionNone;
189 Policy->EventCode = POWER_USER_NOTIFY_SHUTDOWN;
190 break;
191
192 case PowerActionSleep:
193 case PowerActionHibernate:
194 Policy->Action = (POWER_ACTION)ItemData;
195 Policy->EventCode = 0;
196 break;
197
198 default:
199 return FALSE;
200 }
201
202 Policy->Flags = (POWER_ACTION_UI_ALLOWED | POWER_ACTION_QUERY_ALLOWED);
203
204 return TRUE;
205 }
206
207
208 //-------------------------------------------------------------------
209
210 VOID
211 ShowCurrentPowerActionPolicies(HWND hwndDlg)
212 {
213 TCHAR szAction[MAX_PATH];
214
215 if (!IsBatteryUsed())
216 {
217 #if 0
218 /* experimental code */
219 // ShowCurrentPowerButtonAcAction(hList2,
220 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON),
221 g_SystemBatteries,
222 sizeof(g_SystemBatteries) / sizeof(POWER_ACTION),
223 &gGPP.user.LidCloseAc);
224 #else
225 if (LoadString(hApplet, IDS_PowerActionNone1+gGPP.user.LidCloseAc.Action, szAction, MAX_PATH))
226 {
227 SendDlgItemMessage(hwndDlg, IDC_LIDCLOSE,
228 CB_SELECTSTRING,
229 TRUE,
230 (LPARAM)szAction);
231 }
232 #endif
233 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON),
234 g_PowerButton,
235 sizeof(g_PowerButton) / sizeof(POWER_ACTION),
236 &gGPP.user.PowerButtonAc);
237
238 #if 0
239 /* experimental code */
240 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON),
241 g_SleepButton,
242 sizeof(g_SleepButton) / sizeof(POWER_ACTION),
243 &gGPP.user.SleepButtonAc);
244 #else
245 if (LoadString(hApplet, IDS_PowerActionNone1+gGPP.user.SleepButtonAc.Action, szAction, MAX_PATH))
246 {
247 SendDlgItemMessage(hwndDlg, IDC_SLEEPBUTTON,
248 CB_SELECTSTRING,
249 TRUE,
250 (LPARAM)szAction);
251 }
252 #endif
253 }
254 else
255 {
256 #if 0
257
258 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_LIDCLOSE),
259 g_SleepButton,
260 sizeof(g_SleepButton) / sizeof(POWER_ACTION),
261 &gGPP.user.LidCloseDc);
262
263 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON),
264 g_SleepButton,
265 sizeof(g_SleepButton) / sizeof(POWER_ACTION),
266 &gGPP.user.PowerButtonDc);
267
268 ShowCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON),
269 g_SleepButton,
270 sizeof(g_SleepButton) / sizeof(POWER_ACTION),
271 &gGPP.user.SleepButtonDc);
272 #else
273 if (LoadString(hApplet, IDS_PowerActionNone1+gGPP.user.LidCloseDc.Action, szAction, MAX_PATH))
274 {
275 SendDlgItemMessage(hwndDlg, IDC_LIDCLOSE,
276 CB_SELECTSTRING,
277 TRUE,
278 (LPARAM)szAction);
279 }
280 if (LoadString(hApplet, IDS_PowerActionNone1+gGPP.user.PowerButtonDc.Action, szAction, MAX_PATH))
281 {
282 SendDlgItemMessage(hwndDlg, IDC_POWERBUTTON,
283 CB_SELECTSTRING,
284 TRUE,
285 (LPARAM)szAction);
286 }
287 if (LoadString(hApplet, IDS_PowerActionNone1+gGPP.user.SleepButtonDc.Action, szAction, MAX_PATH))
288 {
289 SendDlgItemMessage(hwndDlg, IDC_SLEEPBUTTON,
290 CB_SELECTSTRING,
291 TRUE,
292 (LPARAM)szAction);
293 }
294 #endif
295 }
296 }
297
298 VOID
299 Adv_InitDialog(
300 HWND hwndDlg)
301 {
302 HWND hList1;
303 HWND hList2;
304 HWND hList3;
305
306 BOOLEAN bSuspend = FALSE;
307 BOOLEAN bHibernate;
308 BOOLEAN bShutdown;
309 BOOL bEnabled;
310
311 SYSTEM_POWER_CAPABILITIES spc;
312
313 bEnabled = GetSystrayPowerIconState();
314
315 if (bEnabled)
316 gGPP.user.GlobalFlags |= EnableSysTrayBatteryMeter;
317 else
318 gGPP.user.GlobalFlags &= ~EnableSysTrayBatteryMeter;
319
320 CheckDlgButton(hwndDlg,
321 IDC_SYSTRAYBATTERYMETER,
322 bEnabled ? BST_CHECKED : BST_UNCHECKED);
323 CheckDlgButton(hwndDlg,
324 IDC_PASSWORDLOGON,
325 gGPP.user.GlobalFlags & EnablePasswordLogon ? BST_CHECKED : BST_UNCHECKED);
326 CheckDlgButton(hwndDlg,
327 IDC_VIDEODIMDISPLAY,
328 gGPP.user.GlobalFlags & EnableVideoDimDisplay ? BST_CHECKED : BST_UNCHECKED);
329
330 GetPwrCapabilities(&spc);
331
332 if (spc.SystemS1 || spc.SystemS2 || spc.SystemS3)
333 bSuspend=TRUE;
334
335 bHibernate = spc.HiberFilePresent;
336 bShutdown = spc.SystemS5;
337
338 hList1 = GetDlgItem(hwndDlg, IDC_LIDCLOSE);
339 SendMessage(hList1, CB_RESETCONTENT, 0, 0);
340
341 memset(g_SystemBatteries, 0x0, sizeof(g_SystemBatteries));
342 if (spc.SystemBatteriesPresent)
343 {
344 AddItem(hList1, IDS_PowerActionNone1, (LPARAM)PowerActionNone, g_SystemBatteries);
345
346 if (bSuspend)
347 {
348 AddItem(hList1, IDS_PowerActionSleep, (LPARAM)PowerActionSleep, g_SystemBatteries);
349 }
350
351 if (bHibernate)
352 {
353 AddItem(hList1, IDS_PowerActionHibernate, (LPARAM)PowerActionHibernate, g_SystemBatteries);
354 }
355 }
356 else
357 {
358 ShowWindow(GetDlgItem(hwndDlg, IDC_VIDEODIMDISPLAY), FALSE);
359 ShowWindow(GetDlgItem(hwndDlg, IDC_SLIDCLOSE), FALSE);
360 ShowWindow(hList1, FALSE);
361 }
362
363 hList2 = GetDlgItem(hwndDlg, IDC_POWERBUTTON);
364 SendMessage(hList2, CB_RESETCONTENT, 0, 0);
365
366 memset(g_PowerButton, 0x0, sizeof(g_PowerButton));
367 if (spc.PowerButtonPresent)
368 {
369 AddItem(hList2, IDS_PowerActionNone1, (LPARAM)PowerActionNone, g_PowerButton);
370 AddItem(hList2, IDS_PowerActionWarmEject, (LPARAM)PowerActionWarmEject, g_PowerButton);
371
372 if (bSuspend)
373 {
374 AddItem(hList2, IDS_PowerActionSleep, (LPARAM)PowerActionSleep, g_PowerButton);
375 }
376
377 if (bHibernate)
378 {
379 AddItem(hList2, IDS_PowerActionHibernate, (LPARAM)PowerActionHibernate, g_PowerButton);
380 }
381
382 if (bShutdown)
383 {
384 AddItem(hList2, IDS_PowerActionShutdown, (LPARAM)PowerActionShutdown, g_PowerButton);
385 }
386 }
387 else
388 {
389 ShowWindow(GetDlgItem(hwndDlg, IDC_SPOWERBUTTON), FALSE);
390 ShowWindow(hList2, FALSE);
391 }
392
393 hList3 = GetDlgItem(hwndDlg, IDC_SLEEPBUTTON);
394 SendMessage(hList3, CB_RESETCONTENT, 0, 0);
395 memset(g_SleepButton, 0x0, sizeof(g_SleepButton));
396
397 if (spc.SleepButtonPresent)
398 {
399 AddItem(hList3, IDS_PowerActionNone1, (LPARAM)PowerActionNone, g_SleepButton);
400 AddItem(hList3, IDS_PowerActionWarmEject, (LPARAM)PowerActionWarmEject, g_SleepButton);
401
402 if (bSuspend)
403 {
404 AddItem(hList3, IDS_PowerActionSleep, (LPARAM)PowerActionSleep, g_SleepButton);
405 }
406
407 if (bHibernate)
408 {
409 AddItem(hList3, IDS_PowerActionHibernate, (LPARAM)PowerActionHibernate, g_SleepButton);
410 }
411
412 if (bShutdown)
413 {
414 AddItem(hList3, IDS_PowerActionShutdown, (LPARAM)PowerActionShutdown, g_SleepButton);
415 }
416 }
417 else
418 {
419 ShowWindow(GetDlgItem(hwndDlg, IDC_SSLEEPBUTTON), FALSE);
420 ShowWindow(hList3, FALSE);
421 }
422
423 if (ReadGlobalPwrPolicy(&gGPP))
424 {
425 ShowCurrentPowerActionPolicies(hwndDlg);
426 }
427 }
428
429 static VOID
430 Adv_SaveData(HWND hwndDlg)
431 {
432 BOOL bSystrayBatteryMeter;
433 BOOL bPasswordLogon;
434 BOOL bVideoDimDisplay;
435
436 bSystrayBatteryMeter =
437 (IsDlgButtonChecked(hwndDlg, IDC_SYSTRAYBATTERYMETER) == BST_CHECKED);
438
439 bPasswordLogon =
440 (IsDlgButtonChecked(hwndDlg, IDC_PASSWORDLOGON) == BST_CHECKED);
441
442 bVideoDimDisplay =
443 (IsDlgButtonChecked(hwndDlg, IDC_VIDEODIMDISPLAY) == BST_CHECKED);
444
445 if (bSystrayBatteryMeter)
446 {
447 if (!(gGPP.user.GlobalFlags & EnableSysTrayBatteryMeter))
448 {
449 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags + EnableSysTrayBatteryMeter;
450 }
451 }
452 else
453 {
454 if ((gGPP.user.GlobalFlags & EnableSysTrayBatteryMeter))
455 {
456 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags - EnableSysTrayBatteryMeter;
457 }
458 }
459
460 if (bPasswordLogon)
461 {
462 if (!(gGPP.user.GlobalFlags & EnablePasswordLogon))
463 {
464 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags + EnablePasswordLogon;
465 }
466 }
467 else
468 {
469 if ((gGPP.user.GlobalFlags & EnablePasswordLogon))
470 {
471 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags - EnablePasswordLogon;
472 }
473 }
474
475 if (bVideoDimDisplay)
476 {
477 if (!(gGPP.user.GlobalFlags & EnableVideoDimDisplay))
478 {
479 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags + EnableVideoDimDisplay;
480 }
481 }
482 else
483 {
484 if ((gGPP.user.GlobalFlags & EnableVideoDimDisplay))
485 {
486 gGPP.user.GlobalFlags = gGPP.user.GlobalFlags - EnableVideoDimDisplay;
487 }
488 }
489
490 if (!IsBatteryUsed())
491 {
492 #if 0
493 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_LIDCLOSE), &gGPP.user.LidCloseAc);
494 #endif
495 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON), &gGPP.user.PowerButtonAc);
496 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON), &gGPP.user.SleepButtonAc);
497 }
498 else
499 {
500 #if 0
501 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_LIDCLOSE), &gGPP.user.LidCloseDc);
502 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_POWERBUTTON), &gGPP.user.PowerButtonDc);
503 SaveCurrentPowerActionPolicy(GetDlgItem(hwndDlg, IDC_SLEEPBUTTON), &gGPP.user.SleepButtonDc);
504 #endif
505 }
506
507 if (!WriteGlobalPwrPolicy(&gGPP))
508 {
509 MessageBox(hwndDlg, L"WriteGlobalPwrPolicy failed", NULL, MB_OK);
510 }
511
512 SetSystrayPowerIconState(bSystrayBatteryMeter);
513
514 // Adv_InitDialog(hwndDlg);
515 }
516
517 /* Property page dialog callback */
518 INT_PTR CALLBACK
519 AdvancedDlgProc(HWND hwndDlg,
520 UINT uMsg,
521 WPARAM wParam,
522 LPARAM lParam)
523 {
524 switch (uMsg)
525 {
526 case WM_INITDIALOG:
527 Adv_InitDialog(hwndDlg);
528 return TRUE;
529
530 case WM_COMMAND:
531 switch (LOWORD(wParam))
532 {
533 case IDC_SYSTRAYBATTERYMETER:
534 case IDC_PASSWORDLOGON:
535 case IDC_VIDEODIMDISPLAY:
536 if (HIWORD(wParam) == BN_CLICKED)
537 {
538 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
539 }
540 break;
541
542 case IDC_LIDCLOSE:
543 case IDC_POWERBUTTON:
544 case IDC_SLEEPBUTTON:
545 if (HIWORD(wParam) == CBN_SELCHANGE)
546 {
547 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
548 }
549 break;
550 }
551 break;
552
553 case WM_NOTIFY:
554 switch (((LPNMHDR)lParam)->code)
555 {
556 case PSN_APPLY:
557 Adv_SaveData(hwndDlg);
558 return TRUE;
559
560 case PSN_SETACTIVE:
561 Adv_InitDialog(hwndDlg);
562 return TRUE;
563 }
564 break;
565 }
566
567 return FALSE;
568 }