cc-screen-panel.c 14.9 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
24
#include "cc-screen-resources.h"

25
#include <string.h>
26

Ray Strode's avatar
Ray Strode committed
27
CC_PANEL_REGISTER (CcScreenPanel, cc_screen_panel)
28
29
30
31

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

32
33
#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, s))

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

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

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

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

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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);
}

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

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

  g_type_class_add_private (klass, sizeof (CcScreenPanelPrivate));

  object_class->dispose = cc_screen_panel_dispose;
137
138

  panel_class->get_help_uri = cc_screen_panel_get_help_uri;
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
165
166
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 */
167
168
169
  if (priv->setting_brightness)
    return;

170
171
172
173
174
  priv->setting_brightness = TRUE;

  /* push this to g-p-m */
  percentage = (guint) gtk_range_get_value (range);
  g_dbus_proxy_call (priv->proxy,
175
                     "SetPercentage",
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
                     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;
192
  CcScreenPanel *self = CC_SCREEN_PANEL (user_data);
193
194
195
196

  result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
  if (result == NULL)
    {
197
198
199
200
201
202
203
      /* 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;
	}

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

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

  /* set the slider */
  g_variant_get (result,
                 "(u)",
                 &brightness);
222
  range = GTK_RANGE (WID ("screen_brightness_hscale"));
223
224
225
226
227
228
229
230
231
232
  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
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
258
259
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);
    }
}

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
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,
282
                     "GetPercentage",
283
284
285
286
287
288
289
290
                     NULL,
                     G_DBUS_CALL_FLAGS_NONE,
                     200, /* we don't want to randomly move the bar */
                     priv->cancellable,
                     get_brightness_cb,
                     user_data);
}

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

297
  off_delay = 0;
298
299
300
301

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

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

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
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);
327
328

  set_idle_delay_from_dpms (self, value);
329
330
}

331
332
333
334
335
static void
lock_combo_changed_cb (GtkWidget *widget, CcScreenPanel *self)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
336
  guint delay;
337
338
339
340
341
342
343
344
345
346
  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,
347
                      1, &delay,
348
                      -1);
349
  g_settings_set (self->priv->lock_settings, "lock-delay", "u", delay);
350
351
}

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

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

368
369
370
  value_prev = 0;
  i = 0;

371
372
373
374
375
376
377
  /* 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);
378
      if (value == value_tmp ||
William Jon McCann's avatar
William Jon McCann committed
379
          (value_tmp > value_prev && value < value_tmp))
380
381
        {
          gtk_combo_box_set_active_iter (combo_box, &iter);
382
          return;
383
        }
384
385
      value_prev = value_tmp;
      i++;
386
    } while (gtk_tree_model_iter_next (model, &iter));
387
388
389

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

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

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

408
409
410
  value_prev = 0;
  i = 0;

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

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

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

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

  self->priv = SCREEN_PANEL_PRIVATE (self);
440
  g_resources_register (cc_screen_get_resource ());
441

442
  self->priv->builder = gtk_builder_new ();
443
444

  error = NULL;
445
446
447
  gtk_builder_add_from_resource (self->priv->builder,
                                 "/org/gnome/control-center/screen/screen.ui",
                                 &error);
448
449
450
451
452
453
454
455

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

456
457
458
459
460
461
  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,
462
463
464
                            "org.gnome.SettingsDaemon",
                            "/org/gnome/SettingsDaemon/Power",
                            "org.gnome.SettingsDaemon.Power.Screen",
465
466
467
468
                            self->priv->cancellable,
                            got_power_proxy_cb,
                            self);

469
  self->priv->lock_settings = g_settings_new ("org.gnome.desktop.screensaver");
470
471
472
473
  g_signal_connect (self->priv->lock_settings,
                    "changed",
                    G_CALLBACK (on_lock_settings_changed),
                    self);
474
  self->priv->gsd_settings = g_settings_new ("org.gnome.settings-daemon.plugins.power");
475
  self->priv->session_settings = g_settings_new ("org.gnome.desktop.session");
476
477
478
479
480
  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);
481

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

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

496
497
498
  /* 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
499
500
501
                   "lock-enabled",
                   widget, "active",
                   G_SETTINGS_BIND_DEFAULT);
502
503
504
505
506

  /* 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
507
508
                    G_CALLBACK (lock_combo_changed_cb),
                    self);
509

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

516
517
518
519
520
521
  widget = WID ("show_notifications_check");
  g_settings_bind (self->priv->lock_settings,
                   "show-notifications",
                   widget, "active",
                   G_SETTINGS_BIND_DEFAULT);

522
523
  update_lock_screen_sensitivity (self);

524
  widget = WID ("screen_vbox");
525
  gtk_widget_reparent (widget, (GtkWidget *) self);
526
  g_object_set (self, "valign", GTK_ALIGN_START, NULL);
527
}