* 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:
parent
8536d82fb6
commit
8ca5764554
|
@ -47,6 +47,17 @@ typedef struct 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
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -3,6 +3,7 @@ SubDir HAIKU_TOP src apps powerstatus ;
|
|||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
||||
|
||||
Application PowerStatus :
|
||||
PowerStatusWindow.cpp
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
#include "PowerStatusView.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 <Application.h>
|
||||
#include <Deskbar.h>
|
||||
|
@ -110,7 +115,19 @@ PowerStatusView::_Init()
|
|||
fTimeLeft = 0;
|
||||
|
||||
#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
|
||||
fDevice = open("/dev/misc/apm", O_RDONLY);
|
||||
if (fDevice < 0) {
|
||||
|
@ -422,9 +439,14 @@ PowerStatusView::_Update(bool force)
|
|||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
// TODO: retrieve data from APM/ACPI kernel interface
|
||||
fPercent = 42;
|
||||
fTimeLeft = 1500;
|
||||
fOnline = true;
|
||||
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;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2006-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <apm.h>
|
||||
#include <descriptors.h>
|
||||
#include <generic_syscall.h>
|
||||
#include <safemode.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 -
|
||||
|
||||
|
||||
|
@ -304,6 +355,7 @@ apm_init(kernel_args *args)
|
|||
register_kernel_daemon(apm_daemon, NULL, 10);
|
||||
// run the daemon once every second
|
||||
|
||||
register_generic_syscall(APM_SYSCALLS, apm_control, 1, 0);
|
||||
sAPMEnabled = true;
|
||||
return B_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue