HostPowerWin.cpp revision a62ce5472a6bd50322d061cb720cd84ae5038371
98b57301cf15ff5f95eaf7bc8b81e57750026b8evboxsync/** @file
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync *
9d473abea9a9b6597b2b20bedc950ba33a2e73a5vboxsync * VirtualBox interface to host's power notification service
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync */
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync/*
98b57301cf15ff5f95eaf7bc8b81e57750026b8evboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync *
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * available from http://www.virtualbox.org. This file is free software;
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * you can redistribute it and/or modify it under the terms of the GNU
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * General Public License (GPL) as published by the Free Software
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync *
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
98b57301cf15ff5f95eaf7bc8b81e57750026b8evboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync * additional information or have any questions.
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync */
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync/*******************************************************************************
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync* Header Files *
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync*******************************************************************************/
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync#include <windows.h>
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync#include <VBox/com/ptr.h>
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync#include "HostPower.h"
98b57301cf15ff5f95eaf7bc8b81e57750026b8evboxsync#include "Logging.h"
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsyncstatic WCHAR gachWindowClassName[] = L"VBoxPowerNotifyClass";
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsyncHostPowerServiceWin::HostPowerServiceWin(VirtualBox *aVirtualBox) : HostPowerService(aVirtualBox)
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync{
98b57301cf15ff5f95eaf7bc8b81e57750026b8evboxsync mHwnd = 0;
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync#if 0
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync int rc = RTThreadCreate (&mThread, HostPowerServiceWin::NotificationThread, this, 65536,
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "MainPower");
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync if (RT_FAILURE (rc))
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync {
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync Log(("HostPowerServiceWin::HostPowerServiceWin: RTThreadCreate failed with %Rrc\n", rc));
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync return;
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync }
6be66de4257f4f564e35f7b8ee57a282e3cf3e96vboxsync#endif
bcc2356dccf06ea3fdd1f3e4d4e62b04e95673d0vboxsync}
bcc2356dccf06ea3fdd1f3e4d4e62b04e95673d0vboxsync
bcc2356dccf06ea3fdd1f3e4d4e62b04e95673d0vboxsyncHostPowerServiceWin::~HostPowerServiceWin()
bcc2356dccf06ea3fdd1f3e4d4e62b04e95673d0vboxsync{
bcc2356dccf06ea3fdd1f3e4d4e62b04e95673d0vboxsync if (mHwnd)
bcc2356dccf06ea3fdd1f3e4d4e62b04e95673d0vboxsync {
bcc2356dccf06ea3fdd1f3e4d4e62b04e95673d0vboxsync Log(("HostPowerServiceWin::!HostPowerServiceWin: destroy window %x\n", mHwnd));
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync /* Is this allowed from another thread? */
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync SetWindowLongPtr(mHwnd, 0, 0);
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync /* Send the quit message and wait for it be processed. */
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync SendMessage(mHwnd, WM_QUIT, 0, 0);
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync }
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync}
5b802b5e11fed6e163afca32e9118d2599d312fbvboxsync
DECLCALLBACK(int) HostPowerServiceWin::NotificationThread (RTTHREAD ThreadSelf, void *pInstance)
{
HostPowerServiceWin *pPowerObj = (HostPowerServiceWin *)pInstance;
HWND hwnd = 0;
/* Create a window and make it a power event notification handler. */
int rc = VINF_SUCCESS;
HINSTANCE hInstance = (HINSTANCE)GetModuleHandle (NULL);
/* Register the Window Class. */
WNDCLASS wc;
wc.style = CS_NOCLOSE;
wc.lpfnWndProc = HostPowerServiceWin::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(void *);
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = gachWindowClassName;
ATOM atomWindowClass = RegisterClass(&wc);
if (atomWindowClass == 0)
{
rc = VERR_NOT_SUPPORTED;
Log(("HostPowerServiceWin::NotificationThread: RegisterClassA failed with %x\n", GetLastError()));
}
else
{
/* Create the window. */
hwnd = pPowerObj->mHwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
gachWindowClassName, gachWindowClassName,
WS_POPUPWINDOW,
-200, -200, 100, 100, NULL, NULL, hInstance, NULL);
if (hwnd == NULL)
{
Log(("HostPowerServiceWin::NotificationThread: CreateWindowExA failed with %x\n", GetLastError()));
rc = VERR_NOT_SUPPORTED;
}
else
{
SetWindowLongPtr(hwnd, 0, (LONG_PTR)pPowerObj);
SetWindowPos(hwnd, HWND_TOPMOST, -200, -200, 0, 0,
SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
Log(("HostPowerServiceWin::NotificationThread: exit thread\n"));
if (hwnd)
DestroyWindow (hwnd);
if (atomWindowClass != 0)
{
UnregisterClass (gachWindowClassName, hInstance);
atomWindowClass = 0;
}
return 0;
}
LRESULT CALLBACK HostPowerServiceWin::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_POWERBROADCAST:
{
HostPowerServiceWin *pPowerObj;
pPowerObj = (HostPowerServiceWin *)GetWindowLongPtr(hwnd, 0);
if (pPowerObj)
{
switch(wParam)
{
case PBT_APMSUSPEND:
pPowerObj->notify(HostPowerEvent_Suspend);
break;
case PBT_APMRESUMEAUTOMATIC:
pPowerObj->notify(HostPowerEvent_Resume);
break;
case PBT_APMPOWERSTATUSCHANGE:
{
SYSTEM_POWER_STATUS SystemPowerStatus;
if (GetSystemPowerStatus(&SystemPowerStatus) == TRUE)
{
if ( SystemPowerStatus.BatteryFlag != 255 /* unknown */
&& (SystemPowerStatus.BatteryFlag & 4 /* critical battery status; less than 5% */))
{
pPowerObj->notify(HostPowerEvent_BatteryLow);
}
}
break;
}
}
}
return DefWindowProc (hwnd, msg, wParam, lParam);
}
default:
return DefWindowProc (hwnd, msg, wParam, lParam);
}
}