xref: /reactos/dll/cpl/powercfg/advanced.c (revision 3a207cdf)
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
SetSystrayPowerIconState(BOOL bEnabled)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
GetSystrayPowerIconState(VOID)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
AddItem(HWND hDlgCtrl,INT ResourceId,LPARAM lParam,POWER_ACTION * lpAction)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
FindActionIndex(POWER_ACTION * lpAction,DWORD dwActionSize,POWER_ACTION poAction)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
IsBatteryUsed(VOID)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
GetPowerActionFromPolicy(POWER_ACTION_POLICY * Policy,PSYSTEM_POWER_CAPABILITIES spc,BOOL bIsLid)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
ShowCurrentPowerActionPolicy(HWND hDlgCtrl,POWER_ACTION * lpAction,DWORD dwActionSize,POWER_ACTION_POLICY * Policy,PSYSTEM_POWER_CAPABILITIES spc,BOOL bIsLid)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
SaveCurrentPowerActionPolicy(IN HWND hDlgCtrl,OUT POWER_ACTION_POLICY * Policy)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
ShowCurrentPowerActionPolicies(HWND hwndDlg,PSYSTEM_POWER_CAPABILITIES spc)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
Adv_InitDialog(HWND hwndDlg)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
Adv_SaveData(HWND hwndDlg)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
AdvancedDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)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