mirror of
https://gitlab.freedesktop.org/upower/upower.git
synced 2026-02-01 04:30:25 +01:00
trivial: implement org.freedesktop.DeviceKit.Power.Wakeups
This commit is contained in:
parent
609133f43f
commit
a239eff3bf
2 changed files with 711 additions and 0 deletions
646
src/dkp-wakeups.c
Normal file
646
src/dkp-wakeups.c
Normal file
|
|
@ -0,0 +1,646 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* 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 <glib.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "egg-debug.h"
|
||||
#include "egg-string.h"
|
||||
|
||||
#include "dkp-wakeups.h"
|
||||
#include "dkp-daemon.h"
|
||||
#include "dkp-marshal.h"
|
||||
#include "dkp-wakeups-glue.h"
|
||||
#include "dkp-wakeups-obj.h"
|
||||
|
||||
static void dkp_wakeups_class_init (DkpWakeupsClass *klass);
|
||||
static void dkp_wakeups_init (DkpWakeups *wakeups);
|
||||
static void dkp_wakeups_finalize (GObject *object);
|
||||
|
||||
#define DKP_WAKEUPS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DKP_TYPE_WAKEUPS, DkpWakeupsPrivate))
|
||||
|
||||
#define DKP_WAKEUPS_REQUESTS_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
|
||||
G_TYPE_BOOLEAN, \
|
||||
G_TYPE_UINT, \
|
||||
G_TYPE_UINT, \
|
||||
G_TYPE_STRING, \
|
||||
G_TYPE_STRING, \
|
||||
G_TYPE_INVALID))
|
||||
|
||||
#define DKP_WAKEUPS_POLL_INTERVAL_KERNEL 2 /* seconds */
|
||||
#define DKP_WAKEUPS_POLL_INTERVAL_USERSPACE 2 /* seconds */
|
||||
#define DKP_WAKEUPS_SOURCE_KERNEL "/proc/interrupts"
|
||||
#define DKP_WAKEUPS_SOURCE_USERSPACE "/proc/timer_stats"
|
||||
|
||||
struct DkpWakeupsPrivate
|
||||
{
|
||||
GPtrArray *data;
|
||||
DBusGConnection *connection;
|
||||
};
|
||||
|
||||
enum {
|
||||
TOTAL_CHANGED,
|
||||
DATA_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (DkpWakeups, dkp_wakeups, G_TYPE_OBJECT)
|
||||
|
||||
/**
|
||||
* dkp_wakeups_get_cmdline:
|
||||
**/
|
||||
static gchar *
|
||||
dkp_wakeups_get_cmdline (guint pid)
|
||||
{
|
||||
gboolean ret;
|
||||
gchar *filename = NULL;
|
||||
gchar *cmdline = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
/* get command line from proc */
|
||||
filename = g_strdup_printf ("/proc/%i/cmdline", pid);
|
||||
ret = g_file_get_contents (filename, &cmdline, NULL, &error);
|
||||
if (!ret) {
|
||||
egg_debug ("failed to get cmdline: %s", error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
g_free (filename);
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_data_obj_compare:
|
||||
**/
|
||||
static gint
|
||||
dkp_wakeups_data_obj_compare (const DkpWakeupsObj **obj1, const DkpWakeupsObj **obj2)
|
||||
{
|
||||
if ((*obj1)->value > (*obj2)->value)
|
||||
return -1;
|
||||
if ((*obj1)->value < (*obj2)->value)
|
||||
return 1;
|
||||
return -0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_data_print:
|
||||
**/
|
||||
static void
|
||||
dkp_wakeups_data_print (DkpWakeups *wakeups)
|
||||
{
|
||||
guint i;
|
||||
DkpWakeupsObj *obj;
|
||||
|
||||
/* sort data */
|
||||
g_ptr_array_sort (wakeups->priv->data, (GCompareFunc) dkp_wakeups_data_obj_compare);
|
||||
|
||||
for (i=0; i<wakeups->priv->data->len; i++) {
|
||||
obj = g_ptr_array_index (wakeups->priv->data, i);
|
||||
if (obj->value > 0)
|
||||
dkp_wakeups_obj_print (obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_data_get_or_create:
|
||||
**/
|
||||
static DkpWakeupsObj *
|
||||
dkp_wakeups_data_get_or_create (DkpWakeups *wakeups, guint id)
|
||||
{
|
||||
guint i;
|
||||
DkpWakeupsObj *obj;
|
||||
|
||||
for (i=0; i<wakeups->priv->data->len; i++) {
|
||||
obj = g_ptr_array_index (wakeups->priv->data, i);
|
||||
if (obj->id == id)
|
||||
goto out;
|
||||
}
|
||||
obj = dkp_wakeups_obj_new ();
|
||||
obj->id = id;
|
||||
g_ptr_array_add (wakeups->priv->data, obj);
|
||||
out:
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_data_get_total:
|
||||
**/
|
||||
static guint
|
||||
dkp_wakeups_data_get_total (DkpWakeups *wakeups)
|
||||
{
|
||||
guint i;
|
||||
guint total = 0;
|
||||
DkpWakeupsObj *obj;
|
||||
|
||||
for (i=0; i<wakeups->priv->data->len; i++) {
|
||||
obj = g_ptr_array_index (wakeups->priv->data, i);
|
||||
total += obj->value;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_get_total:
|
||||
*
|
||||
* Gets the current latency
|
||||
**/
|
||||
gboolean
|
||||
dkp_wakeups_get_total (DkpWakeups *wakeups, guint *value, GError **error)
|
||||
{
|
||||
guint total;
|
||||
|
||||
/* no data */
|
||||
total = dkp_wakeups_data_get_total (wakeups);
|
||||
if (total == 0) {
|
||||
*error = g_error_new (DKP_DAEMON_ERROR, DKP_DAEMON_ERROR_GENERAL, "no interrupt data");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* return total */
|
||||
*value = total;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_get_data:
|
||||
**/
|
||||
gboolean
|
||||
dkp_wakeups_get_data (DkpWakeups *wakeups, GPtrArray **data, GError **error)
|
||||
{
|
||||
guint i;
|
||||
GPtrArray *array;
|
||||
DkpWakeupsObj *obj;
|
||||
|
||||
/* sort data */
|
||||
g_ptr_array_sort (wakeups->priv->data, (GCompareFunc) dkp_wakeups_data_obj_compare);
|
||||
|
||||
*data = g_ptr_array_new ();
|
||||
array = wakeups->priv->data;
|
||||
for (i=0; i<array->len; i++) {
|
||||
GValue elem = {0};
|
||||
|
||||
obj = g_ptr_array_index (array, i);
|
||||
if (obj->value == 0)
|
||||
continue;
|
||||
g_value_init (&elem, DKP_WAKEUPS_REQUESTS_STRUCT_TYPE);
|
||||
g_value_take_boxed (&elem, dbus_g_type_specialized_construct (DKP_WAKEUPS_REQUESTS_STRUCT_TYPE));
|
||||
dbus_g_type_struct_set (&elem,
|
||||
0, FALSE,
|
||||
1, obj->value,
|
||||
2, obj->id,
|
||||
3, obj->cmdline,
|
||||
4, obj->details,
|
||||
G_MAXUINT);
|
||||
g_ptr_array_add (*data, g_value_get_boxed (&elem));
|
||||
}
|
||||
|
||||
// dbus_g_method_return (context, data);
|
||||
// g_ptr_array_foreach (*data, (GFunc) g_value_array_free, NULL);
|
||||
// g_ptr_array_free (*data, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_is_in:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_is_in (gchar needle, const gchar *delimiters)
|
||||
{
|
||||
guint i;
|
||||
for (i=0; delimiters[i] != '\0'; i++) {
|
||||
if (delimiters[i] == needle)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_strsplit_complete_set:
|
||||
**/
|
||||
static GPtrArray *
|
||||
dkp_strsplit_complete_set (const gchar *string, const gchar *delimiters, guint max_tokens)
|
||||
{
|
||||
guint i;
|
||||
gboolean ret;
|
||||
const gchar *start = NULL;
|
||||
gchar temp_data[100];
|
||||
guint len;
|
||||
guint tokens = 0;
|
||||
GPtrArray *array;
|
||||
|
||||
/* find sections not delimited by space */
|
||||
array = g_ptr_array_new ();
|
||||
for (i=0; string[i] != '\0'; i++) {
|
||||
ret = dkp_is_in (string[i], delimiters);
|
||||
if (ret) {
|
||||
/* no character data yet */
|
||||
if (start == NULL)
|
||||
continue;
|
||||
if (tokens == max_tokens - 1) {
|
||||
g_ptr_array_add (array, g_strdup (start));
|
||||
break;
|
||||
}
|
||||
|
||||
/* find length of string */
|
||||
len = &string[i] - start;
|
||||
if (len > 100)
|
||||
len = 100;
|
||||
strncpy (temp_data, start, len);
|
||||
temp_data[len] = '\0';
|
||||
|
||||
/* add to array */
|
||||
g_ptr_array_add (array, g_strdup (temp_data));
|
||||
tokens++;
|
||||
start = NULL;
|
||||
continue;
|
||||
}
|
||||
/* we've got character data */
|
||||
if (start == NULL)
|
||||
start = &string[i];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_poll_kernel_cb:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_wakeups_poll_kernel_cb (DkpWakeups *wakeups)
|
||||
{
|
||||
guint i;
|
||||
guint j;
|
||||
gboolean ret;
|
||||
gboolean special_ipi;
|
||||
gchar *data = NULL;
|
||||
gchar **lines = NULL;
|
||||
GError *error = NULL;
|
||||
guint cpus = 0;
|
||||
const gchar *found;
|
||||
guint irq;
|
||||
guint interrupts;
|
||||
guint total;
|
||||
GPtrArray *sections;
|
||||
DkpWakeupsObj *obj;
|
||||
|
||||
egg_warning ("pOLL kernel");
|
||||
|
||||
/* set all kernel data objs to zero */
|
||||
for (i=0; i<wakeups->priv->data->len; i++) {
|
||||
obj = g_ptr_array_index (wakeups->priv->data, i);
|
||||
if (!obj->is_userspace)
|
||||
obj->value = 0;
|
||||
}
|
||||
|
||||
/* get the data */
|
||||
ret = g_file_get_contents (DKP_WAKEUPS_SOURCE_KERNEL, &data, NULL, &error);
|
||||
if (!ret) {
|
||||
egg_warning ("failed to get data: %s", error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* split */
|
||||
lines = g_strsplit (data, "\n", 0);
|
||||
|
||||
/* find out how many processors we have */
|
||||
sections = dkp_strsplit_complete_set (lines[0], " ", 0);
|
||||
cpus = sections->len;
|
||||
g_ptr_array_foreach (sections, (GFunc) g_free, NULL);
|
||||
g_ptr_array_free (sections, TRUE);
|
||||
|
||||
/* get the data from " 9: 29730 365 IO-APIC-fasteoi acpi" */
|
||||
for (i=1; lines[i] != NULL; i++) {
|
||||
|
||||
/* get sections and check correct length */
|
||||
sections = dkp_strsplit_complete_set (lines[i], " :", 2 + cpus);
|
||||
if (sections->len != 2 + cpus)
|
||||
goto skip;
|
||||
|
||||
/* get irq */
|
||||
special_ipi = TRUE;
|
||||
found = g_ptr_array_index (sections, 0);
|
||||
if (strcmp (found, "NMI") == 0)
|
||||
irq = 0xff0;
|
||||
else if (strcmp (found, "LOC") == 0)
|
||||
irq = 0xff1;
|
||||
else if (strcmp (found, "RES") == 0)
|
||||
irq = 0xff2;
|
||||
else if (strcmp (found, "CAL") == 0)
|
||||
irq = 0xff3;
|
||||
else if (strcmp (found, "TLB") == 0)
|
||||
irq = 0xff4;
|
||||
else if (strcmp (found, "TRM") == 0)
|
||||
irq = 0xff5;
|
||||
else if (strcmp (found, "SPU") == 0)
|
||||
irq = 0xff6;
|
||||
else if (strcmp (found, "ERR") == 0)
|
||||
irq = 0xff7;
|
||||
else if (strcmp (found, "MIS") == 0)
|
||||
irq = 0xff8;
|
||||
else {
|
||||
irq = atoi (found);
|
||||
special_ipi = FALSE;
|
||||
}
|
||||
|
||||
/* get the number of interrupts over all processors */
|
||||
interrupts = 0;
|
||||
for (j=1; j<cpus; j++) {
|
||||
found = g_ptr_array_index (sections, j);
|
||||
interrupts += atoi (found);
|
||||
}
|
||||
if (interrupts == 0)
|
||||
goto skip;
|
||||
|
||||
/* get the detail string */
|
||||
found = g_ptr_array_index (sections, cpus+1);
|
||||
|
||||
/* save in database */
|
||||
obj = dkp_wakeups_data_get_or_create (wakeups, irq);
|
||||
if (obj->details == NULL) {
|
||||
if (strcmp (found, "i8042") == 0)
|
||||
obj->details = g_strdup_printf ("<interrupt> : %s", "PS/2 keyboard/mouse/touchpad");
|
||||
else if (special_ipi)
|
||||
obj->details = g_strdup_printf ("<kernel IPI> : %s", found);
|
||||
else
|
||||
obj->details = g_strdup_printf ("<interrupt> : %s", found);
|
||||
obj->cmdline = g_strdup ("<kernel>");
|
||||
obj->is_userspace = FALSE;
|
||||
}
|
||||
/* we report this in minutes, not seconds */
|
||||
if (obj->old > 0)
|
||||
obj->value = (interrupts - obj->old) * 60 / DKP_WAKEUPS_POLL_INTERVAL_KERNEL;
|
||||
obj->old = interrupts;
|
||||
skip:
|
||||
g_ptr_array_foreach (sections, (GFunc) g_free, NULL);
|
||||
g_ptr_array_free (sections, TRUE);
|
||||
}
|
||||
|
||||
dkp_wakeups_data_print (wakeups);
|
||||
|
||||
/* tell GUI we've changed */
|
||||
total = dkp_wakeups_data_get_total (wakeups);
|
||||
g_signal_emit (wakeups, signals [TOTAL_CHANGED], 0, total);
|
||||
out:
|
||||
g_free (data);
|
||||
g_strfreev (lines);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_poll_userspace_cb:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_wakeups_poll_userspace_cb (DkpWakeups *wakeups)
|
||||
{
|
||||
guint i;
|
||||
guint total;
|
||||
gboolean ret;
|
||||
GError *error = NULL;
|
||||
gchar *data = NULL;
|
||||
gchar **lines = NULL;
|
||||
const gchar *string;
|
||||
DkpWakeupsObj *obj;
|
||||
GPtrArray *sections;
|
||||
guint pid;
|
||||
guint interrupts;
|
||||
gfloat interval = 5.0f;
|
||||
|
||||
/* set all userspace data objs to zero */
|
||||
for (i=0; i<wakeups->priv->data->len; i++) {
|
||||
obj = g_ptr_array_index (wakeups->priv->data, i);
|
||||
if (obj->is_userspace)
|
||||
obj->value = 0;
|
||||
}
|
||||
|
||||
/* get the data */
|
||||
ret = g_file_get_contents (DKP_WAKEUPS_SOURCE_USERSPACE, &data, NULL, &error);
|
||||
if (!ret) {
|
||||
egg_warning ("failed to get data: %s", error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* split */
|
||||
lines = g_strsplit (data, "\n", 0);
|
||||
|
||||
/* get the data from " 9: 29730 365 IO-APIC-fasteoi acpi" */
|
||||
for (i=0; lines[i] != NULL; i++) {
|
||||
|
||||
if (strstr (lines[i], "Timer Stats Version:") != NULL)
|
||||
continue;
|
||||
if (strstr (lines[i], "events/sec") != NULL)
|
||||
continue;
|
||||
|
||||
/* get sections */
|
||||
sections = dkp_strsplit_complete_set (lines[i], " :", 4);
|
||||
|
||||
/* get timeout */
|
||||
if (strstr (lines[i], "Sample period:") != NULL) {
|
||||
string = g_ptr_array_index (sections, 2);
|
||||
interval = atof (string);
|
||||
egg_debug ("interval=%f", interval);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
/* check correct length */
|
||||
if (sections->len != 4)
|
||||
goto skip;
|
||||
|
||||
/* if deferred */
|
||||
string = g_ptr_array_index (sections, 0);
|
||||
if (strstr (string, "D") != NULL)
|
||||
goto skip;
|
||||
interrupts = atoi (string);
|
||||
if (interrupts == 0)
|
||||
goto skip;
|
||||
|
||||
/* get pid */
|
||||
string = g_ptr_array_index (sections, 1);
|
||||
pid = atoi (string);
|
||||
|
||||
/* ignore scheduled */
|
||||
string = g_ptr_array_index (sections, 3);
|
||||
if (g_str_has_prefix (string, "tick_nohz_"))
|
||||
goto skip;
|
||||
if (g_str_has_prefix (string, "tick_setup_sched_timer"))
|
||||
goto skip;
|
||||
|
||||
/* get details */
|
||||
|
||||
/* save in database */
|
||||
obj = dkp_wakeups_data_get_or_create (wakeups, pid);
|
||||
if (obj->details == NULL) {
|
||||
/* get process name (truncated) */
|
||||
string = g_ptr_array_index (sections, 2);
|
||||
if (strcmp (string, "insmod") == 0)
|
||||
obj->cmdline = g_strdup ("<kernel module>");
|
||||
else if (strcmp (string, "modprobe") == 0)
|
||||
obj->cmdline = g_strdup ("<kernel module>");
|
||||
else if (strcmp (string, "swapper") == 0)
|
||||
obj->cmdline = g_strdup ("<kernel core>");
|
||||
else {
|
||||
/* try to get a better command line */
|
||||
obj->cmdline = dkp_wakeups_get_cmdline (pid);
|
||||
if (obj->cmdline == NULL)
|
||||
obj->cmdline = g_strdup (string);
|
||||
}
|
||||
string = g_ptr_array_index (sections, 3);
|
||||
obj->details = g_strdup (string);
|
||||
obj->is_userspace = TRUE;
|
||||
}
|
||||
/* we report this in minutes, not seconds */
|
||||
obj->value = (gfloat) interrupts * 60.0f / interval;
|
||||
skip:
|
||||
g_ptr_array_foreach (sections, (GFunc) g_free, NULL);
|
||||
g_ptr_array_free (sections, TRUE);
|
||||
|
||||
}
|
||||
|
||||
/* tell GUI we've changed */
|
||||
total = dkp_wakeups_data_get_total (wakeups);
|
||||
g_signal_emit (wakeups, signals [TOTAL_CHANGED], 0, total);
|
||||
|
||||
dkp_wakeups_data_print (wakeups);
|
||||
|
||||
out:
|
||||
g_free (data);
|
||||
g_strfreev (lines);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_timerstats_enable:
|
||||
**/
|
||||
static gboolean
|
||||
dkp_wakeups_timerstats_enable (DkpWakeups *wakeups, gboolean enabled)
|
||||
{
|
||||
FILE *file;
|
||||
file = fopen (DKP_WAKEUPS_SOURCE_USERSPACE, "w");
|
||||
if (file == NULL)
|
||||
return FALSE;
|
||||
if (enabled)
|
||||
fprintf (file, "1\n");
|
||||
else
|
||||
fprintf (file, "0\n");
|
||||
fclose (file);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_class_init:
|
||||
**/
|
||||
static void
|
||||
dkp_wakeups_class_init (DkpWakeupsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->finalize = dkp_wakeups_finalize;
|
||||
|
||||
signals [TOTAL_CHANGED] =
|
||||
g_signal_new ("total-changed",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (DkpWakeupsClass, total_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE, 1, G_TYPE_UINT);
|
||||
signals [DATA_CHANGED] =
|
||||
g_signal_new ("data-changed",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (DkpWakeupsClass, data_changed),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/* introspection */
|
||||
dbus_g_object_type_install_info (DKP_TYPE_WAKEUPS, &dbus_glib_dkp_wakeups_object_info);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (DkpWakeupsPrivate));
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_init:
|
||||
**/
|
||||
static void
|
||||
dkp_wakeups_init (DkpWakeups *wakeups)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
wakeups->priv = DKP_WAKEUPS_GET_PRIVATE (wakeups);
|
||||
wakeups->priv->data = g_ptr_array_new ();
|
||||
|
||||
wakeups->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
|
||||
if (error != NULL) {
|
||||
egg_warning ("Cannot connect to bus: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* register on the bus */
|
||||
dbus_g_connection_register_g_object (wakeups->priv->connection, "/org/freedesktop/DeviceKit/Power/Wakeups", G_OBJECT (wakeups));
|
||||
|
||||
/* setup polls */
|
||||
g_timeout_add_seconds (DKP_WAKEUPS_POLL_INTERVAL_KERNEL, (GSourceFunc) dkp_wakeups_poll_kernel_cb, wakeups);
|
||||
g_timeout_add_seconds (DKP_WAKEUPS_POLL_INTERVAL_USERSPACE, (GSourceFunc) dkp_wakeups_poll_userspace_cb, wakeups);
|
||||
|
||||
/* setup timerstats */
|
||||
dkp_wakeups_timerstats_enable (wakeups, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_finalize:
|
||||
**/
|
||||
static void
|
||||
dkp_wakeups_finalize (GObject *object)
|
||||
{
|
||||
DkpWakeups *wakeups;
|
||||
|
||||
g_return_if_fail (object != NULL);
|
||||
g_return_if_fail (DKP_IS_WAKEUPS (object));
|
||||
|
||||
wakeups = DKP_WAKEUPS (object);
|
||||
wakeups->priv = DKP_WAKEUPS_GET_PRIVATE (wakeups);
|
||||
|
||||
/* stop timerstats */
|
||||
dkp_wakeups_timerstats_enable (wakeups, FALSE);
|
||||
|
||||
g_ptr_array_foreach (wakeups->priv->data, (GFunc) dkp_wakeups_obj_free, NULL);
|
||||
g_ptr_array_free (wakeups->priv->data, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (dkp_wakeups_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* dkp_wakeups_new:
|
||||
**/
|
||||
DkpWakeups *
|
||||
dkp_wakeups_new (void)
|
||||
{
|
||||
DkpWakeups *wakeups;
|
||||
wakeups = g_object_new (DKP_TYPE_WAKEUPS, NULL);
|
||||
return DKP_WAKEUPS (wakeups);
|
||||
}
|
||||
|
||||
65
src/dkp-wakeups.h
Normal file
65
src/dkp-wakeups.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
||||
*
|
||||
* Copyright (C) 2009 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __DKP_WAKEUPS_H
|
||||
#define __DKP_WAKEUPS_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define DKP_TYPE_WAKEUPS (dkp_wakeups_get_type ())
|
||||
#define DKP_WAKEUPS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DKP_TYPE_WAKEUPS, DkpWakeups))
|
||||
#define DKP_WAKEUPS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DKP_TYPE_WAKEUPS, DkpWakeupsClass))
|
||||
#define DKP_IS_WAKEUPS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DKP_TYPE_WAKEUPS))
|
||||
#define DKP_IS_WAKEUPS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DKP_TYPE_WAKEUPS))
|
||||
#define DKP_WAKEUPS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DKP_TYPE_WAKEUPS, DkpWakeupsClass))
|
||||
|
||||
typedef struct DkpWakeupsPrivate DkpWakeupsPrivate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GObject parent;
|
||||
DkpWakeupsPrivate *priv;
|
||||
} DkpWakeups;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
void (* total_changed) (DkpWakeups *wakeups,
|
||||
guint value);
|
||||
void (* data_changed) (DkpWakeups *wakeups);
|
||||
} DkpWakeupsClass;
|
||||
|
||||
DkpWakeups *dkp_wakeups_new (void);
|
||||
GType dkp_wakeups_get_type (void);
|
||||
gboolean dkp_wakeups_get_total (DkpWakeups *wakeups,
|
||||
guint *value,
|
||||
GError **error);
|
||||
gboolean dkp_wakeups_get_data (DkpWakeups *wakeups,
|
||||
GPtrArray **requests,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __DKP_WAKEUPS_H */
|
||||
|
||||
Loading…
Add table
Reference in a new issue