* Implemented APM generic syscall API to query the current power status.
* PowerStatus is now using this API when compiled for Haiku. * Note, I'm not sure why yet, but running PowerStatus in the background crashes at least my laptop after some time. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21154 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -47,6 +47,17 @@ typedef struct apm_info {
|
|||||||
} apm_info;
|
} apm_info;
|
||||||
|
|
||||||
|
|
||||||
|
// temporary generic syscall interface
|
||||||
|
#define APM_SYSCALLS "apm"
|
||||||
|
#define APM_GET_BATTERY_INFO 1
|
||||||
|
|
||||||
|
struct battery_info {
|
||||||
|
bool online;
|
||||||
|
int32 percent;
|
||||||
|
time_t time_left;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifndef _BOOT_MODE
|
#ifndef _BOOT_MODE
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ SubDir HAIKU_TOP src apps powerstatus ;
|
|||||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
UsePrivateHeaders shared ;
|
UsePrivateHeaders shared ;
|
||||||
|
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
||||||
|
|
||||||
Application PowerStatus :
|
Application PowerStatus :
|
||||||
PowerStatusWindow.cpp
|
PowerStatusWindow.cpp
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
#include "PowerStatusView.h"
|
#include "PowerStatusView.h"
|
||||||
#include "PowerStatus.h"
|
#include "PowerStatus.h"
|
||||||
|
|
||||||
|
#include <arch/x86/apm.h>
|
||||||
|
#include <generic_syscall.h>
|
||||||
|
#include <syscalls.h>
|
||||||
|
// temporary, as long as there is no real power state API
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Deskbar.h>
|
#include <Deskbar.h>
|
||||||
@@ -110,7 +115,19 @@ PowerStatusView::_Init()
|
|||||||
fTimeLeft = 0;
|
fTimeLeft = 0;
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
// TODO: implement me
|
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
|
#else
|
||||||
fDevice = open("/dev/misc/apm", O_RDONLY);
|
fDevice = open("/dev/misc/apm", O_RDONLY);
|
||||||
if (fDevice < 0) {
|
if (fDevice < 0) {
|
||||||
@@ -422,9 +439,14 @@ PowerStatusView::_Update(bool force)
|
|||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
// TODO: retrieve data from APM/ACPI kernel interface
|
// TODO: retrieve data from APM/ACPI kernel interface
|
||||||
fPercent = 42;
|
battery_info info;
|
||||||
fTimeLeft = 1500;
|
status_t status = _kern_generic_syscall(APM_SYSCALLS, APM_GET_BATTERY_INFO, &info,
|
||||||
fOnline = true;
|
sizeof(battery_info));
|
||||||
|
if (status == B_OK) {
|
||||||
|
fPercent = info.percent;
|
||||||
|
fTimeLeft = info.time_left;
|
||||||
|
fOnline = info.online;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (fDevice < 0)
|
if (fDevice < 0)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2006-2007, Axel Dörfler, [email protected]. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <apm.h>
|
#include <apm.h>
|
||||||
#include <descriptors.h>
|
#include <descriptors.h>
|
||||||
|
#include <generic_syscall.h>
|
||||||
#include <safemode.h>
|
#include <safemode.h>
|
||||||
#include <boot/kernel_args.h>
|
#include <boot/kernel_args.h>
|
||||||
|
|
||||||
@@ -196,6 +197,56 @@ apm_daemon(void *arg, int iteration)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
get_battery_info(battery_info *info)
|
||||||
|
{
|
||||||
|
bios_regs regs;
|
||||||
|
regs.eax = BIOS_APM_GET_POWER_STATUS;
|
||||||
|
regs.ebx = APM_ALL_DEVICES;
|
||||||
|
regs.ecx = 0;
|
||||||
|
|
||||||
|
status_t status = call_apm_bios(®s);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
uint16 lineStatus = (regs.ebx >> 8) & 0xff;
|
||||||
|
if (lineStatus == 0xff)
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
info->online = lineStatus != 0 && lineStatus != 2;
|
||||||
|
info->percent = regs.ecx & 0xff;
|
||||||
|
if (info->percent > 100 || info->percent < 0)
|
||||||
|
info->percent = -1;
|
||||||
|
|
||||||
|
info->time_left = info->percent >= 0 ? (int32)(regs.edx & 0xffff) : -1;
|
||||||
|
if (info->time_left & 0x8000)
|
||||||
|
info->time_left = (info->time_left & 0x7fff) * 60;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
apm_control(const char *subsystem, uint32 function,
|
||||||
|
void *buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
struct battery_info info;
|
||||||
|
if (bufferSize != sizeof(struct battery_info))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
switch (function) {
|
||||||
|
case APM_GET_BATTERY_INFO:
|
||||||
|
status_t status = get_battery_info(&info);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
return user_memcpy(buffer, &info, sizeof(struct battery_info));
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -304,6 +355,7 @@ apm_init(kernel_args *args)
|
|||||||
register_kernel_daemon(apm_daemon, NULL, 10);
|
register_kernel_daemon(apm_daemon, NULL, 10);
|
||||||
// run the daemon once every second
|
// run the daemon once every second
|
||||||
|
|
||||||
|
register_generic_syscall(APM_SYSCALLS, apm_control, 1, 0);
|
||||||
sAPMEnabled = true;
|
sAPMEnabled = true;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user