~ubuntu-branches/ubuntu/trusty/unity-control-center/trusty

« back to all changes in this revision

Viewing changes to panels/screen/cc-screen-panel.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2014-01-08 16:29:18 UTC
  • Revision ID: package-import@ubuntu.com-20140108162918-g29dd08tr913y2qh
Tags: upstream-14.04.0
ImportĀ upstreamĀ versionĀ 14.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
 
2
 *
 
3
 * Copyright (C) 2010 Red Hat, Inc
 
4
 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
19
 *
 
20
 */
 
21
 
 
22
#include "cc-screen-panel.h"
 
23
 
 
24
CC_PANEL_REGISTER (CcScreenPanel, cc_screen_panel)
 
25
 
 
26
#define SCREEN_PANEL_PRIVATE(o) \
 
27
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_SCREEN_PANEL, CcScreenPanelPrivate))
 
28
 
 
29
#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, s))
 
30
 
 
31
struct _CcScreenPanelPrivate
 
32
{
 
33
  GSettings     *lock_settings;
 
34
  GSettings     *gsd_settings;
 
35
  GSettings     *session_settings;
 
36
  GSettings     *lockdown_settings;
 
37
  GCancellable  *cancellable;
 
38
  GtkBuilder    *builder;
 
39
  GDBusProxy    *proxy;
 
40
  gboolean       setting_brightness;
 
41
};
 
42
 
 
43
 
 
44
static void
 
45
cc_screen_panel_get_property (GObject    *object,
 
46
                              guint       property_id,
 
47
                              GValue     *value,
 
48
                              GParamSpec *pspec)
 
49
{
 
50
  switch (property_id)
 
51
    {
 
52
    default:
 
53
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
54
    }
 
55
}
 
56
 
 
57
static void
 
58
cc_screen_panel_set_property (GObject      *object,
 
59
                              guint         property_id,
 
60
                              const GValue *value,
 
61
                              GParamSpec   *pspec)
 
62
{
 
63
  switch (property_id)
 
64
    {
 
65
    default:
 
66
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
67
    }
 
68
}
 
69
 
 
70
static void
 
71
cc_screen_panel_dispose (GObject *object)
 
72
{
 
73
  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (object)->priv;
 
74
 
 
75
  if (priv->lock_settings)
 
76
    {
 
77
      g_object_unref (priv->lock_settings);
 
78
      priv->lock_settings = NULL;
 
79
    }
 
80
  if (priv->gsd_settings)
 
81
    {
 
82
      g_object_unref (priv->gsd_settings);
 
83
      priv->gsd_settings = NULL;
 
84
    }
 
85
  if (priv->session_settings)
 
86
    {
 
87
      g_object_unref (priv->session_settings);
 
88
      priv->session_settings = NULL;
 
89
    }
 
90
  if (priv->lockdown_settings)
 
91
    {
 
92
      g_object_unref (priv->lockdown_settings);
 
93
      priv->lockdown_settings = NULL;
 
94
    }
 
95
  if (priv->cancellable != NULL)
 
96
    {
 
97
      g_cancellable_cancel (priv->cancellable);
 
98
      g_object_unref (priv->cancellable);
 
99
      priv->cancellable = NULL;
 
100
    }
 
101
  if (priv->builder != NULL)
 
102
    {
 
103
      g_object_unref (priv->builder);
 
104
      priv->builder = NULL;
 
105
    }
 
106
  if (priv->proxy != NULL)
 
107
    {
 
108
      g_object_unref (priv->proxy);
 
109
      priv->proxy = NULL;
 
110
    }
 
111
 
 
112
  G_OBJECT_CLASS (cc_screen_panel_parent_class)->dispose (object);
 
113
}
 
114
 
 
115
static void
 
116
on_lock_settings_changed (GSettings     *settings,
 
117
                          const char    *key,
 
118
                          CcScreenPanel *panel)
 
119
{
 
120
  if (g_str_equal (key, "lock-delay") == FALSE)
 
121
    return;
 
122
}
 
123
 
 
124
static void
 
125
update_lock_screen_sensitivity (CcScreenPanel *self)
 
126
{
 
127
  GtkWidget *widget;
 
128
  gboolean   locked;
 
129
 
 
130
  widget = WID ("screen_lock_main_box");
 
131
  locked = g_settings_get_boolean (self->priv->lockdown_settings, "disable-lock-screen");
 
132
  gtk_widget_set_sensitive (widget, !locked);
 
133
}
 
134
 
 
135
static void
 
136
on_lockdown_settings_changed (GSettings     *settings,
 
137
                              const char    *key,
 
138
                              CcScreenPanel *panel)
 
139
{
 
140
  if (g_str_equal (key, "disable-lock-screen") == FALSE)
 
141
    return;
 
142
 
 
143
  update_lock_screen_sensitivity (panel);
 
144
}
 
145
 
 
146
static const char *
 
147
cc_screen_panel_get_help_uri (CcPanel *panel)
 
148
{
 
149
  if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity"))
 
150
    return "help:ubuntu-help/prefs-display";
 
151
  else
 
152
    return "help:gnome-help/prefs-display";
 
153
}
 
154
 
 
155
static void
 
156
cc_screen_panel_class_init (CcScreenPanelClass *klass)
 
157
{
 
158
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
159
  CcPanelClass *panel_class = CC_PANEL_CLASS (klass);
 
160
 
 
161
  g_type_class_add_private (klass, sizeof (CcScreenPanelPrivate));
 
162
 
 
163
  object_class->get_property = cc_screen_panel_get_property;
 
164
  object_class->set_property = cc_screen_panel_set_property;
 
165
  object_class->dispose = cc_screen_panel_dispose;
 
166
 
 
167
  panel_class->get_help_uri = cc_screen_panel_get_help_uri;
 
168
}
 
169
 
 
170
static void
 
171
set_brightness_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 
172
{
 
173
  GError *error = NULL;
 
174
  GVariant *result;
 
175
 
 
176
  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;
 
177
 
 
178
  /* not setting, so pay attention to changed signals */
 
179
  priv->setting_brightness = FALSE;
 
180
  result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
 
181
  if (result == NULL)
 
182
    {
 
183
      g_printerr ("Error setting brightness: %s\n", error->message);
 
184
      g_error_free (error);
 
185
      return;
 
186
    }
 
187
}
 
188
 
 
189
static void
 
190
brightness_slider_value_changed_cb (GtkRange *range, gpointer user_data)
 
191
{
 
192
  guint percentage;
 
193
  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;
 
194
 
 
195
  /* do not loop */
 
196
  if (priv->setting_brightness)
 
197
    return;
 
198
 
 
199
  priv->setting_brightness = TRUE;
 
200
 
 
201
  /* push this to g-p-m */
 
202
  percentage = (guint) gtk_range_get_value (range);
 
203
  g_dbus_proxy_call (priv->proxy,
 
204
                     "SetPercentage",
 
205
                     g_variant_new ("(u)",
 
206
                                    percentage),
 
207
                     G_DBUS_CALL_FLAGS_NONE,
 
208
                     -1,
 
209
                     priv->cancellable,
 
210
                     set_brightness_cb,
 
211
                     user_data);
 
212
}
 
213
 
 
214
static void
 
215
get_brightness_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 
216
{
 
217
  GError *error = NULL;
 
218
  GVariant *result;
 
219
  guint brightness;
 
220
  GtkRange *range;
 
221
  CcScreenPanel *self = CC_SCREEN_PANEL (user_data);
 
222
 
 
223
  result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
 
224
  if (result == NULL)
 
225
    {
 
226
      /* We got cancelled, so we're probably exiting */
 
227
      if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
 
228
        {
 
229
          g_error_free (error);
 
230
          return;
 
231
        }
 
232
 
 
233
      gtk_widget_hide (WID ("screen_brightness_hscale"));
 
234
      gtk_widget_hide (WID ("screen_auto_reduce_checkbutton"));
 
235
      gtk_widget_hide (WID ("brightness-frame"));
 
236
      g_object_set (G_OBJECT (WID ("turn-off-alignment")), "left-padding", 0, NULL);
 
237
 
 
238
      if (error->message &&
 
239
          strstr (error->message, "No backlight devices present") == NULL)
 
240
        {
 
241
          g_warning ("Error getting brightness: %s", error->message);
 
242
        }
 
243
      g_error_free (error);
 
244
      return;
 
245
    }
 
246
 
 
247
  /* set the slider */
 
248
  g_variant_get (result,
 
249
                 "(u)",
 
250
                 &brightness);
 
251
  range = GTK_RANGE (WID ("screen_brightness_hscale"));
 
252
  gtk_range_set_range (range, 0, 100);
 
253
  gtk_range_set_increments (range, 1, 10);
 
254
  gtk_range_set_value (range, brightness);
 
255
  g_signal_connect (range,
 
256
                    "value-changed",
 
257
                    G_CALLBACK (brightness_slider_value_changed_cb),
 
258
                    user_data);
 
259
  g_variant_unref (result);
 
260
}
 
261
 
 
262
static void
 
263
on_signal (GDBusProxy *proxy,
 
264
           gchar      *sender_name,
 
265
           gchar      *signal_name,
 
266
           GVariant   *parameters,
 
267
           gpointer    user_data)
 
268
{
 
269
  CcScreenPanel *self = CC_SCREEN_PANEL (user_data);
 
270
 
 
271
  if (g_strcmp0 (signal_name, "Changed") == 0)
 
272
    {
 
273
      /* changed, but ignoring */
 
274
      if (self->priv->setting_brightness)
 
275
        return;
 
276
 
 
277
      /* retrieve the value again from g-s-d */
 
278
      g_dbus_proxy_call (self->priv->proxy,
 
279
                         "GetPercentage",
 
280
                         NULL,
 
281
                         G_DBUS_CALL_FLAGS_NONE,
 
282
                         200, /* we don't want to randomly move the bar */
 
283
                         self->priv->cancellable,
 
284
                         get_brightness_cb,
 
285
                         user_data);
 
286
    }
 
287
}
 
288
 
 
289
static void
 
290
got_power_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 
291
{
 
292
  GError *error = NULL;
 
293
  CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;
 
294
 
 
295
  priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
 
296
  if (priv->proxy == NULL)
 
297
    {
 
298
      g_printerr ("Error creating proxy: %s\n", error->message);
 
299
      g_error_free (error);
 
300
      return;
 
301
    }
 
302
 
 
303
  /* we want to change the bar if the user presses brightness buttons */
 
304
  g_signal_connect (priv->proxy,
 
305
                    "g-signal",
 
306
                    G_CALLBACK (on_signal),
 
307
                    user_data);
 
308
 
 
309
  /* get the initial state */
 
310
  g_dbus_proxy_call (priv->proxy,
 
311
                     "GetPercentage",
 
312
                     NULL,
 
313
                     G_DBUS_CALL_FLAGS_NONE,
 
314
                     200, /* we don't want to randomly move the bar */
 
315
                     priv->cancellable,
 
316
                     get_brightness_cb,
 
317
                     user_data);
 
318
}
 
319
 
 
320
static void
 
321
set_idle_delay_from_dpms (CcScreenPanel *self,
 
322
                          int            value)
 
323
{
 
324
  guint off_delay;
 
325
 
 
326
  off_delay = 0;
 
327
 
 
328
  if (value > 0)
 
329
    off_delay = (guint) value;
 
330
 
 
331
  g_settings_set (self->priv->session_settings, "idle-delay", "u", off_delay);
 
332
}
 
333
 
 
334
static void
 
335
dpms_combo_changed_cb (GtkWidget *widget, CcScreenPanel *self)
 
336
{
 
337
  GtkTreeIter iter;
 
338
  GtkTreeModel *model;
 
339
  gint value;
 
340
  gboolean ret;
 
341
 
 
342
  /* no selection */
 
343
  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter);
 
344
  if (!ret)
 
345
    return;
 
346
 
 
347
  /* get entry */
 
348
  model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget));
 
349
  gtk_tree_model_get (model, &iter,
 
350
                      1, &value,
 
351
                      -1);
 
352
 
 
353
  g_settings_set (self->priv->session_settings, "idle-delay", "u", value);
 
354
 
 
355
  set_idle_delay_from_dpms (self, value);
 
356
}
 
357
 
 
358
static void
 
359
lock_combo_changed_cb (GtkWidget *widget, CcScreenPanel *self)
 
360
{
 
361
  GtkTreeIter iter;
 
362
  GtkTreeModel *model;
 
363
  guint delay;
 
364
  gboolean ret;
 
365
 
 
366
  /* no selection */
 
367
  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX(widget), &iter);
 
368
  if (!ret)
 
369
    return;
 
370
 
 
371
  /* get entry */
 
372
  model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget));
 
373
  gtk_tree_model_get (model, &iter,
 
374
                      1, &delay,
 
375
                      -1);
 
376
  g_settings_set (self->priv->lock_settings, "lock-delay", "u", delay);
 
377
}
 
378
 
 
379
static void
 
380
set_dpms_value_for_combo (GtkComboBox *combo_box, CcScreenPanel *self)
 
381
{
 
382
  GtkTreeIter iter;
 
383
  GtkTreeModel *model;
 
384
  gint value;
 
385
  gint value_tmp, value_prev;
 
386
  gboolean ret;
 
387
  guint i;
 
388
 
 
389
  /* get entry */
 
390
  model = gtk_combo_box_get_model (combo_box);
 
391
  ret = gtk_tree_model_get_iter_first (model, &iter);
 
392
  if (!ret)
 
393
    return;
 
394
 
 
395
  value_prev = 0;
 
396
  i = 0;
 
397
 
 
398
  /* try to make the UI match the AC setting */
 
399
  g_settings_get (self->priv->session_settings, "idle-delay",  "u", &value);
 
400
  do
 
401
    {
 
402
      gtk_tree_model_get (model, &iter,
 
403
                          1, &value_tmp,
 
404
                          -1);
 
405
      if (value == value_tmp)
 
406
        {
 
407
          gtk_combo_box_set_active_iter (combo_box, &iter);
 
408
          return;
 
409
        }
 
410
      value_prev = value_tmp;
 
411
      i++;
 
412
    } while (gtk_tree_model_iter_next (model, &iter));
 
413
 
 
414
  /* If we didn't find the setting in the list */
 
415
  gtk_combo_box_set_active (combo_box, i - 1);
 
416
}
 
417
 
 
418
static void
 
419
set_lock_value_for_combo (GtkComboBox *combo_box, CcScreenPanel *self)
 
420
{
 
421
  GtkTreeIter iter;
 
422
  GtkTreeModel *model;
 
423
  guint value;
 
424
  gint value_tmp, value_prev;
 
425
  gboolean ret;
 
426
  guint i;
 
427
 
 
428
  /* get entry */
 
429
  model = gtk_combo_box_get_model (combo_box);
 
430
  ret = gtk_tree_model_get_iter_first (model, &iter);
 
431
  if (!ret)
 
432
    return;
 
433
 
 
434
  value_prev = 0;
 
435
  i = 0;
 
436
 
 
437
  /* try to make the UI match the lock setting */
 
438
  g_settings_get (self->priv->lock_settings, "lock-delay", "u", &value);
 
439
 
 
440
  do
 
441
    {
 
442
      gtk_tree_model_get (model, &iter,
 
443
                          1, &value_tmp,
 
444
                          -1);
 
445
      if (value == value_tmp ||
 
446
          (value_tmp > value_prev && value < value_tmp))
 
447
        {
 
448
          gtk_combo_box_set_active_iter (combo_box, &iter);
 
449
          return;
 
450
        }
 
451
      value_prev = value_tmp;
 
452
      i++;
 
453
    } while (gtk_tree_model_iter_next (model, &iter));
 
454
 
 
455
  /* If we didn't find the setting in the list */
 
456
  gtk_combo_box_set_active (combo_box, i - 1);
 
457
}
 
458
 
 
459
static void
 
460
cc_screen_panel_init (CcScreenPanel *self)
 
461
{
 
462
  GError     *error;
 
463
  GtkWidget  *widget;
 
464
 
 
465
  self->priv = SCREEN_PANEL_PRIVATE (self);
 
466
 
 
467
  self->priv->builder = gtk_builder_new ();
 
468
 
 
469
  error = NULL;
 
470
  gtk_builder_add_from_file (self->priv->builder,
 
471
                             GNOMECC_UI_DIR "/screen.ui",
 
472
                             &error);
 
473
 
 
474
  if (error != NULL)
 
475
    {
 
476
      g_warning ("Could not load interface file: %s", error->message);
 
477
      g_error_free (error);
 
478
      return;
 
479
    }
 
480
 
 
481
  self->priv->cancellable = g_cancellable_new ();
 
482
 
 
483
  /* get initial brightness version */
 
484
  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
 
485
                            G_DBUS_PROXY_FLAGS_NONE,
 
486
                            NULL,
 
487
                            "org.gnome.SettingsDaemon",
 
488
                            "/org/gnome/SettingsDaemon/Power",
 
489
                            "org.gnome.SettingsDaemon.Power.Screen",
 
490
                            self->priv->cancellable,
 
491
                            got_power_proxy_cb,
 
492
                            self);
 
493
 
 
494
  self->priv->lock_settings = g_settings_new ("org.gnome.desktop.screensaver");
 
495
  g_signal_connect (self->priv->lock_settings,
 
496
                    "changed",
 
497
                    G_CALLBACK (on_lock_settings_changed),
 
498
                    self);
 
499
  self->priv->gsd_settings = g_settings_new ("org.gnome.settings-daemon.plugins.power");
 
500
  self->priv->session_settings = g_settings_new ("org.gnome.desktop.session");
 
501
  self->priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown");
 
502
  g_signal_connect (self->priv->lockdown_settings,
 
503
                    "changed",
 
504
                    G_CALLBACK (on_lockdown_settings_changed),
 
505
                    self);
 
506
 
 
507
  /* bind the auto dim checkbox */
 
508
  widget = WID ("screen_auto_reduce_checkbutton");
 
509
  g_settings_bind (self->priv->gsd_settings,
 
510
                   "idle-dim",
 
511
                   widget, "active",
 
512
                   G_SETTINGS_BIND_DEFAULT);
 
513
 
 
514
  /* display off time */
 
515
  widget = WID ("screen_brightness_combobox");
 
516
  set_dpms_value_for_combo (GTK_COMBO_BOX (widget), self);
 
517
  g_signal_connect (widget, "changed",
 
518
                    G_CALLBACK (dpms_combo_changed_cb),
 
519
                    self);
 
520
 
 
521
  /* bind the screen lock checkbox */
 
522
  widget = WID ("screen_lock_on_switch");
 
523
  g_settings_bind (self->priv->lock_settings,
 
524
                   "lock-enabled",
 
525
                   widget, "active",
 
526
                   G_SETTINGS_BIND_DEFAULT);
 
527
 
 
528
  /* lock time */
 
529
  widget = WID ("screen_lock_combobox");
 
530
  set_lock_value_for_combo (GTK_COMBO_BOX (widget), self);
 
531
  g_signal_connect (widget, "changed",
 
532
                    G_CALLBACK (lock_combo_changed_cb),
 
533
                    self);
 
534
 
 
535
  widget = WID ("screen_lock_hbox");
 
536
  g_settings_bind (self->priv->lock_settings,
 
537
                   "lock-enabled",
 
538
                   widget, "sensitive",
 
539
                   G_SETTINGS_BIND_GET);
 
540
 
 
541
  widget = WID ("show_notifications_check");
 
542
  g_settings_bind (self->priv->lock_settings,
 
543
                   "show-notifications",
 
544
                   widget, "active",
 
545
                   G_SETTINGS_BIND_DEFAULT);
 
546
  if (!g_strcmp0(g_getenv("XDG_CURRENT_DESKTOP"), "Unity"))
 
547
    gtk_widget_hide (widget);
 
548
 
 
549
  update_lock_screen_sensitivity (self);
 
550
 
 
551
  /* bind the screen lock suspend checkbutton */
 
552
  widget = WID ("screen_lock_suspend_checkbutton");
 
553
  g_settings_bind (self->priv->lock_settings,
 
554
                   "ubuntu-lock-on-suspend",
 
555
                   widget, "active",
 
556
                   G_SETTINGS_BIND_DEFAULT);
 
557
 
 
558
  widget = WID ("screen_vbox");
 
559
  gtk_widget_reparent (widget, (GtkWidget *) self);
 
560
  g_object_set (self, "valign", GTK_ALIGN_START, NULL);
 
561
}
 
562
 
 
563
void
 
564
cc_screen_panel_register (GIOModule *module)
 
565
{
 
566
  cc_screen_panel_register_type (G_TYPE_MODULE (module));
 
567
  g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
 
568
                                  CC_TYPE_SCREEN_PANEL,
 
569
                                  "screen", 0);
 
570
}
 
571