VirtualBox

source: vbox/trunk/src/VBox/Main/win/HostPowerWin.cpp@ 19844

Last change on this file since 19844 was 16375, checked in by vboxsync, 16 years ago

Main/Windows: workaround for some header versions lacking the extern "C".

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/** @file
2 *
3 * VirtualBox interface to host's power notification service
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#include <windows.h>
26/* Some SDK versions lack the extern "C" and thus cause linking failures.
27 * This workaround isn't pretty, but there are not many options. */
28extern "C" {
29#include <PowrProf.h>
30}
31
32#include <VBox/com/ptr.h>
33#include "HostPower.h"
34#include "Logging.h"
35
36static WCHAR gachWindowClassName[] = L"VBoxPowerNotifyClass";
37
38HostPowerServiceWin::HostPowerServiceWin(VirtualBox *aVirtualBox) : HostPowerService(aVirtualBox)
39{
40 mHwnd = 0;
41
42 int rc = RTThreadCreate (&mThread, HostPowerServiceWin::NotificationThread, this, 65536,
43 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "MainPower");
44
45 if (RT_FAILURE (rc))
46 {
47 Log(("HostPowerServiceWin::HostPowerServiceWin: RTThreadCreate failed with %Rrc\n", rc));
48 return;
49 }
50}
51
52HostPowerServiceWin::~HostPowerServiceWin()
53{
54 if (mHwnd)
55 {
56 Log(("HostPowerServiceWin::!HostPowerServiceWin: destroy window %x\n", mHwnd));
57
58 /* Is this allowed from another thread? */
59 SetWindowLongPtr(mHwnd, 0, 0);
60 /* Send the quit message and wait for it be processed. */
61 SendMessage(mHwnd, WM_QUIT, 0, 0);
62 }
63}
64
65
66
67DECLCALLBACK(int) HostPowerServiceWin::NotificationThread (RTTHREAD ThreadSelf, void *pInstance)
68{
69 HostPowerServiceWin *pPowerObj = (HostPowerServiceWin *)pInstance;
70 HWND hwnd = 0;
71
72 /* Create a window and make it a power event notification handler. */
73 int rc = VINF_SUCCESS;
74
75 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
76
77 /* Register the Window Class. */
78 WNDCLASS wc;
79
80 wc.style = CS_NOCLOSE;
81 wc.lpfnWndProc = HostPowerServiceWin::WndProc;
82 wc.cbClsExtra = 0;
83 wc.cbWndExtra = sizeof(void *);
84 wc.hInstance = hInstance;
85 wc.hIcon = NULL;
86 wc.hCursor = NULL;
87 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
88 wc.lpszMenuName = NULL;
89 wc.lpszClassName = gachWindowClassName;
90
91 ATOM atomWindowClass = RegisterClass(&wc);
92
93 if (atomWindowClass == 0)
94 {
95 rc = VERR_NOT_SUPPORTED;
96 Log(("HostPowerServiceWin::NotificationThread: RegisterClassA failed with %x\n", GetLastError()));
97 }
98 else
99 {
100 /* Create the window. */
101 hwnd = pPowerObj->mHwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
102 gachWindowClassName, gachWindowClassName,
103 WS_POPUPWINDOW,
104 -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
105
106 if (hwnd == NULL)
107 {
108 Log(("HostPowerServiceWin::NotificationThread: CreateWindowExA failed with %x\n", GetLastError()));
109 rc = VERR_NOT_SUPPORTED;
110 }
111 else
112 {
113 SetWindowLongPtr(hwnd, 0, (LONG_PTR)pPowerObj);
114 SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
115 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
116
117 MSG msg;
118 while (GetMessage(&msg, NULL, 0, 0))
119 {
120 TranslateMessage(&msg);
121 DispatchMessage(&msg);
122 }
123 }
124 }
125
126 Log(("HostPowerServiceWin::NotificationThread: exit thread\n"));
127 if (hwnd)
128 DestroyWindow (hwnd);
129
130 if (atomWindowClass != 0)
131 {
132 UnregisterClass (gachWindowClassName, hInstance);
133 atomWindowClass = 0;
134 }
135
136 return 0;
137}
138
139LRESULT CALLBACK HostPowerServiceWin::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
140{
141 switch (msg)
142 {
143 case WM_POWERBROADCAST:
144 {
145 HostPowerServiceWin *pPowerObj;
146
147 pPowerObj = (HostPowerServiceWin *)GetWindowLongPtr(hwnd, 0);
148 if (pPowerObj)
149 {
150 switch(wParam)
151 {
152 case PBT_APMSUSPEND:
153 pPowerObj->notify(HostPowerEvent_Suspend);
154 break;
155
156 case PBT_APMRESUMEAUTOMATIC:
157 pPowerObj->notify(HostPowerEvent_Resume);
158 break;
159
160 case PBT_APMPOWERSTATUSCHANGE:
161 {
162 SYSTEM_POWER_STATUS SystemPowerStatus;
163
164 Log(("PBT_APMPOWERSTATUSCHANGE\n"));
165 if (GetSystemPowerStatus(&SystemPowerStatus) == TRUE)
166 {
167 Log(("PBT_APMPOWERSTATUSCHANGE ACLineStatus=%d BatteryFlag=%d\n", SystemPowerStatus.ACLineStatus, SystemPowerStatus.BatteryFlag));
168
169 if (SystemPowerStatus.ACLineStatus == 0) /* offline */
170 {
171 if (SystemPowerStatus.BatteryFlag == 2 /* low > 33% */)
172 {
173 LONG rc;
174 SYSTEM_BATTERY_STATE BatteryState;
175
176 rc = CallNtPowerInformation(SystemBatteryState, NULL, 0, (PVOID)&BatteryState, sizeof(BatteryState));
177#ifdef LOG_ENABLED
178 if (rc == 0 /* STATUS_SUCCESS */)
179 Log(("CallNtPowerInformation claims %d seconds of power left\n", BatteryState.EstimatedTime));
180#endif
181 if ( rc == 0 /* STATUS_SUCCESS */
182 && BatteryState.EstimatedTime < 60*5)
183 {
184 pPowerObj->notify(HostPowerEvent_BatteryLow);
185 }
186 }
187 else
188 /* If the machine has less than 5% battery left (and is not connected to the AC), then we should save the state. */
189 if (SystemPowerStatus.BatteryFlag == 4 /* critical battery status; less than 5% */)
190 {
191 pPowerObj->notify(HostPowerEvent_BatteryLow);
192 }
193 }
194 }
195 break;
196 }
197 }
198 }
199 return TRUE;
200 }
201
202 default:
203 return DefWindowProc (hwnd, msg, wParam, lParam);
204 }
205}
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