VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/win/HostPowerWin.cpp@ 51441

Last change on this file since 51441 was 51441, checked in by vboxsync, 11 years ago

Main: code formatting.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1/** @file
2 *
3 * VirtualBox interface to host's power notification service
4 */
5
6/*
7 * Copyright (C) 2006-2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include <windows.h>
22/* Some SDK versions lack the extern "C" and thus cause linking failures.
23 * This workaround isn't pretty, but there are not many options. */
24extern "C" {
25#include <PowrProf.h>
26}
27
28#include <VBox/com/ptr.h>
29#include "HostPower.h"
30#include "Logging.h"
31
32static WCHAR gachWindowClassName[] = L"VBoxPowerNotifyClass";
33
34HostPowerServiceWin::HostPowerServiceWin(VirtualBox *aVirtualBox) : HostPowerService(aVirtualBox), mThread(NIL_RTTHREAD)
35{
36 mHwnd = 0;
37
38 int rc = RTThreadCreate(&mThread, HostPowerServiceWin::NotificationThread, this, 65536,
39 RTTHREADTYPE_GUI, RTTHREADFLAGS_WAITABLE, "MainPower");
40
41 if (RT_FAILURE(rc))
42 {
43 Log(("HostPowerServiceWin::HostPowerServiceWin: RTThreadCreate failed with %Rrc\n", rc));
44 return;
45 }
46}
47
48HostPowerServiceWin::~HostPowerServiceWin()
49{
50 if (mHwnd)
51 {
52 Log(("HostPowerServiceWin::!HostPowerServiceWin: destroy window %x\n", mHwnd));
53
54 /* Is this allowed from another thread? */
55 SetWindowLongPtr(mHwnd, 0, 0);
56 /* Poke the thread out of the event loop and wait for it to clean up. */
57 PostMessage(mHwnd, WM_QUIT, 0, 0);
58 RTThreadWait(mThread, 5000, NULL);
59 mThread = NIL_RTTHREAD;
60 }
61}
62
63
64
65DECLCALLBACK(int) HostPowerServiceWin::NotificationThread(RTTHREAD ThreadSelf, void *pInstance)
66{
67 HostPowerServiceWin *pPowerObj = (HostPowerServiceWin *)pInstance;
68 HWND hwnd = 0;
69
70 /* Create a window and make it a power event notification handler. */
71 int rc = VINF_SUCCESS;
72
73 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
74
75 /* Register the Window Class. */
76 WNDCLASS wc;
77
78 wc.style = CS_NOCLOSE;
79 wc.lpfnWndProc = HostPowerServiceWin::WndProc;
80 wc.cbClsExtra = 0;
81 wc.cbWndExtra = sizeof(void *);
82 wc.hInstance = hInstance;
83 wc.hIcon = NULL;
84 wc.hCursor = NULL;
85 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
86 wc.lpszMenuName = NULL;
87 wc.lpszClassName = gachWindowClassName;
88
89 ATOM atomWindowClass = RegisterClass(&wc);
90
91 if (atomWindowClass == 0)
92 {
93 rc = VERR_NOT_SUPPORTED;
94 Log(("HostPowerServiceWin::NotificationThread: RegisterClassA failed with %x\n", GetLastError()));
95 }
96 else
97 {
98 /* Create the window. */
99 hwnd = pPowerObj->mHwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
100 gachWindowClassName, gachWindowClassName,
101 WS_POPUPWINDOW,
102 -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
103
104 if (hwnd == NULL)
105 {
106 Log(("HostPowerServiceWin::NotificationThread: CreateWindowExA failed with %x\n", GetLastError()));
107 rc = VERR_NOT_SUPPORTED;
108 }
109 else
110 {
111 SetWindowLongPtr(hwnd, 0, (LONG_PTR)pPowerObj);
112 SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
113 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
114
115 MSG msg;
116 BOOL fRet;
117 while ((fRet = GetMessage(&msg, NULL, 0, 0)) != 0)
118 {
119 if (fRet != -1)
120 {
121 TranslateMessage(&msg);
122 DispatchMessage(&msg);
123 }
124 else
125 {
126 // handle the error and possibly exit
127 break;
128 }
129 }
130 }
131 }
132
133 Log(("HostPowerServiceWin::NotificationThread: exit thread\n"));
134 if (hwnd)
135 DestroyWindow(hwnd);
136
137 if (atomWindowClass != 0)
138 {
139 UnregisterClass(gachWindowClassName, hInstance);
140 atomWindowClass = 0;
141 }
142
143 return 0;
144}
145
146LRESULT CALLBACK HostPowerServiceWin::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
147{
148 switch (msg)
149 {
150 case WM_POWERBROADCAST:
151 {
152 HostPowerServiceWin *pPowerObj;
153
154 pPowerObj = (HostPowerServiceWin *)GetWindowLongPtr(hwnd, 0);
155 if (pPowerObj)
156 {
157 switch(wParam)
158 {
159 case PBT_APMSUSPEND:
160 pPowerObj->notify(Reason_HostSuspend);
161 break;
162
163 case PBT_APMRESUMEAUTOMATIC:
164 pPowerObj->notify(Reason_HostResume);
165 break;
166
167 case PBT_APMPOWERSTATUSCHANGE:
168 {
169 SYSTEM_POWER_STATUS SystemPowerStatus;
170
171 Log(("PBT_APMPOWERSTATUSCHANGE\n"));
172 if (GetSystemPowerStatus(&SystemPowerStatus) == TRUE)
173 {
174 Log(("PBT_APMPOWERSTATUSCHANGE ACLineStatus=%d BatteryFlag=%d\n", SystemPowerStatus.ACLineStatus,
175 SystemPowerStatus.BatteryFlag));
176
177 if (SystemPowerStatus.ACLineStatus == 0) /* offline */
178 {
179 if (SystemPowerStatus.BatteryFlag == 2 /* low > 33% */)
180 {
181 LONG rc;
182 SYSTEM_BATTERY_STATE BatteryState;
183
184 rc = CallNtPowerInformation(SystemBatteryState, NULL, 0, (PVOID)&BatteryState,
185 sizeof(BatteryState));
186#ifdef LOG_ENABLED
187 if (rc == 0 /* STATUS_SUCCESS */)
188 Log(("CallNtPowerInformation claims %d seconds of power left\n",
189 BatteryState.EstimatedTime));
190#endif
191 if ( rc == 0 /* STATUS_SUCCESS */
192 && BatteryState.EstimatedTime < 60*5)
193 {
194 pPowerObj->notify(Reason_HostBatteryLow);
195 }
196 }
197 else
198 /* If the machine has less than 5% battery left (and is not connected
199 * to the AC), then we should save the state. */
200 if (SystemPowerStatus.BatteryFlag == 4 /* critical battery status; less than 5% */)
201 {
202 pPowerObj->notify(Reason_HostBatteryLow);
203 }
204 }
205 }
206 break;
207 }
208 default:
209 return DefWindowProc(hwnd, msg, wParam, lParam);
210 }
211 }
212 return TRUE;
213 }
214
215 default:
216 return DefWindowProc(hwnd, msg, wParam, lParam);
217 }
218}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette