cc-screen-panel.c 14.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 *
 * Copyright (C) 2010 Red Hat, Inc
 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

#include "cc-screen-panel.h"
23
#include <string.h>
24

Ray Strode's avatar
Ray Strode committed
25
CC_PANEL_REGISTER (CcScreenPanel, cc_screen_panel)
26
27
28
29

#define SCREEN_PANEL_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_SCREEN_PANEL, CcScreenPanelPrivate))

30
31
#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, s))

32
33
struct _CcScreenPanelPrivate
{
34
35
  GSettings     *lock_settings;
  GSettings     *gsd_settings;
36
  GSettings     *session_settings;
37
  GSettings     *lockdown_settings;
38
39
40
41
  GCancellable  *cancellable;
  GtkBuilder    *builder;
  GDBusProxy    *proxy;
  gboolean       setting_brightness;
42
43
44
45
46
47
48
49
50
51
52
53
};

static void
cc_screen_panel_dispose (GObject *object)
{
  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (object)->priv;

  if (priv->lock_settings)
    {
      g_object_unref (priv->lock_settings);
      priv->lock_settings = NULL;
    }
54
55
56
57
58
  if (priv->gsd_settings)
    {
      g_object_unref (priv->gsd_settings);
      priv->gsd_settings = NULL;
    }
59
60
61
62
63
  if (priv->session_settings)
    {
      g_object_unref (priv->session_settings);
      priv->session_settings = NULL;
    }
64
65
66
67
68
  if (priv->lockdown_settings)
    {
      g_object_unref (priv->lockdown_settings);
      priv->lockdown_settings = NULL;
    }
69
70
  if (priv->cancellable != NULL)
    {
71
      g_cancellable_cancel (priv->cancellable);
72
73
74
75
76
77
78
79
80
81
82
83
84
      g_object_unref (priv->cancellable);
      priv->cancellable = NULL;
    }
  if (priv->builder != NULL)
    {
      g_object_unref (priv->builder);
      priv->builder = NULL;
    }
  if (priv->proxy != NULL)
    {
      g_object_unref (priv->proxy);
      priv->proxy = NULL;
    }
85
86
87
88
89
90
91
92
93

  G_OBJECT_CLASS (cc_screen_panel_parent_class)->dispose (object);
}

static void
on_lock_settings_changed (GSettings     *settings,
                          const char    *key,
                          CcScreenPanel *panel)
{
94
95
  if (g_str_equal (key, "lock-delay") == FALSE)
    return;
96
97
}

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
static void
update_lock_screen_sensitivity (CcScreenPanel *self)
{
  GtkWidget *widget;
  gboolean   locked;

  widget = WID ("screen_lock_main_box");
  locked = g_settings_get_boolean (self->priv->lockdown_settings, "disable-lock-screen");
  gtk_widget_set_sensitive (widget, !locked);
}

static void
on_lockdown_settings_changed (GSettings     *settings,
                              const char    *key,
                              CcScreenPanel *panel)
{
  if (g_str_equal (key, "disable-lock-screen") == FALSE)
    return;

  update_lock_screen_sensitivity (panel);
}

120
121
122
123
124
125
static const char *
cc_screen_panel_get_help_uri (CcPanel *panel)
{
  return "help:gnome-help/prefs-display";
}

126
127
128
129
static void
cc_screen_panel_class_init (CcScreenPanelClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
130
  CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
131
132
133
134

  g_type_class_add_private (klass, sizeof (CcScreenPanelPrivate));

  object_class->dispose = cc_screen_panel_dispose;
135
136

  panel_class->get_help_uri = cc_screen_panel_get_help_uri;
137
138
}

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
static void
set_brightness_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  GError *error = NULL;
  GVariant *result;

  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;

  /* not setting, so pay attention to changed signals */
  priv->setting_brightness = FALSE;
  result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
  if (result == NULL)
    {
      g_printerr ("Error setting brightness: %s\n", error->message);
      g_error_free (error);
      return;
    }
}

static void
brightness_slider_value_changed_cb (GtkRange *range, gpointer user_data)
{
  guint percentage;
  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;

  /* do not loop */
165
166
167
  if (priv->setting_brightness)
    return;

168
169
170
171
172
  priv->setting_brightness = TRUE;

  /* push this to g-p-m */
  percentage = (guint) gtk_range_get_value (range);
  g_dbus_proxy_call (priv->proxy,
173
                     "SetPercentage",
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
                     g_variant_new ("(u)",
                                    percentage),
                     G_DBUS_CALL_FLAGS_NONE,
                     -1,
                     priv->cancellable,
                     set_brightness_cb,
                     user_data);
}

static void
get_brightness_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  GError *error = NULL;
  GVariant *result;
  guint brightness;
  GtkRange *range;
190
  CcScreenPanel *self = CC_SCREEN_PANEL (user_data);
191
192
193
194

  result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
  if (result == NULL)
    {
195
196
197
198
199
200
201
      /* We got cancelled, so we're probably exiting */
      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
        {
          g_error_free (error);
          return;
	}

202
203
      gtk_widget_hide (WID ("screen_brightness_hscale"));
      gtk_widget_hide (WID ("screen_auto_reduce_checkbutton"));
204
      gtk_widget_hide (WID ("brightness-frame"));
205
      g_object_set (G_OBJECT (WID ("turn-off-alignment")), "left-padding", 0, NULL);
206

207
208
209
210
211
      if (error->message &&
      	  strstr (error->message, "No backlight devices present") == NULL)
        {
          g_warning ("Error getting brightness: %s", error->message);
        }
212
213
214
215
216
217
218
219
      g_error_free (error);
      return;
    }

  /* set the slider */
  g_variant_get (result,
                 "(u)",
                 &brightness);
220
  range = GTK_RANGE (WID ("screen_brightness_hscale"));
221
222
223
224
225
226
227
228
229
230
  gtk_range_set_range (range, 0, 100);
  gtk_range_set_increments (range, 1, 10);
  gtk_range_set_value (range, brightness);
  g_signal_connect (range,
                    "value-changed",
                    G_CALLBACK (brightness_slider_value_changed_cb),
                    user_data);
  g_variant_unref (result);
}

Matthias Clasen's avatar
Matthias Clasen committed
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
static void
on_signal (GDBusProxy *proxy,
           gchar      *sender_name,
           gchar      *signal_name,
           GVariant   *parameters,
           gpointer    user_data)
{
  CcScreenPanel *self = CC_SCREEN_PANEL (user_data);

  if (g_strcmp0 (signal_name, "Changed") == 0)
    {
      /* changed, but ignoring */
      if (self->priv->setting_brightness)
        return;

      /* retrieve the value again from g-s-d */
      g_dbus_proxy_call (self->priv->proxy,
                         "GetPercentage",
                         NULL,
                         G_DBUS_CALL_FLAGS_NONE,
                         200, /* we don't want to randomly move the bar */
                         self->priv->cancellable,
                         get_brightness_cb,
                         user_data);
    }
}

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
static void
got_power_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
  GError *error = NULL;
  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;

  priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
  if (priv->proxy == NULL)
    {
      g_printerr ("Error creating proxy: %s\n", error->message);
      g_error_free (error);
      return;
    }

  /* we want to change the bar if the user presses brightness buttons */
  g_signal_connect (priv->proxy,
                    "g-signal",
                    G_CALLBACK (on_signal),
                    user_data);

  /* get the initial state */
  g_dbus_proxy_call (priv->proxy,
280
                     "GetPercentage",
281
282
283
284
285
286
287
288
                     NULL,
                     G_DBUS_CALL_FLAGS_NONE,
                     200, /* we don't want to randomly move the bar */
                     priv->cancellable,
                     get_brightness_cb,
                     user_data);
}

289
290
291
292
293
294
static void
set_idle_delay_from_dpms (CcScreenPanel *self,
                          int            value)
{
  guint off_delay;

295
  off_delay = 0;
296
297
298
299

  if (value > 0)
    off_delay = (guint) value;

300
  g_settings_set (self->priv->session_settings, "idle-delay", "u", off_delay);
301
302
}

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
static void
dpms_combo_changed_cb (GtkWidget *widget, CcScreenPanel *self)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  gint value;
  gboolean ret;

  /* no selection */
  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter);
  if (!ret)
    return;

  /* get entry */
  model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget));
  gtk_tree_model_get (model, &iter,
                      1, &value,
                      -1);

  /* set both battery and ac keys */
  g_settings_set_int (self->priv->gsd_settings, "sleep-display-ac", value);
  g_settings_set_int (self->priv->gsd_settings, "sleep-display-battery", value);
325
326

  set_idle_delay_from_dpms (self, value);
327
328
}

329
330
331
332
333
static void
lock_combo_changed_cb (GtkWidget *widget, CcScreenPanel *self)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
334
  guint delay;
335
336
337
338
339
340
341
342
343
344
  gboolean ret;

  /* no selection */
  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter);
  if (!ret)
    return;

  /* get entry */
  model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget));
  gtk_tree_model_get (model, &iter,
345
                      1, &delay,
346
                      -1);
347
  g_settings_set (self->priv->lock_settings, "lock-delay", "u", delay);
348
349
}

350
351
352
353
354
355
static void
set_dpms_value_for_combo (GtkComboBox *combo_box, CcScreenPanel *self)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  gint value;
356
  gint value_tmp, value_prev;
357
  gboolean ret;
358
  guint i;
359
360
361
362
363
364
365

  /* get entry */
  model = gtk_combo_box_get_model (combo_box);
  ret = gtk_tree_model_get_iter_first (model, &iter);
  if (!ret)
    return;

366
367
368
  value_prev = 0;
  i = 0;

369
370
371
372
373
374
375
  /* try to make the UI match the AC setting */
  value = g_settings_get_int (self->priv->gsd_settings, "sleep-display-ac");
  do
    {
      gtk_tree_model_get (model, &iter,
                          1, &value_tmp,
                          -1);
376
      if (value == value_tmp ||
William Jon McCann's avatar
William Jon McCann committed
377
          (value_tmp > value_prev && value < value_tmp))
378
379
        {
          gtk_combo_box_set_active_iter (combo_box, &iter);
380
          return;
381
        }
382
383
      value_prev = value_tmp;
      i++;
384
    } while (gtk_tree_model_iter_next (model, &iter));
385
386
387

  /* If we didn't find the setting in the list */
  gtk_combo_box_set_active (combo_box, i - 1);
388
389
}

390
391
392
393
394
395
static void
set_lock_value_for_combo (GtkComboBox *combo_box, CcScreenPanel *self)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  guint value;
396
  gint value_tmp, value_prev;
397
  gboolean ret;
398
  guint i;
399
400
401
402
403
404
405

  /* get entry */
  model = gtk_combo_box_get_model (combo_box);
  ret = gtk_tree_model_get_iter_first (model, &iter);
  if (!ret)
    return;

406
407
408
  value_prev = 0;
  i = 0;

409
  /* try to make the UI match the lock setting */
410
  g_settings_get (self->priv->lock_settings, "lock-delay", "u", &value);
411

412
413
414
415
416
  do
    {
      gtk_tree_model_get (model, &iter,
                          1, &value_tmp,
                          -1);
417
      if (value == value_tmp ||
William Jon McCann's avatar
William Jon McCann committed
418
          (value_tmp > value_prev && value < value_tmp))
419
420
        {
          gtk_combo_box_set_active_iter (combo_box, &iter);
421
          return;
422
        }
423
424
      value_prev = value_tmp;
      i++;
425
    } while (gtk_tree_model_iter_next (model, &iter));
426
427
428

  /* If we didn't find the setting in the list */
  gtk_combo_box_set_active (combo_box, i - 1);
429
430
}

431
432
433
434
435
436
437
438
static void
cc_screen_panel_init (CcScreenPanel *self)
{
  GError     *error;
  GtkWidget  *widget;

  self->priv = SCREEN_PANEL_PRIVATE (self);

439
  self->priv->builder = gtk_builder_new ();
440
441

  error = NULL;
442
  gtk_builder_add_from_file (self->priv->builder,
443
444
445
446
447
448
449
450
451
452
                             GNOMECC_UI_DIR "/screen.ui",
                             &error);

  if (error != NULL)
    {
      g_warning ("Could not load interface file: %s", error->message);
      g_error_free (error);
      return;
    }

453
454
455
456
457
458
  self->priv->cancellable = g_cancellable_new ();

  /* get initial brightness version */
  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
                            G_DBUS_PROXY_FLAGS_NONE,
                            NULL,
459
460
461
                            "org.gnome.SettingsDaemon",
                            "/org/gnome/SettingsDaemon/Power",
                            "org.gnome.SettingsDaemon.Power.Screen",
462
463
464
465
                            self->priv->cancellable,
                            got_power_proxy_cb,
                            self);

466
  self->priv->lock_settings = g_settings_new ("org.gnome.desktop.screensaver");
467
468
469
470
  g_signal_connect (self->priv->lock_settings,
                    "changed",
                    G_CALLBACK (on_lock_settings_changed),
                    self);
471
  self->priv->gsd_settings = g_settings_new ("org.gnome.settings-daemon.plugins.power");
472
  self->priv->session_settings = g_settings_new ("org.gnome.desktop.session");
473
474
475
476
477
  self->priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown");
  g_signal_connect (self->priv->lockdown_settings,
                    "changed",
                    G_CALLBACK (on_lockdown_settings_changed),
                    self);
478

479
  /* bind the auto dim checkbox */
480
  widget = WID ("screen_auto_reduce_checkbutton");
481
482
483
484
  g_settings_bind (self->priv->gsd_settings,
                   "idle-dim-battery",
                   widget, "active",
                   G_SETTINGS_BIND_DEFAULT);
485

486
  /* display off time */
487
  widget = WID ("screen_brightness_combobox");
488
489
490
491
492
  set_dpms_value_for_combo (GTK_COMBO_BOX (widget), self);
  g_signal_connect (widget, "changed",
                    G_CALLBACK (dpms_combo_changed_cb),
                    self);

493
494
495
  /* bind the screen lock checkbox */
  widget = WID ("screen_lock_on_switch");
  g_settings_bind (self->priv->lock_settings,
William Jon McCann's avatar
William Jon McCann committed
496
497
498
                   "lock-enabled",
                   widget, "active",
                   G_SETTINGS_BIND_DEFAULT);
499
500
501
502
503

  /* lock time */
  widget = WID ("screen_lock_combobox");
  set_lock_value_for_combo (GTK_COMBO_BOX (widget), self);
  g_signal_connect (widget, "changed",
William Jon McCann's avatar
William Jon McCann committed
504
505
                    G_CALLBACK (lock_combo_changed_cb),
                    self);
506

507
  widget = WID ("screen_lock_hbox");
508
  g_settings_bind (self->priv->lock_settings,
William Jon McCann's avatar
William Jon McCann committed
509
510
511
                   "lock-enabled",
                   widget, "sensitive",
                   G_SETTINGS_BIND_GET);
512

513
514
515
516
517
518
  widget = WID ("show_notifications_check");
  g_settings_bind (self->priv->lock_settings,
                   "show-notifications",
                   widget, "active",
                   G_SETTINGS_BIND_DEFAULT);

519
520
  update_lock_screen_sensitivity (self);

521
  widget = WID ("screen_vbox");
522
  gtk_widget_reparent (widget, (GtkWidget *) self);
523
  g_object_set (self, "valign", GTK_ALIGN_START, NULL);
524
}