summaryrefslogtreecommitdiff
path: root/src/xfpm-hal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xfpm-hal.c')
-rw-r--r--src/xfpm-hal.c1131
1 files changed, 1131 insertions, 0 deletions
diff --git a/src/xfpm-hal.c b/src/xfpm-hal.c
new file mode 100644
index 00000000..4cfda168
--- /dev/null
+++ b/src/xfpm-hal.c
@@ -0,0 +1,1131 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+ *
+ * * Copyright (C) 2008 Ali <aliov@xfce.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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include "xfpm-hal.h"
+#include "xfpm-debug.h"
+#include "xfpm-dbus-messages.h"
+
+#include "xfpm-marshal.h"
+
+#ifndef _
+#define _(x) x
+#endif
+
+/* Init */
+static void xfpm_hal_class_init(XfpmHalClass *klass);
+static void xfpm_hal_init (XfpmHal *xfpm_hal);
+static void xfpm_hal_finalize (GObject *object);
+
+/*functions listner to HAL events*/
+static void xfpm_hal_device_added (LibHalContext *ctx,
+ const gchar *udi);
+
+static void xfpm_hal_device_removed (LibHalContext *ctx,
+ const gchar *udi);
+
+static void xfpm_hal_device_property_modified (LibHalContext *ctx,
+ const gchar *udi,
+ const gchar *key,
+ dbus_bool_t is_removed,
+ dbus_bool_t is_added);
+static void xfpm_hal_device_condition (LibHalContext *ctx,
+ const gchar *udi,
+ const gchar *condition_name,
+ const gchar *condition_detail);
+
+static gboolean xfpm_hal_monitor (XfpmHal *xfpm_hal);
+
+#define XFPM_HAL_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE((o),XFPM_TYPE_HAL,XfpmHalPrivate))
+
+GQuark
+xfpm_hal_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("xfpm_hal_error");
+
+ return quark;
+}
+
+struct XfpmHalPrivate
+{
+
+ DBusConnection *connection;
+ LibHalContext *ctx;
+ gboolean connected;
+
+};
+
+enum
+{
+ XFPM_DEVICE_ADDED,
+ XFPM_DEVICE_REMOVED,
+ XFPM_DEVICE_PROPERTY_CHANGED,
+ XFPM_DEVICE_CONDITION,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0,};
+
+G_DEFINE_TYPE(XfpmHal,xfpm_hal,G_TYPE_OBJECT)
+
+static void
+xfpm_hal_class_init(XfpmHalClass *klass) {
+
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ object_class->finalize = xfpm_hal_finalize;
+
+ g_type_class_add_private(klass,sizeof(XfpmHalPrivate));
+
+ signals[XFPM_DEVICE_ADDED] = g_signal_new("xfpm-device-added",
+ XFPM_TYPE_HAL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(XfpmHalClass,device_added),
+ NULL,NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,1,G_TYPE_STRING);
+
+ signals[XFPM_DEVICE_REMOVED] = g_signal_new("xfpm-device-removed",
+ XFPM_TYPE_HAL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(XfpmHalClass,device_removed),
+ NULL,NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,1,G_TYPE_STRING);
+
+ signals[XFPM_DEVICE_PROPERTY_CHANGED] = g_signal_new("xfpm-device-property-changed",
+ XFPM_TYPE_HAL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(XfpmHalClass,device_property_changed),
+ NULL,NULL,
+ _xfpm_marshal_VOID__STRING_STRING_BOOLEAN_BOOLEAN,
+ G_TYPE_NONE,4,
+ G_TYPE_STRING,G_TYPE_STRING,
+ G_TYPE_BOOLEAN,G_TYPE_BOOLEAN);
+
+ signals[XFPM_DEVICE_CONDITION] = g_signal_new("xfpm-device-condition",
+ XFPM_TYPE_HAL,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(XfpmHalClass,device_condition),
+ NULL,NULL,
+ _xfpm_marshal_VOID__STRING_STRING_STRING,
+ G_TYPE_NONE,3,
+ G_TYPE_STRING,G_TYPE_STRING,
+ G_TYPE_STRING);
+
+}
+
+static void
+xfpm_hal_init(XfpmHal *xfpm_hal) {
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ priv->ctx = NULL;
+
+ // If this happens then nobody cares
+ if ( !xfpm_hal_monitor(xfpm_hal) )
+ {
+ g_printerr(_("Error monitoring HAL events"));
+ g_print("\n");
+ priv->connected = FALSE;
+ }
+ else
+ {
+ priv->connected = TRUE;
+ }
+}
+
+static void
+xfpm_hal_finalize(GObject *object) {
+
+ XfpmHal *xfpm_hal;
+ xfpm_hal = XFPM_HAL(object);
+ xfpm_hal->priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ if ( xfpm_hal->priv->ctx )
+ {
+ libhal_ctx_shutdown(xfpm_hal->priv->ctx,NULL);
+ libhal_ctx_free(xfpm_hal->priv->ctx);
+ }
+
+ if ( xfpm_hal->priv->connection )
+ {
+ dbus_connection_unref(xfpm_hal->priv->connection);
+ }
+
+ G_OBJECT_CLASS(xfpm_hal_parent_class)->finalize(object);
+}
+
+XfpmHal *
+xfpm_hal_new(void) {
+
+ XfpmHal *xfpm_hal = NULL;
+ xfpm_hal = g_object_new (XFPM_TYPE_HAL,NULL);
+ return xfpm_hal;
+
+}
+
+static void
+xfpm_hal_device_added(LibHalContext *ctx,const gchar *udi) {
+
+ XfpmHal *xfpm_hal = libhal_ctx_get_user_data(ctx);
+ g_signal_emit(G_OBJECT(xfpm_hal),signals[XFPM_DEVICE_ADDED],0,udi);
+
+}
+
+static void
+xfpm_hal_device_removed(LibHalContext *ctx,const gchar *udi) {
+
+ XfpmHal *xfpm_hal = libhal_ctx_get_user_data(ctx);
+ g_signal_emit(G_OBJECT(xfpm_hal),signals[XFPM_DEVICE_REMOVED],0,udi);
+
+}
+
+static void
+xfpm_hal_device_property_modified(LibHalContext *ctx,const gchar *udi,
+ const gchar *key,dbus_bool_t is_removed,
+ dbus_bool_t is_added) {
+
+ XfpmHal *xfpm_hal = libhal_ctx_get_user_data(ctx);
+ g_signal_emit(G_OBJECT(xfpm_hal),signals[XFPM_DEVICE_PROPERTY_CHANGED],0,udi,key,is_removed,is_added);
+
+}
+
+static void xfpm_hal_device_condition (LibHalContext *ctx,
+ const gchar *udi,
+ const gchar *condition_name,
+ const gchar *condition_detail) {
+
+ XfpmHal *xfpm_hal = libhal_ctx_get_user_data(ctx);
+ g_signal_emit(G_OBJECT(xfpm_hal),signals[XFPM_DEVICE_CONDITION],0,udi,condition_name,condition_detail);
+
+}
+
+
+static gboolean
+xfpm_hal_monitor(XfpmHal *xfpm_hal) {
+
+ XfpmHalPrivate *priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ DBusError error;
+ dbus_error_init(&error);
+
+ priv->connection = dbus_bus_get(DBUS_BUS_SYSTEM,&error);
+
+ if ( !priv->connection || dbus_error_is_set(&error) )
+ {
+ g_critical(_("Unable to connect to DBus: %s"),error.message);
+ g_print("\n");
+ return FALSE;
+ }
+
+ if ( !xfpm_dbus_name_has_owner(priv->connection,HAL_DBUS_SERVICE) )
+ {
+ g_critical(_("HAL is not running or not responding"));
+ g_print("\n");
+ return FALSE;
+ }
+ priv->ctx = libhal_ctx_new();
+
+ dbus_connection_setup_with_g_main(priv->connection,NULL);
+
+ libhal_ctx_set_dbus_connection(priv->ctx,priv->connection);
+ libhal_ctx_init(priv->ctx,&error);
+
+ if ( dbus_error_is_set(&error) ) {
+ g_printerr(_("Unable to connect to DBus: %s"),error.message);
+ g_print("\n");
+ return FALSE;
+ }
+
+ libhal_ctx_set_user_data(priv->ctx,xfpm_hal);
+ return TRUE;
+}
+
+gboolean xfpm_hal_is_connected(XfpmHal *hal)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(hal),FALSE);
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(hal);
+
+ return (priv->connected);
+}
+
+gboolean xfpm_hal_power_management_can_be_used(XfpmHal *hal)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(hal),FALSE);
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusError error;
+
+ message = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_POWER,
+ "JustToCheck");
+
+ if (!message)
+ {
+ return FALSE;
+ }
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,message,2000,&error);
+ dbus_message_unref(message);
+
+ if ( reply ) dbus_message_unref(reply);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ /* This is the only one place in the program we will
+ * be happy when we seeDBusError is set */
+ if (!strcmp(error.name,"org.freedesktop.DBus.Error.UnknownMethod"))
+ {
+ dbus_error_free(&error);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+gboolean xfpm_hal_cpu_freq_interface_can_be_used(XfpmHal *hal)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(hal),FALSE);
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusError error;
+
+ message = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_CPU,
+ "CpuFreqJustToCheck");
+
+ if (!message)
+ {
+ return FALSE;
+ }
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,message,2000,&error);
+ dbus_message_unref(message);
+
+ if ( reply ) dbus_message_unref(reply);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ if (!strcmp(error.name,"org.freedesktop.DBus.Error.UnknownMethod"))
+ {
+ dbus_error_free(&error);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+gboolean xfpm_hal_connect_to_signals(XfpmHal *hal,
+ gboolean device_removed,
+ gboolean device_added,
+ gboolean device_property_changed,
+ gboolean device_condition)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(hal),FALSE);
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusError error;
+ dbus_error_init(&error);
+
+ if (device_added )
+ {
+ libhal_ctx_set_device_added(priv->ctx,xfpm_hal_device_added);
+ }
+ if ( device_removed )
+ {
+ libhal_ctx_set_device_removed(priv->ctx,xfpm_hal_device_removed);
+ }
+ if ( device_property_changed )
+ {
+ libhal_ctx_set_device_property_modified(priv->ctx,xfpm_hal_device_property_modified);
+ }
+ if ( device_condition )
+ {
+ libhal_ctx_set_device_condition(priv->ctx,xfpm_hal_device_condition);
+ }
+
+ libhal_device_property_watch_all(priv->ctx,&error);
+
+ if ( dbus_error_is_set(&error) ) {
+ g_printerr(_("Unable to watch device using HAL: %s"),error.message);
+ g_print("\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gchar **
+xfpm_hal_get_device_udi_by_capability(XfpmHal *xfpm_hal,const gchar *capability,
+ gint *num,GError **gerror) {
+
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),NULL);
+ XfpmHalPrivate *priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,NULL);
+
+ gchar **udi_info = NULL;
+ DBusError error;
+
+ dbus_error_init(&error);
+ udi_info = libhal_find_device_by_capability(priv->ctx,
+ capability,
+ num,
+ &error);
+ if ( dbus_error_is_set(&error) ) {
+ g_printerr("Cannot get device by capability: %s\n",error.message);
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return NULL;
+ } else {
+ return udi_info;
+ }
+}
+
+gint32
+xfpm_hal_get_int_info(XfpmHal *xfpm_hal,const gchar *udi,
+ const gchar *property,GError **gerror) {
+
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),-1);
+ XfpmHalPrivate *priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,-1);
+
+ DBusError error;
+ gint ret;
+
+ dbus_error_init(&error);
+
+ ret = libhal_device_get_property_int(priv->ctx,
+ udi,
+ property,
+ &error);
+
+
+ if ( dbus_error_is_set(&error)) {
+ g_printerr("Cannot get device int info : %s\n",error.message);
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return -1;
+ } else {
+ return ret;
+ }
+
+}
+
+gchar *
+xfpm_hal_get_string_info(XfpmHal *xfpm_hal,const gchar *udi,
+ const gchar *property,GError **gerror) {
+
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),NULL);
+ XfpmHalPrivate *priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,NULL);
+
+ DBusError error;
+ gchar *ret;
+
+ dbus_error_init(&error);
+
+ ret = libhal_device_get_property_string(priv->ctx,
+ udi,
+ property,
+ &error);
+
+
+ if ( dbus_error_is_set(&error) ) {
+ g_printerr("Cannot get device string info : %s\n",error.message);
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return NULL;
+ } else {
+ return ret;
+ }
+
+}
+
+gboolean
+xfpm_hal_get_bool_info(XfpmHal *xfpm_hal,const gchar *udi,
+ const gchar *property,GError **gerror) {
+
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),FALSE);
+ XfpmHalPrivate *priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusError error;
+ gboolean ret;
+
+ dbus_error_init(&error);
+
+ ret = libhal_device_get_property_bool(priv->ctx,
+ udi,
+ property,
+ &error);
+
+
+ if ( dbus_error_is_set(&error)) {
+ g_printerr("Cannot get device bool info : %s\n",error.message);
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return FALSE;
+ } else {
+ return ret;
+ }
+
+}
+
+gboolean
+xfpm_hal_device_have_key (XfpmHal *xfpm_hal,const gchar *udi,
+ const gchar *key)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),FALSE);
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ gboolean ret = libhal_device_property_exists(priv->ctx,
+ udi,
+ key,
+ &error);
+ if ( dbus_error_is_set(&error) )
+ {
+ g_printerr("Error getting device property %s\n",error.message);
+ dbus_error_free(&error);
+ return FALSE;
+ }
+
+ return ret;
+}
+
+gboolean
+xfpm_hal_device_have_capability(XfpmHal *xfpm_hal,
+ const gchar *udi,
+ const gchar *capability)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),FALSE);
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusError error;
+ dbus_error_init(&error);
+
+ gboolean ret = libhal_device_query_capability(priv->ctx,
+ udi,
+ capability,
+ &error);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ g_printerr("Error query device capability %s\n",error.message);
+ dbus_error_free(&error);
+ return FALSE;
+ }
+
+ return ret;
+}
+
+gboolean xfpm_hal_shutdown(XfpmHal *xfpm_hal)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),FALSE);
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusMessage *mess;
+
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_POWER,
+ "Shutdown");
+
+ if (!mess) {
+ return FALSE;
+ }
+
+ if(!dbus_connection_send(priv->connection,
+ mess,
+ NULL)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static const gchar *
+_filter_error_message(const gchar *error)
+{
+ if(!strcmp("No back-end for your operating system",error))
+ {
+ return _("No back-end for your operating system");
+ }
+ else if (!strcmp("No hibernate script found",error) )
+ {
+ return _("No hibernate script found");
+ }
+ else if (!strcmp("No suspend script found",error) )
+ {
+ return _("No suspend script found");
+ }
+ else if (!strcmp("No suspend method found",error) )
+ {
+ return _("No suspend method found");
+ }
+ else if (!strcmp("No hibernate method found",error))
+ {
+ return _("No hibernate method found");
+ }
+ return NULL;
+}
+
+gboolean
+xfpm_hal_hibernate(XfpmHal *xfpm_hal,GError **gerror,guint8 *critical)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),FALSE);
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusMessage *mess,*reply;
+ DBusError error;
+ gint exit_code;
+
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_POWER,
+ "Hibernate");
+ if (!mess)
+ {
+ *critical = 1;
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ return FALSE;
+ }
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,
+ mess,
+ -1,
+ &error);
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ XFPM_DEBUG("error=%s\n",error.message);
+ const gchar *error_ret = _filter_error_message(error.message);
+ if ( error_ret )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,"%s",error_ret);
+ *critical = 1;
+ }
+ else
+ {
+ *critical = 0;
+ }
+ dbus_error_free(&error);
+ return FALSE;
+ }
+
+ if ( !reply )
+ {
+ critical = 0;
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Message hibernate didn't get a reply"));
+ return FALSE;
+ }
+
+ *critical = 1;
+ switch(dbus_message_get_type(reply)) {
+
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ dbus_message_get_args(reply,NULL,
+ DBUS_TYPE_INT32,
+ &exit_code,
+ DBUS_TYPE_INVALID);
+ XFPM_DEBUG("MESSAGE_TYPE_RETURN exit_code=%d\n",exit_code);
+ dbus_message_unref(reply);
+ if ( exit_code == 0 )
+ {
+ *critical = 0;
+ return TRUE;
+ }
+ if ( exit_code > 1 )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("System failed to hibernate"));
+ return FALSE;
+ }
+ break;
+ case DBUS_MESSAGE_TYPE_ERROR:
+ dbus_message_unref(reply);
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Error occured while trying to suspend"));
+ return FALSE;
+ default:
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Unknown reply from the message daemon"));
+ dbus_message_unref(reply);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean
+xfpm_hal_suspend(XfpmHal *xfpm_hal,GError **gerror,guint8 *critical)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),FALSE);
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,FALSE);
+
+ DBusMessage *mess,*reply;
+ DBusError error;
+ int seconds = 0;
+ gint exit_code;
+
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_POWER,
+ "Suspend");
+ if (!mess)
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ *critical = 1;
+ return FALSE;
+ }
+
+ dbus_message_append_args(mess,DBUS_TYPE_INT32,&seconds,DBUS_TYPE_INVALID);
+
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,
+ mess,
+ -1,
+ &error);
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ XFPM_DEBUG("error=%s\n",error.message);
+ const gchar *error_ret = _filter_error_message(error.message);
+ if ( error_ret )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,"%s",error_ret);
+ *critical = 1;
+ }
+ else
+ {
+ *critical = 0;
+ }
+ dbus_error_free(&error);
+ return FALSE;
+ }
+
+ if ( !reply )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Message suspend didn't get a reply"));
+ *critical = 0;
+ return FALSE;
+ }
+
+ *critical = 1;
+ switch(dbus_message_get_type(reply)) {
+
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ dbus_message_get_args(reply,NULL,
+ DBUS_TYPE_INT32,
+ &exit_code,
+ DBUS_TYPE_INVALID);
+ XFPM_DEBUG("MESSAGE_TYPE_RETURN exit_code=%d\n",exit_code);
+ dbus_message_unref(reply);
+ if ( exit_code == 0 )
+ {
+ *critical = 0;
+ return TRUE;
+ }
+ if ( exit_code > 1 )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("System failed to suspend"));
+ return FALSE;
+ }
+ break;
+ case DBUS_MESSAGE_TYPE_ERROR:
+ dbus_message_unref(reply);
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Error occured while trying to suspend"));
+ return FALSE;
+ default:
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Unknown reply from the message daemon"));
+ dbus_message_unref(reply);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+xfpm_hal_set_brightness (XfpmHal *xfpm_hal,
+ const gchar *interface,
+ gint32 level,
+ GError **gerror)
+
+{
+ g_return_if_fail(XFPM_IS_HAL(xfpm_hal));
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_if_fail(priv->connected == TRUE);
+
+ DBusMessage *mess,*reply;
+ DBusError error;
+
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ interface,
+ HAL_DBUS_INTERFACE_LCD,
+ "SetBrightness");
+ if (!mess)
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ return;
+ }
+
+ dbus_message_append_args(mess,DBUS_TYPE_INT32,&level,DBUS_TYPE_INVALID);
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,mess,-1,&error);
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return;
+ }
+
+ if ( !reply )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("No reply from HAL daemon to set monitor brightness level"));
+ return;
+ }
+
+ dbus_message_unref(reply);
+ return;
+}
+
+gint32
+xfpm_hal_get_brightness (XfpmHal *xfpm_hal,
+ const gchar *interface,
+ GError **gerror)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),-1);
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,-1);
+
+ DBusMessage *mess,*reply;
+ DBusError error;
+ gint32 brightness_level = 0;
+
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ interface,
+ HAL_DBUS_INTERFACE_LCD,
+ "GetBrightness");
+ if (!mess)
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ return -1;
+ }
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,mess,-1,&error);
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return -1;
+ }
+
+ if ( !reply )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("No reply from HAL daemon to get monitor brightness level"));
+ return -1;
+ }
+
+ dbus_message_get_args(reply,NULL,DBUS_TYPE_INT32,&brightness_level);
+ dbus_message_unref(reply);
+
+ return brightness_level;
+}
+
+gchar
+**xfpm_hal_get_available_cpu_governors(XfpmHal *xfpm_hal,GError **gerror)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),NULL);
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,NULL);
+
+ DBusMessage *mess;
+ DBusMessage *reply;
+ DBusError error;
+ gchar **govs = NULL;
+ int dummy;
+
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_CPU,
+ "GetCPUFreqAvailableGovernors");
+ if (!mess)
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ return NULL;
+ }
+
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,mess,-1,&error);
+
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return NULL;
+ }
+
+ if ( !reply )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("No reply from HAL daemon to get available cpu governors"));
+ return NULL;
+ }
+
+ dbus_message_get_args(reply,NULL,
+ DBUS_TYPE_ARRAY,DBUS_TYPE_STRING,
+ &govs,&dummy,
+ DBUS_TYPE_INVALID,DBUS_TYPE_INVALID);
+ dbus_message_unref(reply);
+ return govs;
+}
+
+gchar
+*xfpm_hal_get_current_cpu_governor(XfpmHal *xfpm_hal,GError **gerror)
+{
+ g_return_val_if_fail(XFPM_IS_HAL(xfpm_hal),NULL);
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_val_if_fail(priv->connected == TRUE,NULL);
+
+ DBusMessage *mess;
+ DBusMessage *reply;
+ DBusError error;
+ gchar *gov = NULL;
+
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_CPU,
+ "GetCPUFreqGovernor");
+
+ if (!mess)
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ return NULL;
+ }
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,mess,-1,&error);
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return NULL;
+ }
+
+ if ( !reply )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("No reply from HAL daemon to get current cpu governor"));
+ return NULL;
+ }
+
+ dbus_message_get_args(reply,NULL,DBUS_TYPE_STRING,&gov,DBUS_TYPE_INVALID);
+ XFPM_DEBUG("Got governor %s\n",gov);
+ dbus_message_unref(reply);
+ return gov;
+}
+
+
+void
+xfpm_hal_set_cpu_governor (XfpmHal *xfpm_hal,
+ const gchar *governor,
+ GError **gerror)
+{
+ g_return_if_fail(XFPM_IS_HAL(xfpm_hal));
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_if_fail(priv->connected == TRUE);
+
+ XFPM_DEBUG("Setting CPU gov %s\n",governor);
+
+ DBusMessage *mess;
+ DBusMessage *reply;
+ DBusError error;
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_CPU,
+ "SetCPUFreqGovernor");
+ if (!mess)
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ return;
+ }
+
+ dbus_message_append_args(mess,DBUS_TYPE_STRING,&governor,DBUS_TYPE_INVALID);
+
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,mess,-1,&error);
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return;
+ }
+
+ if ( !reply )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("No reply from HAL daemon to set cpu governor"));
+ return;
+ }
+ dbus_message_unref(reply);
+}
+
+void
+xfpm_hal_set_power_save (XfpmHal *xfpm_hal,
+ gboolean power_save,
+ GError **gerror)
+{
+ g_return_if_fail(XFPM_IS_HAL(xfpm_hal));
+
+ XfpmHalPrivate *priv;
+ priv = XFPM_HAL_GET_PRIVATE(xfpm_hal);
+
+ g_return_if_fail(priv->connected == TRUE);
+
+ DBusMessage *mess;
+ DBusMessage *reply;
+ DBusError error;
+ mess = dbus_message_new_method_call(HAL_DBUS_SERVICE,
+ HAL_ROOT_COMPUTER,
+ HAL_DBUS_INTERFACE_POWER,
+ "SetPowerSave");
+ if (!mess)
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("Out of memory"));
+ return;
+ }
+
+ dbus_message_append_args(mess,DBUS_TYPE_BOOLEAN,&power_save,DBUS_TYPE_INVALID);
+
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(priv->connection,mess,-1,&error);
+ dbus_message_unref(mess);
+
+ if ( dbus_error_is_set(&error) )
+ {
+ dbus_set_g_error(gerror,&error);
+ dbus_error_free(&error);
+ return;
+ }
+
+ if ( !reply )
+ {
+ g_set_error(gerror,XFPM_HAL_ERROR,XFPM_HAL_ERROR_GENERAL,_("No reply from HAL daemon to set power save profile"));
+ return;
+ }
+ dbus_message_unref(reply);
+}