VirtualBox

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

Last change on this file since 43978 was 35368, checked in by vboxsync, 14 years ago

Main: source re-org.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/** @file
2 *
3 * VirtualBox interface to host's power notification service
4 */
5
6/*
7 * Copyright (C) 2006-2007 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)
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 /* Send the quit message and wait for it be processed. */
57 SendMessage(mHwnd, WM_QUIT, 0, 0);
58 }
59}
60
61
62
63DECLCALLBACK(int) HostPowerServiceWin::NotificationThread (RTTHREAD ThreadSelf, void *pInstance)
64{
65 HostPowerServiceWin *pPowerObj = (HostPowerServiceWin *)pInstance;
66 HWND hwnd = 0;
67
68 /* Create a window and make it a power event notification handler. */
69 int rc = VINF_SUCCESS;
70
71 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
72
73 /* Register the Window Class. */
74 WNDCLASS wc;
75
76 wc.style = CS_NOCLOSE;
77 wc.lpfnWndProc = HostPowerServiceWin::WndProc;
78 wc.cbClsExtra = 0;
79 wc.cbWndExtra = sizeof(void *);
80 wc.hInstance = hInstance;
81 wc.hIcon = NULL;
82 wc.hCursor = NULL;
83 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
84 wc.lpszMenuName = NULL;
85 wc.lpszClassName = gachWindowClassName;
86
87 ATOM atomWindowClass = RegisterClass(&wc);
88
89 if (atomWindowClass == 0)
90 {
91 rc = VERR_NOT_SUPPORTED;
92 Log(("HostPowerServiceWin::NotificationThread: RegisterClassA failed with %x\n", GetLastError()));
93 }
94 else
95 {
96 /* Create the window. */
97 hwnd = pPowerObj->mHwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
98 gachWindowClassName, gachWindowClassName,
99 WS_POPUPWINDOW,
100 -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
101
102 if (hwnd == NULL)
103 {
104 Log(("HostPowerServiceWin::NotificationThread: CreateWindowExA failed with %x\n", GetLastError()));
105 rc = VERR_NOT_SUPPORTED;
106 }
107 else
108 {
109 SetWindowLongPtr(hwnd, 0, (LONG_PTR)pPowerObj);
110 SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
111 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
112
113 MSG msg;
114 while (GetMessage(&msg, NULL, 0, 0))
115 {
116 TranslateMessage(&msg);
117 DispatchMessage(&msg);
118 }
119 }
120 }
121
122 Log(("HostPowerServiceWin::NotificationThread: exit thread\n"));
123 if (hwnd)
124 DestroyWindow (hwnd);
125
126 if (atomWindowClass != 0)
127 {
128 UnregisterClass (gachWindowClassName, hInstance);
129 atomWindowClass = 0;
130 }
131
132 return 0;
133}
134
135LRESULT CALLBACK HostPowerServiceWin::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
136{
137 switch (msg)
138 {
139 case WM_POWERBROADCAST:
140 {
141 HostPowerServiceWin *pPowerObj;
142
143 pPowerObj = (HostPowerServiceWin *)GetWindowLongPtr(hwnd, 0);
144 if (pPowerObj)
145 {
146 switch(wParam)
147 {
148 case PBT_APMSUSPEND:
149 pPowerObj->notify(HostPowerEvent_Suspend);
150 break;
151
152 case PBT_APMRESUMEAUTOMATIC:
153 pPowerObj->notify(HostPowerEvent_Resume);
154 break;
155
156 case PBT_APMPOWERSTATUSCHANGE:
157 {
158 SYSTEM_POWER_STATUS SystemPowerStatus;
159
160 Log(("PBT_APMPOWERSTATUSCHANGE\n"));
161 if (GetSystemPowerStatus(&SystemPowerStatus) == TRUE)
162 {
163 Log(("PBT_APMPOWERSTATUSCHANGE ACLineStatus=%d BatteryFlag=%d\n", SystemPowerStatus.ACLineStatus, SystemPowerStatus.BatteryFlag));
164
165 if (SystemPowerStatus.ACLineStatus == 0) /* offline */
166 {
167 if (SystemPowerStatus.BatteryFlag == 2 /* low > 33% */)
168 {
169 LONG rc;
170 SYSTEM_BATTERY_STATE BatteryState;
171
172 rc = CallNtPowerInformation(SystemBatteryState, NULL, 0, (PVOID)&BatteryState, sizeof(BatteryState));
173#ifdef LOG_ENABLED
174 if (rc == 0 /* STATUS_SUCCESS */)
175 Log(("CallNtPowerInformation claims %d seconds of power left\n", BatteryState.EstimatedTime));
176#endif
177 if ( rc == 0 /* STATUS_SUCCESS */
178 && BatteryState.EstimatedTime < 60*5)
179 {
180 pPowerObj->notify(HostPowerEvent_BatteryLow);
181 }
182 }
183 else
184 /* If the machine has less than 5% battery left (and is not connected to the AC), then we should save the state. */
185 if (SystemPowerStatus.BatteryFlag == 4 /* critical battery status; less than 5% */)
186 {
187 pPowerObj->notify(HostPowerEvent_BatteryLow);
188 }
189 }
190 }
191 break;
192 }
193 default:
194 return DefWindowProc (hwnd, msg, wParam, lParam);
195 }
196 }
197 return TRUE;
198 }
199
200 default:
201 return DefWindowProc (hwnd, msg, wParam, lParam);
202 }
203}
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