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