mirror of
https://gitlab.freedesktop.org/upower/upower.git
synced 2026-04-23 21:30:46 +02:00
import the FreeBSD backend
Add a backend for FreeBSD supporting AC power lines, batteries, and lid state.
This commit is contained in:
parent
725acd4d35
commit
131bc12a81
17 changed files with 2091 additions and 3 deletions
|
|
@ -1,6 +1,8 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = devkit-power-gobject src doc tools policy po rules
|
||||
SUBDIRS = devkit-power-gobject src doc tools policy po $(UDEV_RULES)
|
||||
|
||||
DIST_SUBDIRS = devkit-power-gobject src doc tools policy po rules
|
||||
|
||||
# Creating ChangeLog from git log (taken from cairo/Makefile.am):
|
||||
ChangeLog: $(srcdir)/ChangeLog
|
||||
|
|
|
|||
|
|
@ -149,11 +149,14 @@ dnl - Compile time default choice of backend
|
|||
dnl ---------------------------------------------------------------------------
|
||||
AC_ARG_WITH([backend],
|
||||
AS_HELP_STRING([--with-backend=<option>],
|
||||
[Default backend to use linux, dummy (dummy)]))
|
||||
[Default backend to use linux, freebsd, dummy (dummy)]))
|
||||
UDEV_RULES=
|
||||
# default to a sane option
|
||||
if test x$with_backend = x; then
|
||||
if test -e /usr/include/gudev-1.0/gudev/gudev.h ; then
|
||||
with_backend=linux
|
||||
elif test -e /usr/include/dev/acpica/acpiio.h ; then
|
||||
with_backend=freebsd
|
||||
else
|
||||
with_backend=dummy
|
||||
fi
|
||||
|
|
@ -170,11 +173,14 @@ if test x$with_backend = xlinux; then
|
|||
dnl Check libusb also
|
||||
AC_CHECK_HEADERS(usb.h, , [AC_MSG_ERROR([Can't find usb.h. Please install libusb.])])
|
||||
AC_CHECK_LIB([usb], [usb_find_devices], [], [AC_MSG_ERROR([Can't use libusb.])])
|
||||
UDEV_RULES="rules"
|
||||
fi
|
||||
AC_SUBST(UDEV_RULES)
|
||||
|
||||
# export to Makefile.am
|
||||
AM_CONDITIONAL(BACKEND_TYPE_DUMMY, [test x$with_backend = xdummy])
|
||||
AM_CONDITIONAL(BACKEND_TYPE_LINUX, [test x$with_backend = xlinux])
|
||||
AM_CONDITIONAL(BACKEND_TYPE_FREEBSD, [test x$with_backend = xfreebsd])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl - Build self tests
|
||||
|
|
@ -201,6 +207,7 @@ Makefile
|
|||
devkit-power-gobject.pc
|
||||
src/Makefile
|
||||
src/dummy/Makefile
|
||||
src/freebsd/Makefile
|
||||
src/linux/Makefile
|
||||
tools/Makefile
|
||||
doc/Makefile
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = dummy linux
|
||||
SUBDIRS = dummy freebsd linux
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_builddir)/src -I$(top_srcdir)/src \
|
||||
|
|
@ -104,6 +104,12 @@ devkit_power_daemon_LDADD += \
|
|||
dummy/libdkpshared.la
|
||||
endif
|
||||
|
||||
if BACKEND_TYPE_FREEBSD
|
||||
devkit_power_daemon_LDADD += \
|
||||
freebsd/libdkpshared.la \
|
||||
$(DEVKIT_POWER_LIBS)
|
||||
endif
|
||||
|
||||
if BACKEND_TYPE_LINUX
|
||||
devkit_power_daemon_LDADD += \
|
||||
linux/libdkpshared.la \
|
||||
|
|
|
|||
45
src/freebsd/Makefile.am
Normal file
45
src/freebsd/Makefile.am
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_builddir)/src -I$(top_srcdir)/src \
|
||||
-DEGG_LOG_FILE=\""$(DKP_LOG_DIR)/DeviceKit-power"\" \
|
||||
-DEGG_VERBOSE="\"DKP_VERBOSE\"" \
|
||||
-DEGG_LOGGING="\"DKP_LOGGING\"" \
|
||||
-DEGG_CONSOLE="\"DKP_CONSOLE\"" \
|
||||
-DDKP_COMPILATION \
|
||||
-I$(top_srcdir)/devkit-power-gobject \
|
||||
$(DBUS_GLIB_CFLAGS) \
|
||||
$(POLKIT_CFLAGS) \
|
||||
$(GLIB_CFLAGS)
|
||||
|
||||
if BACKEND_TYPE_FREEBSD
|
||||
noinst_LTLIBRARIES = libdkpshared.la
|
||||
endif
|
||||
|
||||
libdkpshared_la_SOURCES = \
|
||||
dkp-acpi-native.c \
|
||||
dkp-acpi-native.h \
|
||||
dkp-backend-acpi.h \
|
||||
dkp-backend.c \
|
||||
dkp-devd.c \
|
||||
dkp-devd.h \
|
||||
dkp-device-supply.c \
|
||||
dkp-device-supply.h \
|
||||
dkp-native.c \
|
||||
dkp-util.c \
|
||||
dkp-util.h \
|
||||
$(BUILT_SOURCES)
|
||||
|
||||
libdkpshared_la_CFLAGS = \
|
||||
$(WARNINGFLAGS_C)
|
||||
|
||||
libdkpshared_la_LIBADD = \
|
||||
-lkvm
|
||||
|
||||
EXTRA_DIST = \
|
||||
dkp-acpi-native.vala \
|
||||
TODO
|
||||
|
||||
clean-local :
|
||||
rm -f *~
|
||||
|
||||
4
src/freebsd/TODO
Normal file
4
src/freebsd/TODO
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
FreeBSD doesn't have udev, so the udev rules can't be automatically applied.
|
||||
However, they are useful in that they contain some needed battery recall
|
||||
information. To that end, they should be incorporated into the FreeBSD
|
||||
backend probably by adding them to a static array, or a hashtable.
|
||||
234
src/freebsd/dkp-acpi-native.c
Normal file
234
src/freebsd/dkp-acpi-native.c
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
/* dkp-acpi-native.c generated by valac, the Vala compiler
|
||||
* generated from dkp-acpi-native.vala, do not modify */
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define TYPE_DKP_ACPI_NATIVE (dkp_acpi_native_get_type ())
|
||||
#define DKP_ACPI_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DKP_ACPI_NATIVE, DkpAcpiNative))
|
||||
#define DKP_ACPI_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DKP_ACPI_NATIVE, DkpAcpiNativeClass))
|
||||
#define IS_DKP_ACPI_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DKP_ACPI_NATIVE))
|
||||
#define IS_DKP_ACPI_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DKP_ACPI_NATIVE))
|
||||
#define DKP_ACPI_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DKP_ACPI_NATIVE, DkpAcpiNativeClass))
|
||||
|
||||
typedef struct _DkpAcpiNative DkpAcpiNative;
|
||||
typedef struct _DkpAcpiNativeClass DkpAcpiNativeClass;
|
||||
typedef struct _DkpAcpiNativePrivate DkpAcpiNativePrivate;
|
||||
#define _g_free0(var) (var = (g_free (var), NULL))
|
||||
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_unref (var), NULL)))
|
||||
#define _g_match_info_free0(var) ((var == NULL) ? NULL : (var = (g_match_info_free (var), NULL)))
|
||||
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
|
||||
|
||||
struct _DkpAcpiNative {
|
||||
GObject parent_instance;
|
||||
DkpAcpiNativePrivate * priv;
|
||||
};
|
||||
|
||||
struct _DkpAcpiNativeClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
struct _DkpAcpiNativePrivate {
|
||||
char* _driver;
|
||||
gint _unit;
|
||||
char* _path;
|
||||
};
|
||||
|
||||
|
||||
static gpointer dkp_acpi_native_parent_class = NULL;
|
||||
|
||||
GType dkp_acpi_native_get_type (void);
|
||||
#define DKP_ACPI_NATIVE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DKP_ACPI_NATIVE, DkpAcpiNativePrivate))
|
||||
enum {
|
||||
DKP_ACPI_NATIVE_DUMMY_PROPERTY,
|
||||
DKP_ACPI_NATIVE_DRIVER,
|
||||
DKP_ACPI_NATIVE_UNIT,
|
||||
DKP_ACPI_NATIVE_PATH
|
||||
};
|
||||
DkpAcpiNative* dkp_acpi_native_new (const char* path);
|
||||
DkpAcpiNative* dkp_acpi_native_construct (GType object_type, const char* path);
|
||||
DkpAcpiNative* dkp_acpi_native_new_driver_unit (const char* driver, gint unit);
|
||||
DkpAcpiNative* dkp_acpi_native_construct_driver_unit (GType object_type, const char* driver, gint unit);
|
||||
const char* dkp_acpi_native_get_driver (DkpAcpiNative* self);
|
||||
gint dkp_acpi_native_get_unit (DkpAcpiNative* self);
|
||||
const char* dkp_acpi_native_get_path (DkpAcpiNative* self);
|
||||
static void dkp_acpi_native_finalize (GObject* obj);
|
||||
static void dkp_acpi_native_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
|
||||
|
||||
|
||||
|
||||
DkpAcpiNative* dkp_acpi_native_construct (GType object_type, const char* path) {
|
||||
GError * _inner_error_;
|
||||
DkpAcpiNative * self;
|
||||
GRegex* r;
|
||||
GMatchInfo* mi;
|
||||
gboolean ret = FALSE;
|
||||
char* _tmp9_;
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
_inner_error_ = NULL;
|
||||
self = (DkpAcpiNative*) g_object_new (object_type, NULL);
|
||||
r = NULL;
|
||||
mi = NULL;
|
||||
{
|
||||
GRegex* _tmp0_;
|
||||
GRegex* _tmp1_;
|
||||
GMatchInfo* _tmp4_;
|
||||
gboolean _tmp3_;
|
||||
GMatchInfo* _tmp2_ = NULL;
|
||||
_tmp0_ = g_regex_new ("dev\\.([^\\.])\\.(\\d+)", 0, 0, &_inner_error_);
|
||||
if (_inner_error_ != NULL) {
|
||||
if (_inner_error_->domain == G_REGEX_ERROR) {
|
||||
goto __catch0_g_regex_error;
|
||||
}
|
||||
goto __finally0;
|
||||
}
|
||||
r = (_tmp1_ = _tmp0_, _g_regex_unref0 (r), _tmp1_);
|
||||
ret = (_tmp3_ = g_regex_match (r, path, 0, &_tmp2_), mi = (_tmp4_ = _tmp2_, _g_match_info_free0 (mi), _tmp4_), _tmp3_);
|
||||
if (ret) {
|
||||
char* _tmp5_;
|
||||
char* _tmp6_;
|
||||
self->priv->_driver = (_tmp5_ = g_match_info_fetch (mi, 1), _g_free0 (self->priv->_driver), _tmp5_);
|
||||
self->priv->_unit = atoi (_tmp6_ = g_match_info_fetch (mi, 2));
|
||||
_g_free0 (_tmp6_);
|
||||
} else {
|
||||
char* _tmp7_;
|
||||
self->priv->_driver = (_tmp7_ = NULL, _g_free0 (self->priv->_driver), _tmp7_);
|
||||
self->priv->_unit = -1;
|
||||
}
|
||||
}
|
||||
goto __finally0;
|
||||
__catch0_g_regex_error:
|
||||
{
|
||||
GError * re;
|
||||
re = _inner_error_;
|
||||
_inner_error_ = NULL;
|
||||
{
|
||||
char* _tmp8_;
|
||||
self->priv->_driver = (_tmp8_ = NULL, _g_free0 (self->priv->_driver), _tmp8_);
|
||||
self->priv->_unit = -1;
|
||||
_g_error_free0 (re);
|
||||
}
|
||||
}
|
||||
__finally0:
|
||||
if (_inner_error_ != NULL) {
|
||||
_g_regex_unref0 (r);
|
||||
_g_match_info_free0 (mi);
|
||||
g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
|
||||
g_clear_error (&_inner_error_);
|
||||
return NULL;
|
||||
}
|
||||
self->priv->_path = (_tmp9_ = g_strdup (path), _g_free0 (self->priv->_path), _tmp9_);
|
||||
_g_regex_unref0 (r);
|
||||
_g_match_info_free0 (mi);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
DkpAcpiNative* dkp_acpi_native_new (const char* path) {
|
||||
return dkp_acpi_native_construct (TYPE_DKP_ACPI_NATIVE, path);
|
||||
}
|
||||
|
||||
|
||||
DkpAcpiNative* dkp_acpi_native_construct_driver_unit (GType object_type, const char* driver, gint unit) {
|
||||
DkpAcpiNative * self;
|
||||
char* _tmp0_;
|
||||
char* _tmp1_;
|
||||
g_return_val_if_fail (driver != NULL, NULL);
|
||||
self = (DkpAcpiNative*) g_object_new (object_type, NULL);
|
||||
self->priv->_driver = (_tmp0_ = g_strdup (driver), _g_free0 (self->priv->_driver), _tmp0_);
|
||||
self->priv->_unit = unit;
|
||||
self->priv->_path = (_tmp1_ = g_strdup_printf ("dev.%s.%i", self->priv->_driver, self->priv->_unit), _g_free0 (self->priv->_path), _tmp1_);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
DkpAcpiNative* dkp_acpi_native_new_driver_unit (const char* driver, gint unit) {
|
||||
return dkp_acpi_native_construct_driver_unit (TYPE_DKP_ACPI_NATIVE, driver, unit);
|
||||
}
|
||||
|
||||
|
||||
const char* dkp_acpi_native_get_driver (DkpAcpiNative* self) {
|
||||
const char* result;
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
result = self->priv->_driver;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
gint dkp_acpi_native_get_unit (DkpAcpiNative* self) {
|
||||
gint result;
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
result = self->priv->_unit;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const char* dkp_acpi_native_get_path (DkpAcpiNative* self) {
|
||||
const char* result;
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
result = self->priv->_path;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void dkp_acpi_native_class_init (DkpAcpiNativeClass * klass) {
|
||||
dkp_acpi_native_parent_class = g_type_class_peek_parent (klass);
|
||||
g_type_class_add_private (klass, sizeof (DkpAcpiNativePrivate));
|
||||
G_OBJECT_CLASS (klass)->get_property = dkp_acpi_native_get_property;
|
||||
G_OBJECT_CLASS (klass)->finalize = dkp_acpi_native_finalize;
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), DKP_ACPI_NATIVE_DRIVER, g_param_spec_string ("driver", "driver", "driver", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), DKP_ACPI_NATIVE_UNIT, g_param_spec_int ("unit", "unit", "unit", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), DKP_ACPI_NATIVE_PATH, g_param_spec_string ("path", "path", "path", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
|
||||
static void dkp_acpi_native_instance_init (DkpAcpiNative * self) {
|
||||
self->priv = DKP_ACPI_NATIVE_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
|
||||
static void dkp_acpi_native_finalize (GObject* obj) {
|
||||
DkpAcpiNative * self;
|
||||
self = DKP_ACPI_NATIVE (obj);
|
||||
_g_free0 (self->priv->_driver);
|
||||
_g_free0 (self->priv->_path);
|
||||
G_OBJECT_CLASS (dkp_acpi_native_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
|
||||
GType dkp_acpi_native_get_type (void) {
|
||||
static GType dkp_acpi_native_type_id = 0;
|
||||
if (dkp_acpi_native_type_id == 0) {
|
||||
static const GTypeInfo g_define_type_info = { sizeof (DkpAcpiNativeClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dkp_acpi_native_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DkpAcpiNative), 0, (GInstanceInitFunc) dkp_acpi_native_instance_init, NULL };
|
||||
dkp_acpi_native_type_id = g_type_register_static (G_TYPE_OBJECT, "DkpAcpiNative", &g_define_type_info, 0);
|
||||
}
|
||||
return dkp_acpi_native_type_id;
|
||||
}
|
||||
|
||||
|
||||
static void dkp_acpi_native_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
|
||||
DkpAcpiNative * self;
|
||||
self = DKP_ACPI_NATIVE (object);
|
||||
switch (property_id) {
|
||||
case DKP_ACPI_NATIVE_DRIVER:
|
||||
g_value_set_string (value, dkp_acpi_native_get_driver (self));
|
||||
break;
|
||||
case DKP_ACPI_NATIVE_UNIT:
|
||||
g_value_set_int (value, dkp_acpi_native_get_unit (self));
|
||||
break;
|
||||
case DKP_ACPI_NATIVE_PATH:
|
||||
g_value_set_string (value, dkp_acpi_native_get_path (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
48
src/freebsd/dkp-acpi-native.h
Normal file
48
src/freebsd/dkp-acpi-native.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* dkp-acpi-native.h generated by valac, the Vala compiler, do not modify */
|
||||
|
||||
|
||||
#ifndef __DKP_ACPI_NATIVE_H__
|
||||
#define __DKP_ACPI_NATIVE_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define TYPE_DKP_ACPI_NATIVE (dkp_acpi_native_get_type ())
|
||||
#define DKP_ACPI_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DKP_ACPI_NATIVE, DkpAcpiNative))
|
||||
#define DKP_ACPI_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DKP_ACPI_NATIVE, DkpAcpiNativeClass))
|
||||
#define IS_DKP_ACPI_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DKP_ACPI_NATIVE))
|
||||
#define IS_DKP_ACPI_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DKP_ACPI_NATIVE))
|
||||
#define DKP_ACPI_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DKP_ACPI_NATIVE, DkpAcpiNativeClass))
|
||||
|
||||
typedef struct _DkpAcpiNative DkpAcpiNative;
|
||||
typedef struct _DkpAcpiNativeClass DkpAcpiNativeClass;
|
||||
typedef struct _DkpAcpiNativePrivate DkpAcpiNativePrivate;
|
||||
|
||||
struct _DkpAcpiNative {
|
||||
GObject parent_instance;
|
||||
DkpAcpiNativePrivate * priv;
|
||||
};
|
||||
|
||||
struct _DkpAcpiNativeClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType dkp_acpi_native_get_type (void);
|
||||
DkpAcpiNative* dkp_acpi_native_new (const char* path);
|
||||
DkpAcpiNative* dkp_acpi_native_construct (GType object_type, const char* path);
|
||||
DkpAcpiNative* dkp_acpi_native_new_driver_unit (const char* driver, gint unit);
|
||||
DkpAcpiNative* dkp_acpi_native_construct_driver_unit (GType object_type, const char* driver, gint unit);
|
||||
const char* dkp_acpi_native_get_driver (DkpAcpiNative* self);
|
||||
gint dkp_acpi_native_get_unit (DkpAcpiNative* self);
|
||||
const char* dkp_acpi_native_get_path (DkpAcpiNative* self);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
46
src/freebsd/dkp-acpi-native.vala
Normal file
46
src/freebsd/dkp-acpi-native.vala
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
public class DkpAcpiNative : Object {
|
||||
private string? _driver;
|
||||
private int _unit;
|
||||
private string _path;
|
||||
|
||||
public string driver {
|
||||
get { return _driver; }
|
||||
}
|
||||
|
||||
public int unit {
|
||||
get { return _unit; }
|
||||
}
|
||||
|
||||
public string path {
|
||||
get { return _path; }
|
||||
}
|
||||
|
||||
public DkpAcpiNative (string path) {
|
||||
Regex r;
|
||||
MatchInfo mi;
|
||||
bool ret;
|
||||
|
||||
try {
|
||||
r = new Regex("dev\\.([^\\.])\\.(\\d+)");
|
||||
ret = r.match(path, 0, out mi);
|
||||
if (ret) {
|
||||
_driver = mi.fetch(1);
|
||||
_unit = mi.fetch(2).to_int();
|
||||
} else {
|
||||
_driver = null;
|
||||
_unit = -1;
|
||||
}
|
||||
} catch (RegexError re) {
|
||||
_driver = null;
|
||||
_unit = -1;
|
||||
}
|
||||
|
||||
_path = path;
|
||||
}
|
||||
|
||||
public DkpAcpiNative.driver_unit (string driver, int unit) {
|
||||
_driver = driver;
|
||||
_unit = unit;
|
||||
_path = "dev.%s.%i".printf (_driver, _unit);
|
||||
}
|
||||
}
|
||||
33
src/freebsd/dkp-backend-acpi.h
Normal file
33
src/freebsd/dkp-backend-acpi.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/***************************************************************************
|
||||
* CVSID: $Id$
|
||||
*
|
||||
* dkp-backend-acpi.h : define some backend objects
|
||||
*
|
||||
* Copyright (C) 2006, 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef _DKP_BACKEND_ACPI_H
|
||||
#define _DKP_BACKEND_ACPI_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "dkp-devd.h"
|
||||
|
||||
extern DkpDevdHandler dkp_backend_acpi_devd_handler;
|
||||
|
||||
#endif /* _DKP_BACKEND_ACPI_H */
|
||||
511
src/freebsd/dkp-backend.c
Normal file
511
src/freebsd/dkp-backend.c
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
|
||||
*
|
||||
* Licensed under the GNU General Public License Version 2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <kvm.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "dkp-acpi-native.h"
|
||||
#include "dkp-backend-acpi.h"
|
||||
#include "dkp-devd.h"
|
||||
#include "dkp-device-supply.h"
|
||||
#include "dkp-util.h"
|
||||
|
||||
#include "egg-debug.h"
|
||||
|
||||
#include "dkp-backend.h"
|
||||
#include "dkp-daemon.h"
|
||||
#include "dkp-marshal.h"
|
||||
#include "dkp-device.h"
|
||||
|
||||
#define DKP_BACKEND_REFRESH_TIMEOUT 30 /* seconds */
|
||||
#define DKP_BACKEND_SUSPEND_COMMAND "/usr/sbin/zzz"
|
||||
#define DKP_BACKEND_HIBERNATE_COMMAND "/usr/sbin/acpiconf -s 4"
|
||||
|
||||
static void dkp_backend_class_init (DkpBackendClass *klass);
|
||||
static void dkp_backend_init (DkpBackend *backend);
|
||||
static void dkp_backend_finalize (GObject *object);
|
||||
|
||||
static gboolean dkp_backend_refresh_devices (gpointer user_data);
|
||||
static gboolean dkp_backend_acpi_devd_notify (DkpBackend *backend, const char *system, const char *subsystem, const char *type, const char *data);
|
||||
static gboolean dkp_backend_create_new_device (DkpBackend *backend, DkpAcpiNative *native);
|
||||
static void dkp_backend_lid_coldplug (DkpBackend *backend);
|
||||
static gboolean dkp_backend_supports_sleep_state (const char *state);
|
||||
|
||||
#define DKP_BACKEND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_TYPE_BACKEND, DkpBackendPrivate))
|
||||
|
||||
struct DkpBackendPrivate
|
||||
{
|
||||
DkpDaemon *daemon;
|
||||
DkpDeviceList *device_list;
|
||||
GHashTable *handle_map;
|
||||
guint poll_timer_id;
|
||||
};
|
||||
|
||||
enum {
|
||||
SIGNAL_DEVICE_ADDED,
|
||||
SIGNAL_DEVICE_REMOVED,
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
static guint signals [SIGNAL_LAST] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (DkpBackend, dkp_backend, G_TYPE_OBJECT)
|
||||
|
||||
static const char *handlers[] = {
|
||||
"battery",
|
||||
};
|
||||
|
||||
DkpDevdHandler dkp_backend_acpi_devd_handler = {
|
||||
.notify = dkp_backend_acpi_devd_notify
|
||||
};
|
||||
|
||||
/**
|
||||
* dkp_backend_refresh_devices:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_backend_refresh_devices (gpointer user_data)
|
||||
{
|
||||
DkpBackend *backend;
|
||||
GPtrArray *array;
|
||||
DkpDevice *device;
|
||||
guint i;
|
||||
|
||||
backend = DKP_BACKEND (user_data);
|
||||
array = dkp_device_list_get_array (backend->priv->device_list);
|
||||
|
||||
for (i = 0; i < array->len; i++) {
|
||||
device = DKP_DEVICE (g_ptr_array_index (array, i));
|
||||
dkp_device_refresh_internal (device);
|
||||
}
|
||||
|
||||
g_ptr_array_unref (array);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_acpi_devd_notify:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_backend_acpi_devd_notify (DkpBackend *backend, const char *system, const char *subsystem, const char *type, const char *data)
|
||||
{
|
||||
GObject *object = NULL;
|
||||
DkpAcpiNative *native = NULL;
|
||||
|
||||
if (strcmp (system, "ACPI"))
|
||||
return FALSE;
|
||||
|
||||
if (!strcmp (subsystem, "ACAD")) {
|
||||
native = dkp_acpi_native_new ("hw.acpi.acline");
|
||||
object = dkp_device_list_lookup (backend->priv->device_list, G_OBJECT (native));
|
||||
} else if (!strcmp (subsystem, "CMBAT")) {
|
||||
char *ptr;
|
||||
int unit;
|
||||
|
||||
ptr = strstr (type, ".BAT");
|
||||
|
||||
if (ptr != NULL && sscanf (ptr, ".BAT%i", &unit)) {
|
||||
native = dkp_acpi_native_new_driver_unit ("battery", unit);
|
||||
object = dkp_device_list_lookup (backend->priv->device_list, G_OBJECT (native));
|
||||
if (object == NULL) {
|
||||
gpointer hptr;
|
||||
|
||||
hptr = g_hash_table_lookup (backend->priv->handle_map, type);
|
||||
if (hptr != NULL) {
|
||||
object = dkp_device_list_lookup (backend->priv->device_list, G_OBJECT (hptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!strcmp (subsystem, "Lid")) {
|
||||
gboolean is_present;
|
||||
gboolean is_closed;
|
||||
|
||||
g_object_get (backend->priv->daemon,
|
||||
"lid-is-present", &is_present, NULL);
|
||||
if (!is_present) {
|
||||
egg_warning ("received lid event without a configured lid; cold-plugging one");
|
||||
dkp_backend_lid_coldplug (backend);
|
||||
/* FALLTHROUGH */
|
||||
}
|
||||
|
||||
is_closed = (data != NULL && !strcmp (data, "notify=0x00")) ?
|
||||
TRUE : FALSE;
|
||||
g_object_set (backend->priv->daemon, "lid-is-closed", is_closed, NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (native == NULL)
|
||||
goto out;
|
||||
|
||||
if (object == NULL) {
|
||||
egg_warning ("did not find existing %s device; cold-plugging a new one", subsystem);
|
||||
dkp_backend_create_new_device (backend, native);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dkp_device_refresh_internal (DKP_DEVICE (object));
|
||||
|
||||
if (object != NULL)
|
||||
g_object_unref (object);
|
||||
out:
|
||||
if (native != NULL)
|
||||
g_object_unref (native);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_create_new_device:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_backend_create_new_device (DkpBackend *backend, DkpAcpiNative *native)
|
||||
{
|
||||
DkpDevice *device;
|
||||
gboolean ret;
|
||||
|
||||
device = DKP_DEVICE (dkp_device_supply_new ());
|
||||
ret = dkp_device_coldplug (device, backend->priv->daemon, G_OBJECT (native));
|
||||
if (!ret)
|
||||
g_object_unref (device);
|
||||
else {
|
||||
if (!strncmp (dkp_acpi_native_get_path (native), "dev.", strlen ("dev."))) {
|
||||
const char *path;
|
||||
|
||||
path = dkp_acpi_native_get_path (native);
|
||||
if (dkp_has_sysctl ("%s.%%location", path)) {
|
||||
char *location;
|
||||
|
||||
location = dkp_get_string_sysctl (NULL, "%s.%%location", path);
|
||||
if (location != NULL && strstr (location, "handle=") != NULL) {
|
||||
char *handle;
|
||||
|
||||
handle = strstr (location, "handle=");
|
||||
handle += strlen ("handle=");
|
||||
g_hash_table_insert (backend->priv->handle_map, g_strdup (handle), g_object_ref (native));
|
||||
}
|
||||
g_free (location);
|
||||
}
|
||||
}
|
||||
|
||||
g_signal_emit (backend, signals[SIGNAL_DEVICE_ADDED], 0, native, device);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_lid_coldplug:
|
||||
**/
|
||||
static void
|
||||
dkp_backend_lid_coldplug (DkpBackend *backend)
|
||||
{
|
||||
char *lid_state;
|
||||
|
||||
lid_state = dkp_get_string_sysctl (NULL, "hw.acpi.lid_switch_state");
|
||||
if (lid_state && strcmp (lid_state, "NONE")) {
|
||||
g_object_set (backend->priv->daemon, "lid-is-present", TRUE, NULL);
|
||||
}
|
||||
g_free (lid_state);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dkp_backend_coldplug:
|
||||
* @backend: The %DkpBackend class instance
|
||||
* @daemon: The %DkpDaemon controlling instance
|
||||
*
|
||||
* Finds all the devices already plugged in, and emits device-add signals for
|
||||
* each of them.
|
||||
*
|
||||
* Return value: %TRUE for success
|
||||
**/
|
||||
gboolean
|
||||
dkp_backend_coldplug (DkpBackend *backend, DkpDaemon *daemon)
|
||||
{
|
||||
DkpAcpiNative *acnative;
|
||||
int i;
|
||||
|
||||
backend->priv->daemon = g_object_ref (daemon);
|
||||
backend->priv->device_list = dkp_daemon_get_device_list (daemon);
|
||||
|
||||
for (i = 0; i < (int) G_N_ELEMENTS (handlers); i++) {
|
||||
int j;
|
||||
|
||||
for (j = 0; dkp_has_sysctl ("dev.%s.%i.%%driver", handlers[i], j); j++) {
|
||||
DkpAcpiNative *native;
|
||||
DkpDevice *device;
|
||||
GObject *object;
|
||||
|
||||
native = dkp_acpi_native_new_driver_unit (handlers[i], j);
|
||||
object = dkp_device_list_lookup (backend->priv->device_list, G_OBJECT (native));
|
||||
if (object != NULL) {
|
||||
device = DKP_DEVICE (object);
|
||||
egg_warning ("treating add event as change event on %s", dkp_device_get_object_path (device));
|
||||
dkp_device_refresh_internal (device);
|
||||
} else {
|
||||
dkp_backend_create_new_device (backend, native);
|
||||
}
|
||||
|
||||
if (object != NULL) {
|
||||
g_object_unref (object);
|
||||
}
|
||||
if (native != NULL) {
|
||||
g_object_unref (native);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dkp_backend_lid_coldplug (backend);
|
||||
|
||||
acnative = dkp_acpi_native_new ("hw.acpi.acline");
|
||||
dkp_backend_create_new_device (backend, acnative);
|
||||
g_object_unref (acnative);
|
||||
|
||||
dkp_devd_init (backend);
|
||||
|
||||
backend->priv->poll_timer_id =
|
||||
g_timeout_add_seconds (DKP_BACKEND_REFRESH_TIMEOUT,
|
||||
(GSourceFunc) dkp_backend_refresh_devices,
|
||||
backend);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_get_powersave_command:
|
||||
**/
|
||||
gchar *
|
||||
dkp_backend_get_powersave_command (DkpBackend *backend, gboolean powersave)
|
||||
{
|
||||
/* XXX: Do we want to use powerd here? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_get_suspend_command:
|
||||
**/
|
||||
gchar *
|
||||
dkp_backend_get_suspend_command (DkpBackend *backend)
|
||||
{
|
||||
return g_strdup (DKP_BACKEND_SUSPEND_COMMAND);
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_get_hibernate_command:
|
||||
**/
|
||||
gchar *
|
||||
dkp_backend_get_hibernate_command (DkpBackend *backend)
|
||||
{
|
||||
return g_strdup (DKP_BACKEND_HIBERNATE_COMMAND);
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_can_suspend:
|
||||
**/
|
||||
gboolean
|
||||
dkp_backend_can_suspend (DkpBackend *backend)
|
||||
{
|
||||
return dkp_backend_supports_sleep_state ("S3");
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_can_hibernate:
|
||||
**/
|
||||
gboolean
|
||||
dkp_backend_can_hibernate (DkpBackend *backend)
|
||||
{
|
||||
return dkp_backend_supports_sleep_state ("S4");
|
||||
}
|
||||
|
||||
gboolean
|
||||
dkp_backend_has_encrypted_swap (DkpBackend *backend)
|
||||
{
|
||||
/* XXX: Add support for GELI? */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gfloat
|
||||
dkp_backend_get_used_swap (DkpBackend *backend)
|
||||
{
|
||||
gfloat percent;
|
||||
kvm_t *kd;
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
int nswdev;
|
||||
struct kvm_swap kvmsw[16];
|
||||
|
||||
kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf);
|
||||
if (kd == NULL) {
|
||||
egg_warning ("failed to open kvm: '%s'", errbuf);
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
nswdev = kvm_getswapinfo (kd, kvmsw, 16, 0);
|
||||
if (nswdev == 0) {
|
||||
percent = 100.0f;
|
||||
goto out;
|
||||
}
|
||||
if (nswdev < 0) {
|
||||
egg_warning ("failed to get swap info: '%s'", kvm_geterr (kd));
|
||||
percent = 0.0f;
|
||||
goto out;
|
||||
}
|
||||
|
||||
percent = (gfloat) ((gfloat) ((gfloat) kvmsw[nswdev].ksw_used / (gfloat) kvmsw[nswdev].ksw_total) * 100.0f);
|
||||
|
||||
out:
|
||||
kvm_close (kd);
|
||||
|
||||
return percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_supports_sleep_state:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_backend_supports_sleep_state (const char *state)
|
||||
{
|
||||
char *sleep_states;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
sleep_states = dkp_get_string_sysctl (NULL, "hw.acpi.supported_sleep_state");
|
||||
if (sleep_states != NULL) {
|
||||
if (strstr (sleep_states, state) != NULL)
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
g_free (sleep_states);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_class_init:
|
||||
* @klass: The DkpBackendClass
|
||||
**/
|
||||
static void
|
||||
dkp_backend_class_init (DkpBackendClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->finalize = dkp_backend_finalize;
|
||||
|
||||
signals [SIGNAL_DEVICE_ADDED] =
|
||||
g_signal_new ("device-added",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (DkpBackendClass, device_added),
|
||||
NULL, NULL, dkp_marshal_VOID__POINTER_POINTER,
|
||||
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
signals [SIGNAL_DEVICE_REMOVED] =
|
||||
g_signal_new ("device-removed",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (DkpBackendClass, device_removed),
|
||||
NULL, NULL, dkp_marshal_VOID__POINTER_POINTER,
|
||||
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (DkpBackendPrivate));
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_init:
|
||||
**/
|
||||
static void
|
||||
dkp_backend_init (DkpBackend *backend)
|
||||
{
|
||||
backend->priv = DKP_BACKEND_GET_PRIVATE (backend);
|
||||
backend->priv->daemon = NULL;
|
||||
backend->priv->device_list = NULL;
|
||||
backend->priv->handle_map = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref);
|
||||
backend->priv->poll_timer_id = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_finalize:
|
||||
**/
|
||||
static void
|
||||
dkp_backend_finalize (GObject *object)
|
||||
{
|
||||
DkpBackend *backend;
|
||||
|
||||
g_return_if_fail (DKP_IS_BACKEND (object));
|
||||
|
||||
backend = DKP_BACKEND (object);
|
||||
|
||||
if (backend->priv->daemon != NULL)
|
||||
g_object_unref (backend->priv->daemon);
|
||||
if (backend->priv->device_list != NULL)
|
||||
g_object_unref (backend->priv->device_list);
|
||||
if (backend->priv->handle_map != NULL)
|
||||
g_hash_table_unref (backend->priv->handle_map);
|
||||
if (backend->priv->poll_timer_id > 0)
|
||||
g_source_remove (backend->priv->poll_timer_id);
|
||||
|
||||
G_OBJECT_CLASS (dkp_backend_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_backend_new:
|
||||
*
|
||||
* Return value: a new %DkpBackend object.
|
||||
**/
|
||||
DkpBackend *
|
||||
dkp_backend_new (void)
|
||||
{
|
||||
DkpBackend *backend;
|
||||
backend = g_object_new (DKP_TYPE_BACKEND, NULL);
|
||||
return DKP_BACKEND (backend);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*** MAKE CHECK TESTS ***
|
||||
***************************************************************************/
|
||||
#ifdef EGG_TEST
|
||||
#include "egg-test.h"
|
||||
|
||||
void
|
||||
dkp_backend_test (gpointer user_data)
|
||||
{
|
||||
EggTest *test = (EggTest *) user_data;
|
||||
DkpBackend *backend;
|
||||
|
||||
if (!egg_test_start (test, "DkpBackend"))
|
||||
return;
|
||||
|
||||
/************************************************************/
|
||||
egg_test_title (test, "get instance");
|
||||
backend = dkp_backend_new ();
|
||||
egg_test_assert (test, backend != NULL);
|
||||
|
||||
/* unref */
|
||||
g_object_unref (backend);
|
||||
|
||||
egg_test_end (test);
|
||||
}
|
||||
#endif
|
||||
|
||||
245
src/freebsd/dkp-devd.c
Normal file
245
src/freebsd/dkp-devd.c
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/***************************************************************************
|
||||
* CVSID: $Id$
|
||||
*
|
||||
* dkp-devd.c : process devd events
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Joe Marcus Clarke <marcus@FreeBSD.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "egg-debug.h"
|
||||
|
||||
#include "dkp-backend.h"
|
||||
#include "dkp-backend-acpi.h"
|
||||
#include "dkp-devd.h"
|
||||
|
||||
#define DKP_DEVD_SOCK_PATH "/var/run/devd.pipe"
|
||||
|
||||
#define DKP_DEVD_EVENT_NOTIFY '!'
|
||||
#define DKP_DEVD_EVENT_ADD '+'
|
||||
#define DKP_DEVD_EVENT_REMOVE '-'
|
||||
#define DKP_DEVD_EVENT_NOMATCH '?'
|
||||
|
||||
static DkpDevdHandler *handlers[] = {
|
||||
&dkp_backend_acpi_devd_handler,
|
||||
};
|
||||
|
||||
static gboolean dkp_devd_inited = FALSE;
|
||||
|
||||
#if 0
|
||||
static GHashTable *
|
||||
dkp_devd_parse_params (const char *str)
|
||||
{
|
||||
GHashTable *params;
|
||||
char **pairs;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail(str != NULL, FALSE);
|
||||
|
||||
params = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||
|
||||
pairs = g_strsplit(str, " ", 0);
|
||||
for (i = 0; pairs[i]; i++) {
|
||||
char *equal;
|
||||
|
||||
equal = strchr(pairs[i], '=');
|
||||
g_hash_table_insert(params,
|
||||
equal ? g_strndup(pairs[i], equal - pairs[i]) : g_strdup(pairs[i]),
|
||||
equal ? g_strdup(equal + 1) : NULL);
|
||||
}
|
||||
g_strfreev(pairs);
|
||||
|
||||
return params;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
dkp_devd_parse_notify (const char *event,
|
||||
char **system,
|
||||
char **subsystem,
|
||||
char **type,
|
||||
char **data)
|
||||
{
|
||||
char **items;
|
||||
gboolean status = FALSE;
|
||||
|
||||
/*
|
||||
!system=IFNET subsystem=bge0 type=LINK_DOWN
|
||||
*/
|
||||
|
||||
g_return_val_if_fail(event != NULL, FALSE);
|
||||
g_return_val_if_fail(system != NULL, FALSE);
|
||||
g_return_val_if_fail(subsystem != NULL, FALSE);
|
||||
g_return_val_if_fail(type != NULL, FALSE);
|
||||
g_return_val_if_fail(data != NULL, FALSE);
|
||||
|
||||
items = g_strsplit(event, " ", 0);
|
||||
if (g_strv_length(items) < 3)
|
||||
goto end;
|
||||
|
||||
if (! g_str_has_prefix(items[0], "system=") ||
|
||||
! g_str_has_prefix(items[1], "subsystem=") ||
|
||||
! g_str_has_prefix(items[2], "type="))
|
||||
goto end;
|
||||
|
||||
*system = g_strdup(items[0] + 7);
|
||||
*subsystem = g_strdup(items[1] + 10);
|
||||
*type = g_strdup(items[2] + 5);
|
||||
*data = g_strdup(items[3]); /* may be NULL */
|
||||
|
||||
status = TRUE;
|
||||
|
||||
end:
|
||||
g_strfreev(items);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
dkp_devd_process_notify_event (DkpBackend *backend,
|
||||
const char *system,
|
||||
const char *subsystem,
|
||||
const char *type,
|
||||
const char *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
g_return_if_fail(backend != NULL);
|
||||
g_return_if_fail(system != NULL);
|
||||
g_return_if_fail(subsystem != NULL);
|
||||
g_return_if_fail(type != NULL);
|
||||
g_return_if_fail(data != NULL);
|
||||
|
||||
for (i = 0; i < (int) G_N_ELEMENTS(handlers); i++)
|
||||
if (handlers[i]->notify && handlers[i]->notify(backend, system, subsystem, type, data))
|
||||
return;
|
||||
|
||||
/* no default action */
|
||||
}
|
||||
|
||||
static void
|
||||
dkp_devd_process_event (const char *event, gpointer user_data)
|
||||
{
|
||||
DkpBackend *backend;
|
||||
|
||||
g_return_if_fail(event != NULL);
|
||||
|
||||
backend = DKP_BACKEND(user_data);
|
||||
|
||||
egg_debug("received devd event: '%s'", event);
|
||||
|
||||
switch (event[0]) {
|
||||
case DKP_DEVD_EVENT_ADD:
|
||||
case DKP_DEVD_EVENT_REMOVE:
|
||||
/* Do nothing as we don't currently hotplug ACPI devices. */
|
||||
return;
|
||||
|
||||
case DKP_DEVD_EVENT_NOTIFY: {
|
||||
char *system;
|
||||
char *subsystem;
|
||||
char *type;
|
||||
char *data;
|
||||
|
||||
if (! dkp_devd_parse_notify(event + 1, &system, &subsystem, &type, &data))
|
||||
goto malformed;
|
||||
|
||||
dkp_devd_process_notify_event(backend, system, subsystem, type, data);
|
||||
|
||||
g_free(system);
|
||||
g_free(subsystem);
|
||||
g_free(type);
|
||||
g_free(data);
|
||||
}
|
||||
return;
|
||||
|
||||
case DKP_DEVD_EVENT_NOMATCH:
|
||||
/* Do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
malformed:
|
||||
egg_warning("malformed devd event: %s", event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dkp_devd_event_cb (GIOChannel *source, GIOCondition condition,
|
||||
gpointer user_data)
|
||||
{
|
||||
char *event;
|
||||
gsize terminator;
|
||||
GIOStatus status;
|
||||
|
||||
status = g_io_channel_read_line(source, &event, NULL, &terminator, NULL);
|
||||
|
||||
if (status == G_IO_STATUS_NORMAL) {
|
||||
event[terminator] = 0;
|
||||
dkp_devd_process_event(event, user_data);
|
||||
g_free(event);
|
||||
} else if (status == G_IO_STATUS_AGAIN) {
|
||||
dkp_devd_init(DKP_BACKEND(user_data));
|
||||
if (dkp_devd_inited) {
|
||||
int fd;
|
||||
|
||||
fd = g_io_channel_unix_get_fd(source);
|
||||
g_io_channel_shutdown(source, FALSE, NULL);
|
||||
close(fd);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dkp_devd_init (DkpBackend *backend)
|
||||
{
|
||||
int event_fd;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
event_fd = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (event_fd < 0) {
|
||||
egg_warning("failed to create event socket: '%s'", g_strerror(errno));
|
||||
dkp_devd_inited = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, DKP_DEVD_SOCK_PATH, sizeof(addr.sun_path));
|
||||
if (connect(event_fd, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
|
||||
GIOChannel *channel;
|
||||
|
||||
channel = g_io_channel_unix_new(event_fd);
|
||||
g_io_add_watch(channel, G_IO_IN, dkp_devd_event_cb, backend);
|
||||
g_io_channel_unref(channel);
|
||||
dkp_devd_inited = TRUE;
|
||||
} else {
|
||||
egg_warning("failed to connect to %s: '%s'", DKP_DEVD_SOCK_PATH,
|
||||
g_strerror(errno));
|
||||
close(event_fd);
|
||||
dkp_devd_inited = FALSE;
|
||||
}
|
||||
}
|
||||
46
src/freebsd/dkp-devd.h
Normal file
46
src/freebsd/dkp-devd.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/***************************************************************************
|
||||
* CVSID: $Id$
|
||||
*
|
||||
* dkp-devd.h : process devd events
|
||||
*
|
||||
* Copyright (C) 2006, 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef _DKP_DEVD_H
|
||||
#define _DKP_DEVD_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "dkp-backend.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* return TRUE to consume the event and stop processing */
|
||||
|
||||
gboolean (*notify) (DkpBackend *backend,
|
||||
const char *system,
|
||||
const char *subsystem,
|
||||
const char *type,
|
||||
const char *data); /* may be NULL */
|
||||
} DkpDevdHandler;
|
||||
|
||||
void dkp_devd_init (DkpBackend *backend);
|
||||
|
||||
#endif /* _DKP_DEVD_H */
|
||||
544
src/freebsd/dkp-device-supply.c
Normal file
544
src/freebsd/dkp-device-supply.c
Normal file
|
|
@ -0,0 +1,544 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2009 Joe Marcus Clarke <marcus@FreeBSD.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <dev/acpica/acpiio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib/gprintf.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "dkp-acpi-native.h"
|
||||
#include "dkp-util.h"
|
||||
|
||||
#include "egg-debug.h"
|
||||
|
||||
#include "dkp-enum.h"
|
||||
#include "dkp-device-supply.h"
|
||||
|
||||
#define DKP_ACPIDEV "/dev/acpi"
|
||||
|
||||
G_DEFINE_TYPE (DkpDeviceSupply, dkp_device_supply, DKP_TYPE_DEVICE)
|
||||
|
||||
static gboolean dkp_device_supply_refresh (DkpDevice *device);
|
||||
static DkpDeviceTechnology dkp_device_supply_convert_device_technology (const char *type);
|
||||
static gboolean dkp_device_supply_acline_coldplug (DkpDevice *device);
|
||||
static gboolean dkp_device_supply_battery_coldplug (DkpDevice *device, DkpAcpiNative *native);
|
||||
static gboolean dkp_device_supply_acline_set_properties (DkpDevice *device);
|
||||
static gboolean dkp_device_supply_battery_set_properties (DkpDevice *device, DkpAcpiNative *native);
|
||||
static gboolean dkp_device_supply_get_on_battery (DkpDevice *device, gboolean *on_battery);
|
||||
static gboolean dkp_device_supply_get_low_battery (DkpDevice *device, gboolean *low_battery);
|
||||
static gboolean dkp_device_supply_get_online (DkpDevice *device, gboolean *online);
|
||||
|
||||
/**
|
||||
* dkp_device_supply_convert_device_technology:
|
||||
*
|
||||
* This is taken from linux/dkp-device-supply.c.
|
||||
**/
|
||||
static DkpDeviceTechnology
|
||||
dkp_device_supply_convert_device_technology (const char *type)
|
||||
{
|
||||
if (type == NULL)
|
||||
return DKP_DEVICE_TECHNOLOGY_UNKNOWN;
|
||||
if (g_ascii_strcasecmp (type, "li-ion") == 0 ||
|
||||
g_ascii_strcasecmp (type, "lion") == 0)
|
||||
return DKP_DEVICE_TECHNOLOGY_LITHIUM_ION;
|
||||
if (g_ascii_strcasecmp (type, "pb") == 0 ||
|
||||
g_ascii_strcasecmp (type, "pbac") == 0)
|
||||
return DKP_DEVICE_TECHNOLOGY_LEAD_ACID;
|
||||
if (g_ascii_strcasecmp (type, "lip") == 0 ||
|
||||
g_ascii_strcasecmp (type, "lipo") == 0 ||
|
||||
g_ascii_strcasecmp (type, "li-poly") == 0)
|
||||
return DKP_DEVICE_TECHNOLOGY_LITHIUM_POLYMER;
|
||||
if (g_ascii_strcasecmp (type, "nimh") == 0)
|
||||
return DKP_DEVICE_TECHNOLOGY_NICKEL_METAL_HYDRIDE;
|
||||
if (g_ascii_strcasecmp (type, "lifo") == 0)
|
||||
return DKP_DEVICE_TECHNOLOGY_LITHIUM_IRON_PHOSPHATE;
|
||||
return DKP_DEVICE_TECHNOLOGY_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_reset_values:
|
||||
**/
|
||||
static void
|
||||
dkp_device_supply_reset_values (DkpDevice *device)
|
||||
{
|
||||
/* reset to default */
|
||||
g_object_set (device,
|
||||
"vendor", NULL,
|
||||
"model", NULL,
|
||||
"serial", NULL,
|
||||
"update-time", (guint64) 0,
|
||||
"power-supply", FALSE,
|
||||
"online", FALSE,
|
||||
"energy", (gdouble) 0.0,
|
||||
"is-present", FALSE,
|
||||
"is-rechargeable", FALSE,
|
||||
"has-history", FALSE,
|
||||
"has-statistics", FALSE,
|
||||
"state", DKP_DEVICE_STATE_UNKNOWN,
|
||||
"capacity", (gdouble) 0.0,
|
||||
"energy-empty", (gdouble) 0.0,
|
||||
"energy-full", (gdouble) 0.0,
|
||||
"energy-full-design", (gdouble) 0.0,
|
||||
"energy-rate", (gdouble) 0.0,
|
||||
"voltage", (gdouble) 0.0,
|
||||
"time-to-empty", (guint64) 0,
|
||||
"time-to-full", (guint64) 0,
|
||||
"percentage", (gdouble) 0.0,
|
||||
"technology", DKP_DEVICE_TECHNOLOGY_UNKNOWN,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_acline_coldplug:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_acline_coldplug (DkpDevice *device)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
g_object_set (device,
|
||||
"online", FALSE,
|
||||
"power-supply", TRUE,
|
||||
"type", DKP_DEVICE_TYPE_LINE_POWER,
|
||||
NULL);
|
||||
|
||||
ret = dkp_device_supply_acline_set_properties (device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_battery_coldplug:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_battery_coldplug (DkpDevice *device, DkpAcpiNative *native)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
g_object_set (device, "type", DKP_DEVICE_TYPE_BATTERY, NULL);
|
||||
ret = dkp_device_supply_battery_set_properties (device, native);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dkp_device_supply_battery_set_properties:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_battery_set_properties (DkpDevice *device, DkpAcpiNative *native)
|
||||
{
|
||||
int fd;
|
||||
gdouble volt, dvolt, rate, lastfull, cap, dcap, lcap, capacity;
|
||||
gboolean is_present;
|
||||
gboolean ret = FALSE;
|
||||
guint64 time_to_empty, time_to_full;
|
||||
char *vendor, *model, *serial;
|
||||
DkpDeviceTechnology technology;
|
||||
DkpDeviceState state;
|
||||
union acpi_battery_ioctl_arg battif, battst, battinfo;
|
||||
|
||||
if (!dkp_has_sysctl ("hw.acpi.battery.units"))
|
||||
return FALSE;
|
||||
|
||||
battif.unit = battst.unit = battinfo.unit =
|
||||
dkp_acpi_native_get_unit (native);
|
||||
fd = open (DKP_ACPIDEV, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
egg_warning ("unable to open %s: '%s'", DKP_ACPIDEV, g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ioctl (fd, ACPIIO_BATT_GET_BIF, &battif) == -1) {
|
||||
egg_warning ("ioctl ACPIIO_BATT_GET_BIF failed for battery %d: '%s'", battif.unit, g_strerror (errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ioctl (fd, ACPIIO_BATT_GET_BST, &battst) == -1) {
|
||||
egg_warning ("ioctl ACPIIO_BATT_GET_BST failed for battery %d: '%s'", battst.unit, g_strerror (errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ioctl (fd, ACPIIO_BATT_GET_BATTINFO, &battinfo) == -1) {
|
||||
egg_warning ("ioctl ACPIIO_BATT_GET_BATTINFO failed for battery %d: '%s'", battinfo.unit, g_strerror (errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
is_present = (battst.bst.state == ACPI_BATT_STAT_NOT_PRESENT) ? FALSE : TRUE;
|
||||
g_object_set (device, "is-present", is_present, NULL);
|
||||
|
||||
if (!is_present) {
|
||||
dkp_device_supply_reset_values (device);
|
||||
goto end;
|
||||
}
|
||||
|
||||
vendor = dkp_make_safe_string (battif.bif.oeminfo);
|
||||
model = dkp_make_safe_string (battif.bif.model);
|
||||
serial = dkp_make_safe_string (battif.bif.serial);
|
||||
technology = dkp_device_supply_convert_device_technology (battif.bif.type);
|
||||
|
||||
g_object_set (device,
|
||||
"vendor", vendor,
|
||||
"model", model,
|
||||
"serial", serial,
|
||||
"power-supply", TRUE,
|
||||
"technology", technology,
|
||||
"has-history", TRUE,
|
||||
"has-statistics", TRUE,
|
||||
NULL);
|
||||
g_free (vendor);
|
||||
g_free (model);
|
||||
g_free (serial);
|
||||
|
||||
g_object_set (device, "is-rechargeable",
|
||||
battif.bif.btech == 0 ? FALSE : TRUE, NULL);
|
||||
|
||||
volt = (gdouble) battst.bst.volt;
|
||||
dvolt = (gdouble) battif.bif.dvol;
|
||||
lastfull = (gdouble) battif.bif.lfcap;
|
||||
dcap = (gdouble) battif.bif.dcap;
|
||||
rate = (gdouble) battst.bst.rate;
|
||||
cap = (gdouble) battst.bst.cap;
|
||||
lcap = (gdouble) battif.bif.lcap;
|
||||
if (rate == 0xffff)
|
||||
rate = 0.0f;
|
||||
if (rate > 100.0f * 1000.0f)
|
||||
rate = 0.0f;
|
||||
|
||||
dvolt /= 1000.0f;
|
||||
volt /= 1000.0f;
|
||||
|
||||
if (battif.bif.units == ACPI_BIF_UNITS_MA) {
|
||||
if (dvolt <= 0.0f)
|
||||
dvolt = 1.0f;
|
||||
if (volt <= 0.0f || volt > dvolt)
|
||||
volt = dvolt;
|
||||
|
||||
dcap *= volt;
|
||||
lastfull *= volt;
|
||||
rate *= volt;
|
||||
cap *= volt;
|
||||
lcap *= volt;
|
||||
}
|
||||
|
||||
dcap /= 1000.0f;
|
||||
lastfull /= 1000.0f;
|
||||
rate /= 1000.0f;
|
||||
cap /= 1000.0f;
|
||||
lcap /= 1000.0f;
|
||||
|
||||
if (cap == 0.0f)
|
||||
rate = 0.0f;
|
||||
|
||||
capacity = 0.0f;
|
||||
if (lastfull > 0 && dcap > 0) {
|
||||
capacity = (lastfull / dcap) * 100.0f;
|
||||
if (capacity < 0)
|
||||
capacity = 0.0f;
|
||||
if (capacity > 100.0)
|
||||
capacity = 100.0f;
|
||||
}
|
||||
|
||||
g_object_set (device,
|
||||
"percentage", (gdouble) battinfo.battinfo.cap,
|
||||
"energy", cap,
|
||||
"energy-full", lastfull,
|
||||
"energy-full-design", dcap,
|
||||
"energy-rate", rate,
|
||||
"energy-empty", lcap,
|
||||
"voltage", volt,
|
||||
"capacity", capacity,
|
||||
NULL);
|
||||
|
||||
time_to_empty = 0;
|
||||
time_to_full = 0;
|
||||
|
||||
if (battinfo.battinfo.state & ACPI_BATT_STAT_DISCHARG) {
|
||||
state = DKP_DEVICE_STATE_DISCHARGING;
|
||||
if (battinfo.battinfo.min > 0)
|
||||
time_to_empty = battinfo.battinfo.min * 60;
|
||||
else if (rate > 0) {
|
||||
time_to_empty = 3600 * (cap / rate);
|
||||
if (time_to_empty > (20 * 60 * 60))
|
||||
time_to_empty = 0;
|
||||
}
|
||||
} else if (battinfo.battinfo.state & ACPI_BATT_STAT_CHARGING) {
|
||||
state = DKP_DEVICE_STATE_CHARGING;
|
||||
if (battinfo.battinfo.min > 0)
|
||||
time_to_full = battinfo.battinfo.min * 60;
|
||||
else if (rate > 0) {
|
||||
time_to_full = 3600 * ((lastfull - cap) / rate);
|
||||
if (time_to_full > (20 * 60 * 60))
|
||||
time_to_full = 0;
|
||||
}
|
||||
} else if (battinfo.battinfo.state & ACPI_BATT_STAT_CRITICAL) {
|
||||
state = DKP_DEVICE_STATE_EMPTY;
|
||||
} else if (battinfo.battinfo.state == 0) {
|
||||
state = DKP_DEVICE_STATE_FULLY_CHARGED;
|
||||
} else {
|
||||
state = DKP_DEVICE_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
g_object_set (device,
|
||||
"state", state,
|
||||
"time-to-empty", time_to_empty,
|
||||
"time-to-full", time_to_full,
|
||||
NULL);
|
||||
|
||||
end:
|
||||
close (fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_acline_set_properties:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_acline_set_properties (DkpDevice *device)
|
||||
{
|
||||
int acstate;
|
||||
|
||||
if (dkp_get_int_sysctl (&acstate, NULL, "hw.acpi.acline")) {
|
||||
g_object_set (device, "online", acstate ? TRUE : FALSE, NULL);
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_coldplug:
|
||||
* Return %TRUE on success, %FALSE if we failed to get data and should be removed
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_coldplug (DkpDevice *device)
|
||||
{
|
||||
DkpAcpiNative *native;
|
||||
const gchar *native_path;
|
||||
const gchar *driver;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
dkp_device_supply_reset_values (device);
|
||||
|
||||
native = DKP_ACPI_NATIVE (dkp_device_get_native (device));
|
||||
native_path = dkp_acpi_native_get_path (native);
|
||||
driver = dkp_acpi_native_get_driver (native);
|
||||
if (native_path == NULL) {
|
||||
egg_warning ("could not get native path for %p", device);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!strcmp (native_path, "hw.acpi.acline")) {
|
||||
ret = dkp_device_supply_acline_coldplug (device);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!g_strcmp0 (driver, "battery")) {
|
||||
ret = dkp_device_supply_battery_coldplug (device, native);
|
||||
goto out;
|
||||
}
|
||||
|
||||
egg_warning ("invalid device %s with driver %s", native_path, driver);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_refresh:
|
||||
*
|
||||
* Return %TRUE on success, %FALSE if we failed to refresh or no data
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_refresh (DkpDevice *device)
|
||||
{
|
||||
GObject *object;
|
||||
GTimeVal timeval;
|
||||
DkpDeviceType type;
|
||||
gboolean ret;
|
||||
|
||||
g_object_get (device, "type", &type, NULL);
|
||||
switch (type) {
|
||||
case DKP_DEVICE_TYPE_LINE_POWER:
|
||||
ret = dkp_device_supply_acline_set_properties (device);
|
||||
break;
|
||||
case DKP_DEVICE_TYPE_BATTERY:
|
||||
object = dkp_device_get_native (device);
|
||||
ret = dkp_device_supply_battery_set_properties (device, DKP_ACPI_NATIVE (object));
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
g_get_current_time (&timeval);
|
||||
g_object_set (device, "update-time", (guint64) timeval.tv_sec, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_get_on_battery:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_get_on_battery (DkpDevice *device, gboolean *on_battery)
|
||||
{
|
||||
DkpDeviceType type;
|
||||
DkpDeviceState state;
|
||||
gboolean is_present;
|
||||
|
||||
g_return_val_if_fail (on_battery != NULL, FALSE);
|
||||
|
||||
g_object_get (device,
|
||||
"type", &type,
|
||||
"state", &state,
|
||||
"is-present", &is_present,
|
||||
NULL);
|
||||
|
||||
if (type != DKP_DEVICE_TYPE_BATTERY)
|
||||
return FALSE;
|
||||
if (state == DKP_DEVICE_STATE_UNKNOWN)
|
||||
return FALSE;
|
||||
if (!is_present)
|
||||
return FALSE;
|
||||
|
||||
*on_battery = (state == DKP_DEVICE_STATE_DISCHARGING);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_get_low_battery:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_get_low_battery (DkpDevice *device, gboolean *low_battery)
|
||||
{
|
||||
gboolean ret;
|
||||
gboolean on_battery;
|
||||
gdouble percentage;
|
||||
|
||||
g_return_val_if_fail (low_battery != NULL, FALSE);
|
||||
|
||||
ret = dkp_device_supply_get_on_battery (device, &on_battery);
|
||||
if (!ret)
|
||||
return FALSE;
|
||||
|
||||
if (!on_battery) {
|
||||
*low_battery = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_object_get (device, "percentage", &percentage, NULL);
|
||||
*low_battery = (percentage < 10.0f);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_get_online:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_device_supply_get_online (DkpDevice *device, gboolean *online)
|
||||
{
|
||||
DkpDeviceType type;
|
||||
gboolean online_tmp;
|
||||
|
||||
g_return_val_if_fail (online != NULL, FALSE);
|
||||
|
||||
g_object_get (device,
|
||||
"type", &type,
|
||||
"online", &online_tmp,
|
||||
NULL);
|
||||
|
||||
if (type != DKP_DEVICE_TYPE_LINE_POWER)
|
||||
return FALSE;
|
||||
|
||||
*online = online_tmp;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_init:
|
||||
**/
|
||||
static void
|
||||
dkp_device_supply_init (DkpDeviceSupply *supply)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_finalize:
|
||||
**/
|
||||
static void
|
||||
dkp_device_supply_finalize (GObject *object)
|
||||
{
|
||||
DkpDeviceSupply *supply;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (DKP_IS_SUPPLY (object));
|
||||
|
||||
supply = DKP_DEVICE_SUPPLY (object);
|
||||
|
||||
G_OBJECT_CLASS (dkp_device_supply_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_class_init:
|
||||
**/
|
||||
static void
|
||||
dkp_device_supply_class_init (DkpDeviceSupplyClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
DkpDeviceClass *device_class = DKP_DEVICE_CLASS (klass);
|
||||
|
||||
object_class->finalize = dkp_device_supply_finalize;
|
||||
device_class->get_on_battery = dkp_device_supply_get_on_battery;
|
||||
device_class->get_low_battery = dkp_device_supply_get_low_battery;
|
||||
device_class->get_online = dkp_device_supply_get_online;
|
||||
device_class->coldplug = dkp_device_supply_coldplug;
|
||||
device_class->refresh = dkp_device_supply_refresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_device_supply_new:
|
||||
**/
|
||||
DkpDeviceSupply *
|
||||
dkp_device_supply_new (void)
|
||||
{
|
||||
return g_object_new (DKP_TYPE_SUPPLY, NULL);
|
||||
}
|
||||
|
||||
56
src/freebsd/dkp-device-supply.h
Normal file
56
src/freebsd/dkp-device-supply.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2008 David Zeuthen <davidz@redhat.com>
|
||||
* Copyright (C) 2008 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DKP_DEVICE_SUPPLY_H__
|
||||
#define __DKP_DEVICE_SUPPLY_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include "dkp-device.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define DKP_TYPE_SUPPLY (dkp_device_supply_get_type ())
|
||||
#define DKP_DEVICE_SUPPLY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_TYPE_SUPPLY, DkpDeviceSupply))
|
||||
#define DKP_DEVICE_SUPPLY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_TYPE_SUPPLY, DkpDeviceSupplyClass))
|
||||
#define DKP_IS_SUPPLY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_TYPE_SUPPLY))
|
||||
#define DKP_IS_SUPPLY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_TYPE_SUPPLY))
|
||||
#define DKP_DEVICE_SUPPLY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_SUPPLY, DkpDeviceSupplyClass))
|
||||
|
||||
typedef struct DkpDeviceSupplyPrivate DkpDeviceSupplyPrivate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DkpDevice parent;
|
||||
DkpDeviceSupplyPrivate *priv;
|
||||
} DkpDeviceSupply;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DkpDeviceClass parent_class;
|
||||
} DkpDeviceSupplyClass;
|
||||
|
||||
GType dkp_device_supply_get_type (void);
|
||||
DkpDeviceSupply *dkp_device_supply_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __DKP_DEVICE_SUPPLY_H__ */
|
||||
|
||||
66
src/freebsd/dkp-native.c
Normal file
66
src/freebsd/dkp-native.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include "dkp-acpi-native.h"
|
||||
|
||||
#include "dkp-native.h"
|
||||
|
||||
/**
|
||||
* dkp_native_get_native_path:
|
||||
* @object: the native tracking object
|
||||
*
|
||||
* This converts a GObject used as the device data into a native path.
|
||||
*
|
||||
* Return value: The native path for the device which is unique, e.g. "/sys/class/power/BAT1"
|
||||
**/
|
||||
const gchar *
|
||||
dkp_native_get_native_path (GObject *object)
|
||||
{
|
||||
return dkp_acpi_native_get_path (DKP_ACPI_NATIVE (object));
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*** MAKE CHECK TESTS ***
|
||||
***************************************************************************/
|
||||
#ifdef EGG_TEST
|
||||
#include "egg-test.h"
|
||||
|
||||
void
|
||||
dkp_native_test (gpointer user_data)
|
||||
{
|
||||
EggTest *test = (EggTest *) user_data;
|
||||
DkpAcpiNative *dan;
|
||||
const gchar *path;
|
||||
|
||||
if (!egg_test_start (test, "DkpNative"))
|
||||
return;
|
||||
|
||||
/************************************************************/
|
||||
egg_test_title (test, "get instance");
|
||||
dan = dkp_acpi_native_new_driver_unit ("battery", 0);
|
||||
path = dkp_native_get_native_path (dan);
|
||||
egg_test_assert (test, (g_strcmp0 (path, "dev.battery.0") == 0));
|
||||
g_object_unref (dan);
|
||||
|
||||
egg_test_end (test);
|
||||
}
|
||||
#endif
|
||||
|
||||
145
src/freebsd/dkp-util.c
Normal file
145
src/freebsd/dkp-util.c
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/***************************************************************************
|
||||
* CVSID: $Id$
|
||||
*
|
||||
* dkp-util.c : utilities
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Jean-Yves Lefort <jylefort@FreeBSD.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "egg-debug.h"
|
||||
|
||||
#include "dkp-util.h"
|
||||
|
||||
gboolean
|
||||
dkp_has_sysctl (const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *name;
|
||||
size_t value_len;
|
||||
gboolean status;
|
||||
|
||||
g_return_val_if_fail(format != NULL, FALSE);
|
||||
|
||||
va_start(args, format);
|
||||
name = g_strdup_vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
status = sysctlbyname(name, NULL, &value_len, NULL, 0) == 0;
|
||||
|
||||
g_free(name);
|
||||
return status;
|
||||
}
|
||||
|
||||
gboolean
|
||||
dkp_get_int_sysctl (int *value, GError **err, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *name;
|
||||
size_t value_len = sizeof(int);
|
||||
gboolean status;
|
||||
|
||||
g_return_val_if_fail(value != NULL, FALSE);
|
||||
g_return_val_if_fail(format != NULL, FALSE);
|
||||
|
||||
va_start(args, format);
|
||||
name = g_strdup_vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
status = sysctlbyname(name, value, &value_len, NULL, 0) == 0;
|
||||
if (! status)
|
||||
g_set_error(err, 0, 0, "%s", g_strerror(errno));
|
||||
|
||||
g_free(name);
|
||||
return status;
|
||||
}
|
||||
|
||||
char *
|
||||
dkp_get_string_sysctl (GError **err, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *name;
|
||||
size_t value_len;
|
||||
char *str = NULL;
|
||||
|
||||
g_return_val_if_fail(format != NULL, FALSE);
|
||||
|
||||
va_start(args, format);
|
||||
name = g_strdup_vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
if (sysctlbyname(name, NULL, &value_len, NULL, 0) == 0) {
|
||||
str = g_new(char, value_len + 1);
|
||||
if (sysctlbyname(name, str, &value_len, NULL, 0) == 0)
|
||||
str[value_len] = 0;
|
||||
else {
|
||||
g_free(str);
|
||||
str = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (! str)
|
||||
g_set_error(err, 0, 0, "%s", g_strerror(errno));
|
||||
|
||||
g_free(name);
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_util_make_safe_string:
|
||||
*
|
||||
* This is adapted from linux/dkp-device-supply.c.
|
||||
**/
|
||||
char *
|
||||
dkp_make_safe_string (const char *text)
|
||||
{
|
||||
guint i;
|
||||
guint idx = 0;
|
||||
char *ret;
|
||||
|
||||
/* no point in checking */
|
||||
if (text == NULL)
|
||||
return NULL;
|
||||
|
||||
ret = g_strdup (text);
|
||||
|
||||
/* shunt up only safe chars */
|
||||
for (i = 0; ret[i] != '\0'; i++) {
|
||||
if (g_ascii_isprint (ret[i])) {
|
||||
/* only copy if the address is going to change */
|
||||
if (idx != i)
|
||||
ret[idx] = ret[i];
|
||||
idx++;
|
||||
} else {
|
||||
egg_debug ("invalid char '%c'", ret[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure null terminated */
|
||||
ret[idx] = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
50
src/freebsd/dkp-util.h
Normal file
50
src/freebsd/dkp-util.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/***************************************************************************
|
||||
* CVSID: $Id$
|
||||
*
|
||||
* dkp-util.h : utilities
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Jean-Yves Lefort <jylefort@FreeBSD.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef _DKP_UTIL_H
|
||||
#define _DKP_UTIL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define DKP_BOOL_TO_STRING(val) ((val) ? "true" : "false")
|
||||
|
||||
#define DKP_LIST_FOREACH(var, head) \
|
||||
for ((var) = (head); \
|
||||
(var); \
|
||||
(var) = (var)->next)
|
||||
|
||||
gboolean dkp_has_sysctl (const char *format, ...) G_GNUC_PRINTF(1, 2);
|
||||
gboolean dkp_get_int_sysctl (int *value,
|
||||
GError **err,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(3, 4);
|
||||
char *dkp_get_string_sysctl (GError **err,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
char *dkp_make_safe_string (const char *text);
|
||||
|
||||
#endif /* _DKP_UTIL_H */
|
||||
Loading…
Add table
Reference in a new issue