--- klaptopdaemon/portable.cpp.orig	2007-09-14 18:54:04.000000000 +0400
+++ klaptopdaemon/portable.cpp	2007-09-14 18:54:18.000000000 +0400
@@ -2001,7 +2001,488 @@
 	return(0);
 }
 
-#elif defined(__FreeBSD__) && HAVE_MACHINE_APM_BIOS_H
+#elif defined(__FreeBSD__) 
+
+#include <osreldate.h>
+
+#if __FreeBSD_version >= 502010 
+
+/*
+** This is the FreeBSD-specific code for FreeBSD newer than 5.2.1.
+*/
+
+#include <sys/param.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#include <dev/acpica/acpiio.h>
+
+#define ACPIDEV         "/dev/acpi"
+
+
+#include <qpushbutton.h>
+#include <qobject.h>
+#include <kactivelabel.h>
+#include <kprocess.h>
+
+//
+//	returns 1 if we support power management
+//
+/*
+791:int laptop_portable::has_apm(int type)
+806:int laptop_portable::has_acpi(int type)
+857:int laptop_portable::has_power_management()
+873:int laptop_portable::has_battery_time()
+886:int laptop_portable::has_suspend()
+903:int laptop_portable::has_standby()
+921:int laptop_portable::has_hibernation()
+940:KActiveLabel *laptop_portable::no_power_management_explanation(QWidget *parent)
+955:QLabel *laptop_portable::how_to_do_suspend_resume(QWidget *parent)
+1041:QLabel *laptop_portable::pcmcia_info(int x, QWidget *parent)
+1062:void laptop_portable::invoke_standby()
+1096:void laptop_portable::invoke_suspend()
+1135:void laptop_portable::invoke_hibernation()
+1184:struct power_result laptop_portable::poll_battery_state()
+1264:bool laptop_portable::has_lav()
+1269:float laptop_portable::get_load_average()
+1287:int laptop_portable::has_cpufreq() {
+1301:QString laptop_portable::cpu_frequency() {
+
+2067:int laptop_portable::has_battery_time()
+2092:int laptop_portable::has_suspend()
+2113:int laptop_portable::has_standby()
+2136:int laptop_portable::has_hibernation()
+2147:KActiveLabel *laptop_portable::no_power_management_explanation(QWidget *parent)
+2180:QLabel *laptop_portable::how_to_do_suspend_resume(QWidget *parent)
+2191:QLabel *laptop_portable::pcmcia_info(int x, QWidget *parent)
+2200:void laptop_portable::invoke_standby()
+2216:void laptop_portable::invoke_suspend()
+2231:void laptop_portable::invoke_hibernation()
+2252:int laptop_portable::has_acpi(int)
+2258:int laptop_portable::has_apm(int type)
+2285:struct power_result laptop_portable::poll_battery_state()
+2326:bool laptop_portable::has_lav() { return 0; }
+2328:float laptop_portable::get_load_average()
+2334:int laptop_portable::has_cpufreq() {
+2339:QString laptop_portable::cpu_frequency()
+*/
+#include <iostream>
+using namespace std;
+
+//
+//	something changed maybe we need to check out environment again
+//
+void
+laptop_portable::power_management_restart()
+{
+	// INSERT HERE
+}
+
+int
+laptop_portable::has_power_management()
+{
+	/*int ret, fd;
+	 
+	fd = ::open(ACPIDEV, O_RDWR);
+	if (fd == -1)
+	    fd = ::open(ACPIDEV, O_RDONLY);
+	if (fd == -1) {
+	    return 0;
+	}
+	else {
+	    ::close(fd);
+	    return 1;
+	}*/
+	if (::access(ACPIDEV, O_RDWR) == -1)
+		if (::access(ACPIDEV, O_RDONLY) == -1) {
+			return 0;
+		}
+		else	return 1;
+}
+//
+//	returns 1 if the BIOS returns the time left in the battery rather than a % of full
+//
+int laptop_portable::has_battery_time()
+{
+	int ret, fd;
+	union acpi_battery_ioctl_arg battio;
+	
+	battio.unit = 0;
+	
+	fd = ::open(ACPIDEV, O_RDWR);
+	if (fd == -1)
+	    fd = ::open(ACPIDEV, O_RDONLY);
+	if (fd == -1) {
+	    return 0;
+	}
+	
+	if (ioctl(fd, ACPIIO_BATT_GET_BIF, &battio) == -1) {
+	    return (0);
+	}
+	::close(fd);
+	return 1;
+}
+
+//
+//	returns 1 if we can perform a change-to-suspend-mode operation for the user
+//	(has_power_management() has already returned 1)
+//
+int laptop_portable::has_suspend()
+{
+	/*int ret, fd = ::open(APMDEV, O_RDWR);
+
+	if (fd == -1)
+	  return 0;
+
+	struct apm_info info;
+	ret=ioctl(fd, APMIO_GETINFO, &info);
+	::close(fd);
+
+	if (ret == -1)
+	  return 0;
+
+	return (info.ai_capabilities & 0x02);*/
+	return 0;
+}
+//
+//	returns 1 if we can perform a change-to-standby-mode operation for the user
+//	(has_power_management() has already returned 1)
+//
+int laptop_portable::has_standby()
+{
+	/*int ret, fd = ::open(APMDEV, O_RDWR);
+
+	if (fd == -1)
+	  return 0;
+
+	struct apm_info info;
+	ret=ioctl(fd, APMIO_GETINFO, &info);
+	::close(fd);
+
+	if (ret == -1)
+	  return 0;
+
+	return (info.ai_capabilities & 0x01);*/
+	return 0;
+}
+//
+//	returns 1 if we can perform a change-to-hibernate-mode for a user
+//      (has_power_management() has already returned 1)  [hibernate is the save-to-disk mode
+//	not supported by linux - different laptops have their own - the first here is for 
+//	a ThinkPad]
+//
+int laptop_portable::has_hibernation()
+{
+	if (::access(PATH_TPCTL, X_OK)==0)
+		return(1);
+	return(0);
+}
+
+//
+//	explain to the user what they need to do if has_power_management() returned 0
+//	to get any software they lack
+//
+KActiveLabel *laptop_portable::no_power_management_explanation(QWidget *parent)
+{
+  int fd;
+  KActiveLabel *explain;
+
+  fd = ::open(ACPIDEV, O_RDWR);
+  if (fd == -1) {
+    switch (errno) {
+    case ENOENT:
+      explain = new KActiveLabel(i18n("There is no /dev/acpi file on this system. Please review the FreeBSD handbook on how to add acpi support to your kernel(man 4 acpi)."), parent);
+      break;
+    case EACCES:
+      explain = new KActiveLabel(i18n("Your system has the proper device node for ACPI support, however you cannot access it. If you are logged in as root right now, you have a problem, otherwise contact your local sysadmin and ask for read/write access to /dev/acpi."), parent);
+      break;
+    case ENXIO:
+      explain = new KActiveLabel(i18n("Your kernel lacks support for ACPI."), parent);
+      break;
+      break;
+    default:
+      explain = new KActiveLabel(i18n("There was a generic error while opening /dev/acpi."), parent);
+      break;
+    }
+  } else {
+    close(fd);
+    explain = new KActiveLabel(i18n("ACPI has most likely been disabled."), parent);
+  }
+  
+  return(explain);
+}
+
+//
+//	explain to the user what they need to do to get suspend/resume to work from user mode
+//
+QLabel *laptop_portable::how_to_do_suspend_resume(QWidget *parent)
+{
+ 	QLabel* note = new QLabel(" ", parent);
+	return(note);
+}
+
+
+//
+//	pcmcia support - this will be replaced by better - pcmcia support being worked on by
+//	others
+//
+QLabel *laptop_portable::pcmcia_info(int x, QWidget *parent)
+{
+      	if (x == 0)
+		return(new QLabel(i18n("No PCMCIA controller detected"), parent));
+      	return(new QLabel(i18n(""), parent));
+}
+//
+//	puts us into standby mode
+//
+void laptop_portable::invoke_standby()
+{
+  	/*int fd = ::open(APMDEV, O_RDWR);
+
+	if (fd == -1)
+	  return;
+
+	ioctl(fd, APMIO_STANDBY, NULL);
+	::close(fd);*/
+
+	return;
+}
+
+//
+//	puts us into suspend mode
+//
+void laptop_portable::invoke_suspend()
+{
+  	/*int fd = ::open(APMDEV, O_RDWR);
+
+	if (fd == -1)
+	  return;
+
+	ioctl(fd, APMIO_SUSPEND, NULL);
+	::close(fd);*/
+
+	return;
+}
+//
+//	puts us into hibernate mode
+//
+void laptop_portable::invoke_hibernation()
+{
+	KProcess thisProc;
+
+	if (::access(PATH_TPCTL, X_OK)==0) {
+		thisProc << PATH_TPCTL;
+		thisProc << "---hibernate";
+		thisProc.start(KProcess::Block);
+		return;
+	}
+}
+
+void
+laptop_portable::acpi_set_mask(bool, bool, bool, bool, bool )
+{
+	// INSERT HERE
+}
+
+int laptop_portable::has_acpi(int)
+{
+	if (::access(ACPIDEV, O_RDONLY) != 0) return 0;
+	return (1);
+}
+
+int laptop_portable::has_apm(int type)
+{
+	if (type == 1)		// implement me .... this is the hook that pops up the panel for making /usr/sbin/apm setuid
+		return 0;
+	return (0);
+}
+
+void
+laptop_portable::apm_set_mask(bool , bool )
+{
+}
+
+
+//
+//	adds extra widgets to the battery panel
+//
+void
+laptop_portable::extra_config(QWidget * /*parent*/, KConfig * /*config*/, QVBoxLayout * /*layout*/)
+{
+	// INSERT HERE
+}
+
+
+
+//
+//	return current battery state
+//
+struct power_result laptop_portable::poll_battery_state()
+{
+	struct power_result p;
+       	
+	int ret, fd;
+	union acpi_battery_ioctl_arg battio;
+	
+	battio.unit = ACPI_BATTERY_ALL_UNITS;
+	ret = 0;
+	
+	fd = ::open(ACPIDEV, O_RDONLY);
+	if (fd == -1) {
+	    goto bad;
+	}
+	
+	if (ioctl(fd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1) {
+	    goto bad;
+	}
+	
+	if (ioctl(fd, ACPIIO_ACAD_GET_STATUS, &ret) == -1) {
+	    goto bad;
+	}
+	
+       	::close(fd);
+	
+       	p.powered = ret;
+       	p.percentage = battio.battinfo.cap;
+       	p.time = battio.battinfo.min;
+       	return(p);
+
+bad:
+       	p.powered = 1; 
+	p.percentage = 100;
+	p.time = 0;
+	return(p);
+}
+
+//
+//	return the system load 
+//	
+
+bool laptop_portable::has_lav() { return 1; }
+
+float laptop_portable::get_load_average()
+{
+	// INSERT HERE
+	return(-1);
+}
+
+int laptop_portable::has_cpufreq() {
+	// INSERT HERE
+	return 0;
+}
+
+QString laptop_portable::cpu_frequency() {
+	// INSERT HERE
+	return "";
+}
+
+int
+laptop_portable::has_brightness()
+{
+	// INSERT HERE
+	return 0;
+}
+
+void 
+laptop_portable::set_brightness(bool /*blank*/, int /*val*/)	// val = 0-255 255 brightest, 0 means dimmest (if !blank it must be still visible), 
+{
+	// INSERT HERE
+}
+
+int 
+laptop_portable::get_brightness()
+{
+	// INSERT HERE
+	return(-1);	// means can't extract it
+}
+
+bool
+laptop_portable::get_system_performance(bool, int &current, QStringList &s, bool *&)	 // do something to help get system profiles from places like ACPI
+{
+	// INSERT HERE
+	current = 0;
+	s.clear();
+	return(0);	// if no profiles are available
+}
+
+bool
+laptop_portable::get_system_throttling(bool, int &current, QStringList &s, bool *&)   // do something to help get system throttling data from places like ACPI
+{
+	// INSERT HERE
+	current = 0;
+	s.clear();
+	return(0);
+}
+
+void
+laptop_portable::set_system_performance(QString)
+{
+	// INSERT HERE
+}
+
+void
+laptop_portable::set_system_throttling(QString)
+{
+	// INSERT HERE
+}
+
+bool
+laptop_portable::has_button(LaptopButton)	// true if we have support for a particular button
+{
+	// INSERT HERE
+	return(0);
+}
+
+bool
+laptop_portable::get_button(LaptopButton)	// true if a button is pressed
+{
+	// INSERT HERE
+	return(0);
+}
+
+void
+laptop_portable::get_battery_status(int &num_batteries, QStringList &names, QStringList &state, QStringList &values) // get multiple battery status
+{
+	struct power_result r;
+
+	if (!has_power_management()) {
+		num_batteries = 0;
+		names.clear();
+		state.clear();
+		values.clear();
+		return;
+	}
+
+	// INSERT HERE
+	
+	num_batteries = 1;
+	r = poll_battery_state();
+	names.append("BAT1");
+	state.append("yes");
+	QString s;
+	s.setNum(r.percentage);
+	values.append(s);
+}
+
+bool
+laptop_portable::has_software_suspend(int /*type*/)
+{
+	return false; // (::has_software_suspend(type));
+}
+
+void
+laptop_portable::software_suspend_set_mask(bool /*hibernate*/)
+{
+	// software_suspend_is_preferred = hibernate;
+}
+
+#endif
+
+#if defined(__FreeBSD__) && defined(HAVE_MACHINE_APM_BIOS_H) && (__FreeBSD_version < 502010)
 
 /*
 ** This is the FreeBSD-specific code.
@@ -2426,6 +2907,7 @@
 	// software_suspend_is_preferred = hibernate;
 }
 
+#endif
 
 #elif  defined(__NetBSD_APM__)
 
