Add a ACPI battery driver interface to the PowerStatus app. If there is anyone with a working APM please test if its still working!
TODO: - Get along with the Layout engine, the extended info window looks "no very nice". - Reading the battery status takes too long so put it into a thread or cache it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31484 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ACPIDriverInterface.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
|
||||||
|
RateBuffer::RateBuffer()
|
||||||
|
:
|
||||||
|
fPosition(0),
|
||||||
|
fSize(kRateBufferSize),
|
||||||
|
fCurrentSize(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RateBuffer::AddRate(int32 rate)
|
||||||
|
{
|
||||||
|
fRateBuffer[fPosition] = rate;
|
||||||
|
fPosition ++;
|
||||||
|
if (fPosition >= fSize)
|
||||||
|
fPosition = 0;
|
||||||
|
|
||||||
|
if (fCurrentSize < fSize)
|
||||||
|
fCurrentSize ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
RateBuffer::GetMeanRate()
|
||||||
|
{
|
||||||
|
int mean = 0;
|
||||||
|
for (int i = 0; i < fCurrentSize; i++) {
|
||||||
|
mean += fRateBuffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fCurrentSize == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return mean / fCurrentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Battery::Battery(int driverHandler)
|
||||||
|
:
|
||||||
|
fDriverHandler(driverHandler)
|
||||||
|
{
|
||||||
|
_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Battery::~Battery()
|
||||||
|
{
|
||||||
|
close(fDriverHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Battery::InitCheck()
|
||||||
|
{
|
||||||
|
return fInitStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Battery::GetBatteryInfo(battery_info* info)
|
||||||
|
{
|
||||||
|
acpi_battery_info acpiInfo;
|
||||||
|
status_t status;
|
||||||
|
status = ioctl(fDriverHandler, GET_BATTERY_INFO, &acpiInfo,
|
||||||
|
sizeof(acpi_battery_info));
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
info->state = acpiInfo.state;
|
||||||
|
info->current_rate = acpiInfo.current_rate;
|
||||||
|
info->capacity = acpiInfo.capacity;
|
||||||
|
info->full_capacity = fExtendedBatteryInfo.last_full_charge;
|
||||||
|
fRateBuffer.AddRate(acpiInfo.current_rate);
|
||||||
|
if (acpiInfo.current_rate > 0)
|
||||||
|
info->time_left = 3600 * acpiInfo.capacity / fRateBuffer.GetMeanRate();
|
||||||
|
else
|
||||||
|
info->time_left = -1;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Battery::GetExtendedBatteryInfo(acpi_extended_battery_info* info)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
status = ioctl(fDriverHandler, GET_EXTENDED_BATTERY_INFO, info,
|
||||||
|
sizeof(acpi_extended_battery_info));
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Battery::_Init()
|
||||||
|
{
|
||||||
|
uint32 magicId = 0;
|
||||||
|
fInitStatus = ioctl(fDriverHandler, IDENTIFY_DEVICE, &magicId,
|
||||||
|
sizeof(uint32));
|
||||||
|
if (fInitStatus != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fInitStatus = ioctl(fDriverHandler, GET_EXTENDED_BATTERY_INFO,
|
||||||
|
&fExtendedBatteryInfo, sizeof(acpi_extended_battery_info));
|
||||||
|
if (fInitStatus != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
acpi_battery_info info;
|
||||||
|
fInitStatus = ioctl(fDriverHandler, GET_BATTERY_INFO, &info,
|
||||||
|
sizeof(acpi_battery_info));
|
||||||
|
if (fInitStatus != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printf("ACPI driver found\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ACPIDriverInterface::~ACPIDriverInterface()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fDriverList.CountItems(); i++)
|
||||||
|
delete fDriverList.ItemAt(i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* kDriverDir = "/dev/power";
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ACPIDriverInterface::Connect()
|
||||||
|
{
|
||||||
|
printf("ACPI connect\n");
|
||||||
|
return _FindDrivers(kDriverDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ACPIDriverInterface::GetBatteryInfo(battery_info* info, int32 index)
|
||||||
|
{
|
||||||
|
BAutolock autolock(fBatteryStatusLock);
|
||||||
|
if (index < 0 || index >= fDriverList.CountItems())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status_t status;
|
||||||
|
status = fDriverList.ItemAt(index)->GetBatteryInfo(info);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ACPIDriverInterface::GetExtendedBatteryInfo(acpi_extended_battery_info* info,
|
||||||
|
int32 index)
|
||||||
|
{
|
||||||
|
BAutolock autolock(fBatteryStatusLock);
|
||||||
|
if (index < 0 || index >= fDriverList.CountItems())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
status_t status;
|
||||||
|
status = fDriverList.ItemAt(index)->GetExtendedBatteryInfo(info);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
ACPIDriverInterface::GetBatteryCount()
|
||||||
|
{
|
||||||
|
return fDriverList.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ACPIDriverInterface::_WatchPowerStatus()
|
||||||
|
{
|
||||||
|
const bigtime_t kUpdateInterval = 2000000;
|
||||||
|
// every two seconds
|
||||||
|
|
||||||
|
while (atomic_get(&fIsWatching) > 0) {
|
||||||
|
Broadcast(kMsgUpdate);
|
||||||
|
snooze(kUpdateInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ACPIDriverInterface::_FindDrivers(const char* path)
|
||||||
|
{
|
||||||
|
BDirectory dir(path);
|
||||||
|
BEntry entry;
|
||||||
|
|
||||||
|
status_t status = B_ERROR;
|
||||||
|
|
||||||
|
while (dir.GetNextEntry(&entry) == B_OK) {
|
||||||
|
BPath path;
|
||||||
|
entry.GetPath(&path);
|
||||||
|
|
||||||
|
if (entry.IsDirectory()) {
|
||||||
|
if (_FindDrivers(path.Path()) == B_OK)
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int32 handler = open(path.Path(), O_RDWR);
|
||||||
|
if (handler >= 0) {
|
||||||
|
printf("try %s\n", path.Path());
|
||||||
|
Battery* battery = new Battery(handler);
|
||||||
|
if (battery->InitCheck() == B_OK) {
|
||||||
|
fDriverList.AddItem(battery);
|
||||||
|
status = B_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delete battery;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ACPI_DRIVER_INTERFACE_H
|
||||||
|
#define ACPI_DRIVER_INTERFACE_H
|
||||||
|
|
||||||
|
#include "DriverInterface.h"
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
const int8 kRateBufferSize = 10;
|
||||||
|
|
||||||
|
class RateBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RateBuffer();
|
||||||
|
void AddRate(int32 rate);
|
||||||
|
int32 GetMeanRate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fRateBuffer[kRateBufferSize];
|
||||||
|
int8 fPosition;
|
||||||
|
int8 fSize;
|
||||||
|
int8 fCurrentSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Battery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Battery(int driverHandler);
|
||||||
|
~Battery();
|
||||||
|
|
||||||
|
status_t InitCheck();
|
||||||
|
|
||||||
|
status_t GetBatteryInfo(battery_info* info);
|
||||||
|
status_t GetExtendedBatteryInfo(
|
||||||
|
acpi_extended_battery_info* info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _Init();
|
||||||
|
|
||||||
|
|
||||||
|
int fDriverHandler;
|
||||||
|
status_t fInitStatus;
|
||||||
|
|
||||||
|
acpi_extended_battery_info fExtendedBatteryInfo;
|
||||||
|
|
||||||
|
RateBuffer fRateBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ACPIDriverInterface : public PowerStatusDriverInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ACPIDriverInterface();
|
||||||
|
|
||||||
|
virtual status_t Connect();
|
||||||
|
virtual status_t GetBatteryInfo(battery_info* info, int32 index);
|
||||||
|
virtual status_t GetExtendedBatteryInfo(
|
||||||
|
acpi_extended_battery_info* info, int32 index);
|
||||||
|
|
||||||
|
virtual int32 GetBatteryCount();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void _WatchPowerStatus();
|
||||||
|
virtual status_t _FindDrivers(const char* path);
|
||||||
|
|
||||||
|
BObjectList<Battery> fDriverList;
|
||||||
|
|
||||||
|
BLocker fBatteryStatusLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "APMDriverInterface.h"
|
||||||
|
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
# include <arch/x86/apm_defs.h>
|
||||||
|
# include <generic_syscall_defs.h>
|
||||||
|
# include <syscalls.h>
|
||||||
|
// temporary, as long as there is no real power state API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
const bigtime_t kUpdateInterval = 2000000;
|
||||||
|
// every two seconds
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
// definitions for the APM driver available for BeOS
|
||||||
|
enum {
|
||||||
|
APM_CONTROL = B_DEVICE_OP_CODES_END + 1,
|
||||||
|
APM_DUMP_POWER_STATUS,
|
||||||
|
APM_BIOS_CALL,
|
||||||
|
APM_SET_SAFETY
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BIOS_APM_GET_POWER_STATUS 0x530a
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
APMDriverInterface::~APMDriverInterface()
|
||||||
|
{
|
||||||
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
close(fDevice);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
APMDriverInterface::Connect()
|
||||||
|
{
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
uint32 version = 0;
|
||||||
|
status_t status = _kern_generic_syscall(APM_SYSCALLS, B_SYSCALL_INFO,
|
||||||
|
&version, sizeof(version));
|
||||||
|
if (status == B_OK) {
|
||||||
|
battery_info info;
|
||||||
|
status = _kern_generic_syscall(APM_SYSCALLS, APM_GET_BATTERY_INFO,
|
||||||
|
&info, sizeof(battery_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
|
||||||
|
#else
|
||||||
|
fDevice = open("/dev/misc/apm", O_RDONLY);
|
||||||
|
if (fDevice < 0) {
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
APMDriverInterface::GetBatteryInfo(battery_info* info, int32 index)
|
||||||
|
{
|
||||||
|
if (index != 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
info->current_rate = -1;
|
||||||
|
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
// TODO: retrieve data from APM kernel interface
|
||||||
|
apm_battery_info apmInfo;
|
||||||
|
status_t status = _kern_generic_syscall(APM_SYSCALLS, APM_GET_BATTERY_INFO,
|
||||||
|
&apmInfo, sizeof(apm_battery_info));
|
||||||
|
if (status == B_OK) {
|
||||||
|
info->state = apmInfo.online ? BATTERY_CHARGING : BATTERY_DISCHARGING;
|
||||||
|
info->capacity = apmInfo.percent;
|
||||||
|
info->full_capacity = 100;
|
||||||
|
info->time_left = apmInfo.time_left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
#else
|
||||||
|
if (fDevice < 0)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
uint16 regs[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
regs[0] = BIOS_APM_GET_POWER_STATUS;
|
||||||
|
regs[1] = 0x1;
|
||||||
|
if (ioctl(fDevice, APM_BIOS_CALL, regs) == 0) {
|
||||||
|
bool online = (regs[1] >> 8) != 0 && (regs[1] >> 8) != 2;
|
||||||
|
info->state = online ? BATTERY_CHARGING : BATTERY_DISCHARGING;
|
||||||
|
info->capacity = regs[2] & 255;
|
||||||
|
if (info->capacity > 100)
|
||||||
|
info->capacity = -1;
|
||||||
|
info->full_capacity = 100;
|
||||||
|
info->time_left = info->capacity >= 0 ? regs[3] : -1;
|
||||||
|
if (info->time_left > 0xffff)
|
||||||
|
info->time_left = -1;
|
||||||
|
else if (info->time_left & 0x8000)
|
||||||
|
info->time_left = (info->time_left & 0x7fff) * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
APMDriverInterface::GetExtendedBatteryInfo(acpi_extended_battery_info* info,
|
||||||
|
int32 index)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
APMDriverInterface::GetBatteryCount()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
APMDriverInterface::_WatchPowerStatus()
|
||||||
|
{
|
||||||
|
while (atomic_get(&fIsWatching) > 0) {
|
||||||
|
Broadcast(kMsgUpdate);
|
||||||
|
snooze(kUpdateInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APM_DRIVER_INTERFACE_H
|
||||||
|
#define APM_DRIVER_INTERFACE_H
|
||||||
|
|
||||||
|
#include "DriverInterface.h"
|
||||||
|
|
||||||
|
|
||||||
|
class APMDriverInterface : public PowerStatusDriverInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~APMDriverInterface();
|
||||||
|
|
||||||
|
virtual status_t Connect();
|
||||||
|
virtual status_t GetBatteryInfo(battery_info* info, int32 index);
|
||||||
|
virtual status_t GetExtendedBatteryInfo(acpi_extended_battery_info* info,
|
||||||
|
int32 index);
|
||||||
|
virtual int32 GetBatteryCount();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void _WatchPowerStatus();
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
int fDevice;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "DriverInterface.h"
|
||||||
|
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
|
||||||
|
|
||||||
|
Monitor::~Monitor()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Monitor::StartWatching(BHandler* target)
|
||||||
|
{
|
||||||
|
if (fWatcherList.HasItem(target))
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
fWatcherList.AddItem(target);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Monitor::StopWatching(BHandler* target)
|
||||||
|
{
|
||||||
|
return fWatcherList.RemoveItem(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Monitor::Broadcast(uint32 message)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fWatcherList.CountItems(); i++)
|
||||||
|
{
|
||||||
|
BMessenger messenger(fWatcherList.ItemAt(i));
|
||||||
|
messenger.SendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusDriverInterface::PowerStatusDriverInterface()
|
||||||
|
:
|
||||||
|
fIsWatching(0),
|
||||||
|
fThreadId(-1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerStatusDriverInterface::~PowerStatusDriverInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
status_t
|
||||||
|
PowerStatusDriverInterface::StartWatching(BHandler* target)
|
||||||
|
{
|
||||||
|
BAutolock autolock(fListLocker);
|
||||||
|
|
||||||
|
status_t status = Monitor::StartWatching(target);
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (fThreadId > 0)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
printf("spawn\n");
|
||||||
|
fThreadId = spawn_thread(&_ThreadWatchPowerFunction, "PowerStatusThread",
|
||||||
|
B_LOW_PRIORITY, this);
|
||||||
|
if (fThreadId >= 0) {
|
||||||
|
atomic_set(&fIsWatching, 1);
|
||||||
|
status = resume_thread(fThreadId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return fThreadId;
|
||||||
|
|
||||||
|
if (status != B_OK && fWatcherList.CountItems() == 0) {
|
||||||
|
atomic_set(&fIsWatching, 0);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PowerStatusDriverInterface::StopWatching(BHandler* target)
|
||||||
|
{
|
||||||
|
BAutolock autolock(fListLocker);
|
||||||
|
|
||||||
|
if (fThreadId < 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
status_t status;
|
||||||
|
if (fWatcherList.CountItems() == 1) {
|
||||||
|
atomic_set(&fIsWatching, 0);
|
||||||
|
|
||||||
|
status = wait_for_thread(fThreadId, &status);
|
||||||
|
fThreadId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Monitor::StopWatching(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusDriverInterface::Disconnect()
|
||||||
|
{
|
||||||
|
atomic_set(&fIsWatching, 0);
|
||||||
|
status_t status;
|
||||||
|
wait_for_thread(fThreadId, &status);
|
||||||
|
fThreadId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
PowerStatusDriverInterface::_ThreadWatchPowerFunction(void* data)
|
||||||
|
{
|
||||||
|
PowerStatusDriverInterface* that = (PowerStatusDriverInterface*)data;
|
||||||
|
that->_WatchPowerStatus();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DRIVER_INTERFACE_H
|
||||||
|
#define DRIVER_INTERFACE_H
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <ObjectList.h>
|
||||||
|
#include <Handler.h>
|
||||||
|
|
||||||
|
#include "device/power_managment.h"
|
||||||
|
|
||||||
|
typedef BObjectList<BHandler> WatcherList;
|
||||||
|
|
||||||
|
const uint32 kMsgUpdate = 'updt';
|
||||||
|
|
||||||
|
|
||||||
|
struct battery_info
|
||||||
|
{
|
||||||
|
int8 state;
|
||||||
|
int32 capacity;
|
||||||
|
int32 full_capacity;
|
||||||
|
time_t time_left;
|
||||||
|
int32 current_rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*! Handle a list of watcher and broadcast a messages to them. */
|
||||||
|
class Monitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Monitor();
|
||||||
|
|
||||||
|
virtual status_t StartWatching(BHandler* target);
|
||||||
|
virtual status_t StopWatching(BHandler* target);
|
||||||
|
|
||||||
|
virtual void Broadcast(uint32 message);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
WatcherList fWatcherList;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PowerStatusDriverInterface : public Monitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PowerStatusDriverInterface();
|
||||||
|
~PowerStatusDriverInterface();
|
||||||
|
virtual status_t StartWatching(BHandler* target);
|
||||||
|
virtual status_t StopWatching(BHandler* target);
|
||||||
|
|
||||||
|
virtual status_t Connect() = 0;
|
||||||
|
virtual void Disconnect();
|
||||||
|
|
||||||
|
virtual status_t GetBatteryInfo(battery_info* status, int32 index) = 0;
|
||||||
|
virtual status_t GetExtendedBatteryInfo(acpi_extended_battery_info* info,
|
||||||
|
int32 index) = 0;
|
||||||
|
|
||||||
|
virtual int32 GetBatteryCount() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void _WatchPowerStatus() = 0;
|
||||||
|
|
||||||
|
vint32 fIsWatching;
|
||||||
|
private:
|
||||||
|
static int32 _ThreadWatchPowerFunction(void* data);
|
||||||
|
|
||||||
|
thread_id fThreadId;
|
||||||
|
|
||||||
|
BLocker fListLocker;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ExtendedInfoWindow.h"
|
||||||
|
|
||||||
|
#include <Box.h>
|
||||||
|
#include <GroupLayout.h>
|
||||||
|
#include <GroupView.h>
|
||||||
|
#include <SpaceLayoutItem.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
BatteryInfoView::BatteryInfoView(BRect frame, int32 resizingMode)
|
||||||
|
:
|
||||||
|
BView(frame, "battery info view", resizingMode, B_WILL_DRAW |
|
||||||
|
B_FULL_UPDATE_ON_RESIZE)
|
||||||
|
{
|
||||||
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BatteryInfoView::Update(battery_info& info, acpi_extended_battery_info& extInfo)
|
||||||
|
{
|
||||||
|
fBatteryInfo = info;
|
||||||
|
fBatteryExtendedInfo = extInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BatteryInfoView::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
|
BString powerUnit;
|
||||||
|
BString rateUnit;
|
||||||
|
switch (fBatteryExtendedInfo.power_unit) {
|
||||||
|
case 0:
|
||||||
|
powerUnit = " mWh";
|
||||||
|
rateUnit = " mW";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
powerUnit = " mAh";
|
||||||
|
rateUnit = " mA";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BString text;
|
||||||
|
if (fBatteryInfo.state & BATTERY_CHARGING)
|
||||||
|
text = "Battery charging";
|
||||||
|
else if (fBatteryInfo.state & BATTERY_DISCHARGING)
|
||||||
|
text = "Battery discharging";
|
||||||
|
else if (fBatteryInfo.state & BATTERY_CRITICAL_STATE)
|
||||||
|
text = "Empty Battery Slot";
|
||||||
|
else
|
||||||
|
text = "Battery unused";
|
||||||
|
BPoint point(10, 10);
|
||||||
|
int textHeight = 15;
|
||||||
|
int space = textHeight + 5;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Capacity: ";
|
||||||
|
text << fBatteryInfo.capacity;
|
||||||
|
text << powerUnit;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Last full Charge: ";
|
||||||
|
text << fBatteryInfo.full_capacity;
|
||||||
|
text << powerUnit;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Current Rate: ";
|
||||||
|
text << fBatteryInfo.current_rate;
|
||||||
|
text << rateUnit;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Design Capacity: ";
|
||||||
|
text << fBatteryExtendedInfo.design_capacity;
|
||||||
|
text << powerUnit;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Technology: ";
|
||||||
|
text << fBatteryExtendedInfo.technology;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Design Voltage: ";
|
||||||
|
text << fBatteryExtendedInfo.design_voltage;
|
||||||
|
text << " mV";
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Design Capacity Warning: ";
|
||||||
|
text << fBatteryExtendedInfo.design_capacity_warning;
|
||||||
|
text << powerUnit;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Design Capacity low Warning: ";
|
||||||
|
text << fBatteryExtendedInfo.design_capacity_low;
|
||||||
|
text << powerUnit;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Capacity Granularity 1: ";
|
||||||
|
text << fBatteryExtendedInfo.capacity_granularity_1;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Capacity Granularity 2: ";
|
||||||
|
text << fBatteryExtendedInfo.capacity_granularity_2;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Model Number: ";
|
||||||
|
text << fBatteryExtendedInfo.model_number;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Serial number: ";
|
||||||
|
text << fBatteryExtendedInfo.serial_number;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "Type: ";
|
||||||
|
text += fBatteryExtendedInfo.type;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
text = "OEM Info: ";
|
||||||
|
text += fBatteryExtendedInfo.oem_info;
|
||||||
|
DrawString(text.String(), point);
|
||||||
|
point.y += space;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExtPowerStatusView::ExtPowerStatusView(PowerStatusDriverInterface* interface,
|
||||||
|
BRect frame, int32 resizingMode, int batteryId,
|
||||||
|
ExtendedInfoWindow* window)
|
||||||
|
:
|
||||||
|
PowerStatusView(interface, frame, resizingMode, batteryId),
|
||||||
|
fExtendedInfoWindow(window),
|
||||||
|
fBatteryInfoView(window->GetExtendedBatteryInfoView()),
|
||||||
|
fSelected(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtPowerStatusView::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
if (fSelected) {
|
||||||
|
SetLowColor(102, 152, 203);
|
||||||
|
SetHighColor(102, 152, 203);
|
||||||
|
FillRect(updateRect);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
FillRect(updateRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerStatusView::Draw(updateRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtPowerStatusView::MouseDown(BPoint where)
|
||||||
|
{
|
||||||
|
if (!fSelected) {
|
||||||
|
fSelected = true;
|
||||||
|
_Update(true);
|
||||||
|
fExtendedInfoWindow->BatterySelected(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtPowerStatusView::Select(bool select)
|
||||||
|
{
|
||||||
|
fSelected = select;
|
||||||
|
_Update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ExtPowerStatusView::IsValid()
|
||||||
|
{
|
||||||
|
if (fBatteryInfo.state & BATTERY_CRITICAL_STATE)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtPowerStatusView::_Update(bool force)
|
||||||
|
{
|
||||||
|
PowerStatusView::_Update(force);
|
||||||
|
if (!fSelected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
acpi_extended_battery_info extInfo;
|
||||||
|
fDriverInterface->GetExtendedBatteryInfo(&extInfo, fBatteryId);
|
||||||
|
|
||||||
|
fBatteryInfoView->Update(fBatteryInfo, extInfo);
|
||||||
|
fBatteryInfoView->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExtendedInfoWindow::ExtendedInfoWindow(PowerStatusDriverInterface* interface)
|
||||||
|
:
|
||||||
|
BWindow(BRect(100, 150, 500, 500), "Extended Battery Info", B_TITLED_WINDOW,
|
||||||
|
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS),
|
||||||
|
fDriverInterface(interface),
|
||||||
|
fSelectedView(NULL)
|
||||||
|
{
|
||||||
|
BView *view = new BView(Bounds(), "view", B_FOLLOW_ALL, 0);
|
||||||
|
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
AddChild(view);
|
||||||
|
|
||||||
|
BGroupLayout* mainLayout = new BGroupLayout(B_VERTICAL);
|
||||||
|
mainLayout->SetSpacing(10);
|
||||||
|
mainLayout->SetInsets(10, 10, 10, 10);
|
||||||
|
view->SetLayout(mainLayout);
|
||||||
|
|
||||||
|
BRect rect = Bounds();
|
||||||
|
rect.InsetBy(5, 5);
|
||||||
|
BBox *infoBox = new BBox(rect, "Power Status Box");
|
||||||
|
infoBox->SetLabel("Battery Info");
|
||||||
|
BGroupLayout* infoLayout = new BGroupLayout(B_HORIZONTAL);
|
||||||
|
infoLayout->SetInsets(10, infoBox->TopBorderOffset() * 2 + 10, 10, 10);
|
||||||
|
infoLayout->SetSpacing(10);
|
||||||
|
infoBox->SetLayout(infoLayout);
|
||||||
|
mainLayout->AddView(infoBox);
|
||||||
|
|
||||||
|
BGroupView* batteryView = new BGroupView(B_VERTICAL);
|
||||||
|
batteryView->GroupLayout()->SetSpacing(10);
|
||||||
|
infoLayout->AddView(batteryView);
|
||||||
|
|
||||||
|
fBatteryInfoView = new BatteryInfoView(BRect(0, 0, 270, 310), B_FOLLOW_ALL);
|
||||||
|
|
||||||
|
BGroupLayout* batteryLayout = batteryView->GroupLayout();
|
||||||
|
BRect batteryRect(0, 0, 50, 30);
|
||||||
|
for (int i = 0; i < interface->GetBatteryCount(); i++) {
|
||||||
|
ExtPowerStatusView* view = new ExtPowerStatusView(interface,
|
||||||
|
batteryRect, B_FOLLOW_ALL, i, this);
|
||||||
|
batteryLayout->AddView(view);
|
||||||
|
fBatteryViewList.AddItem(view);
|
||||||
|
fDriverInterface->StartWatching(view);
|
||||||
|
if (view->IsValid())
|
||||||
|
fSelectedView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
batteryLayout->AddItem(BSpaceLayoutItem::CreateGlue());
|
||||||
|
|
||||||
|
infoLayout->AddView(fBatteryInfoView, 20);
|
||||||
|
|
||||||
|
if (!fSelectedView && fBatteryViewList.CountItems() > 0)
|
||||||
|
fSelectedView = fBatteryViewList.ItemAt(0);
|
||||||
|
fSelectedView->Select();
|
||||||
|
|
||||||
|
BSize size = mainLayout->PreferredSize();
|
||||||
|
ResizeTo(size.width, size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExtendedInfoWindow::~ExtendedInfoWindow()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fBatteryViewList.CountItems(); i++) {
|
||||||
|
fDriverInterface->StopWatching(fBatteryViewList.ItemAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BatteryInfoView*
|
||||||
|
ExtendedInfoWindow::GetExtendedBatteryInfoView()
|
||||||
|
{
|
||||||
|
return fBatteryInfoView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ExtendedInfoWindow::BatterySelected(ExtPowerStatusView* view)
|
||||||
|
{
|
||||||
|
if (fSelectedView) {
|
||||||
|
fSelectedView->Select(false);
|
||||||
|
fSelectedView->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
fSelectedView = view;
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EXTENDED_INFO_WINDOW_H
|
||||||
|
#define EXTENDED_INFO_WINDOW_H
|
||||||
|
|
||||||
|
#include <ObjectList.h>
|
||||||
|
#include <StringView.h>
|
||||||
|
#include <View.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "DriverInterface.h"
|
||||||
|
#include "PowerStatusView.h"
|
||||||
|
|
||||||
|
|
||||||
|
class BatteryInfoView : public BView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BatteryInfoView(BRect frame, int32 resizingMode);
|
||||||
|
|
||||||
|
virtual void Update(battery_info& info,
|
||||||
|
acpi_extended_battery_info& extInfo);
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
|
||||||
|
private:
|
||||||
|
battery_info fBatteryInfo;
|
||||||
|
acpi_extended_battery_info fBatteryExtendedInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ExtendedInfoWindow;
|
||||||
|
|
||||||
|
class ExtPowerStatusView : public PowerStatusView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExtPowerStatusView(PowerStatusDriverInterface* interface,
|
||||||
|
BRect frame, int32 resizingMode, int batteryId,
|
||||||
|
ExtendedInfoWindow* window);
|
||||||
|
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
virtual void MouseDown(BPoint where);
|
||||||
|
|
||||||
|
virtual void Select(bool select = true);
|
||||||
|
|
||||||
|
// return true if it battery is in a none critical state
|
||||||
|
virtual bool IsValid();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void _Update(bool force = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ExtendedInfoWindow* fExtendedInfoWindow;
|
||||||
|
BatteryInfoView* fBatteryInfoView;
|
||||||
|
|
||||||
|
bool fSelected;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ExtendedInfoWindow : public BWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExtendedInfoWindow(PowerStatusDriverInterface* interface);
|
||||||
|
~ExtendedInfoWindow();
|
||||||
|
|
||||||
|
BatteryInfoView* GetExtendedBatteryInfoView();
|
||||||
|
|
||||||
|
void BatterySelected(ExtPowerStatusView* view);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PowerStatusDriverInterface* fDriverInterface;
|
||||||
|
BObjectList<ExtPowerStatusView> fBatteryViewList;
|
||||||
|
|
||||||
|
BatteryInfoView* fBatteryInfoView;
|
||||||
|
|
||||||
|
ExtPowerStatusView* fSelectedView;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -6,6 +6,10 @@ UsePrivateHeaders shared ;
|
|||||||
UsePrivateSystemHeaders ;
|
UsePrivateSystemHeaders ;
|
||||||
|
|
||||||
Application PowerStatus :
|
Application PowerStatus :
|
||||||
|
ACPIDriverInterface.cpp
|
||||||
|
APMDriverInterface.cpp
|
||||||
|
DriverInterface.cpp
|
||||||
|
ExtendedInfoWindow.cpp
|
||||||
PowerStatusWindow.cpp
|
PowerStatusWindow.cpp
|
||||||
PowerStatusView.cpp
|
PowerStatusView.cpp
|
||||||
PowerStatus.cpp
|
PowerStatus.cpp
|
||||||
|
|||||||
@@ -12,4 +12,5 @@
|
|||||||
extern const char* kSignature;
|
extern const char* kSignature;
|
||||||
extern const char* kDeskbarItemName;
|
extern const char* kDeskbarItemName;
|
||||||
|
|
||||||
|
|
||||||
#endif // POWER_STATUS_H
|
#endif // POWER_STATUS_H
|
||||||
|
|||||||
@@ -4,19 +4,13 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "PowerStatusView.h"
|
#include "PowerStatusView.h"
|
||||||
#include "PowerStatus.h"
|
#include "PowerStatus.h"
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
|
||||||
# include <arch/x86/apm_defs.h>
|
|
||||||
# include <generic_syscall_defs.h>
|
|
||||||
# include <syscalls.h>
|
|
||||||
// temporary, as long as there is no real power state API
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Deskbar.h>
|
#include <Deskbar.h>
|
||||||
@@ -32,52 +26,34 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "ACPIDriverInterface.h"
|
||||||
|
#include "APMDriverInterface.h"
|
||||||
|
#include "ExtendedInfoWindow.h"
|
||||||
|
|
||||||
|
|
||||||
extern "C" _EXPORT BView *instantiate_deskbar_item(void);
|
extern "C" _EXPORT BView *instantiate_deskbar_item(void);
|
||||||
|
|
||||||
|
|
||||||
const uint32 kMsgUpdate = 'updt';
|
|
||||||
const uint32 kMsgToggleLabel = 'tglb';
|
const uint32 kMsgToggleLabel = 'tglb';
|
||||||
const uint32 kMsgToggleTime = 'tgtm';
|
const uint32 kMsgToggleTime = 'tgtm';
|
||||||
const uint32 kMsgToggleStatusIcon = 'tgsi';
|
const uint32 kMsgToggleStatusIcon = 'tgsi';
|
||||||
|
const uint32 kMsgToggleExtInfo = 'texi';
|
||||||
|
|
||||||
const uint32 kMinIconWidth = 16;
|
const uint32 kMinIconWidth = 16;
|
||||||
const uint32 kMinIconHeight = 16;
|
const uint32 kMinIconHeight = 16;
|
||||||
|
|
||||||
const bigtime_t kUpdateInterval = 2000000;
|
|
||||||
// every two seconds
|
|
||||||
|
|
||||||
|
PowerStatusView::PowerStatusView(PowerStatusDriverInterface* interface,
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
BRect frame, int32 resizingMode, int batteryId, bool inDeskbar)
|
||||||
// definitions for the APM driver available for BeOS
|
:
|
||||||
enum {
|
BView(frame, kDeskbarItemName, resizingMode,
|
||||||
APM_CONTROL = B_DEVICE_OP_CODES_END + 1,
|
|
||||||
APM_DUMP_POWER_STATUS,
|
|
||||||
APM_BIOS_CALL,
|
|
||||||
APM_SET_SAFETY
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BIOS_APM_GET_POWER_STATUS 0x530a
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
PowerStatusView::PowerStatusView(BRect frame, int32 resizingMode, bool inDeskbar)
|
|
||||||
: BView(frame, kDeskbarItemName, resizingMode,
|
|
||||||
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
|
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
|
||||||
|
fDriverInterface(interface),
|
||||||
|
fBatteryId(batteryId),
|
||||||
fInDeskbar(inDeskbar)
|
fInDeskbar(inDeskbar)
|
||||||
{
|
{
|
||||||
|
fPreferredSize.width = frame.Width();
|
||||||
|
fPreferredSize.height = frame.Height();
|
||||||
_Init();
|
_Init();
|
||||||
|
|
||||||
if (!inDeskbar) {
|
|
||||||
// we were obviously added to a standard window - let's add a dragger
|
|
||||||
frame.OffsetTo(B_ORIGIN);
|
|
||||||
frame.top = frame.bottom - 7;
|
|
||||||
frame.left = frame.right - 7;
|
|
||||||
BDragger* dragger = new BDragger(frame, this,
|
|
||||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
|
||||||
AddChild(dragger);
|
|
||||||
} else
|
|
||||||
_Update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -93,14 +69,33 @@ PowerStatusView::PowerStatusView(BMessage* archive)
|
|||||||
fShowStatusIcon = value;
|
fShowStatusIcon = value;
|
||||||
if (archive->FindBool("show time", &value) == B_OK)
|
if (archive->FindBool("show time", &value) == B_OK)
|
||||||
fShowTime = value;
|
fShowTime = value;
|
||||||
|
int32 intValue;
|
||||||
|
if (archive->FindInt32("battery id", &intValue) == B_OK)
|
||||||
|
fBatteryId = intValue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PowerStatusView::~PowerStatusView()
|
PowerStatusView::~PowerStatusView()
|
||||||
{
|
{
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
|
||||||
close(fDevice);
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PowerStatusView::Archive(BMessage* archive, bool deep) const
|
||||||
|
{
|
||||||
|
status_t status = BView::Archive(archive, deep);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddBool("show label", fShowLabel);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddBool("show icon", fShowStatusIcon);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddBool("show time", fShowTime);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddInt32("battery id", fBatteryId);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,72 +106,10 @@ PowerStatusView::_Init()
|
|||||||
fShowTime = false;
|
fShowTime = false;
|
||||||
fShowStatusIcon = true;
|
fShowStatusIcon = true;
|
||||||
|
|
||||||
fMessageRunner = NULL;
|
|
||||||
fPercent = -1;
|
fPercent = -1;
|
||||||
fOnline = true;
|
fOnline = true;
|
||||||
fTimeLeft = 0;
|
fTimeLeft = 0;
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
|
||||||
uint32 version = 0;
|
|
||||||
status_t status = _kern_generic_syscall(APM_SYSCALLS, B_SYSCALL_INFO,
|
|
||||||
&version, sizeof(version));
|
|
||||||
if (status == B_OK) {
|
|
||||||
battery_info info;
|
|
||||||
status = _kern_generic_syscall(APM_SYSCALLS, APM_GET_BATTERY_INFO, &info,
|
|
||||||
sizeof(battery_info));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != B_OK) {
|
|
||||||
fprintf(stderr, "No power interface found.\n");
|
|
||||||
_Quit();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
fDevice = open("/dev/misc/apm", O_RDONLY);
|
|
||||||
if (fDevice < 0) {
|
|
||||||
fprintf(stderr, "No power interface found.\n");
|
|
||||||
_Quit();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PowerStatusView::_Quit()
|
|
||||||
{
|
|
||||||
if (fInDeskbar) {
|
|
||||||
BDeskbar deskbar;
|
|
||||||
deskbar.RemoveItem(kDeskbarItemName);
|
|
||||||
} else
|
|
||||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PowerStatusView *
|
|
||||||
PowerStatusView::Instantiate(BMessage* archive)
|
|
||||||
{
|
|
||||||
if (!validate_instantiation(archive, "PowerStatusView"))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return new PowerStatusView(archive);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
PowerStatusView::Archive(BMessage* archive, bool deep) const
|
|
||||||
{
|
|
||||||
status_t status = BView::Archive(archive, deep);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = archive->AddString("add_on", kSignature);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = archive->AddString("class", "PowerStatusView");
|
|
||||||
if (status == B_OK)
|
|
||||||
status = archive->AddBool("show label", fShowLabel);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = archive->AddBool("show icon", fShowStatusIcon);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = archive->AddBool("show time", fShowTime);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -191,9 +124,6 @@ PowerStatusView::AttachedToWindow()
|
|||||||
|
|
||||||
SetLowColor(ViewColor());
|
SetLowColor(ViewColor());
|
||||||
|
|
||||||
BMessage update(kMsgUpdate);
|
|
||||||
fMessageRunner = new BMessageRunner(this, &update, kUpdateInterval);
|
|
||||||
|
|
||||||
_Update();
|
_Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +131,7 @@ PowerStatusView::AttachedToWindow()
|
|||||||
void
|
void
|
||||||
PowerStatusView::DetachedFromWindow()
|
PowerStatusView::DetachedFromWindow()
|
||||||
{
|
{
|
||||||
delete fMessageRunner;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -213,35 +143,20 @@ PowerStatusView::MessageReceived(BMessage *message)
|
|||||||
_Update();
|
_Update();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kMsgToggleLabel:
|
|
||||||
fShowLabel = !fShowLabel;
|
|
||||||
_Update(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMsgToggleTime:
|
|
||||||
fShowTime = !fShowTime;
|
|
||||||
_Update(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kMsgToggleStatusIcon:
|
|
||||||
fShowStatusIcon = !fShowStatusIcon;
|
|
||||||
_Update(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_ABOUT_REQUESTED:
|
|
||||||
_AboutRequested();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case B_QUIT_REQUESTED:
|
|
||||||
_Quit();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BView::MessageReceived(message);
|
BView::MessageReceived(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::GetPreferredSize(float *width, float *height)
|
||||||
|
{
|
||||||
|
*width = fPreferredSize.width;
|
||||||
|
*height = fPreferredSize.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PowerStatusView::_DrawBattery(BRect rect)
|
PowerStatusView::_DrawBattery(BRect rect)
|
||||||
{
|
{
|
||||||
@@ -261,8 +176,7 @@ PowerStatusView::_DrawBattery(BRect rect)
|
|||||||
gap = 2;
|
gap = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fOnline)
|
SetHighColor(92, 92, 92);
|
||||||
SetHighColor(92, 92, 92);
|
|
||||||
|
|
||||||
StrokeRect(rect);
|
StrokeRect(rect);
|
||||||
|
|
||||||
@@ -277,6 +191,8 @@ PowerStatusView::_DrawBattery(BRect rect)
|
|||||||
if (percent > 0) {
|
if (percent > 0) {
|
||||||
if (percent < 16)
|
if (percent < 16)
|
||||||
SetHighColor(180, 0, 0);
|
SetHighColor(180, 0, 0);
|
||||||
|
else
|
||||||
|
SetHighColor(20, 180, 0);
|
||||||
|
|
||||||
rect.InsetBy(gap + 1, gap + 1);
|
rect.InsetBy(gap + 1, gap + 1);
|
||||||
if (gap > 1) {
|
if (gap > 1) {
|
||||||
@@ -358,53 +274,6 @@ PowerStatusView::Draw(BRect updateRect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PowerStatusView::MouseDown(BPoint point)
|
|
||||||
{
|
|
||||||
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
|
||||||
menu->SetFont(be_plain_font);
|
|
||||||
|
|
||||||
BMenuItem* item;
|
|
||||||
menu->AddItem(item = new BMenuItem("Show Text Label", new BMessage(kMsgToggleLabel)));
|
|
||||||
if (fShowLabel)
|
|
||||||
item->SetMarked(true);
|
|
||||||
menu->AddItem(item = new BMenuItem("Show Status Icon",
|
|
||||||
new BMessage(kMsgToggleStatusIcon)));
|
|
||||||
if (fShowStatusIcon)
|
|
||||||
item->SetMarked(true);
|
|
||||||
menu->AddItem(new BMenuItem(!fShowTime ? "Show Time" : "Show Percent",
|
|
||||||
new BMessage(kMsgToggleTime)));
|
|
||||||
|
|
||||||
menu->AddSeparatorItem();
|
|
||||||
menu->AddItem(new BMenuItem("About" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED)));
|
|
||||||
menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED)));
|
|
||||||
menu->SetTargetForItems(this);
|
|
||||||
|
|
||||||
ConvertToScreen(&point);
|
|
||||||
menu->Go(point, true, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PowerStatusView::_AboutRequested()
|
|
||||||
{
|
|
||||||
BAlert *alert = new BAlert("about", "PowerStatus\n"
|
|
||||||
"\twritten by Axel Dörfler\n"
|
|
||||||
"\tCopyright 2006, Haiku, Inc.\n", "Ok");
|
|
||||||
BTextView *view = alert->TextView();
|
|
||||||
BFont font;
|
|
||||||
|
|
||||||
view->SetStylable(true);
|
|
||||||
|
|
||||||
view->GetFont(&font);
|
|
||||||
font.SetSize(18);
|
|
||||||
font.SetFace(B_BOLD_FACE);
|
|
||||||
view->SetFontAndColor(0, 11, &font);
|
|
||||||
|
|
||||||
alert->Go();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PowerStatusView::_SetLabel(char* buffer, size_t bufferLength)
|
PowerStatusView::_SetLabel(char* buffer, size_t bufferLength)
|
||||||
{
|
{
|
||||||
@@ -432,6 +301,7 @@ PowerStatusView::_SetLabel(char* buffer, size_t bufferLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PowerStatusView::_Update(bool force)
|
PowerStatusView::_Update(bool force)
|
||||||
{
|
{
|
||||||
@@ -439,36 +309,15 @@ PowerStatusView::_Update(bool force)
|
|||||||
bool previousTimeLeft = fTimeLeft;
|
bool previousTimeLeft = fTimeLeft;
|
||||||
bool wasOnline = fOnline;
|
bool wasOnline = fOnline;
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
_GetBatteryInfo(&fBatteryInfo, fBatteryId);
|
||||||
// TODO: retrieve data from APM/ACPI kernel interface
|
|
||||||
battery_info info;
|
|
||||||
status_t status = _kern_generic_syscall(APM_SYSCALLS, APM_GET_BATTERY_INFO, &info,
|
|
||||||
sizeof(battery_info));
|
|
||||||
if (status == B_OK) {
|
|
||||||
fPercent = info.percent;
|
|
||||||
fTimeLeft = info.time_left;
|
|
||||||
fOnline = info.online;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (fDevice < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint16 regs[6] = {0, 0, 0, 0, 0, 0};
|
|
||||||
regs[0] = BIOS_APM_GET_POWER_STATUS;
|
|
||||||
regs[1] = 0x1;
|
|
||||||
if (ioctl(fDevice, APM_BIOS_CALL, regs) == 0) {
|
|
||||||
fOnline = (regs[1] >> 8) != 0 && (regs[1] >> 8) != 2;
|
|
||||||
fPercent = regs[2] & 255;
|
|
||||||
if (fPercent > 100)
|
|
||||||
fPercent = -1;
|
|
||||||
fTimeLeft = fPercent >= 0 ? regs[3] : -1;
|
|
||||||
if (fTimeLeft > 0xffff)
|
|
||||||
fTimeLeft = -1;
|
|
||||||
else if (fTimeLeft & 0x8000)
|
|
||||||
fTimeLeft = (fTimeLeft & 0x7fff) * 60;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
fPercent = (100 * fBatteryInfo.capacity) / fBatteryInfo.full_capacity;
|
||||||
|
fTimeLeft = fBatteryInfo.time_left;
|
||||||
|
if (fBatteryInfo.state & BATTERY_CHARGING)
|
||||||
|
fOnline = true;
|
||||||
|
else
|
||||||
|
fOnline = false;
|
||||||
|
|
||||||
if (fInDeskbar) {
|
if (fInDeskbar) {
|
||||||
// make sure the tray icon is large enough
|
// make sure the tray icon is large enough
|
||||||
float width = fShowStatusIcon ? kMinIconWidth + 2 : 0;
|
float width = fShowStatusIcon ? kMinIconWidth + 2 : 0;
|
||||||
@@ -496,12 +345,242 @@ PowerStatusView::_Update(bool force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::_GetBatteryInfo(battery_info* batteryInfo, int batteryId)
|
||||||
|
{
|
||||||
|
if (batteryId >= 0) {
|
||||||
|
fDriverInterface->GetBatteryInfo(batteryInfo, batteryId);
|
||||||
|
}
|
||||||
|
else for (int i = 0; i < fDriverInterface->GetBatteryCount(); i++) {
|
||||||
|
battery_info tmpInfo;
|
||||||
|
fDriverInterface->GetBatteryInfo(&tmpInfo, i);
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
*batteryInfo = tmpInfo;
|
||||||
|
else {
|
||||||
|
batteryInfo->state &= tmpInfo.state;
|
||||||
|
batteryInfo->capacity += tmpInfo.capacity;
|
||||||
|
batteryInfo->full_capacity += tmpInfo.full_capacity;
|
||||||
|
batteryInfo->time_left += tmpInfo.time_left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusReplicant::PowerStatusReplicant(BRect frame, int32 resizingMode,
|
||||||
|
bool inDeskbar)
|
||||||
|
:
|
||||||
|
PowerStatusView(NULL, frame, resizingMode, -1, inDeskbar)
|
||||||
|
{
|
||||||
|
_Init();
|
||||||
|
|
||||||
|
if (!inDeskbar) {
|
||||||
|
// we were obviously added to a standard window - let's add a dragger
|
||||||
|
frame.OffsetTo(B_ORIGIN);
|
||||||
|
frame.top = frame.bottom - 7;
|
||||||
|
frame.left = frame.right - 7;
|
||||||
|
BDragger* dragger = new BDragger(frame, this,
|
||||||
|
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||||
|
AddChild(dragger);
|
||||||
|
} else
|
||||||
|
_Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusReplicant::PowerStatusReplicant(BMessage* archive)
|
||||||
|
:
|
||||||
|
PowerStatusView(archive)
|
||||||
|
{
|
||||||
|
_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusReplicant::~PowerStatusReplicant()
|
||||||
|
{
|
||||||
|
if (fExtWindowMessenger)
|
||||||
|
delete fExtWindowMessenger;
|
||||||
|
|
||||||
|
fDriverInterface->StopWatching(this);
|
||||||
|
fDriverInterface->Disconnect();
|
||||||
|
delete fDriverInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusReplicant*
|
||||||
|
PowerStatusReplicant::Instantiate(BMessage* archive)
|
||||||
|
{
|
||||||
|
if (!validate_instantiation(archive, "PowerStatusReplicant"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return new PowerStatusReplicant(archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PowerStatusReplicant::Archive(BMessage* archive, bool deep) const
|
||||||
|
{
|
||||||
|
status_t status = PowerStatusView::Archive(archive, deep);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddString("add_on", kSignature);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddString("class", "PowerStatusReplicant");
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusReplicant::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case kMsgToggleLabel:
|
||||||
|
fShowLabel = !fShowLabel;
|
||||||
|
_Update(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMsgToggleTime:
|
||||||
|
fShowTime = !fShowTime;
|
||||||
|
_Update(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMsgToggleStatusIcon:
|
||||||
|
fShowStatusIcon = !fShowStatusIcon;
|
||||||
|
_Update(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMsgToggleExtInfo:
|
||||||
|
_OpenExtendedWindow();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_ABOUT_REQUESTED:
|
||||||
|
_AboutRequested();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_QUIT_REQUESTED:
|
||||||
|
_Quit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
PowerStatusView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusReplicant::MouseDown(BPoint point)
|
||||||
|
{
|
||||||
|
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
||||||
|
menu->SetFont(be_plain_font);
|
||||||
|
|
||||||
|
BMenuItem* item;
|
||||||
|
menu->AddItem(item = new BMenuItem("Show Text Label",
|
||||||
|
new BMessage(kMsgToggleLabel)));
|
||||||
|
if (fShowLabel)
|
||||||
|
item->SetMarked(true);
|
||||||
|
menu->AddItem(item = new BMenuItem("Show Status Icon",
|
||||||
|
new BMessage(kMsgToggleStatusIcon)));
|
||||||
|
if (fShowStatusIcon)
|
||||||
|
item->SetMarked(true);
|
||||||
|
menu->AddItem(new BMenuItem(!fShowTime ? "Show Time" : "Show Percent",
|
||||||
|
new BMessage(kMsgToggleTime)));
|
||||||
|
|
||||||
|
menu->AddItem(new BMenuItem("Battery Info",
|
||||||
|
new BMessage(kMsgToggleExtInfo)));
|
||||||
|
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
menu->AddItem(new BMenuItem("About" B_UTF8_ELLIPSIS,
|
||||||
|
new BMessage(B_ABOUT_REQUESTED)));
|
||||||
|
menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED)));
|
||||||
|
menu->SetTargetForItems(this);
|
||||||
|
|
||||||
|
ConvertToScreen(&point);
|
||||||
|
menu->Go(point, true, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusReplicant::_AboutRequested()
|
||||||
|
{
|
||||||
|
BAlert *alert = new BAlert("about", "PowerStatus\n"
|
||||||
|
"written by Axel Dörfler,\n"
|
||||||
|
"\tClemens Zeidler\n"
|
||||||
|
"\tCopyright 2006, Haiku, Inc.\n", "Ok");
|
||||||
|
BTextView *view = alert->TextView();
|
||||||
|
BFont font;
|
||||||
|
|
||||||
|
view->SetStylable(true);
|
||||||
|
|
||||||
|
view->GetFont(&font);
|
||||||
|
font.SetSize(18);
|
||||||
|
font.SetFace(B_BOLD_FACE);
|
||||||
|
view->SetFontAndColor(0, 11, &font);
|
||||||
|
|
||||||
|
alert->Go();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusReplicant::_Init()
|
||||||
|
{
|
||||||
|
fDriverInterface = new ACPIDriverInterface;
|
||||||
|
if (fDriverInterface->Connect() != B_OK) {
|
||||||
|
delete fDriverInterface;
|
||||||
|
fDriverInterface = new APMDriverInterface;
|
||||||
|
if (fDriverInterface->Connect() != B_OK) {
|
||||||
|
fprintf(stderr, "No power interface found.\n");
|
||||||
|
_Quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fExtendedWindow = NULL;
|
||||||
|
fExtWindowMessenger = NULL;
|
||||||
|
|
||||||
|
fDriverInterface->StartWatching(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusReplicant::_Quit()
|
||||||
|
{
|
||||||
|
if (fInDeskbar) {
|
||||||
|
BDeskbar deskbar;
|
||||||
|
deskbar.RemoveItem(kDeskbarItemName);
|
||||||
|
} else
|
||||||
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusReplicant::_OpenExtendedWindow()
|
||||||
|
{
|
||||||
|
if (!fExtendedWindow) {
|
||||||
|
fExtendedWindow = new ExtendedInfoWindow(fDriverInterface);
|
||||||
|
fExtWindowMessenger = new BMessenger(NULL, fExtendedWindow);
|
||||||
|
fExtendedWindow->Show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BMessage msg(B_SET_PROPERTY);
|
||||||
|
msg.AddSpecifier("Hidden", int32(0));
|
||||||
|
if (fExtWindowMessenger->SendMessage(&msg) == B_BAD_PORT_ID) {
|
||||||
|
fExtendedWindow = new ExtendedInfoWindow(fDriverInterface);
|
||||||
|
fExtWindowMessenger = new BMessenger(NULL, fExtendedWindow);
|
||||||
|
fExtendedWindow->Show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fExtendedWindow->Activate();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
extern "C" _EXPORT BView *
|
extern "C" _EXPORT BView *
|
||||||
instantiate_deskbar_item(void)
|
instantiate_deskbar_item(void)
|
||||||
{
|
{
|
||||||
return new PowerStatusView(BRect(0, 0, 15, 15), B_FOLLOW_NONE, true);
|
return new PowerStatusReplicant(BRect(0, 0, 15, 15), B_FOLLOW_NONE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,53 +4,90 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
|
* Clemens Zeidler, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef POWER_STATUS_VIEW_H
|
#ifndef POWER_STATUS_VIEW_H
|
||||||
#define POWER_STATUS_VIEW_H
|
#define POWER_STATUS_VIEW_H
|
||||||
|
|
||||||
|
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
class BMessageRunner;
|
#include "DriverInterface.h"
|
||||||
|
|
||||||
|
|
||||||
class PowerStatusView : public BView {
|
class PowerStatusView : public BView {
|
||||||
public:
|
public:
|
||||||
PowerStatusView(BRect frame, int32 resizingMode, bool inDeskbar = false);
|
PowerStatusView(PowerStatusDriverInterface* interface,
|
||||||
PowerStatusView(BMessage* archive);
|
BRect frame, int32 resizingMode, int batteryId = -1,
|
||||||
|
bool inDeskbar = false);
|
||||||
|
|
||||||
virtual ~PowerStatusView();
|
virtual ~PowerStatusView();
|
||||||
|
|
||||||
static PowerStatusView* Instantiate(BMessage* archive);
|
|
||||||
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
||||||
|
|
||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
virtual void DetachedFromWindow();
|
virtual void DetachedFromWindow();
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
virtual void MouseDown(BPoint where);
|
|
||||||
virtual void Draw(BRect updateRect);
|
virtual void Draw(BRect updateRect);
|
||||||
|
virtual void GetPreferredSize(float *width, float *height);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PowerStatusView(BMessage* archive);
|
||||||
|
|
||||||
|
virtual void _Update(bool force = false);
|
||||||
|
virtual void _GetBatteryInfo(battery_info* info, int batteryId);
|
||||||
|
|
||||||
private:
|
PowerStatusDriverInterface* fDriverInterface;
|
||||||
void _AboutRequested();
|
|
||||||
void _Quit();
|
|
||||||
void _Init();
|
|
||||||
void _SetLabel(char* buffer, size_t bufferLength);
|
|
||||||
void _Update(bool force = false);
|
|
||||||
void _DrawBattery(BRect rect);
|
|
||||||
|
|
||||||
BMessageRunner* fMessageRunner;
|
|
||||||
bool fInDeskbar;
|
|
||||||
bool fShowLabel;
|
bool fShowLabel;
|
||||||
bool fShowTime;
|
bool fShowTime;
|
||||||
bool fShowStatusIcon;
|
bool fShowStatusIcon;
|
||||||
|
|
||||||
|
int fBatteryId;
|
||||||
|
bool fInDeskbar;
|
||||||
|
|
||||||
|
battery_info fBatteryInfo;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _Init();
|
||||||
|
void _SetLabel(char* buffer, size_t bufferLength);
|
||||||
|
void _DrawBattery(BRect rect);
|
||||||
|
|
||||||
int32 fPercent;
|
int32 fPercent;
|
||||||
time_t fTimeLeft;
|
time_t fTimeLeft;
|
||||||
bool fOnline;
|
bool fOnline;
|
||||||
|
|
||||||
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
BSize fPreferredSize;
|
||||||
int fDevice;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PowerStatusReplicant : public PowerStatusView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PowerStatusReplicant(BRect frame, int32 resizingMode,
|
||||||
|
bool inDeskbar = false);
|
||||||
|
PowerStatusReplicant(BMessage* archive);
|
||||||
|
|
||||||
|
virtual ~PowerStatusReplicant();
|
||||||
|
|
||||||
|
static PowerStatusReplicant* Instantiate(BMessage* archive);
|
||||||
|
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual void MouseDown(BPoint where);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _AboutRequested();
|
||||||
|
void _Init();
|
||||||
|
void _Quit();
|
||||||
|
|
||||||
|
void _OpenExtendedWindow();
|
||||||
|
|
||||||
|
BWindow* fExtendedWindow;
|
||||||
|
BMessenger* fExtWindowMessenger;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // POWER_STATUS_VIEW_H
|
#endif // POWER_STATUS_VIEW_H
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ PowerStatusWindow::PowerStatusWindow()
|
|||||||
topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
AddChild(topView);
|
AddChild(topView);
|
||||||
|
|
||||||
topView->AddChild(new PowerStatusView(Bounds(), B_FOLLOW_ALL));
|
topView->AddChild(new PowerStatusReplicant(Bounds(), B_FOLLOW_ALL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user