Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 366735
Collapse All | Expand All

(-)gnome-power-manager-2.32.0-r1-orig/work/gnome-power-manager-2.32.0/src/Makefile.am (+2 lines)
Lines 146-151 Link Here
146
	gpm-phone.c					\
146
	gpm-phone.c					\
147
	gpm-backlight.h					\
147
	gpm-backlight.h					\
148
	gpm-backlight.c					\
148
	gpm-backlight.c					\
149
	gpm-backlight-kbd.h				\
150
	gpm-backlight-kbd.c				\
149
	gpm-prefs-server.h				\
151
	gpm-prefs-server.h				\
150
	gpm-prefs-server.c				\
152
	gpm-prefs-server.c				\
151
	gpm-idle.h					\
153
	gpm-idle.h					\
(-)gnome-power-manager-2.32.0-r1-orig/work/gnome-power-manager-2.32.0/src/gpm-backlight-kbd.c (+681 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2
 *
3
 * Copyright (C) 2010 Alex Murray <murray.alex@gmail.com>
4
 * Copyright (C) 2005-2009 Richard Hughes <richard@hughsie.com>
5
 * Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
6
 *
7
 * Licensed under the GNU General Public License Version 2
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
 */
23
24
#ifdef HAVE_CONFIG_H
25
#  include <config.h>
26
#endif
27
28
#include <stdlib.h>
29
#include <stdio.h>
30
#include <time.h>
31
#include <errno.h>
32
33
#include <string.h>
34
#include <sys/time.h>
35
#include <sys/types.h>
36
#include <math.h>
37
#ifdef HAVE_UNISTD_H
38
#include <unistd.h>
39
#endif /* HAVE_UNISTD_H */
40
41
#include <glib/gi18n.h>
42
#include <dbus/dbus-glib.h>
43
#include <gconf/gconf-client.h>
44
#include <libupower-glib/upower.h>
45
46
#include "gpm-button.h"
47
#include "gpm-backlight-kbd.h"
48
#include "gpm-control.h"
49
#include "gpm-common.h"
50
#include "egg-debug.h"
51
#include "gsd-media-keys-window.h"
52
#include "gpm-dpms.h"
53
#include "gpm-idle.h"
54
#include "gpm-marshal.h"
55
#include "gpm-stock-icons.h"
56
#include "gpm-prefs-server.h"
57
#include "egg-console-kit.h"
58
59
#define GPM_BACKLIGHT_KBD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_BACKLIGHT_KBD, GpmBacklightKbdPrivate))
60
61
struct GpmBacklightKbdPrivate
62
{
63
	UpClient		*client;
64
	DBusGProxy		*proxy;
65
	GpmButton		*button;
66
	GConfClient		*conf;
67
	GtkWidget		*popup;
68
	GpmControl		*control;
69
	GpmDpms			*dpms;
70
	GpmIdle			*idle;
71
	EggConsoleKit		*consolekit;
72
	gboolean		 system_is_idle;
73
	GTimer			*idle_timer;
74
	guint			 idle_dim_timeout;
75
	gint			 master_percentage;
76
	gint			 max_brightness;
77
	gboolean		 off;
78
};
79
80
G_DEFINE_TYPE (GpmBacklightKbd, gpm_backlight_kbd, G_TYPE_OBJECT)
81
82
#define BACKLIGHT_KBD_SERVICE     "org.freedesktop.UPower"
83
#define BACKLIGHT_KBD_PATH        "/org/freedesktop/UPower/KbdBacklight"
84
#define BACKLIGHT_KBD_INTERFACE   "org.freedesktop.UPower.KbdBacklight"
85
86
/**
87
 * gpm_backlight_kbd_dialog_init:
88
 *
89
 * Initialises the popup, and makes sure that it matches the compositing of the screen.
90
 **/
91
static void
92
gpm_backlight_kbd_dialog_init (GpmBacklightKbd *backlight_kbd)
93
{
94
	if (backlight_kbd->priv->popup != NULL
95
	    && !gsd_media_keys_window_is_valid (GSD_MEDIA_KEYS_WINDOW (backlight_kbd->priv->popup))) {
96
		gtk_widget_destroy (backlight_kbd->priv->popup);
97
		backlight_kbd->priv->popup = NULL;
98
	}
99
100
	if (backlight_kbd->priv->popup == NULL) {
101
		backlight_kbd->priv->popup= gsd_media_keys_window_new ();
102
		gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight_kbd->priv->popup),
103
							 "gpm-brightness-kbd",
104
							 TRUE);
105
		gtk_window_set_position (GTK_WINDOW (backlight_kbd->priv->popup), GTK_WIN_POS_NONE);
106
	}
107
}
108
109
/**
110
 * gpm_backlight_kbd_dialog_show:
111
 *
112
 * Show the brightness popup, and place it nicely on the screen.
113
 **/
114
static void
115
gpm_backlight_kbd_dialog_show (GpmBacklightKbd *backlight_kbd)
116
{
117
	int            orig_w;
118
	int            orig_h;
119
	int            screen_w;
120
	int            screen_h;
121
	int            x;
122
	int            y;
123
	int            pointer_x;
124
	int            pointer_y;
125
	GtkRequisition win_req;
126
	GdkScreen     *pointer_screen;
127
	GdkRectangle   geometry;
128
	int            monitor;
129
130
	/*
131
	 * get the window size
132
	 * if the window hasn't been mapped, it doesn't necessarily
133
	 * know its true size, yet, so we need to jump through hoops
134
	 */
135
	gtk_window_get_default_size (GTK_WINDOW (backlight_kbd->priv->popup), &orig_w, &orig_h);
136
	gtk_widget_size_request (backlight_kbd->priv->popup, &win_req);
137
138
	if (win_req.width > orig_w) {
139
		orig_w = win_req.width;
140
	}
141
	if (win_req.height > orig_h) {
142
		orig_h = win_req.height;
143
	}
144
145
	pointer_screen = NULL;
146
	gdk_display_get_pointer (gtk_widget_get_display (backlight_kbd->priv->popup),
147
				 &pointer_screen,
148
				 &pointer_x,
149
				 &pointer_y,
150
				 NULL);
151
	monitor = gdk_screen_get_monitor_at_point (pointer_screen,
152
						   pointer_x,
153
						   pointer_y);
154
155
	gdk_screen_get_monitor_geometry (pointer_screen,
156
					 monitor,
157
					 &geometry);
158
159
	screen_w = geometry.width;
160
	screen_h = geometry.height;
161
162
	x = ((screen_w - orig_w) / 2) + geometry.x;
163
	y = geometry.y + (screen_h / 2) + (screen_h / 2 - orig_h) / 2;
164
165
	gtk_window_move (GTK_WINDOW (backlight_kbd->priv->popup), x, y);
166
167
	gtk_widget_show (backlight_kbd->priv->popup);
168
169
	gdk_display_sync (gtk_widget_get_display (backlight_kbd->priv->popup));
170
}
171
172
/**
173
 * gpm_backlight_kbd_brightness_evaluate_and_set:
174
 **/
175
static gboolean
176
gpm_backlight_kbd_brightness_evaluate_and_set (GpmBacklightKbd *backlight_kbd, gboolean interactive)
177
{
178
	gfloat brightness;
179
	gfloat scale;
180
	gboolean ret;
181
	gboolean on_battery;
182
	gboolean do_laptop_lcd;
183
	gboolean enable_action;
184
	gboolean battery_reduce;
185
	GError *error = NULL;
186
	gint value;
187
	gint old_value;
188
189
	if (backlight_kbd->priv->proxy == NULL) {
190
		egg_warning ("no kbd backlight hardware");
191
		return FALSE;
192
	}
193
194
	do_laptop_lcd = gconf_client_get_bool (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_ENABLE, NULL);
195
	if (do_laptop_lcd == FALSE) {
196
		egg_warning ("policy is no dimming");
197
		return FALSE;
198
	}
199
200
	/* get the last set brightness */
201
	brightness = backlight_kbd->priv->master_percentage / 100.0f;
202
	egg_debug ("1. main brightness %f", brightness);
203
204
	/* get battery status */
205
	g_object_get (backlight_kbd->priv->client,
206
		      "on-battery", &on_battery,
207
		      NULL);
208
209
	/* reduce if on battery power if we should */
210
	battery_reduce = gconf_client_get_bool (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_BATTERY_REDUCE, NULL);
211
	if (on_battery && battery_reduce) {
212
		value = gconf_client_get_int (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_BRIGHTNESS_DIM_BATT, NULL);
213
		if (value > 100) {
214
			egg_warning ("cannot use battery brightness value %i, correcting to 50", value);
215
			value = 50;
216
		}
217
		scale = (100 - value) / 100.0f;
218
		brightness *= scale;
219
	} else {
220
		scale = 1.0f;
221
	}
222
	egg_debug ("2. battery scale %f, brightness %f", scale, brightness);
223
224
	/* reduce if system is momentarily idle */
225
	if (!on_battery)
226
		enable_action = gconf_client_get_bool (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_IDLE_DIM_AC, NULL);
227
	else
228
		enable_action = gconf_client_get_bool (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_IDLE_DIM_BATT, NULL);
229
	if (enable_action && backlight_kbd->priv->system_is_idle) {
230
		value = gconf_client_get_int (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_IDLE_BRIGHTNESS, NULL);
231
		if (value > 100) {
232
			egg_warning ("cannot use idle brightness value %i, correcting to 50", value);
233
			value = 50;
234
		}
235
		scale = value / 100.0f;
236
		brightness *= scale;
237
	} else {
238
		scale = 1.0f;
239
	}
240
	egg_debug ("3. idle scale %f, brightness %f", scale, brightness);
241
242
	/* convert to percentage */
243
	value = (gint) ((brightness * 100.0f) + 0.5);
244
245
	/* normalize to max brightness */
246
	value = value * backlight_kbd->priv->max_brightness / 100;
247
248
	if (backlight_kbd->priv->off)
249
		value = 0;
250
251
	/* only do stuff if the brightness is different */
252
	ret = dbus_g_proxy_call (backlight_kbd->priv->proxy,
253
				 "GetBrightness", &error,
254
				 G_TYPE_INVALID,
255
				 G_TYPE_INT, &old_value,
256
				 G_TYPE_INVALID);
257
	if (error) {
258
		egg_debug ("ERROR: %s", error->message);
259
		g_error_free (error);
260
	}
261
	if (!ret) {
262
		egg_warning ("GetBrightness failed!");
263
		return FALSE;
264
	}
265
	if (old_value == value) {
266
		egg_debug ("values are the same, no action");
267
		return FALSE;
268
	}
269
270
	/* only show dialog if interactive */
271
	if (interactive) {
272
		gpm_backlight_kbd_dialog_init (backlight_kbd);
273
		gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight_kbd->priv->popup),
274
							round (brightness));
275
		gpm_backlight_kbd_dialog_show (backlight_kbd);
276
	}
277
278
	egg_debug ("Setting brightness to %d", value);
279
	return dbus_g_proxy_call (backlight_kbd->priv->proxy,
280
				  "SetBrightness", NULL,
281
				  G_TYPE_INT, value,
282
				  G_TYPE_INVALID, G_TYPE_INVALID);
283
	return TRUE;
284
}
285
286
/**
287
 * gpm_conf_gconf_key_changed_cb:
288
 *
289
 * We might have to do things when the gconf keys change; do them here.
290
 **/
291
static void
292
gpm_conf_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, GpmBacklightKbd *backlight_kbd)
293
{
294
	GConfValue *value;
295
	gboolean on_battery;
296
297
	value = gconf_entry_get_value (entry);
298
	if (value == NULL)
299
		return;
300
301
	/* get battery status */
302
	g_object_get (backlight_kbd->priv->client,
303
		      "on-battery", &on_battery,
304
		      NULL);
305
306
	if (!on_battery && strcmp (entry->key, GPM_CONF_BACKLIGHT_BRIGHTNESS_AC) == 0) {
307
		backlight_kbd->priv->master_percentage = gconf_value_get_int (value);
308
		gpm_backlight_kbd_brightness_evaluate_and_set (backlight_kbd, FALSE);
309
310
	} else if (on_battery && strcmp (entry->key, GPM_CONF_BACKLIGHT_BRIGHTNESS_DIM_BATT) == 0) {
311
		gpm_backlight_kbd_brightness_evaluate_and_set (backlight_kbd, FALSE);
312
313
	} else if (strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_DIM_AC) == 0 ||
314
		   strcmp (entry->key, GPM_CONF_BACKLIGHT_ENABLE) == 0 ||
315
		   strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT) == 0 ||
316
		   strcmp (entry->key, GPM_CONF_BACKLIGHT_BATTERY_REDUCE) == 0 ||
317
		   strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_BRIGHTNESS) == 0) {
318
		gpm_backlight_kbd_brightness_evaluate_and_set (backlight_kbd, FALSE);
319
320
	} else if (strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_DIM_TIME) == 0) {
321
		backlight_kbd->priv->idle_dim_timeout = gconf_value_get_int (value);
322
		gpm_idle_set_timeout_dim (backlight_kbd->priv->idle, backlight_kbd->priv->idle_dim_timeout);
323
	} else {
324
		egg_debug ("unknown key %s", entry->key);
325
	}
326
}
327
328
/**
329
 * gpm_backlight_kbd_client_changed_cb:
330
 * @client: The up_client class instance
331
 * @backlight_kbd: This class instance
332
 *
333
 * Does the actions when the ac power source is inserted/removed.
334
 **/
335
static void
336
gpm_backlight_kbd_client_changed_cb (UpClient *client, GpmBacklightKbd *backlight_kbd)
337
{
338
	gpm_backlight_kbd_brightness_evaluate_and_set (backlight_kbd, FALSE);
339
}
340
341
/**
342
 * gpm_backlight_kbd_button_pressed_cb:
343
 * @power: The power class instance
344
 * @type: The button type, e.g. "power"
345
 * @state: The state, where TRUE is depressed or closed
346
 * @brightness: This class instance
347
 **/
348
static void
349
gpm_backlight_kbd_button_pressed_cb (GpmButton *button, const gchar *type, GpmBacklightKbd *backlight_kbd)
350
{
351
	GError *error = NULL;
352
	gboolean ret = FALSE;
353
	gint percentage = -1, brightness;
354
	egg_debug ("Button press event type=%s", type);
355
356
	if (strcmp (type, GPM_BUTTON_KBD_BRIGHT_UP) == 0) {
357
		percentage = MIN(100, backlight_kbd->priv->master_percentage + 10);
358
		brightness = percentage * backlight_kbd->priv->max_brightness / 100;
359
		egg_debug ("Setting brightness to %d", brightness);
360
		ret = dbus_g_proxy_call (backlight_kbd->priv->proxy,
361
					 "SetBrightness", &error,
362
					 G_TYPE_INT, brightness,
363
					 G_TYPE_INVALID, G_TYPE_INVALID);
364
	} else if (strcmp (type, GPM_BUTTON_KBD_BRIGHT_DOWN) == 0) {
365
		percentage = MAX(0, backlight_kbd->priv->master_percentage - 10);
366
		brightness = percentage * backlight_kbd->priv->max_brightness / 100;
367
		egg_debug ("Setting brightness to %d", brightness);
368
		ret = dbus_g_proxy_call (backlight_kbd->priv->proxy,
369
					 "SetBrightness", &error,
370
					 G_TYPE_INT, brightness,
371
					 G_TYPE_INVALID, G_TYPE_INVALID);
372
	}
373
	if (ret) {
374
		gpm_backlight_kbd_dialog_init (backlight_kbd);
375
		gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight_kbd->priv->popup),
376
							percentage);
377
		gpm_backlight_kbd_dialog_show (backlight_kbd);
378
		/* save the new percentage */
379
		backlight_kbd->priv->master_percentage = percentage;
380
	} else if (percentage >= 0) {
381
		egg_warning ("failed to set brightness to %d: %s", brightness, error->message);
382
		g_error_free (error);
383
	}
384
}
385
386
/**
387
 * gpm_backlight_kbd_notify_system_idle_changed:
388
 **/
389
static gboolean
390
gpm_backlight_kbd_notify_system_idle_changed (GpmBacklightKbd *backlight_kbd, gboolean is_idle)
391
{
392
	gdouble elapsed;
393
394
	/* no point continuing */
395
	if (backlight_kbd->priv->system_is_idle == is_idle) {
396
		egg_debug ("state not changed");
397
		return FALSE;
398
	}
399
400
	/* get elapsed time and reset timer */
401
	elapsed = g_timer_elapsed (backlight_kbd->priv->idle_timer, NULL);
402
	g_timer_reset (backlight_kbd->priv->idle_timer);
403
404
	if (is_idle == FALSE) {
405
		egg_debug ("we have just been idle for %lfs", elapsed);
406
407
		/* The user immediatly undimmed the screen!
408
		 * We should double the timeout to avoid this happening again */
409
		if (elapsed < 10) {
410
			/* double the event time */
411
			backlight_kbd->priv->idle_dim_timeout *= 2.0;
412
			egg_debug ("increasing idle dim time to %is", backlight_kbd->priv->idle_dim_timeout);
413
			gpm_idle_set_timeout_dim (backlight_kbd->priv->idle, backlight_kbd->priv->idle_dim_timeout);
414
		}
415
416
		/* We reset the dimming after 2 minutes of idle,
417
		 * as the user will have changed tasks */
418
		if (elapsed > 2*60) {
419
			/* reset back to our default dimming */
420
			backlight_kbd->priv->idle_dim_timeout =
421
				gconf_client_get_int (backlight_kbd->priv->conf,
422
						      GPM_CONF_BACKLIGHT_IDLE_DIM_TIME, NULL);
423
			egg_debug ("resetting idle dim time to %is", backlight_kbd->priv->idle_dim_timeout);
424
			gpm_idle_set_timeout_dim (backlight_kbd->priv->idle, backlight_kbd->priv->idle_dim_timeout);
425
		}
426
	} else {
427
		egg_debug ("we were active for %lfs", elapsed);
428
	}
429
430
	egg_debug ("changing powersave idle status to %i", is_idle);
431
	backlight_kbd->priv->system_is_idle = is_idle;
432
	return TRUE;
433
}
434
435
/**
436
 * idle_changed_cb:
437
 * @idle: The idle class instance
438
 * @mode: The idle mode, e.g. GPM_IDLE_MODE_BLANK
439
 * @manager: This class instance
440
 *
441
 * This callback is called when gnome-screensaver detects that the idle state
442
 * has changed. GPM_IDLE_MODE_BLANK is when the session has become inactive,
443
 * and GPM_IDLE_MODE_SLEEP is where the session has become inactive, AND the
444
 * session timeout has elapsed for the idle action.
445
 **/
446
static void
447
idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmBacklightKbd *backlight_kbd)
448
{
449
	/* don't dim or undim the screen when the lid is closed */
450
	if (gpm_button_is_lid_closed (backlight_kbd->priv->button))
451
		return;
452
453
	/* don't dim or undim the screen unless we are on the active console */
454
	if (!egg_console_kit_is_active (backlight_kbd->priv->consolekit)) {
455
		egg_debug ("ignoring as not on active console");
456
		return;
457
	}
458
459
	if (mode == GPM_IDLE_MODE_NORMAL ||
460
	    mode == GPM_IDLE_MODE_DIM ||
461
	    mode == GPM_IDLE_MODE_BLANK) {
462
		/* sync brightness */
463
		gpm_backlight_kbd_notify_system_idle_changed (backlight_kbd,
464
							      mode != GPM_IDLE_MODE_NORMAL);
465
		gpm_backlight_kbd_brightness_evaluate_and_set (backlight_kbd, FALSE);
466
	}
467
}
468
469
/**
470
 * control_resume_cb:
471
 * @control: The control class instance
472
 * @action: The action
473
 * @backlight_kbd: The keyboard backlight instance
474
 *
475
 * We want to ensure the keyboard backlight is on after resume
476
 */
477
static void
478
control_resume_cb (GpmControl *control, GpmControlAction action, GpmBacklightKbd *backlight_kbd)
479
{
480
	gpm_backlight_kbd_brightness_evaluate_and_set(backlight_kbd, FALSE);
481
}
482
483
/**
484
 * dpms_mode_changed_cb:
485
 * @dpms: The dpms class instance
486
 * @mode: The dpms mode
487
 * @backlight_kbd: The keyboard backlight instance
488
 *
489
 * We want to stay in sync with screen dpms
490
 */
491
static void
492
dpms_mode_changed_cb (GpmDpms *dpms, GpmDpmsMode mode, GpmBacklightKbd *backlight_kbd)
493
{
494
	backlight_kbd->priv->off = (mode != GPM_DPMS_MODE_ON);
495
	gpm_backlight_kbd_brightness_evaluate_and_set (backlight_kbd, FALSE);
496
}
497
/**
498
 * gpm_backlight_kbd_finalize:
499
 **/
500
static void
501
gpm_backlight_kbd_finalize (GObject *object)
502
{
503
	GpmBacklightKbd *backlight_kbd;
504
	g_return_if_fail (object != NULL);
505
	g_return_if_fail (GPM_IS_BACKLIGHT_KBD (object));
506
	backlight_kbd = GPM_BACKLIGHT_KBD (object);
507
508
	g_timer_destroy (backlight_kbd->priv->idle_timer);
509
	gtk_widget_destroy (backlight_kbd->priv->popup);
510
511
	g_object_unref (backlight_kbd->priv->dpms);
512
	g_object_unref (backlight_kbd->priv->control);
513
	g_object_unref (backlight_kbd->priv->conf);
514
	g_object_unref (backlight_kbd->priv->client);
515
	g_object_unref (backlight_kbd->priv->button);
516
	g_object_unref (backlight_kbd->priv->idle);
517
	g_object_unref (backlight_kbd->priv->proxy);
518
	g_object_unref (backlight_kbd->priv->consolekit);
519
520
	g_return_if_fail (backlight_kbd->priv != NULL);
521
	G_OBJECT_CLASS (gpm_backlight_kbd_parent_class)->finalize (object);
522
}
523
524
/**
525
 * gpm_backlight_kbd_class_init:
526
 **/
527
static void
528
gpm_backlight_kbd_class_init (GpmBacklightKbdClass *klass)
529
{
530
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
531
	object_class->finalize	   = gpm_backlight_kbd_finalize;
532
533
	g_type_class_add_private (klass, sizeof (GpmBacklightKbdPrivate));
534
}
535
536
/**
537
 * gpm_backlight_kbd_init:
538
 * @brightness: This brightness class instance
539
 *
540
 * initialises the brightness class. NOTE: We expect laptop_panel objects
541
 * to *NOT* be removed or added during the session.
542
 * We only control the first laptop_panel object if there are more than one.
543
 **/
544
static void
545
gpm_backlight_kbd_init (GpmBacklightKbd *backlight_kbd)
546
{
547
	DBusGConnection *connection;
548
	GError *error = NULL;
549
	gboolean ret;
550
	gint brightness;
551
552
	backlight_kbd->priv = GPM_BACKLIGHT_KBD_GET_PRIVATE (backlight_kbd);
553
554
	/* record our idle time */
555
	backlight_kbd->priv->idle_timer = g_timer_new ();
556
557
	/* we use up_client for the ac-adapter-changed signal */
558
	backlight_kbd->priv->client = up_client_new ();
559
	g_signal_connect (backlight_kbd->priv->client, "changed",
560
			  G_CALLBACK (gpm_backlight_kbd_client_changed_cb), backlight_kbd);
561
562
	/* watch for dim value changes */
563
	backlight_kbd->priv->conf = gconf_client_get_default ();
564
565
	/* watch gnome-power-manager keys */
566
	gconf_client_add_dir (backlight_kbd->priv->conf, GPM_CONF_DIR, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
567
	gconf_client_notify_add (backlight_kbd->priv->conf, GPM_CONF_DIR,
568
				 (GConfClientNotifyFunc) gpm_conf_gconf_key_changed_cb,
569
				 backlight_kbd, NULL, NULL);
570
571
	/* set the main brightness, this is designed to be updated if the user changes the
572
	 * brightness so we can undim to the 'correct' value */
573
	backlight_kbd->priv->master_percentage = gconf_client_get_int (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_BRIGHTNESS_AC, NULL);
574
575
	/* watch for brightness up and down buttons and also check lid state */
576
	backlight_kbd->priv->button = gpm_button_new ();
577
	g_signal_connect (backlight_kbd->priv->button, "button-pressed",
578
			  G_CALLBACK (gpm_backlight_kbd_button_pressed_cb), backlight_kbd);
579
580
	/* watch for idle mode changes */
581
	backlight_kbd->priv->idle = gpm_idle_new ();
582
	g_signal_connect (backlight_kbd->priv->idle, "idle-changed",
583
			  G_CALLBACK (idle_changed_cb), backlight_kbd);
584
585
	/* assumption */
586
	backlight_kbd->priv->system_is_idle = FALSE;
587
	backlight_kbd->priv->idle_dim_timeout = gconf_client_get_int (backlight_kbd->priv->conf, GPM_CONF_BACKLIGHT_IDLE_DIM_TIME, NULL);
588
	gpm_idle_set_timeout_dim (backlight_kbd->priv->idle, backlight_kbd->priv->idle_dim_timeout);
589
590
	/* use a visual widget */
591
	backlight_kbd->priv->popup = gsd_media_keys_window_new ();
592
	gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight_kbd->priv->popup),
593
						 "gpm-brightness-lcd",
594
						 TRUE);
595
	gtk_window_set_position (GTK_WINDOW (backlight_kbd->priv->popup), GTK_WIN_POS_NONE);
596
597
	/* DPMS mode poll class */
598
	backlight_kbd->priv->dpms = gpm_dpms_new ();
599
	g_signal_connect (backlight_kbd->priv->dpms, "mode-changed",
600
			  G_CALLBACK (dpms_mode_changed_cb), backlight_kbd);
601
602
	/* we refresh backlight on resume */
603
	backlight_kbd->priv->control = gpm_control_new ();
604
	g_signal_connect (backlight_kbd->priv->control, "resume",
605
			  G_CALLBACK (control_resume_cb), backlight_kbd);
606
607
	/* Don't do dimming on inactive console */
608
	backlight_kbd->priv->consolekit = egg_console_kit_new ();
609
610
	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
611
	backlight_kbd->priv->proxy = dbus_g_proxy_new_for_name (connection,
612
								BACKLIGHT_KBD_SERVICE,
613
								BACKLIGHT_KBD_PATH,
614
								BACKLIGHT_KBD_INTERFACE);
615
616
	if (!backlight_kbd->priv->proxy) {
617
		egg_warning ("Failed to get proxy to kbdbacklight interface");
618
		return;
619
	}
620
621
	ret = dbus_g_proxy_call (backlight_kbd->priv->proxy,
622
				 "GetBrightness", &error,
623
				 G_TYPE_INVALID,
624
				 G_TYPE_INT, &brightness,
625
				 G_TYPE_INVALID);
626
	if (error) {
627
		egg_debug ("ERROR: %s", error->message);
628
		g_error_free (error);
629
	}
630
	if (!ret) {
631
		egg_warning ("GetBrightness failed!");
632
		return;
633
	}
634
635
	ret = dbus_g_proxy_call (backlight_kbd->priv->proxy,
636
				 "GetMaxBrightness", &error,
637
				 G_TYPE_INVALID,
638
				 G_TYPE_INT, &backlight_kbd->priv->max_brightness,
639
				 G_TYPE_INVALID);
640
	if (error) {
641
		egg_debug ("ERROR: %s", error->message);
642
		g_error_free (error);
643
	}
644
	if (!ret) {
645
		egg_warning ("GetMaxBrightness failed!");
646
		return;
647
	}
648
649
	brightness = (backlight_kbd->priv->max_brightness *
650
		      backlight_kbd->priv->master_percentage / 100);
651
	egg_debug ("Setting brightness to %d", brightness);
652
	/* set initial brightness to max */
653
	ret = dbus_g_proxy_call (backlight_kbd->priv->proxy,
654
				 "SetBrightness", &error,
655
				 G_TYPE_INT, brightness,
656
				 G_TYPE_INVALID, G_TYPE_INVALID);
657
	if (error) {
658
		egg_debug ("ERROR: %s", error->message);
659
		g_error_free (error);
660
	}
661
	if (!ret) {
662
		egg_warning ("SetBrightness failed!");
663
	}
664
665
	/* sync at startup */
666
	gpm_backlight_kbd_brightness_evaluate_and_set (backlight_kbd, FALSE);
667
668
}
669
670
671
/**
672
 * gpm_backlight_kbd_new:
673
 * Return value: A new brightness class instance.
674
 **/
675
GpmBacklightKbd *
676
gpm_backlight_kbd_new (void)
677
{
678
	GpmBacklightKbd *backlight_kbd = g_object_new (GPM_TYPE_BACKLIGHT_KBD, NULL);
679
	return backlight_kbd;
680
}
681
(-)gnome-power-manager-2.32.0-r1-orig/work/gnome-power-manager-2.32.0/src/gpm-backlight-kbd.h (+57 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2
 *
3
 * Copyright (C) 2010 Alex Murray <murray.alex@gmail.com>
4
 * Copyright (C) 2005-2007 Richard Hughes <richard@hughsie.com>
5
 * Copyright (C) 2004-2005 William Jon McCann <mccann@jhu.edu>
6
 *
7
 * Licensed under the GNU General Public License Version 2
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
 */
23
24
#ifndef __GPM_BACKLIGHT_KBD_H
25
#define __GPM_BACKLIGHT_KBD_H
26
27
#include <glib-object.h>
28
29
G_BEGIN_DECLS
30
31
#define GPM_TYPE_BACKLIGHT_KBD		(gpm_backlight_kbd_get_type ())
32
#define GPM_BACKLIGHT_KBD(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_BACKLIGHT_KBD, GpmBacklightKbd))
33
#define GPM_BACKLIGHT_KBD_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_BACKLIGHT_KBD, GpmBacklightKbdClass))
34
#define GPM_IS_BACKLIGHT_KBD(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_BACKLIGHT_KBD))
35
#define GPM_IS_BACKLIGHT_KBD_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_BACKLIGHT_KBD))
36
#define GPM_BACKLIGHT_KBD_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_BACKLIGHT_KBD, GpmBacklightKbdClass))
37
38
typedef struct GpmBacklightKbdPrivate GpmBacklightKbdPrivate;
39
40
typedef struct
41
{
42
	GObject		         parent;
43
	GpmBacklightKbdPrivate *priv;
44
} GpmBacklightKbd;
45
46
typedef struct
47
{
48
	GObjectClass	parent_class;
49
} GpmBacklightKbdClass;
50
51
GType		 gpm_backlight_kbd_get_type			(void);
52
GpmBacklightKbd	*gpm_backlight_kbd_new			(void);
53
54
G_END_DECLS
55
56
#endif /* __GPM_BACKLIGHT_KBD_H */
57
(-)gnome-power-manager-2.32.0-r1-orig/work/gnome-power-manager-2.32.0/src/gpm-manager.c (+4 lines)
Lines 54-59 Link Here
54
#include "gpm-manager.h"
54
#include "gpm-manager.h"
55
#include "gpm-screensaver.h"
55
#include "gpm-screensaver.h"
56
#include "gpm-backlight.h"
56
#include "gpm-backlight.h"
57
#include "gpm-backlight-kbd.h"
57
#include "gpm-session.h"
58
#include "gpm-session.h"
58
#include "gpm-stock-icons.h"
59
#include "gpm-stock-icons.h"
59
#include "gpm-prefs-server.h"
60
#include "gpm-prefs-server.h"
Lines 87-92 Link Here
87
	GpmTrayIcon		*tray_icon;
88
	GpmTrayIcon		*tray_icon;
88
	GpmEngine		*engine;
89
	GpmEngine		*engine;
89
	GpmBacklight		*backlight;
90
	GpmBacklight		*backlight;
91
	GpmBacklightKbd		*backlight_kbd;
90
	EggConsoleKit		*console;
92
	EggConsoleKit		*console;
91
	guint32			 screensaver_ac_throttle_id;
93
	guint32			 screensaver_ac_throttle_id;
92
	guint32			 screensaver_dpms_throttle_id;
94
	guint32			 screensaver_dpms_throttle_id;
Lines 1993-1998 Link Here
1993
		dbus_g_connection_register_g_object (connection, GPM_DBUS_PATH_BACKLIGHT,
1995
		dbus_g_connection_register_g_object (connection, GPM_DBUS_PATH_BACKLIGHT,
1994
						     G_OBJECT (manager->priv->backlight));
1996
						     G_OBJECT (manager->priv->backlight));
1995
	}
1997
	}
1998
	manager->priv->backlight_kbd = gpm_backlight_kbd_new ();
1996
1999
1997
	manager->priv->idle = gpm_idle_new ();
2000
	manager->priv->idle = gpm_idle_new ();
1998
	g_signal_connect (manager->priv->idle, "idle-changed",
2001
	g_signal_connect (manager->priv->idle, "idle-changed",
Lines 2089-2094 Link Here
2089
	g_object_unref (manager->priv->control);
2092
	g_object_unref (manager->priv->control);
2090
	g_object_unref (manager->priv->button);
2093
	g_object_unref (manager->priv->button);
2091
	g_object_unref (manager->priv->backlight);
2094
	g_object_unref (manager->priv->backlight);
2095
	g_object_unref (manager->priv->backlight_kbd);
2092
	g_object_unref (manager->priv->console);
2096
	g_object_unref (manager->priv->console);
2093
	g_object_unref (manager->priv->client);
2097
	g_object_unref (manager->priv->client);
2094
	g_object_unref (manager->priv->status_icon);
2098
	g_object_unref (manager->priv->status_icon);
(-)gnome-power-manager-2.32.0-r1-orig/work/gnome-power-manager-2.32.0/src/gpm-manager.c.orig (+2110 lines)
Line 0 Link Here
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2
 *
3
 * Copyright (C) 2005 William Jon McCann <mccann@jhu.edu>
4
 * Copyright (C) 2005-2008 Richard Hughes <richard@hughsie.com>
5
 *
6
 * Licensed under the GNU General Public License Version 2
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22
23
#include "config.h"
24
25
#include <stdlib.h>
26
#include <stdio.h>
27
#include <time.h>
28
#include <errno.h>
29
30
#include <string.h>
31
#include <sys/time.h>
32
#include <sys/types.h>
33
#ifdef HAVE_UNISTD_H
34
#include <unistd.h>
35
#endif /* HAVE_UNISTD_H */
36
37
#include <glib/gi18n.h>
38
#include <gtk/gtk.h>
39
#include <dbus/dbus-glib.h>
40
#include <dbus/dbus-glib-lowlevel.h>
41
#include <gconf/gconf-client.h>
42
#include <canberra-gtk.h>
43
#include <libupower-glib/upower.h>
44
#include <libnotify/notify.h>
45
46
#include "egg-debug.h"
47
#include "egg-console-kit.h"
48
49
#include "gpm-button.h"
50
#include "gpm-control.h"
51
#include "gpm-common.h"
52
#include "gpm-dpms.h"
53
#include "gpm-idle.h"
54
#include "gpm-manager.h"
55
#include "gpm-screensaver.h"
56
#include "gpm-backlight.h"
57
#include "gpm-session.h"
58
#include "gpm-stock-icons.h"
59
#include "gpm-prefs-server.h"
60
#include "gpm-tray-icon.h"
61
#include "gpm-engine.h"
62
#include "gpm-upower.h"
63
#include "gpm-disks.h"
64
65
#include "org.gnome.PowerManager.Backlight.h"
66
67
static void     gpm_manager_finalize	(GObject	 *object);
68
69
#define GPM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_MANAGER, GpmManagerPrivate))
70
#define GPM_MANAGER_RECALL_DELAY		30 /* seconds */
71
#define GPM_MANAGER_NOTIFY_TIMEOUT_NEVER	0 /* ms */
72
#define GPM_MANAGER_NOTIFY_TIMEOUT_SHORT	10 * 1000 /* ms */
73
#define GPM_MANAGER_NOTIFY_TIMEOUT_LONG		30 * 1000 /* ms */
74
75
#define GPM_MANAGER_CRITICAL_ALERT_TIMEOUT      5 /* seconds */
76
77
struct GpmManagerPrivate
78
{
79
	GpmButton		*button;
80
	GConfClient		*conf;
81
	GpmDisks		*disks;
82
	GpmDpms			*dpms;
83
	GpmIdle			*idle;
84
	GpmPrefsServer		*prefs_server;
85
	GpmControl		*control;
86
	GpmScreensaver		*screensaver;
87
	GpmTrayIcon		*tray_icon;
88
	GpmEngine		*engine;
89
	GpmBacklight		*backlight;
90
	EggConsoleKit		*console;
91
	guint32			 screensaver_ac_throttle_id;
92
	guint32			 screensaver_dpms_throttle_id;
93
	guint32			 screensaver_lid_throttle_id;
94
	guint32                  critical_alert_timeout_id;
95
	ca_proplist             *critical_alert_loop_props;
96
	UpClient		*client;
97
	gboolean		 on_battery;
98
	gboolean		 just_resumed;
99
	GtkStatusIcon		*status_icon;
100
	NotifyNotification	*notification_general;
101
	NotifyNotification	*notification_warning_low;
102
	NotifyNotification	*notification_discharging;
103
	NotifyNotification	*notification_fully_charged;
104
};
105
106
typedef enum {
107
	GPM_MANAGER_SOUND_POWER_PLUG,
108
	GPM_MANAGER_SOUND_POWER_UNPLUG,
109
	GPM_MANAGER_SOUND_LID_OPEN,
110
	GPM_MANAGER_SOUND_LID_CLOSE,
111
	GPM_MANAGER_SOUND_BATTERY_CAUTION,
112
	GPM_MANAGER_SOUND_BATTERY_LOW,
113
	GPM_MANAGER_SOUND_BATTERY_FULL,
114
	GPM_MANAGER_SOUND_SUSPEND_START,
115
	GPM_MANAGER_SOUND_SUSPEND_RESUME,
116
	GPM_MANAGER_SOUND_SUSPEND_ERROR,
117
	GPM_MANAGER_SOUND_LAST
118
} GpmManagerSound;
119
120
G_DEFINE_TYPE (GpmManager, gpm_manager, G_TYPE_OBJECT)
121
122
/**
123
 * gpm_manager_error_quark:
124
 * Return value: Our personal error quark.
125
 **/
126
GQuark
127
gpm_manager_error_quark (void)
128
{
129
	static GQuark quark = 0;
130
	if (!quark)
131
		quark = g_quark_from_static_string ("gpm_manager_error");
132
	return quark;
133
}
134
135
/**
136
 * gpm_manager_error_get_type:
137
 **/
138
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
139
GType
140
gpm_manager_error_get_type (void)
141
{
142
	static GType etype = 0;
143
144
	if (etype == 0) {
145
		static const GEnumValue values[] =
146
		{
147
			ENUM_ENTRY (GPM_MANAGER_ERROR_DENIED, "PermissionDenied"),
148
			ENUM_ENTRY (GPM_MANAGER_ERROR_NO_HW, "NoHardwareSupport"),
149
			{ 0, 0, 0 }
150
		};
151
		etype = g_enum_register_static ("GpmManagerError", values);
152
	}
153
	return etype;
154
}
155
156
/**
157
 * gpm_manager_play_loop_timeout_cb:
158
 **/
159
static gboolean
160
gpm_manager_play_loop_timeout_cb (GpmManager *manager)
161
{
162
	ca_context *context;
163
	context = ca_gtk_context_get_for_screen (gdk_screen_get_default ());
164
	ca_context_play_full (context, 0,
165
			      manager->priv->critical_alert_loop_props,
166
			      NULL,
167
			      NULL);
168
	return TRUE;
169
}
170
171
/**
172
 * gpm_manager_play_loop_stop:
173
 **/
174
static gboolean
175
gpm_manager_play_loop_stop (GpmManager *manager)
176
{
177
	if (manager->priv->critical_alert_timeout_id == 0) {
178
		egg_warning ("no sound loop present to stop");
179
		return FALSE;
180
	}
181
182
	g_source_remove (manager->priv->critical_alert_timeout_id);
183
	ca_proplist_destroy (manager->priv->critical_alert_loop_props);
184
185
	manager->priv->critical_alert_loop_props = NULL;
186
	manager->priv->critical_alert_timeout_id = 0;
187
188
	return TRUE;
189
}
190
191
/**
192
 * gpm_manager_play_loop_start:
193
 **/
194
static gboolean
195
gpm_manager_play_loop_start (GpmManager *manager, GpmManagerSound action, gboolean force, guint timeout)
196
{
197
	const gchar *id = NULL;
198
	const gchar *desc = NULL;
199
	gboolean ret;
200
	gint retval;
201
	ca_context *context;
202
203
	ret = gconf_client_get_bool (manager->priv->conf, GPM_CONF_UI_ENABLE_SOUND, NULL);
204
	if (!ret && !force) {
205
		egg_debug ("ignoring sound due to policy");
206
		return FALSE;
207
	}
208
209
	if (timeout == 0) {
210
		egg_warning ("received invalid timeout");
211
		return FALSE;
212
	}
213
214
	/* if a sound loop is already running, stop the existing loop */
215
	if (manager->priv->critical_alert_timeout_id != 0) {
216
		egg_warning ("was instructed to play a sound loop with one already playing");
217
		gpm_manager_play_loop_stop (manager);
218
	}
219
220
	if (action == GPM_MANAGER_SOUND_BATTERY_LOW) {
221
		id = "battery-low";
222
		/* TRANSLATORS: this is the sound description */
223
		desc = _("Battery is very low");
224
	}
225
226
	/* no match */
227
	if (id == NULL) {
228
		egg_warning ("no sound match for %i", action);
229
		return FALSE;
230
	}
231
232
	ca_proplist_create (&(manager->priv->critical_alert_loop_props));
233
	ca_proplist_sets (manager->priv->critical_alert_loop_props,
234
			  CA_PROP_EVENT_ID, id);
235
	ca_proplist_sets (manager->priv->critical_alert_loop_props,
236
			  CA_PROP_EVENT_DESCRIPTION, desc);
237
238
	manager->priv->critical_alert_timeout_id = g_timeout_add_seconds (timeout,
239
									  (GSourceFunc) gpm_manager_play_loop_timeout_cb,
240
									  manager);
241
242
	/* play the sound, using sounds from the naming spec */
243
	context = ca_gtk_context_get_for_screen (gdk_screen_get_default ());
244
	retval = ca_context_play (context, 0,
245
				  CA_PROP_EVENT_ID, id,
246
				  CA_PROP_EVENT_DESCRIPTION, desc, NULL);
247
	if (retval < 0)
248
		egg_warning ("failed to play %s: %s", id, ca_strerror (retval));
249
	return TRUE;
250
}
251
252
/**
253
 * gpm_manager_play:
254
 **/
255
static gboolean
256
gpm_manager_play (GpmManager *manager, GpmManagerSound action, gboolean force)
257
{
258
	const gchar *id = NULL;
259
	const gchar *desc = NULL;
260
	gboolean ret;
261
	gint retval;
262
	ca_context *context;
263
264
	ret = gconf_client_get_bool (manager->priv->conf, GPM_CONF_UI_ENABLE_SOUND, NULL);
265
	if (!ret && !force) {
266
		egg_debug ("ignoring sound due to policy");
267
		return FALSE;
268
	}
269
270
	if (action == GPM_MANAGER_SOUND_POWER_PLUG) {
271
		id = "power-plug";
272
		/* TRANSLATORS: this is the sound description */
273
		desc = _("Power plugged in");
274
	} else if (action == GPM_MANAGER_SOUND_POWER_UNPLUG) {
275
		id = "power-unplug";
276
		/* TRANSLATORS: this is the sound description */
277
		desc = _("Power unplugged");
278
	} else if (action == GPM_MANAGER_SOUND_LID_OPEN) {
279
		id = "lid-open";
280
		/* TRANSLATORS: this is the sound description */
281
		desc = _("Lid has opened");
282
	} else if (action == GPM_MANAGER_SOUND_LID_CLOSE) {
283
		id = "lid-close";
284
		/* TRANSLATORS: this is the sound description */
285
		desc = _("Lid has closed");
286
	} else if (action == GPM_MANAGER_SOUND_BATTERY_CAUTION) {
287
		id = "battery-caution";
288
		/* TRANSLATORS: this is the sound description */
289
		desc = _("Battery is low");
290
	} else if (action == GPM_MANAGER_SOUND_BATTERY_LOW) {
291
		id = "battery-low";
292
		/* TRANSLATORS: this is the sound description */
293
		desc = _("Battery is very low");
294
	} else if (action == GPM_MANAGER_SOUND_BATTERY_FULL) {
295
		id = "battery-full";
296
		/* TRANSLATORS: this is the sound description */
297
		desc = _("Battery is full");
298
	} else if (action == GPM_MANAGER_SOUND_SUSPEND_START) {
299
		id = "suspend-start";
300
		/* TRANSLATORS: this is the sound description */
301
		desc = _("Suspend started");
302
	} else if (action == GPM_MANAGER_SOUND_SUSPEND_RESUME) {
303
		id = "suspend-resume";
304
		/* TRANSLATORS: this is the sound description */
305
		desc = _("Resumed");
306
	} else if (action == GPM_MANAGER_SOUND_SUSPEND_ERROR) {
307
		id = "suspend-error";
308
		/* TRANSLATORS: this is the sound description */
309
		desc = _("Suspend failed");
310
	}
311
312
	/* no match */
313
	if (id == NULL) {
314
		egg_warning ("no match");
315
		return FALSE;
316
	}
317
318
	/* play the sound, using sounds from the naming spec */
319
	context = ca_gtk_context_get_for_screen (gdk_screen_get_default ());
320
	retval = ca_context_play (context, 0,
321
				  CA_PROP_EVENT_ID, id,
322
				  CA_PROP_EVENT_DESCRIPTION, desc, NULL);
323
	if (retval < 0)
324
		egg_warning ("failed to play %s: %s", id, ca_strerror (retval));
325
	return TRUE;
326
}
327
328
/**
329
 * gpm_manager_is_inhibit_valid:
330
 * @manager: This class instance
331
 * @action: The action we want to do, e.g. "suspend"
332
 *
333
 * Checks to see if the specific action has been inhibited by a program.
334
 *
335
 * Return value: TRUE if we can perform the action.
336
 **/
337
static gboolean
338
gpm_manager_is_inhibit_valid (GpmManager *manager, gboolean user_action, const char *action)
339
{
340
	return TRUE;
341
}
342
343
/**
344
 * gpm_manager_sync_policy_sleep:
345
 * @manager: This class instance
346
 *
347
 * Changes the policy if required, setting brightness, display and computer
348
 * timeouts.
349
 * We have to make sure gnome-screensaver disables screensaving, and enables
350
 * monitor DPMS instead when on batteries to save power.
351
 **/
352
static void
353
gpm_manager_sync_policy_sleep (GpmManager *manager)
354
{
355
	guint sleep_display;
356
	guint sleep_computer;
357
358
	if (!manager->priv->on_battery) {
359
		sleep_computer = gconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC, NULL);
360
		sleep_display = gconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC, NULL);
361
	} else {
362
		sleep_computer = gconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT, NULL);
363
		sleep_display = gconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT, NULL);
364
	}
365
366
	/* set the new sleep (inactivity) value */
367
	gpm_idle_set_timeout_blank (manager->priv->idle, sleep_display);
368
	gpm_idle_set_timeout_sleep (manager->priv->idle, sleep_computer);
369
}
370
371
/**
372
 * gpm_manager_blank_screen:
373
 * @manager: This class instance
374
 *
375
 * Turn off the backlight of the LCD when we shut the lid, and lock
376
 * if required. This is required because some laptops do not turn off the
377
 * LCD backlight when the lid is closed.
378
 * See http://bugzilla.gnome.org/show_bug.cgi?id=321313
379
 *
380
 * Return value: Success.
381
 **/
382
static gboolean
383
gpm_manager_blank_screen (GpmManager *manager, GError **noerror)
384
{
385
	gboolean do_lock;
386
	gboolean ret = TRUE;
387
	GError *error = NULL;
388
389
	do_lock = gpm_control_get_lock_policy (manager->priv->control,
390
					       GPM_CONF_LOCK_ON_BLANK_SCREEN);
391
	if (do_lock) {
392
		if (!gpm_screensaver_lock (manager->priv->screensaver))
393
			egg_debug ("Could not lock screen via gnome-screensaver");
394
	}
395
	gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_OFF, &error);
396
	if (error) {
397
		egg_debug ("Unable to set DPMS mode: %s", error->message);
398
		g_error_free (error);
399
		ret = FALSE;
400
	}
401
	return ret;
402
}
403
404
/**
405
 * gpm_manager_unblank_screen:
406
 * @manager: This class instance
407
 *
408
 * Unblank the screen after we have opened the lid of the laptop
409
 *
410
 * Return value: Success.
411
 **/
412
static gboolean
413
gpm_manager_unblank_screen (GpmManager *manager, GError **noerror)
414
{
415
	gboolean do_lock;
416
	gboolean ret = TRUE;
417
	GError *error = NULL;
418
419
	gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
420
	if (error) {
421
		egg_debug ("Unable to set DPMS mode: %s", error->message);
422
		g_error_free (error);
423
		ret = FALSE;
424
	}
425
426
	do_lock = gpm_control_get_lock_policy (manager->priv->control, GPM_CONF_LOCK_ON_BLANK_SCREEN);
427
	if (do_lock)
428
		gpm_screensaver_poke (manager->priv->screensaver);
429
	return ret;
430
}
431
432
/**
433
 * gpm_manager_notify_close:
434
 **/
435
static gboolean
436
gpm_manager_notify_close (GpmManager *manager, NotifyNotification *notification)
437
{
438
	gboolean ret = FALSE;
439
	GError *error = NULL;
440
441
	/* exists? */
442
	if (notification == NULL)
443
		goto out;
444
445
	/* try to close */
446
	ret = notify_notification_close (notification, &error);
447
	if (!ret) {
448
		egg_warning ("failed to close notification: %s", error->message);
449
		g_error_free (error);
450
		goto out;
451
	}
452
out:
453
	return ret;
454
}
455
456
/**
457
 * gpm_manager_notification_closed_cb:
458
 **/
459
static void
460
gpm_manager_notification_closed_cb (NotifyNotification *notification, NotifyNotification **notification_class)
461
{
462
	egg_debug ("caught notification closed signal %p", notification);
463
	/* the object is already unreffed in _close_signal_handler */
464
	*notification_class = NULL;
465
}
466
467
/**
468
 * gpm_manager_notify:
469
 **/
470
static gboolean
471
gpm_manager_notify (GpmManager *manager, NotifyNotification **notification_class,
472
		    const gchar *title, const gchar *message,
473
		    guint timeout, const gchar *icon, NotifyUrgency urgency)
474
{
475
	gboolean ret;
476
	GError *error = NULL;
477
	NotifyNotification *notification;
478
	GtkWidget *dialog;
479
480
	/* close any existing notification of this class */
481
	gpm_manager_notify_close (manager, *notification_class);
482
483
	/* if the status icon is hidden, don't point at it */
484
	if (manager->priv->status_icon != NULL &&
485
	    gtk_status_icon_is_embedded (manager->priv->status_icon))
486
		notification = notify_notification_new_with_status_icon (title, message, icon, manager->priv->status_icon);
487
	else
488
		notification = notify_notification_new (title, message, icon, NULL);
489
	notify_notification_set_timeout (notification, timeout);
490
	notify_notification_set_urgency (notification, urgency);
491
	g_signal_connect (notification, "closed", G_CALLBACK (gpm_manager_notification_closed_cb), notification_class);
492
493
	egg_debug ("notification %p: %s : %s", notification, title, message);
494
495
	/* try to show */
496
	ret = notify_notification_show (notification, &error);
497
	if (!ret) {
498
		egg_warning ("failed to show notification: %s", error->message);
499
		g_error_free (error);
500
501
		/* show modal dialog as libnotify failed */
502
		dialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
503
							     GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
504
							     "<span size='larger'><b>%s</b></span>", title);
505
		gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
506
507
		/* wait async for close */
508
		gtk_widget_show (dialog);
509
		g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
510
511
		g_object_unref (notification);
512
		goto out;
513
	}
514
515
	/* save this local instance as the class instance */
516
	g_object_add_weak_pointer (G_OBJECT (notification), (gpointer) &notification);
517
	*notification_class = notification;
518
out:
519
	return ret;
520
}
521
522
523
/**
524
 * gpm_manager_sleep_failure_response_cb:
525
 **/
526
static void
527
gpm_manager_sleep_failure_response_cb (GtkDialog *dialog, gint response_id, GpmManager *manager)
528
{
529
	GdkScreen *screen;
530
	GtkWidget *dialog_error;
531
	GError *error = NULL;
532
	gboolean ret;
533
	gchar *uri = NULL;
534
535
	/* user clicked the help button */
536
	if (response_id == GTK_RESPONSE_HELP) {
537
		uri = gconf_client_get_string (manager->priv->conf, GPM_CONF_NOTIFY_SLEEP_FAILED_URI, NULL);
538
		screen = gdk_screen_get_default();
539
		ret = gtk_show_uri (screen, uri, gtk_get_current_event_time (), &error);
540
		if (!ret) {
541
			dialog_error = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
542
							       "Failed to show uri %s", error->message);
543
			gtk_dialog_run (GTK_DIALOG (dialog_error));
544
			g_error_free (error);
545
		}
546
	}
547
548
	gtk_widget_destroy (GTK_WIDGET (dialog));
549
	g_free (uri);
550
}
551
552
/**
553
 * gpm_manager_sleep_failure:
554
 **/
555
static void
556
gpm_manager_sleep_failure (GpmManager *manager, gboolean is_suspend, const gchar *detail)
557
{
558
	gboolean show_sleep_failed;
559
	GString *string = NULL;
560
	const gchar *title;
561
	gchar *uri = NULL;
562
	const gchar *icon;
563
	GtkWidget *dialog;
564
565
	/* only show this if specified in gconf */
566
	show_sleep_failed = gconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_SLEEP_FAILED, NULL);
567
568
	egg_debug ("sleep failed");
569
	gpm_manager_play (manager, GPM_MANAGER_SOUND_SUSPEND_ERROR, TRUE);
570
571
	/* only emit if in GConf */
572
	if (!show_sleep_failed)
573
		goto out;
574
575
	/* TRANSLATORS: window title: there was a problem putting the machine to sleep */
576
	string = g_string_new ("");
577
	if (is_suspend) {
578
		/* TRANSLATORS: message text */
579
		g_string_append (string, _("Computer failed to suspend."));
580
		/* TRANSLATORS: title text */
581
		title = _("Failed to suspend");
582
		icon = GPM_STOCK_SUSPEND;
583
	} else {
584
		/* TRANSLATORS: message text */
585
		g_string_append (string, _("Computer failed to hibernate."));
586
		/* TRANSLATORS: title text */
587
		title = _("Failed to hibernate");
588
		icon = GPM_STOCK_HIBERNATE;
589
	}
590
591
	/* TRANSLATORS: message text */
592
	g_string_append_printf (string, "\n\n%s %s", _("Failure was reported as:"), detail);
593
594
	/* show modal dialog */
595
	dialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
596
						     GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
597
						     "<span size='larger'><b>%s</b></span>", title);
598
	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", string->str);
599
	gtk_window_set_icon_name (GTK_WINDOW(dialog), icon);
600
601
	/* show a button? */
602
	uri = gconf_client_get_string (manager->priv->conf, GPM_CONF_NOTIFY_SLEEP_FAILED_URI, NULL);
603
	if (uri != NULL && uri[0] != '\0') {
604
		/* TRANSLATORS: button text, visit the suspend help website */
605
		gtk_dialog_add_button (GTK_DIALOG (dialog), _("Visit help page"), GTK_RESPONSE_HELP);
606
	}
607
608
	/* wait async for close */
609
	gtk_widget_show (dialog);
610
	g_signal_connect (dialog, "response", G_CALLBACK (gpm_manager_sleep_failure_response_cb), manager);
611
out:
612
	g_free (uri);
613
	g_string_free (string, TRUE);
614
}
615
616
/**
617
 * gpm_manager_action_suspend:
618
 **/
619
static gboolean
620
gpm_manager_action_suspend (GpmManager *manager, const gchar *reason)
621
{
622
	gboolean ret;
623
	GError *error = NULL;
624
625
	/* check to see if we are inhibited */
626
	if (gpm_manager_is_inhibit_valid (manager, FALSE, "suspend") == FALSE)
627
		return FALSE;
628
629
	egg_debug ("suspending, reason: %s", reason);
630
	ret = gpm_control_suspend (manager->priv->control, &error);
631
	if (!ret) {
632
		gpm_manager_sleep_failure (manager, TRUE, error->message);
633
		g_error_free (error);
634
	}
635
	gpm_button_reset_time (manager->priv->button);
636
	return TRUE;
637
}
638
639
/**
640
 * gpm_manager_action_hibernate:
641
 **/
642
static gboolean
643
gpm_manager_action_hibernate (GpmManager *manager, const gchar *reason)
644
{
645
	gboolean ret;
646
	GError *error = NULL;
647
648
	/* check to see if we are inhibited */
649
	if (gpm_manager_is_inhibit_valid (manager, FALSE, "hibernate") == FALSE)
650
		return FALSE;
651
652
	egg_debug ("hibernating, reason: %s", reason);
653
	ret = gpm_control_hibernate (manager->priv->control, &error);
654
	if (!ret) {
655
		gpm_manager_sleep_failure (manager, TRUE, error->message);
656
		g_error_free (error);
657
	}
658
	gpm_button_reset_time (manager->priv->button);
659
	return TRUE;
660
}
661
662
/**
663
 * gpm_manager_perform_policy:
664
 * @manager: This class instance
665
 * @policy: The policy that we should do, e.g. "suspend"
666
 * @reason: The reason we are performing the policy action, e.g. "battery critical"
667
 *
668
 * Does one of the policy actions specified in gconf.
669
 **/
670
static gboolean
671
gpm_manager_perform_policy (GpmManager  *manager, const gchar *policy_key, const gchar *reason)
672
{
673
	gchar *action = NULL;
674
	GpmActionPolicy policy;
675
676
	/* are we inhibited? */
677
	if (gpm_manager_is_inhibit_valid (manager, FALSE, "policy action") == FALSE)
678
		return FALSE;
679
680
	action = gconf_client_get_string (manager->priv->conf, policy_key, NULL);
681
	egg_debug ("action: %s set to %s (%s)", policy_key, action, reason);
682
	policy = gpm_action_policy_from_string (action);
683
684
	if (policy == GPM_ACTION_POLICY_NOTHING) {
685
		egg_debug ("doing nothing, reason: %s", reason);
686
	} else if (policy == GPM_ACTION_POLICY_SUSPEND) {
687
		gpm_manager_action_suspend (manager, reason);
688
689
	} else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
690
		gpm_manager_action_hibernate (manager, reason);
691
692
	} else if (policy == GPM_ACTION_POLICY_BLANK) {
693
		gpm_manager_blank_screen (manager, NULL);
694
695
	} else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
696
		egg_debug ("shutting down, reason: %s", reason);
697
		gpm_control_shutdown (manager->priv->control, NULL);
698
699
	} else if (policy == GPM_ACTION_POLICY_INTERACTIVE) {
700
		GpmSession *session;
701
		egg_debug ("logout, reason: %s", reason);
702
		session = gpm_session_new ();
703
		gpm_session_logout (session);
704
		g_object_unref (session);
705
	} else {
706
		egg_warning ("unknown action %s", action);
707
	}
708
709
	g_free (action);
710
	return TRUE;
711
}
712
713
/**
714
 * gpm_manager_get_preferences_options:
715
 **/
716
gboolean
717
gpm_manager_get_preferences_options (GpmManager *manager, gint *capability, GError **error)
718
{
719
	g_return_val_if_fail (manager != NULL, FALSE);
720
	g_return_val_if_fail (GPM_IS_MANAGER (manager), FALSE);
721
	return gpm_prefs_server_get_capability (manager->priv->prefs_server, capability);
722
}
723
724
/**
725
 * gpm_manager_idle_do_sleep:
726
 * @manager: This class instance
727
 *
728
 * This callback is called when we want to sleep. Use the users
729
 * preference from gconf, but change it if we can't do the action.
730
 **/
731
static void
732
gpm_manager_idle_do_sleep (GpmManager *manager)
733
{
734
	gchar *action = NULL;
735
	gboolean ret;
736
	GError *error = NULL;
737
	GpmActionPolicy policy;
738
739
	if (!manager->priv->on_battery)
740
		action = gconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_SLEEP_TYPE_AC, NULL);
741
	else
742
		action = gconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_SLEEP_TYPE_BATT, NULL);
743
	policy = gpm_action_policy_from_string (action);
744
745
	if (policy == GPM_ACTION_POLICY_NOTHING) {
746
		egg_debug ("doing nothing as system idle action");
747
748
	} else if (policy == GPM_ACTION_POLICY_SUSPEND) {
749
		egg_debug ("suspending, reason: System idle");
750
		ret = gpm_control_suspend (manager->priv->control, &error);
751
		if (!ret) {
752
			egg_warning ("cannot suspend (error: %s), so trying hibernate", error->message);
753
			g_error_free (error);
754
			error = NULL;
755
			ret = gpm_control_hibernate (manager->priv->control, &error);
756
			if (!ret) {
757
				egg_warning ("cannot suspend or hibernate: %s", error->message);
758
				g_error_free (error);
759
			}
760
		}
761
762
	} else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
763
		egg_debug ("hibernating, reason: System idle");
764
		ret = gpm_control_hibernate (manager->priv->control, &error);
765
		if (!ret) {
766
			egg_warning ("cannot hibernate (error: %s), so trying suspend", error->message);
767
			g_error_free (error);
768
			error = NULL;
769
			ret = gpm_control_suspend (manager->priv->control, &error);
770
			if (!ret) {
771
				egg_warning ("cannot suspend or hibernate: %s", error->message);
772
				g_error_free (error);
773
			}
774
		}
775
	}
776
	g_free (action);
777
}
778
779
/**
780
 * gpm_manager_idle_changed_cb:
781
 * @idle: The idle class instance
782
 * @mode: The idle mode, e.g. GPM_IDLE_MODE_BLANK
783
 * @manager: This class instance
784
 *
785
 * This callback is called when the idle class detects that the idle state
786
 * has changed. GPM_IDLE_MODE_BLANK is when the session has become inactive,
787
 * and GPM_IDLE_MODE_SLEEP is where the session has become inactive, AND the
788
 * session timeout has elapsed for the idle action.
789
 **/
790
static void
791
gpm_manager_idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmManager *manager)
792
{
793
	/* ConsoleKit says we are not on active console */
794
	if (!egg_console_kit_is_active (manager->priv->console)) {
795
		egg_debug ("ignoring as not on active console");
796
		return;
797
	}
798
799
	/* Ignore back-to-NORMAL events when the lid is closed, as the DPMS is
800
	 * already off, and we don't want to re-enable the screen when the user
801
	 * moves the mouse on systems that do not support hardware blanking. */
802
	if (gpm_button_is_lid_closed (manager->priv->button) &&
803
	    mode == GPM_IDLE_MODE_NORMAL) {
804
		egg_debug ("lid is closed, so we are ignoring ->NORMAL state changes");
805
		return;
806
	}
807
808
	if (mode == GPM_IDLE_MODE_SLEEP) {
809
		egg_debug ("Idle state changed: SLEEP");
810
		if (gpm_manager_is_inhibit_valid (manager, FALSE, "timeout action") == FALSE)
811
			return;
812
		gpm_manager_idle_do_sleep (manager);
813
	}
814
}
815
816
/**
817
 * gpm_manager_lid_button_pressed:
818
 * @manager: This class instance
819
 * @state: TRUE for closed
820
 *
821
 * Does actions when the lid is closed, depending on if we are on AC or
822
 * battery power.
823
 **/
824
static void
825
gpm_manager_lid_button_pressed (GpmManager *manager, gboolean pressed)
826
{
827
	if (pressed)
828
		gpm_manager_play (manager, GPM_MANAGER_SOUND_LID_CLOSE, FALSE);
829
	else
830
		gpm_manager_play (manager, GPM_MANAGER_SOUND_LID_OPEN, FALSE);
831
832
	if (pressed == FALSE) {
833
		/* we turn the lid dpms back on unconditionally */
834
		gpm_manager_unblank_screen (manager, NULL);
835
		return;
836
	}
837
838
	if (!manager->priv->on_battery) {
839
		egg_debug ("Performing AC policy");
840
		gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_LID_AC,
841
					    "The lid has been closed on ac power.");
842
		return;
843
	}
844
845
	egg_debug ("Performing battery policy");
846
	gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_LID_BATT,
847
				    "The lid has been closed on battery power.");
848
}
849
850
static void
851
gpm_manager_update_dpms_throttle (GpmManager *manager)
852
{
853
	GpmDpmsMode mode;
854
	gpm_dpms_get_mode (manager->priv->dpms, &mode, NULL);
855
856
	/* Throttle the manager when DPMS is active since we can't see it anyway */
857
	if (mode == GPM_DPMS_MODE_ON) {
858
		if (manager->priv->screensaver_dpms_throttle_id != 0) {
859
			gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_dpms_throttle_id);
860
			manager->priv->screensaver_dpms_throttle_id = 0;
861
		}
862
	} else {
863
		/* if throttle already exists then remove */
864
		if (manager->priv->screensaver_dpms_throttle_id != 0) {
865
			gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_dpms_throttle_id);
866
		}
867
		/* TRANSLATORS: this is the gnome-screensaver throttle */
868
		manager->priv->screensaver_dpms_throttle_id = gpm_screensaver_add_throttle (manager->priv->screensaver, _("Display DPMS activated"));
869
	}
870
}
871
872
static void
873
gpm_manager_update_ac_throttle (GpmManager *manager)
874
{
875
	/* Throttle the manager when we are not on AC power so we don't
876
	   waste the battery */
877
	if (!manager->priv->on_battery) {
878
		if (manager->priv->screensaver_ac_throttle_id != 0) {
879
			gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_ac_throttle_id);
880
			manager->priv->screensaver_ac_throttle_id = 0;
881
		}
882
	} else {
883
		/* if throttle already exists then remove */
884
		if (manager->priv->screensaver_ac_throttle_id != 0)
885
			gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_ac_throttle_id);
886
		/* TRANSLATORS: this is the gnome-screensaver throttle */
887
		manager->priv->screensaver_ac_throttle_id = gpm_screensaver_add_throttle (manager->priv->screensaver, _("On battery power"));
888
	}
889
}
890
891
static void
892
gpm_manager_update_lid_throttle (GpmManager *manager, gboolean lid_is_closed)
893
{
894
	/* Throttle the screensaver when the lid is close since we can't see it anyway
895
	   and it may overheat the laptop */
896
	if (lid_is_closed == FALSE) {
897
		if (manager->priv->screensaver_lid_throttle_id != 0) {
898
			gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_lid_throttle_id);
899
			manager->priv->screensaver_lid_throttle_id = 0;
900
		}
901
	} else {
902
		/* if throttle already exists then remove */
903
		if (manager->priv->screensaver_lid_throttle_id != 0)
904
			gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_lid_throttle_id);
905
		manager->priv->screensaver_lid_throttle_id = gpm_screensaver_add_throttle (manager->priv->screensaver, _("Laptop lid is closed"));
906
	}
907
}
908
909
/**
910
 * gpm_manager_button_pressed_cb:
911
 * @power: The power class instance
912
 * @type: The button type, e.g. "power"
913
 * @state: The state, where TRUE is depressed or closed
914
 * @manager: This class instance
915
 **/
916
static void
917
gpm_manager_button_pressed_cb (GpmButton *button, const gchar *type, GpmManager *manager)
918
{
919
	gchar *message;
920
	egg_debug ("Button press event type=%s", type);
921
922
	/* ConsoleKit says we are not on active console */
923
	if (!egg_console_kit_is_active (manager->priv->console)) {
924
		egg_debug ("ignoring as not on active console");
925
		return;
926
	}
927
928
	if (g_strcmp0 (type, GPM_BUTTON_POWER) == 0) {
929
		gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_POWER, "The power button has been pressed.");
930
	} else if (g_strcmp0 (type, GPM_BUTTON_SLEEP) == 0) {
931
		gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_SUSPEND, "The suspend button has been pressed.");
932
	} else if (g_strcmp0 (type, GPM_BUTTON_SUSPEND) == 0) {
933
		gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_SUSPEND, "The suspend button has been pressed.");
934
	} else if (g_strcmp0 (type, GPM_BUTTON_HIBERNATE) == 0) {
935
		gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_HIBERNATE, "The hibernate button has been pressed.");
936
	} else if (g_strcmp0 (type, GPM_BUTTON_LID_OPEN) == 0) {
937
		gpm_manager_lid_button_pressed (manager, FALSE);
938
	} else if (g_strcmp0 (type, GPM_BUTTON_LID_CLOSED) == 0) {
939
		gpm_manager_lid_button_pressed (manager, TRUE);
940
	} else if (g_strcmp0 (type, GPM_BUTTON_BATTERY) == 0) {
941
		message = gpm_engine_get_summary (manager->priv->engine);
942
		gpm_manager_notify (manager, &manager->priv->notification_general,
943
				    _("Power Information"),
944
				    message,
945
				    GPM_MANAGER_NOTIFY_TIMEOUT_LONG,
946
				    GTK_STOCK_DIALOG_INFO,
947
				    NOTIFY_URGENCY_NORMAL);
948
		g_free (message);
949
	}
950
951
	/* really belongs in gnome-screensaver */
952
	if (g_strcmp0 (type, GPM_BUTTON_LOCK) == 0)
953
		gpm_screensaver_lock (manager->priv->screensaver);
954
955
	/* disable or enable the fancy screensaver, as we don't want
956
	 * this starting when the lid is shut */
957
	if (g_strcmp0 (type, GPM_BUTTON_LID_CLOSED) == 0)
958
		gpm_manager_update_lid_throttle (manager, TRUE);
959
	else if (g_strcmp0 (type, GPM_BUTTON_LID_OPEN) == 0)
960
		gpm_manager_update_lid_throttle (manager, FALSE);
961
}
962
963
/**
964
 * gpm_manager_get_spindown_timeout:
965
 **/
966
static gint
967
gpm_manager_get_spindown_timeout (GpmManager *manager)
968
{
969
	gboolean enabled;
970
	gint timeout;
971
972
	/* get policy */
973
	if (!manager->priv->on_battery) {
974
		enabled = gconf_client_get_bool (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_ENABLE_AC, NULL);
975
		timeout = gconf_client_get_int (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_TIMEOUT_AC, NULL);
976
	} else {
977
		enabled = gconf_client_get_bool (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_ENABLE_BATT, NULL);
978
		timeout = gconf_client_get_int (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_TIMEOUT_BATT, NULL);
979
	}
980
	if (!enabled)
981
		timeout = 0;
982
	return timeout;
983
}
984
985
/**
986
 * gpm_manager_client_changed_cb:
987
 **/
988
static void
989
gpm_manager_client_changed_cb (UpClient *client, GpmManager *manager)
990
{
991
	gboolean event_when_closed;
992
	gint timeout;
993
	gboolean on_battery;
994
	gboolean lid_is_closed;
995
996
	/* get the client state */
997
	g_object_get (client,
998
		      "on-battery", &on_battery,
999
		      "lid-is-closed", &lid_is_closed,
1000
		      NULL);
1001
	if (on_battery == manager->priv->on_battery) {
1002
		egg_debug ("same state as before, ignoring");
1003
		return;
1004
	}
1005
1006
	/* close any discharging notifications */
1007
	if (!on_battery) {
1008
		egg_debug ("clearing notify due ac being present");
1009
		gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
1010
		gpm_manager_notify_close (manager, manager->priv->notification_discharging);
1011
	}
1012
1013
	/* if we are playing a critical charge sound loop, stop it */
1014
	if (!on_battery && manager->priv->critical_alert_timeout_id) {
1015
		egg_debug ("stopping alert loop due to ac being present");
1016
		gpm_manager_play_loop_stop (manager);
1017
	}
1018
1019
	/* save in local cache */
1020
	manager->priv->on_battery = on_battery;
1021
1022
	/* ConsoleKit says we are not on active console */
1023
	if (!egg_console_kit_is_active (manager->priv->console)) {
1024
		egg_debug ("ignoring as not on active console");
1025
		return;
1026
	}
1027
1028
	egg_debug ("on_battery: %d", on_battery);
1029
1030
	/* set disk spindown threshold */
1031
	timeout = gpm_manager_get_spindown_timeout (manager);
1032
	gpm_disks_set_spindown_timeout (manager->priv->disks, timeout);
1033
1034
	gpm_manager_sync_policy_sleep (manager);
1035
1036
	gpm_manager_update_ac_throttle (manager);
1037
1038
	/* simulate user input, but only when the lid is open */
1039
	if (!lid_is_closed)
1040
		gpm_screensaver_poke (manager->priv->screensaver);
1041
1042
	if (!on_battery)
1043
		gpm_manager_play (manager, GPM_MANAGER_SOUND_POWER_PLUG, FALSE);
1044
	else
1045
		gpm_manager_play (manager, GPM_MANAGER_SOUND_POWER_UNPLUG, FALSE);
1046
1047
	/* We do the lid close on battery action if the ac adapter is removed
1048
	   when the laptop is closed and on battery. Fixes #331655 */
1049
	event_when_closed = gconf_client_get_bool (manager->priv->conf, GPM_CONF_ACTIONS_SLEEP_WHEN_CLOSED, NULL);
1050
1051
	/* We keep track of the lid state so we can do the
1052
	   lid close on battery action if the ac adapter is removed when the laptop
1053
	   is closed. Fixes #331655 */
1054
	if (event_when_closed && on_battery && lid_is_closed) {
1055
		gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_LID_BATT,
1056
					    "The lid has been closed, and the ac adapter "
1057
					    "removed (and gconf is okay).");
1058
	}
1059
}
1060
1061
/**
1062
 * manager_critical_action_do:
1063
 * @manager: This class instance
1064
 *
1065
 * This is the stub function when we have waited a few seconds for the user to
1066
 * see the message, explaining what we are about to do.
1067
 *
1068
 * Return value: FALSE, as we don't want to repeat this action on resume.
1069
 **/
1070
static gboolean
1071
manager_critical_action_do (GpmManager *manager)
1072
{
1073
	/* stop playing the alert as it's too late to do anything now */
1074
	if (manager->priv->critical_alert_timeout_id)
1075
		gpm_manager_play_loop_stop (manager);
1076
1077
	gpm_manager_perform_policy (manager, GPM_CONF_ACTIONS_CRITICAL_BATT, "Battery is critically low.");
1078
	return FALSE;
1079
}
1080
1081
/**
1082
 * gpm_manager_class_init:
1083
 * @klass: The GpmManagerClass
1084
 **/
1085
static void
1086
gpm_manager_class_init (GpmManagerClass *klass)
1087
{
1088
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
1089
	object_class->finalize = gpm_manager_finalize;
1090
	g_type_class_add_private (klass, sizeof (GpmManagerPrivate));
1091
}
1092
1093
/**
1094
 * gpm_conf_gconf_key_changed_cb:
1095
 *
1096
 * We might have to do things when the gconf keys change; do them here.
1097
 **/
1098
static void
1099
gpm_conf_gconf_key_changed_cb (GConfClient *client, guint cnxn_id, GConfEntry *entry, GpmManager *manager)
1100
{
1101
	GConfValue *value;
1102
1103
	value = gconf_entry_get_value (entry);
1104
	if (value == NULL)
1105
		return;
1106
1107
	if (g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT) == 0 ||
1108
	    g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC) == 0 ||
1109
	    g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT) == 0 ||
1110
	    g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC) == 0)
1111
		gpm_manager_sync_policy_sleep (manager);
1112
}
1113
1114
#if 0
1115
/**
1116
 * gpm_manager_screensaver_auth_request_cb:
1117
 * @manager: This manager class instance
1118
 * @auth: If we are trying to authenticate
1119
 *
1120
 * Called when the user is trying or has authenticated
1121
 **/
1122
static void
1123
gpm_manager_screensaver_auth_request_cb (GpmScreensaver *screensaver, gboolean auth_begin, GpmManager *manager)
1124
{
1125
	GError *error = NULL;
1126
1127
	if (auth_begin) {
1128
		/* We turn on the monitor unconditionally, as we may be using
1129
		 * a smartcard to authenticate and DPMS might still be on.
1130
		 * See #350291 for more details */
1131
		gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
1132
		if (error != NULL) {
1133
			egg_warning ("Failed to turn on DPMS: %s", error->message);
1134
			g_error_free (error);
1135
			error = NULL;
1136
		}
1137
	}
1138
}
1139
#endif
1140
1141
/**
1142
 * gpm_manager_perhaps_recall_response_cb:
1143
 */
1144
static void
1145
gpm_manager_perhaps_recall_response_cb (GtkDialog *dialog, gint response_id, GpmManager *manager)
1146
{
1147
	GdkScreen *screen;
1148
	GtkWidget *dialog_error;
1149
	GError *error = NULL;
1150
	gboolean ret;
1151
	const gchar *website;
1152
1153
	/* don't show this again */
1154
	if (response_id == GTK_RESPONSE_CANCEL) {
1155
		gconf_client_set_bool (manager->priv->conf, GPM_CONF_NOTIFY_PERHAPS_RECALL, FALSE, NULL);
1156
		goto out;
1157
	}
1158
1159
	/* visit recall website */
1160
	if (response_id == GTK_RESPONSE_OK) {
1161
		screen = gdk_screen_get_default();
1162
		website = (const gchar *) g_object_get_data (G_OBJECT (manager), "recall-oem-website");
1163
		ret = gtk_show_uri (screen, website, gtk_get_current_event_time (), &error);
1164
		if (!ret) {
1165
			dialog_error = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
1166
							       "Failed to show url %s", error->message);
1167
			gtk_dialog_run (GTK_DIALOG (dialog_error));
1168
			g_error_free (error);
1169
		}
1170
		goto out;
1171
	}
1172
out:
1173
	gtk_widget_destroy (GTK_WIDGET (dialog));
1174
	return;
1175
}
1176
1177
/**
1178
 * gpm_manager_perhaps_recall_delay_cb:
1179
 */
1180
static gboolean
1181
gpm_manager_perhaps_recall_delay_cb (GpmManager *manager)
1182
{
1183
	const gchar *oem_vendor;
1184
	gchar *title = NULL;
1185
	gchar *message = NULL;
1186
	GtkWidget *dialog;
1187
1188
	oem_vendor = (const gchar *) g_object_get_data (G_OBJECT (manager), "recall-oem-vendor");
1189
1190
	/* TRANSLATORS: the battery may be recalled by it's vendor */
1191
	title = g_strdup_printf ("%s: %s", GPM_NAME, _("Battery may be recalled"));
1192
	message = g_strdup_printf (_("A battery in your computer may have been "
1193
				     "recalled by %s and you may be at risk.\n\n"
1194
				     "For more information visit the battery recall website."), oem_vendor);
1195
	dialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
1196
						     GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
1197
						     "<span size='larger'><b>%s</b></span>", title);
1198
1199
	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
1200
1201
	/* TRANSLATORS: button text, visit the manufacturers recall website */
1202
	gtk_dialog_add_button (GTK_DIALOG (dialog), _("Visit recall website"), GTK_RESPONSE_OK);
1203
1204
	/* TRANSLATORS: button text, do not show this bubble again */
1205
	gtk_dialog_add_button (GTK_DIALOG (dialog), _("Do not show me this again"), GTK_RESPONSE_CANCEL);
1206
1207
	/* wait async for response */
1208
	gtk_widget_show (dialog);
1209
	g_signal_connect (dialog, "response", G_CALLBACK (gpm_manager_perhaps_recall_response_cb), manager);
1210
1211
	g_free (title);
1212
	g_free (message);
1213
1214
	/* never repeat */
1215
	return FALSE;
1216
}
1217
1218
/**
1219
 * gpm_manager_engine_perhaps_recall_cb:
1220
 */
1221
static void
1222
gpm_manager_engine_perhaps_recall_cb (GpmEngine *engine, UpDevice *device, gchar *oem_vendor, gchar *website, GpmManager *manager)
1223
{
1224
	gboolean ret;
1225
1226
	/* don't show when running under GDM */
1227
	if (g_getenv ("RUNNING_UNDER_GDM") != NULL) {
1228
		egg_debug ("running under gdm, so no notification");
1229
		return;
1230
	}
1231
1232
	/* already shown, and dismissed */
1233
	ret = gconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_PERHAPS_RECALL, NULL);
1234
	if (!ret) {
1235
		egg_debug ("GConf prevents notification: %s", GPM_CONF_NOTIFY_PERHAPS_RECALL);
1236
		return;
1237
	}
1238
1239
	g_object_set_data_full (G_OBJECT (manager), "recall-oem-vendor", (gpointer) g_strdup (oem_vendor), (GDestroyNotify) g_free);
1240
	g_object_set_data_full (G_OBJECT (manager), "recall-oem-website", (gpointer) g_strdup (website), (GDestroyNotify) g_free);
1241
1242
	/* delay by a few seconds so the panel can load */
1243
	g_timeout_add_seconds (GPM_MANAGER_RECALL_DELAY, (GSourceFunc) gpm_manager_perhaps_recall_delay_cb, manager);
1244
}
1245
1246
/**
1247
 * gpm_manager_engine_icon_changed_cb:
1248
 */
1249
static void
1250
gpm_manager_engine_icon_changed_cb (GpmEngine  *engine, gchar *icon, GpmManager *manager)
1251
{
1252
	gpm_tray_icon_set_icon (manager->priv->tray_icon, icon);
1253
}
1254
1255
/**
1256
 * gpm_manager_engine_summary_changed_cb:
1257
 */
1258
static void
1259
gpm_manager_engine_summary_changed_cb (GpmEngine *engine, gchar *summary, GpmManager *manager)
1260
{
1261
	gpm_tray_icon_set_tooltip (manager->priv->tray_icon, summary);
1262
}
1263
1264
/**
1265
 * gpm_manager_engine_low_capacity_cb:
1266
 */
1267
static void
1268
gpm_manager_engine_low_capacity_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
1269
{
1270
	gchar *message = NULL;
1271
	const gchar *title;
1272
	gdouble capacity;
1273
1274
	/* don't show when running under GDM */
1275
	if (g_getenv ("RUNNING_UNDER_GDM") != NULL) {
1276
		egg_debug ("running under gdm, so no notification");
1277
		goto out;
1278
	}
1279
1280
	/* get device properties */
1281
	g_object_get (device,
1282
		      "capacity", &capacity,
1283
		      NULL);
1284
1285
	/* We should notify the user if the battery has a low capacity,
1286
	 * where capacity is the ratio of the last_full capacity with that of
1287
	 * the design capacity. (#326740) */
1288
1289
	/* TRANSLATORS: battery is old or broken */
1290
	title = _("Battery may be broken");
1291
1292
	/* TRANSLATORS: notify the user that that battery is broken as the capacity is very low */
1293
	message = g_strdup_printf (_("Battery has a very low capacity (%1.1f%%), "
1294
				     "which means that it may be old or broken."), capacity);
1295
	gpm_manager_notify (manager, &manager->priv->notification_general, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_SHORT,
1296
			    GTK_STOCK_DIALOG_INFO, NOTIFY_URGENCY_LOW);
1297
out:
1298
	g_free (message);
1299
}
1300
1301
/**
1302
 * gpm_manager_engine_fully_charged_cb:
1303
 */
1304
static void
1305
gpm_manager_engine_fully_charged_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
1306
{
1307
	UpDeviceKind kind;
1308
	gchar *native_path = NULL;
1309
	gboolean ret;
1310
	guint plural = 1;
1311
	const gchar *title;
1312
1313
	/* only action this if specified in gconf */
1314
	ret = gconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_FULLY_CHARGED, NULL);
1315
	if (!ret) {
1316
		egg_debug ("no notification");
1317
		goto out;
1318
	}
1319
1320
	/* don't show when running under GDM */
1321
	if (g_getenv ("RUNNING_UNDER_GDM") != NULL) {
1322
		egg_debug ("running under gdm, so no notification");
1323
		goto out;
1324
	}
1325
1326
	/* get device properties */
1327
	g_object_get (device,
1328
		      "kind", &kind,
1329
		      "native-path", &native_path,
1330
		      NULL);
1331
1332
	if (kind == UP_DEVICE_KIND_BATTERY) {
1333
		/* is this a dummy composite device, which is plural? */
1334
		if (g_str_has_prefix (native_path, "dummy"))
1335
			plural = 2;
1336
1337
		/* hide the discharging notification */
1338
		gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
1339
		gpm_manager_notify_close (manager, manager->priv->notification_discharging);
1340
1341
		/* TRANSLATORS: show the charged notification */
1342
		title = ngettext ("Battery Charged", "Batteries Charged", plural);
1343
		gpm_manager_notify (manager, &manager->priv->notification_fully_charged,
1344
				    title, NULL, GPM_MANAGER_NOTIFY_TIMEOUT_SHORT,
1345
				    GTK_STOCK_DIALOG_INFO, NOTIFY_URGENCY_LOW);
1346
	}
1347
out:
1348
	g_free (native_path);
1349
}
1350
1351
/**
1352
 * gpm_manager_engine_discharging_cb:
1353
 */
1354
static void
1355
gpm_manager_engine_discharging_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
1356
{
1357
	UpDeviceKind kind;
1358
	gboolean ret;
1359
	const gchar *title;
1360
	const gchar *message;
1361
	gdouble percentage;
1362
	gint64 time_to_empty;
1363
	gchar *remaining_text = NULL;
1364
	gchar *icon = NULL;
1365
	const gchar *kind_desc;
1366
1367
	/* only action this if specified in gconf */
1368
	ret = gconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_DISCHARGING, NULL);
1369
	if (!ret) {
1370
		egg_debug ("no notification");
1371
		goto out;
1372
	}
1373
1374
	/* get device properties */
1375
	g_object_get (device,
1376
		      "kind", &kind,
1377
		      "percentage", &percentage,
1378
		      "time-to-empty", &time_to_empty,
1379
		      NULL);
1380
1381
	/* only show text if there is a valid time */
1382
	if (time_to_empty > 0)
1383
		remaining_text = gpm_get_timestring (time_to_empty);
1384
	kind_desc = gpm_device_kind_to_localised_text (kind, 1);
1385
1386
	if (kind == UP_DEVICE_KIND_BATTERY) {
1387
		/* TRANSLATORS: laptop battery is now discharging */
1388
		title = _("Battery Discharging");
1389
1390
		if (remaining_text != NULL) {
1391
			/* TRANSLATORS: tell the user how much time they have got */
1392
			message = g_strdup_printf (_("%s of battery power remaining (%.0f%%)"), remaining_text, percentage);
1393
		} else {
1394
			/* TRANSLATORS: the device is discharging, but we only have a percentage */
1395
			message = g_strdup_printf (_("%s discharging (%.0f%%)"),
1396
						   kind_desc, percentage);
1397
		}
1398
	} else if (kind == UP_DEVICE_KIND_UPS) {
1399
		/* TRANSLATORS: UPS is now discharging */
1400
		title = _("UPS Discharging");
1401
1402
		if (remaining_text != NULL) {
1403
			/* TRANSLATORS: tell the user how much time they have got */
1404
			message = g_strdup_printf (_("%s of UPS backup power remaining (%.0f%%)"), remaining_text, percentage);
1405
		} else {
1406
			/* TRANSLATORS: the device is discharging, but we only have a percentage */
1407
			message = g_strdup_printf (_("%s discharging (%.0f%%)"),
1408
						   kind_desc, percentage);
1409
		}
1410
	} else {
1411
		/* nothing else of interest */
1412
		goto out;
1413
	}
1414
1415
	icon = gpm_upower_get_device_icon (device);
1416
	/* show the notification */
1417
	gpm_manager_notify (manager, &manager->priv->notification_discharging, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_LONG,
1418
			    icon, NOTIFY_URGENCY_NORMAL);
1419
out:
1420
	g_free (icon);
1421
	g_free (remaining_text);
1422
	return;
1423
}
1424
1425
/**
1426
 * gpm_manager_engine_just_laptop_battery:
1427
 */
1428
static gboolean
1429
gpm_manager_engine_just_laptop_battery (GpmManager *manager)
1430
{
1431
	UpDevice *device;
1432
	UpDeviceKind kind;
1433
	GPtrArray *array;
1434
	gboolean ret = TRUE;
1435
	guint i;
1436
1437
	/* find if there are any other device types that mean we have to
1438
	 * be more specific in our wording */
1439
	array = gpm_engine_get_devices (manager->priv->engine);
1440
	for (i=0; i<array->len; i++) {
1441
		device = g_ptr_array_index (array, i);
1442
		g_object_get (device, "kind", &kind, NULL);
1443
		if (kind != UP_DEVICE_KIND_BATTERY) {
1444
			ret = FALSE;
1445
			break;
1446
		}
1447
	}
1448
	g_ptr_array_unref (array);
1449
	return ret;
1450
}
1451
1452
/**
1453
 * gpm_manager_engine_charge_low_cb:
1454
 */
1455
static void
1456
gpm_manager_engine_charge_low_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
1457
{
1458
	const gchar *title = NULL;
1459
	gchar *message = NULL;
1460
	gchar *remaining_text;
1461
	gchar *icon = NULL;
1462
	UpDeviceKind kind;
1463
	gdouble percentage;
1464
	gint64 time_to_empty;
1465
	gboolean ret;
1466
1467
	/* get device properties */
1468
	g_object_get (device,
1469
		      "kind", &kind,
1470
		      "percentage", &percentage,
1471
		      "time-to-empty", &time_to_empty,
1472
		      NULL);
1473
1474
	/* check to see if the batteries have not noticed we are on AC */
1475
	if (kind == UP_DEVICE_KIND_BATTERY) {
1476
		if (!manager->priv->on_battery) {
1477
			egg_warning ("ignoring critically low message as we are not on battery power");
1478
			goto out;
1479
		}
1480
	}
1481
1482
	if (kind == UP_DEVICE_KIND_BATTERY) {
1483
1484
		/* if the user has no other batteries, drop the "Laptop" wording */
1485
		ret = gpm_manager_engine_just_laptop_battery (manager);
1486
		if (ret) {
1487
			/* TRANSLATORS: laptop battery low, and we only have one battery */
1488
			title = _("Battery low");
1489
		} else {
1490
			/* TRANSLATORS: laptop battery low, and we have more than one kind of battery */
1491
			title = _("Laptop battery low");
1492
		}
1493
1494
		remaining_text = gpm_get_timestring (time_to_empty);
1495
1496
		/* TRANSLATORS: tell the user how much time they have got */
1497
		message = g_strdup_printf (_("Approximately <b>%s</b> remaining (%.0f%%)"), remaining_text, percentage);
1498
1499
	} else if (kind == UP_DEVICE_KIND_UPS) {
1500
		/* TRANSLATORS: UPS is starting to get a little low */
1501
		title = _("UPS low");
1502
		remaining_text = gpm_get_timestring (time_to_empty);
1503
1504
		/* TRANSLATORS: tell the user how much time they have got */
1505
		message = g_strdup_printf (_("Approximately <b>%s</b> of remaining UPS backup power (%.0f%%)"),
1506
					   remaining_text, percentage);
1507
	} else if (kind == UP_DEVICE_KIND_MOUSE) {
1508
		/* TRANSLATORS: mouse is getting a little low */
1509
		title = _("Mouse battery low");
1510
1511
		/* TRANSLATORS: tell user more details */
1512
		message = g_strdup_printf (_("Wireless mouse is low in power (%.0f%%)"), percentage);
1513
1514
	} else if (kind == UP_DEVICE_KIND_KEYBOARD) {
1515
		/* TRANSLATORS: keyboard is getting a little low */
1516
		title = _("Keyboard battery low");
1517
1518
		/* TRANSLATORS: tell user more details */
1519
		message = g_strdup_printf (_("Wireless keyboard is low in power (%.0f%%)"), percentage);
1520
1521
	} else if (kind == UP_DEVICE_KIND_PDA) {
1522
		/* TRANSLATORS: PDA is getting a little low */
1523
		title = _("PDA battery low");
1524
1525
		/* TRANSLATORS: tell user more details */
1526
		message = g_strdup_printf (_("PDA is low in power (%.0f%%)"), percentage);
1527
1528
	} else if (kind == UP_DEVICE_KIND_PHONE) {
1529
		/* TRANSLATORS: cell phone (mobile) is getting a little low */
1530
		title = _("Cell phone battery low");
1531
1532
		/* TRANSLATORS: tell user more details */
1533
		message = g_strdup_printf (_("Cell phone is low in power (%.0f%%)"), percentage);
1534
1535
#if UP_CHECK_VERSION(0,9,5)
1536
	} else if (kind == UP_DEVICE_KIND_MEDIA_PLAYER) {
1537
		/* TRANSLATORS: media player, e.g. mp3 is getting a little low */
1538
		title = _("Media player battery low");
1539
1540
		/* TRANSLATORS: tell user more details */
1541
		message = g_strdup_printf (_("Media player is low in power (%.0f%%)"), percentage);
1542
1543
	} else if (kind == UP_DEVICE_KIND_TABLET) {
1544
		/* TRANSLATORS: graphics tablet, e.g. wacom is getting a little low */
1545
		title = _("Tablet battery low");
1546
1547
		/* TRANSLATORS: tell user more details */
1548
		message = g_strdup_printf (_("Tablet is low in power (%.0f%%)"), percentage);
1549
1550
	} else if (kind == UP_DEVICE_KIND_COMPUTER) {
1551
		/* TRANSLATORS: computer, e.g. ipad is getting a little low */
1552
		title = _("Attached computer battery low");
1553
1554
		/* TRANSLATORS: tell user more details */
1555
		message = g_strdup_printf (_("Attached computer is low in power (%.0f%%)"), percentage);
1556
#endif
1557
	}
1558
1559
	/* get correct icon */
1560
	icon = gpm_upower_get_device_icon (device);
1561
	gpm_manager_notify (manager, &manager->priv->notification_warning_low, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_LONG, icon, NOTIFY_URGENCY_NORMAL);
1562
	gpm_manager_play (manager, GPM_MANAGER_SOUND_BATTERY_CAUTION, TRUE);
1563
out:
1564
	g_free (icon);
1565
	g_free (message);
1566
}
1567
1568
/**
1569
 * gpm_manager_engine_charge_critical_cb:
1570
 */
1571
static void
1572
gpm_manager_engine_charge_critical_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
1573
{
1574
	const gchar *title = NULL;
1575
	gchar *message = NULL;
1576
	gchar *action;
1577
	gchar *icon = NULL;
1578
	UpDeviceKind kind;
1579
	gdouble percentage;
1580
	gint64 time_to_empty;
1581
	GpmActionPolicy policy;
1582
	gboolean ret;
1583
1584
	/* get device properties */
1585
	g_object_get (device,
1586
		      "kind", &kind,
1587
		      "percentage", &percentage,
1588
		      "time-to-empty", &time_to_empty,
1589
		      NULL);
1590
1591
	/* check to see if the batteries have not noticed we are on AC */
1592
	if (kind == UP_DEVICE_KIND_BATTERY) {
1593
		if (!manager->priv->on_battery) {
1594
			egg_warning ("ignoring critically low message as we are not on battery power");
1595
			goto out;
1596
		}
1597
	}
1598
1599
	if (kind == UP_DEVICE_KIND_BATTERY) {
1600
1601
		/* if the user has no other batteries, drop the "Laptop" wording */
1602
		ret = gpm_manager_engine_just_laptop_battery (manager);
1603
		if (ret) {
1604
			/* TRANSLATORS: laptop battery critically low, and only have one kind of battery */
1605
			title = _("Battery critically low");
1606
		} else {
1607
			/* TRANSLATORS: laptop battery critically low, and we have more than one type of battery */
1608
			title = _("Laptop battery critically low");
1609
		}
1610
1611
		/* we have to do different warnings depending on the policy */
1612
		action = gconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_CRITICAL_BATT, NULL);
1613
		policy = gpm_action_policy_from_string (action);
1614
1615
		/* use different text for different actions */
1616
		if (policy == GPM_ACTION_POLICY_NOTHING) {
1617
			/* TRANSLATORS: tell the use to insert the plug, as we're not going to do anything */
1618
			message = g_strdup (_("Plug in your AC adapter to avoid losing data."));
1619
1620
		} else if (policy == GPM_ACTION_POLICY_SUSPEND) {
1621
			/* TRANSLATORS: give the user a ultimatum */
1622
			message = g_strdup_printf (_("Computer will suspend very soon unless it is plugged in."));
1623
1624
		} else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
1625
			/* TRANSLATORS: give the user a ultimatum */
1626
			message = g_strdup_printf (_("Computer will hibernate very soon unless it is plugged in."));
1627
1628
		} else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
1629
			/* TRANSLATORS: give the user a ultimatum */
1630
			message = g_strdup_printf (_("Computer will shutdown very soon unless it is plugged in."));
1631
		}
1632
1633
		g_free (action);
1634
	} else if (kind == UP_DEVICE_KIND_UPS) {
1635
		gchar *remaining_text;
1636
1637
		/* TRANSLATORS: the UPS is very low */
1638
		title = _("UPS critically low");
1639
		remaining_text = gpm_get_timestring (time_to_empty);
1640
1641
		/* TRANSLATORS: give the user a ultimatum */
1642
		message = g_strdup_printf (_("Approximately <b>%s</b> of remaining UPS power (%.0f%%). "
1643
					     "Restore AC power to your computer to avoid losing data."),
1644
					   remaining_text, percentage);
1645
		g_free (remaining_text);
1646
	} else if (kind == UP_DEVICE_KIND_MOUSE) {
1647
		/* TRANSLATORS: the mouse battery is very low */
1648
		title = _("Mouse battery low");
1649
1650
		/* TRANSLATORS: the device is just going to stop working */
1651
		message = g_strdup_printf (_("Wireless mouse is very low in power (%.0f%%). "
1652
					     "This device will soon stop functioning if not charged."),
1653
					   percentage);
1654
	} else if (kind == UP_DEVICE_KIND_KEYBOARD) {
1655
		/* TRANSLATORS: the keyboard battery is very low */
1656
		title = _("Keyboard battery low");
1657
1658
		/* TRANSLATORS: the device is just going to stop working */
1659
		message = g_strdup_printf (_("Wireless keyboard is very low in power (%.0f%%). "
1660
					     "This device will soon stop functioning if not charged."),
1661
					   percentage);
1662
	} else if (kind == UP_DEVICE_KIND_PDA) {
1663
1664
		/* TRANSLATORS: the PDA battery is very low */
1665
		title = _("PDA battery low");
1666
1667
		/* TRANSLATORS: the device is just going to stop working */
1668
		message = g_strdup_printf (_("PDA is very low in power (%.0f%%). "
1669
					     "This device will soon stop functioning if not charged."),
1670
					   percentage);
1671
1672
	} else if (kind == UP_DEVICE_KIND_PHONE) {
1673
1674
		/* TRANSLATORS: the cell battery is very low */
1675
		title = _("Cell phone battery low");
1676
1677
		/* TRANSLATORS: the device is just going to stop working */
1678
		message = g_strdup_printf (_("Cell phone is very low in power (%.0f%%). "
1679
					     "This device will soon stop functioning if not charged."),
1680
					   percentage);
1681
1682
#if UP_CHECK_VERSION(0,9,5)
1683
	} else if (kind == UP_DEVICE_KIND_MEDIA_PLAYER) {
1684
1685
		/* TRANSLATORS: the cell battery is very low */
1686
		title = _("Cell phone battery low");
1687
1688
		/* TRANSLATORS: the device is just going to stop working */
1689
		message = g_strdup_printf (_("Media player is very low in power (%.0f%%). "
1690
					     "This device will soon stop functioning if not charged."),
1691
					   percentage);
1692
	} else if (kind == UP_DEVICE_KIND_TABLET) {
1693
1694
		/* TRANSLATORS: the cell battery is very low */
1695
		title = _("Tablet battery low");
1696
1697
		/* TRANSLATORS: the device is just going to stop working */
1698
		message = g_strdup_printf (_("Tablet is very low in power (%.0f%%). "
1699
					     "This device will soon stop functioning if not charged."),
1700
					   percentage);
1701
	} else if (kind == UP_DEVICE_KIND_COMPUTER) {
1702
1703
		/* TRANSLATORS: the cell battery is very low */
1704
		title = _("Attached computer battery low");
1705
1706
		/* TRANSLATORS: the device is just going to stop working */
1707
		message = g_strdup_printf (_("Attached computer is very low in power (%.0f%%). "
1708
					     "The device will soon shutdown if not charged."),
1709
					   percentage);
1710
#endif
1711
	}
1712
1713
	/* get correct icon */
1714
	icon = gpm_upower_get_device_icon (device);
1715
	gpm_manager_notify (manager, &manager->priv->notification_warning_low, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_NEVER, icon, NOTIFY_URGENCY_CRITICAL);
1716
1717
	switch (kind) {
1718
1719
	case UP_DEVICE_KIND_BATTERY:
1720
	case UP_DEVICE_KIND_UPS:
1721
		egg_debug ("critical charge level reached, starting sound loop");
1722
		gpm_manager_play_loop_start (manager,
1723
					     GPM_MANAGER_SOUND_BATTERY_LOW,
1724
					     TRUE,
1725
					     GPM_MANAGER_CRITICAL_ALERT_TIMEOUT);
1726
		break;
1727
1728
	default:
1729
		gpm_manager_play (manager, GPM_MANAGER_SOUND_BATTERY_LOW, TRUE);
1730
	}
1731
out:
1732
	g_free (icon);
1733
	g_free (message);
1734
}
1735
1736
/**
1737
 * gpm_manager_engine_charge_action_cb:
1738
 */
1739
static void
1740
gpm_manager_engine_charge_action_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
1741
{
1742
	const gchar *title = NULL;
1743
	gchar *action;
1744
	gchar *message = NULL;
1745
	gchar *icon = NULL;
1746
	UpDeviceKind kind;
1747
	GpmActionPolicy policy;
1748
1749
	/* get device properties */
1750
	g_object_get (device,
1751
		      "kind", &kind,
1752
		      NULL);
1753
1754
	/* check to see if the batteries have not noticed we are on AC */
1755
	if (kind == UP_DEVICE_KIND_BATTERY) {
1756
		if (!manager->priv->on_battery) {
1757
			egg_warning ("ignoring critically low message as we are not on battery power");
1758
			goto out;
1759
		}
1760
	}
1761
1762
	if (kind == UP_DEVICE_KIND_BATTERY) {
1763
1764
		/* TRANSLATORS: laptop battery is really, really, low */
1765
		title = _("Laptop battery critically low");
1766
1767
		/* we have to do different warnings depending on the policy */
1768
		action = gconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_CRITICAL_BATT, NULL);
1769
		policy = gpm_action_policy_from_string (action);
1770
1771
		/* use different text for different actions */
1772
		if (policy == GPM_ACTION_POLICY_NOTHING) {
1773
			/* TRANSLATORS: computer will shutdown without saving data */
1774
			message = g_strdup (_("The battery is below the critical level and "
1775
					      "this computer will <b>power-off</b> when the "
1776
					      "battery becomes completely empty."));
1777
1778
		} else if (policy == GPM_ACTION_POLICY_SUSPEND) {
1779
			/* TRANSLATORS: computer will suspend */
1780
			message = g_strdup (_("The battery is below the critical level and "
1781
					      "this computer is about to suspend.<br>"
1782
					      "<b>NOTE:</b> A small amount of power is required "
1783
					      "to keep your computer in a suspended state."));
1784
1785
		} else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
1786
			/* TRANSLATORS: computer will hibernate */
1787
			message = g_strdup (_("The battery is below the critical level and "
1788
					      "this computer is about to hibernate."));
1789
1790
		} else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
1791
			/* TRANSLATORS: computer will just shutdown */
1792
			message = g_strdup (_("The battery is below the critical level and "
1793
					      "this computer is about to shutdown."));
1794
		}
1795
1796
		g_free (action);
1797
1798
		/* wait 20 seconds for user-panic */
1799
		g_timeout_add_seconds (20, (GSourceFunc) manager_critical_action_do, manager);
1800
1801
	} else if (kind == UP_DEVICE_KIND_UPS) {
1802
		/* TRANSLATORS: UPS is really, really, low */
1803
		title = _("UPS critically low");
1804
1805
		/* we have to do different warnings depending on the policy */
1806
		action = gconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_CRITICAL_UPS, NULL);
1807
		policy = gpm_action_policy_from_string (action);
1808
1809
		/* use different text for different actions */
1810
		if (policy == GPM_ACTION_POLICY_NOTHING) {
1811
			/* TRANSLATORS: computer will shutdown without saving data */
1812
			message = g_strdup (_("The UPS is below the critical level and "
1813
				              "this computer will <b>power-off</b> when the "
1814
				              "UPS becomes completely empty."));
1815
1816
		} else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
1817
			/* TRANSLATORS: computer will hibernate */
1818
			message = g_strdup (_("The UPS is below the critical level and "
1819
				              "this computer is about to hibernate."));
1820
1821
		} else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
1822
			/* TRANSLATORS: computer will just shutdown */
1823
			message = g_strdup (_("The UPS is below the critical level and "
1824
				              "this computer is about to shutdown."));
1825
		}
1826
1827
		/* wait 20 seconds for user-panic */
1828
		g_timeout_add_seconds (20, (GSourceFunc) manager_critical_action_do, manager);
1829
1830
		g_free (action);
1831
	}
1832
1833
	/* not all types have actions */
1834
	if (title == NULL)
1835
		return;
1836
1837
	/* get correct icon */
1838
	icon = gpm_upower_get_device_icon (device);
1839
	gpm_manager_notify (manager, &manager->priv->notification_warning_low,
1840
			    title, message, GPM_MANAGER_NOTIFY_TIMEOUT_NEVER,
1841
			    icon, NOTIFY_URGENCY_CRITICAL);
1842
	gpm_manager_play (manager, GPM_MANAGER_SOUND_BATTERY_LOW, TRUE);
1843
out:
1844
	g_free (icon);
1845
	g_free (message);
1846
}
1847
1848
/**
1849
 * gpm_manager_dpms_mode_changed_cb:
1850
 * @mode: The DPMS mode, e.g. GPM_DPMS_MODE_OFF
1851
 * @info: This class instance
1852
 *
1853
 * Log when the DPMS mode is changed.
1854
 **/
1855
static void
1856
gpm_manager_dpms_mode_changed_cb (GpmDpms *dpms, GpmDpmsMode mode, GpmManager *manager)
1857
{
1858
	egg_debug ("DPMS mode changed: %d", mode);
1859
1860
	if (mode == GPM_DPMS_MODE_ON)
1861
		egg_debug ("dpms on");
1862
	else if (mode == GPM_DPMS_MODE_STANDBY)
1863
		egg_debug ("dpms standby");
1864
	else if (mode == GPM_DPMS_MODE_SUSPEND)
1865
		egg_debug ("suspend");
1866
	else if (mode == GPM_DPMS_MODE_OFF)
1867
		egg_debug ("dpms off");
1868
1869
	gpm_manager_update_dpms_throttle (manager);
1870
}
1871
1872
/*
1873
 * gpm_manager_reset_just_resumed_cb
1874
 */
1875
static gboolean
1876
gpm_manager_reset_just_resumed_cb (gpointer user_data)
1877
{
1878
	GpmManager *manager = GPM_MANAGER (user_data);
1879
1880
	if (manager->priv->notification_general != NULL)
1881
		gpm_manager_notify_close (manager, manager->priv->notification_general);
1882
	if (manager->priv->notification_warning_low != NULL)
1883
		gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
1884
	if (manager->priv->notification_discharging != NULL)
1885
		gpm_manager_notify_close (manager, manager->priv->notification_discharging);
1886
	if (manager->priv->notification_fully_charged != NULL)
1887
		gpm_manager_notify_close (manager, manager->priv->notification_fully_charged);
1888
1889
	manager->priv->just_resumed = FALSE;
1890
	return FALSE;
1891
}
1892
1893
/**
1894
 * gpm_manager_control_resume_cb
1895
 **/
1896
static void
1897
gpm_manager_control_resume_cb (GpmControl *control, GpmControlAction action, GpmManager *manager)
1898
{
1899
	manager->priv->just_resumed = TRUE;
1900
	g_timeout_add_seconds (1, gpm_manager_reset_just_resumed_cb, manager);
1901
}
1902
1903
/**
1904
 * gpm_manager_init:
1905
 * @manager: This class instance
1906
 **/
1907
static void
1908
gpm_manager_init (GpmManager *manager)
1909
{
1910
	gboolean check_type_cpu;
1911
	gint timeout;
1912
	DBusGConnection *connection;
1913
	GError *error = NULL;
1914
	guint version;
1915
1916
	manager->priv = GPM_MANAGER_GET_PRIVATE (manager);
1917
	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
1918
1919
	/* init to unthrottled */
1920
	manager->priv->screensaver_ac_throttle_id = 0;
1921
	manager->priv->screensaver_dpms_throttle_id = 0;
1922
	manager->priv->screensaver_lid_throttle_id = 0;
1923
1924
	manager->priv->critical_alert_timeout_id = 0;
1925
	manager->priv->critical_alert_loop_props = NULL;
1926
1927
	/* init to not just_resumed */
1928
	manager->priv->just_resumed = FALSE;
1929
1930
	/* don't apply policy when not active, so listen to ConsoleKit */
1931
	manager->priv->console = egg_console_kit_new ();
1932
1933
	/* this is a singleton, so we keep a master copy open here */
1934
	manager->priv->prefs_server = gpm_prefs_server_new ();
1935
1936
	manager->priv->notification_general = NULL;
1937
	manager->priv->notification_warning_low = NULL;
1938
	manager->priv->notification_discharging = NULL;
1939
	manager->priv->notification_fully_charged = NULL;
1940
	manager->priv->disks = gpm_disks_new ();
1941
	manager->priv->conf = gconf_client_get_default ();
1942
	manager->priv->client = up_client_new ();
1943
	g_signal_connect (manager->priv->client, "changed",
1944
			  G_CALLBACK (gpm_manager_client_changed_cb), manager);
1945
1946
	/* use libnotify */
1947
	notify_init (GPM_NAME);
1948
1949
	/* watch gnome-power-manager keys */
1950
	gconf_client_add_dir (manager->priv->conf, GPM_CONF_DIR,
1951
			      GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
1952
	gconf_client_notify_add (manager->priv->conf, GPM_CONF_DIR,
1953
				 (GConfClientNotifyFunc) gpm_conf_gconf_key_changed_cb,
1954
				 manager, NULL, NULL);
1955
1956
	/* check to see if the user has installed the schema properly */
1957
	version = gconf_client_get_int (manager->priv->conf, GPM_CONF_SCHEMA_VERSION, NULL);
1958
	if (version != GPM_CONF_SCHEMA_ID) {
1959
		gpm_manager_notify (manager, &manager->priv->notification_general,
1960
				    /* TRANSLATORS: there was in install problem */
1961
				    _("Install problem!"),
1962
				    /* TRANSLATORS: the GConf schema was not installed properly */
1963
				    _("The configuration defaults for GNOME Power Manager have not been installed correctly.\n"
1964
				      "Please contact your computer administrator."),
1965
				    GPM_MANAGER_NOTIFY_TIMEOUT_LONG,
1966
				    GTK_STOCK_DIALOG_WARNING,
1967
				    NOTIFY_URGENCY_NORMAL);
1968
		egg_error ("no gconf schema installed!");
1969
	}
1970
1971
	/* coldplug so we are in the correct state at startup */
1972
	g_object_get (manager->priv->client,
1973
		      "on-battery", &manager->priv->on_battery,
1974
		      NULL);
1975
1976
	manager->priv->button = gpm_button_new ();
1977
	g_signal_connect (manager->priv->button, "button-pressed",
1978
			  G_CALLBACK (gpm_manager_button_pressed_cb), manager);
1979
1980
	/* try and start an interactive service */
1981
	manager->priv->screensaver = gpm_screensaver_new ();
1982
#if 0
1983
	g_signal_connect (manager->priv->screensaver, "auth-request",
1984
			  G_CALLBACK (gpm_manager_screensaver_auth_request_cb), manager);
1985
#endif
1986
1987
	/* try an start an interactive service */
1988
	manager->priv->backlight = gpm_backlight_new ();
1989
	if (manager->priv->backlight != NULL) {
1990
		/* add the new brightness lcd DBUS interface */
1991
		dbus_g_object_type_install_info (GPM_TYPE_BACKLIGHT,
1992
						 &dbus_glib_gpm_backlight_object_info);
1993
		dbus_g_connection_register_g_object (connection, GPM_DBUS_PATH_BACKLIGHT,
1994
						     G_OBJECT (manager->priv->backlight));
1995
	}
1996
1997
	manager->priv->idle = gpm_idle_new ();
1998
	g_signal_connect (manager->priv->idle, "idle-changed",
1999
			  G_CALLBACK (gpm_manager_idle_changed_cb), manager);
2000
2001
	/* set up the check_type_cpu, so we can disable the CPU load check */
2002
	check_type_cpu = gconf_client_get_bool (manager->priv->conf, GPM_CONF_IDLE_CHECK_CPU, NULL);
2003
	gpm_idle_set_check_cpu (manager->priv->idle, check_type_cpu);
2004
2005
	manager->priv->dpms = gpm_dpms_new ();
2006
	g_signal_connect (manager->priv->dpms, "mode-changed",
2007
			  G_CALLBACK (gpm_manager_dpms_mode_changed_cb), manager);
2008
2009
	/* use the control object */
2010
	egg_debug ("creating new control instance");
2011
	manager->priv->control = gpm_control_new ();
2012
	g_signal_connect (manager->priv->control, "resume",
2013
			  G_CALLBACK (gpm_manager_control_resume_cb), manager);
2014
2015
	egg_debug ("creating new tray icon");
2016
	manager->priv->tray_icon = gpm_tray_icon_new ();
2017
2018
	/* keep a reference for the notifications */
2019
	manager->priv->status_icon = gpm_tray_icon_get_status_icon (manager->priv->tray_icon);
2020
2021
	gpm_manager_sync_policy_sleep (manager);
2022
2023
	manager->priv->engine = gpm_engine_new ();
2024
	g_signal_connect (manager->priv->engine, "perhaps-recall",
2025
			  G_CALLBACK (gpm_manager_engine_perhaps_recall_cb), manager);
2026
	g_signal_connect (manager->priv->engine, "low-capacity",
2027
			  G_CALLBACK (gpm_manager_engine_low_capacity_cb), manager);
2028
	g_signal_connect (manager->priv->engine, "icon-changed",
2029
			  G_CALLBACK (gpm_manager_engine_icon_changed_cb), manager);
2030
	g_signal_connect (manager->priv->engine, "summary-changed",
2031
			  G_CALLBACK (gpm_manager_engine_summary_changed_cb), manager);
2032
	g_signal_connect (manager->priv->engine, "fully-charged",
2033
			  G_CALLBACK (gpm_manager_engine_fully_charged_cb), manager);
2034
	g_signal_connect (manager->priv->engine, "discharging",
2035
			  G_CALLBACK (gpm_manager_engine_discharging_cb), manager);
2036
	g_signal_connect (manager->priv->engine, "charge-low",
2037
			  G_CALLBACK (gpm_manager_engine_charge_low_cb), manager);
2038
	g_signal_connect (manager->priv->engine, "charge-critical",
2039
			  G_CALLBACK (gpm_manager_engine_charge_critical_cb), manager);
2040
	g_signal_connect (manager->priv->engine, "charge-action",
2041
			  G_CALLBACK (gpm_manager_engine_charge_action_cb), manager);
2042
2043
	/* set disk spindown threshold */
2044
	timeout = gpm_manager_get_spindown_timeout (manager);
2045
	gpm_disks_set_spindown_timeout (manager->priv->disks, timeout);
2046
2047
	/* update ac throttle */
2048
	gpm_manager_update_ac_throttle (manager);
2049
}
2050
2051
/**
2052
 * gpm_manager_finalize:
2053
 * @object: The object to finalize
2054
 *
2055
 * Finalise the manager, by unref'ing all the depending modules.
2056
 **/
2057
static void
2058
gpm_manager_finalize (GObject *object)
2059
{
2060
	GpmManager *manager;
2061
2062
	g_return_if_fail (object != NULL);
2063
	g_return_if_fail (GPM_IS_MANAGER (object));
2064
2065
	manager = GPM_MANAGER (object);
2066
2067
	g_return_if_fail (manager->priv != NULL);
2068
2069
	/* close any notifications (also unrefs them) */
2070
	if (manager->priv->notification_general != NULL)
2071
		gpm_manager_notify_close (manager, manager->priv->notification_general);
2072
	if (manager->priv->notification_warning_low != NULL)
2073
		gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
2074
	if (manager->priv->notification_discharging != NULL)
2075
		gpm_manager_notify_close (manager, manager->priv->notification_discharging);
2076
	if (manager->priv->notification_fully_charged != NULL)
2077
		gpm_manager_notify_close (manager, manager->priv->notification_fully_charged);
2078
	if (manager->priv->critical_alert_timeout_id != 0)
2079
		g_source_remove (manager->priv->critical_alert_timeout_id);
2080
2081
	g_object_unref (manager->priv->conf);
2082
	g_object_unref (manager->priv->disks);
2083
	g_object_unref (manager->priv->dpms);
2084
	g_object_unref (manager->priv->idle);
2085
	g_object_unref (manager->priv->engine);
2086
	g_object_unref (manager->priv->tray_icon);
2087
	g_object_unref (manager->priv->screensaver);
2088
	g_object_unref (manager->priv->prefs_server);
2089
	g_object_unref (manager->priv->control);
2090
	g_object_unref (manager->priv->button);
2091
	g_object_unref (manager->priv->backlight);
2092
	g_object_unref (manager->priv->console);
2093
	g_object_unref (manager->priv->client);
2094
	g_object_unref (manager->priv->status_icon);
2095
2096
	G_OBJECT_CLASS (gpm_manager_parent_class)->finalize (object);
2097
}
2098
2099
/**
2100
 * gpm_manager_new:
2101
 *
2102
 * Return value: a new GpmManager object.
2103
 **/
2104
GpmManager *
2105
gpm_manager_new (void)
2106
{
2107
	GpmManager *manager;
2108
	manager = g_object_new (GPM_TYPE_MANAGER, NULL);
2109
	return GPM_MANAGER (manager);
2110
}

Return to bug 366735