1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2008 William Jon McCann <mccann@jhu.edu>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29
#include <glib/gi18n.h>
30
#include <glib-object.h>
31
#include <gio/gdesktopappinfo.h>
34
#include <cairo-xlib.h>
36
#include "gsm-inhibit-dialog.h"
37
#include "gsm-store.h"
38
#include "gsm-client.h"
39
#include "gsm-icon-names.h"
40
#include "gsm-inhibitor.h"
44
#include <X11/extensions/Xrender.h>
47
#define GSM_INHIBIT_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_INHIBIT_DIALOG, GsmInhibitDialogPrivate))
49
#define GTKBUILDER_FILE "gsm-inhibit-dialog.ui"
51
#ifndef DEFAULT_ICON_SIZE
52
#define DEFAULT_ICON_SIZE 32
55
#ifndef DEFAULT_SNAPSHOT_SIZE
56
#define DEFAULT_SNAPSHOT_SIZE 128
59
#define DIALOG_RESPONSE_LOCK_SCREEN 1
61
struct GsmInhibitDialogPrivate
68
GtkListStore *list_store;
69
gboolean have_xrender;
70
int xrender_event_base;
71
int xrender_error_base;
82
INHIBIT_IMAGE_COLUMN = 0,
84
INHIBIT_REASON_COLUMN,
89
static void gsm_inhibit_dialog_class_init (GsmInhibitDialogClass *klass);
90
static void gsm_inhibit_dialog_init (GsmInhibitDialog *inhibit_dialog);
92
G_DEFINE_TYPE (GsmInhibitDialog, gsm_inhibit_dialog, GTK_TYPE_DIALOG)
95
lock_screen (GsmInhibitDialog *dialog)
99
g_spawn_command_line_async ("gnome-screensaver-command --lock", &error);
101
g_warning ("Couldn't lock screen: %s", error->message);
102
g_error_free (error);
107
on_response (GsmInhibitDialog *dialog,
111
if (dialog->priv->is_done) {
112
g_signal_stop_emission_by_name (dialog, "response");
116
switch (response_id) {
117
case DIALOG_RESPONSE_LOCK_SCREEN:
118
g_signal_stop_emission_by_name (dialog, "response");
119
lock_screen (dialog);
122
dialog->priv->is_done = TRUE;
128
gsm_inhibit_dialog_set_action (GsmInhibitDialog *dialog,
131
dialog->priv->action = action;
135
find_inhibitor (GsmInhibitDialog *dialog,
142
g_assert (GSM_IS_INHIBIT_DIALOG (dialog));
145
model = GTK_TREE_MODEL (dialog->priv->list_store);
147
if (!gtk_tree_model_get_iter_first (model, iter)) {
154
gtk_tree_model_get (model,
156
INHIBIT_ID_COLUMN, &item_id,
160
&& strcmp (item_id, id) == 0) {
164
} while (!found_item && gtk_tree_model_iter_next (model, iter));
170
scale_pixbuf (GdkPixbuf *pixbuf,
173
gboolean no_stretch_hint)
177
float scale_factor_x = 1.0;
178
float scale_factor_y = 1.0;
179
float scale_factor = 1.0;
181
pw = gdk_pixbuf_get_width (pixbuf);
182
ph = gdk_pixbuf_get_height (pixbuf);
184
/* Determine which dimension requires the smallest scale. */
185
scale_factor_x = (float) max_width / (float) pw;
186
scale_factor_y = (float) max_height / (float) ph;
188
if (scale_factor_x > scale_factor_y) {
189
scale_factor = scale_factor_y;
191
scale_factor = scale_factor_x;
194
/* always scale down, allow to disable scaling up */
195
if (scale_factor < 1.0 || !no_stretch_hint) {
196
int scale_x = (int) (pw * scale_factor);
197
int scale_y = (int) (ph * scale_factor);
198
g_debug ("Scaling to %dx%d", scale_x, scale_y);
199
return gdk_pixbuf_scale_simple (pixbuf,
202
GDK_INTERP_BILINEAR);
204
return g_object_ref (pixbuf);
211
pixbuf_get_from_pixmap (Display *display,
216
cairo_surface_t *surface;
222
visual = DefaultVisual (display, 0);
223
g_debug ("GsmInhibitDialog: getting foreign pixmap for %u", (guint)xpixmap);
224
surface = cairo_xlib_surface_create (display,
229
if (surface != NULL) {
230
g_debug ("GsmInhibitDialog: getting pixbuf w=%d h=%d", width, height);
231
retval = gdk_pixbuf_get_from_surface (surface,
237
cairo_surface_destroy (surface);
244
get_pixmap_for_window (Display *display,
249
XWindowAttributes attr;
250
XRenderPictureAttributes pa;
252
XRenderPictFormat *format;
259
XGetWindowAttributes (display, window, &attr);
261
format = XRenderFindVisualFormat (display, attr.visual);
262
has_alpha = (format->type == PictTypeDirect && format->direct.alphaMask);
264
height = attr.height;
266
pa.subwindow_mode = IncludeInferiors; /* Don't clip child widgets */
268
src_picture = XRenderCreatePicture (display, window, format, CPSubwindowMode, &pa);
270
pixmap = XCreatePixmap (display,
275
dst_picture = XRenderCreatePicture (display, pixmap, format, 0, 0);
276
XRenderComposite (display,
277
has_alpha ? PictOpOver : PictOpSrc,
285
if (widthp != NULL) {
288
if (heightp != NULL) {
295
#endif /* HAVE_COMPOSITE */
298
get_pixbuf_for_window (GdkDisplay *gdkdisplay,
303
GdkPixbuf *pixbuf = NULL;
311
display = GDK_DISPLAY_XDISPLAY (gdkdisplay);
312
xwindow = (Window) xid;
314
xpixmap = get_pixmap_for_window (display, xwindow, &width, &height);
316
if (xpixmap == None) {
317
g_debug ("GsmInhibitDialog: Unable to get window snapshot for %u", xid);
320
g_debug ("GsmInhibitDialog: Got xpixmap %u", (guint)xpixmap);
323
pixbuf = pixbuf_get_from_pixmap (display, xpixmap, width, height);
325
if (xpixmap != None) {
326
gdk_x11_display_error_trap_push (gdkdisplay);
327
XFreePixmap (display, xpixmap);
328
gdk_x11_display_error_trap_pop_ignored (gdkdisplay);
331
if (pixbuf != NULL) {
333
g_debug ("GsmInhibitDialog: scaling pixbuf to w=%d h=%d", width, height);
334
scaled = scale_pixbuf (pixbuf, thumb_width, thumb_height, TRUE);
335
g_object_unref (pixbuf);
339
g_debug ("GsmInhibitDialog: no support for getting window snapshot");
345
add_inhibitor (GsmInhibitDialog *dialog,
346
GsmInhibitor *inhibitor)
348
GdkDisplay *gdkdisplay;
351
char *desktop_filename;
353
GDesktopAppInfo *app_info;
360
gdkdisplay = gtk_widget_get_display (GTK_WIDGET (dialog));
362
/* FIXME: get info from xid */
369
app_id = gsm_inhibitor_peek_app_id (inhibitor);
371
if (IS_STRING_EMPTY (app_id)) {
372
desktop_filename = NULL;
373
} else if (! g_str_has_suffix (app_id, ".desktop")) {
374
desktop_filename = g_strdup_printf ("%s.desktop", app_id);
376
desktop_filename = g_strdup (app_id);
379
xid = gsm_inhibitor_peek_toplevel_xid (inhibitor);
380
g_debug ("GsmInhibitDialog: inhibitor has XID %u", xid);
381
if (xid > 0 && dialog->priv->have_xrender) {
382
pixbuf = get_pixbuf_for_window (gdkdisplay, xid, DEFAULT_SNAPSHOT_SIZE, DEFAULT_SNAPSHOT_SIZE);
383
if (pixbuf == NULL) {
384
g_debug ("GsmInhibitDialog: unable to read pixbuf from %u", xid);
388
if (desktop_filename != NULL) {
389
search_dirs = gsm_util_get_desktop_dirs (TRUE, FALSE);
391
if (g_path_is_absolute (desktop_filename)) {
394
app_info = g_desktop_app_info_new_from_filename (desktop_filename);
395
if (app_info == NULL) {
396
g_warning ("Unable to load desktop file '%s'",
399
basename = g_path_get_basename (desktop_filename);
400
g_free (desktop_filename);
401
desktop_filename = basename;
405
if (app_info == NULL) {
406
keyfile = g_key_file_new ();
407
if (g_key_file_load_from_dirs (keyfile, desktop_filename, (const gchar **)search_dirs, NULL, 0, NULL))
408
app_info = g_desktop_app_info_new_from_keyfile (keyfile);
409
g_key_file_free (keyfile);
412
/* look for a file with a vendor prefix */
413
if (app_info == NULL) {
414
g_warning ("Unable to find desktop file '%s'",
416
g_free (desktop_filename);
417
desktop_filename = g_strdup_printf ("gnome-%s.desktop", app_id);
418
keyfile = g_key_file_new ();
419
if (g_key_file_load_from_dirs (keyfile, desktop_filename, (const gchar **)search_dirs, NULL, 0, NULL))
420
app_info = g_desktop_app_info_new_from_keyfile (keyfile);
421
g_key_file_free (keyfile);
423
g_strfreev (search_dirs);
425
if (app_info == NULL) {
426
g_warning ("Unable to find desktop file '%s'",
429
name = g_app_info_get_name (G_APP_INFO (app_info));
430
gicon = g_app_info_get_icon (G_APP_INFO (app_info));
432
if (pixbuf == NULL) {
434
info = gtk_icon_theme_lookup_by_gicon (gtk_icon_theme_get_default (),
438
pixbuf = gtk_icon_info_load_icon (info, NULL);
439
gtk_icon_info_free (info);
444
/* try client info */
446
const char *client_id;
447
client_id = gsm_inhibitor_peek_client_id (inhibitor);
448
if (! IS_STRING_EMPTY (client_id)) {
450
client = GSM_CLIENT (gsm_store_lookup (dialog->priv->clients, client_id));
451
if (client != NULL) {
452
freeme = gsm_client_get_app_name (client);
459
if (! IS_STRING_EMPTY (app_id)) {
466
if (pixbuf == NULL) {
468
info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (),
469
GSM_ICON_INHIBITOR_DEFAULT,
472
pixbuf = gtk_icon_info_load_icon (info, NULL);
473
gtk_icon_info_free (info);
476
gtk_list_store_insert_with_values (dialog->priv->list_store,
478
INHIBIT_IMAGE_COLUMN, pixbuf,
479
INHIBIT_NAME_COLUMN, name,
480
INHIBIT_REASON_COLUMN, gsm_inhibitor_peek_reason (inhibitor),
481
INHIBIT_ID_COLUMN, gsm_inhibitor_peek_id (inhibitor),
484
g_free (desktop_filename);
486
g_clear_object (&pixbuf);
487
g_clear_object (&app_info);
491
model_has_one_entry (GtkTreeModel *model)
495
n_rows = gtk_tree_model_iter_n_children (model, NULL);
496
g_debug ("Model has %d rows", n_rows);
498
return (n_rows > 0 && n_rows < 2);
502
update_dialog_text (GsmInhibitDialog *dialog)
504
const char *description_text;
505
const char *header_text;
508
if (model_has_one_entry (GTK_TREE_MODEL (dialog->priv->list_store))) {
509
g_debug ("Found one entry in model");
510
header_text = _("A program is still running:");
511
description_text = _("Waiting for the program to finish. Interrupting the program may cause you to lose work.");
513
g_debug ("Found multiple entries (or none) in model");
514
header_text = _("Some programs are still running:");
515
description_text = _("Waiting for programs to finish. Interrupting these programs may cause you to lose work.");
518
widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
520
if (widget != NULL) {
522
markup = g_strdup_printf ("<b>%s</b>", header_text);
523
gtk_label_set_markup (GTK_LABEL (widget), markup);
527
widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
528
"description-label"));
529
if (widget != NULL) {
530
gtk_label_set_text (GTK_LABEL (widget), description_text);
535
on_store_inhibitor_added (GsmStore *store,
537
GsmInhibitDialog *dialog)
539
GsmInhibitor *inhibitor;
542
g_debug ("GsmInhibitDialog: inhibitor added: %s", id);
544
if (dialog->priv->is_done) {
548
inhibitor = (GsmInhibitor *)gsm_store_lookup (store, id);
551
if (! find_inhibitor (dialog, id, &iter)) {
552
add_inhibitor (dialog, inhibitor);
553
update_dialog_text (dialog);
559
on_store_inhibitor_removed (GsmStore *store,
561
GsmInhibitDialog *dialog)
565
g_debug ("GsmInhibitDialog: inhibitor removed: %s", id);
567
if (dialog->priv->is_done) {
571
/* Remove from model */
572
if (find_inhibitor (dialog, id, &iter)) {
573
gtk_list_store_remove (dialog->priv->list_store, &iter);
574
update_dialog_text (dialog);
577
/* if there are no inhibitors left then trigger response */
578
if (! gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->priv->list_store), &iter)) {
579
gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
584
gsm_inhibit_dialog_set_inhibitor_store (GsmInhibitDialog *dialog,
587
g_return_if_fail (GSM_IS_INHIBIT_DIALOG (dialog));
590
g_object_ref (store);
593
if (dialog->priv->inhibitors != NULL) {
594
g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
595
on_store_inhibitor_added,
597
g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
598
on_store_inhibitor_removed,
601
g_object_unref (dialog->priv->inhibitors);
605
g_debug ("GsmInhibitDialog: setting store %p", store);
607
dialog->priv->inhibitors = store;
609
if (dialog->priv->inhibitors != NULL) {
610
g_signal_connect (dialog->priv->inhibitors,
612
G_CALLBACK (on_store_inhibitor_added),
614
g_signal_connect (dialog->priv->inhibitors,
616
G_CALLBACK (on_store_inhibitor_removed),
622
gsm_inhibit_dialog_set_client_store (GsmInhibitDialog *dialog,
625
g_return_if_fail (GSM_IS_INHIBIT_DIALOG (dialog));
628
g_object_ref (store);
631
if (dialog->priv->clients != NULL) {
632
g_object_unref (dialog->priv->clients);
635
dialog->priv->clients = store;
639
gsm_inhibit_dialog_set_property (GObject *object,
644
GsmInhibitDialog *dialog = GSM_INHIBIT_DIALOG (object);
648
gsm_inhibit_dialog_set_action (dialog, g_value_get_int (value));
650
case PROP_INHIBITOR_STORE:
651
gsm_inhibit_dialog_set_inhibitor_store (dialog, g_value_get_object (value));
653
case PROP_CLIENT_STORE:
654
gsm_inhibit_dialog_set_client_store (dialog, g_value_get_object (value));
657
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
663
gsm_inhibit_dialog_get_property (GObject *object,
668
GsmInhibitDialog *dialog = GSM_INHIBIT_DIALOG (object);
672
g_value_set_int (value, dialog->priv->action);
674
case PROP_INHIBITOR_STORE:
675
g_value_set_object (value, dialog->priv->inhibitors);
677
case PROP_CLIENT_STORE:
678
g_value_set_object (value, dialog->priv->clients);
681
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
687
name_cell_data_func (GtkTreeViewColumn *tree_column,
688
GtkCellRenderer *cell,
691
GsmInhibitDialog *dialog)
699
gtk_tree_model_get (model,
701
INHIBIT_NAME_COLUMN, &name,
702
INHIBIT_REASON_COLUMN, &reason,
705
markup = g_strdup_printf ("<b>%s</b>\n"
706
"<span size=\"small\">%s</span>",
707
name ? name : "(null)",
708
reason ? reason : "(null)");
713
g_object_set (cell, "markup", markup, NULL);
718
add_to_model (const char *id,
719
GsmInhibitor *inhibitor,
720
GsmInhibitDialog *dialog)
722
add_inhibitor (dialog, inhibitor);
727
populate_model (GsmInhibitDialog *dialog)
729
gsm_store_foreach_remove (dialog->priv->inhibitors,
730
(GsmStoreFunc)add_to_model,
732
update_dialog_text (dialog);
736
setup_dialog (GsmInhibitDialog *dialog)
738
const char *button_text;
740
GtkTreeViewColumn *column;
741
GtkCellRenderer *renderer;
743
switch (dialog->priv->action) {
744
case GSM_LOGOUT_ACTION_SWITCH_USER:
745
button_text = _("Switch User Anyway");
747
case GSM_LOGOUT_ACTION_LOGOUT:
748
button_text = _("Log Out Anyway");
750
case GSM_LOGOUT_ACTION_SLEEP:
751
button_text = _("Suspend Anyway");
753
case GSM_LOGOUT_ACTION_HIBERNATE:
754
button_text = _("Hibernate Anyway");
756
case GSM_LOGOUT_ACTION_SHUTDOWN:
757
button_text = _("Shut Down Anyway");
759
case GSM_LOGOUT_ACTION_REBOOT:
760
button_text = _("Restart Anyway");
763
g_assert_not_reached ();
767
gtk_dialog_add_button (GTK_DIALOG (dialog),
769
DIALOG_RESPONSE_LOCK_SCREEN);
770
gtk_dialog_add_button (GTK_DIALOG (dialog),
772
GTK_RESPONSE_CANCEL);
773
gtk_dialog_add_button (GTK_DIALOG (dialog),
775
GTK_RESPONSE_ACCEPT);
776
g_signal_connect (dialog,
778
G_CALLBACK (on_response),
781
dialog->priv->list_store = gtk_list_store_new (NUMBER_OF_COLUMNS,
787
treeview = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
788
"inhibitors-treeview"));
789
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
790
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
791
GTK_TREE_MODEL (dialog->priv->list_store));
794
renderer = gtk_cell_renderer_pixbuf_new ();
795
column = gtk_tree_view_column_new ();
796
gtk_tree_view_column_pack_start (column, renderer, FALSE);
797
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
799
gtk_tree_view_column_set_attributes (column,
801
"pixbuf", INHIBIT_IMAGE_COLUMN,
804
g_object_set (renderer, "xalign", 1.0, NULL);
807
renderer = gtk_cell_renderer_text_new ();
808
column = gtk_tree_view_column_new ();
809
gtk_tree_view_column_pack_start (column, renderer, FALSE);
810
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
811
gtk_tree_view_column_set_cell_data_func (column,
813
(GtkTreeCellDataFunc) name_cell_data_func,
817
gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview),
818
INHIBIT_REASON_COLUMN);
820
populate_model (dialog);
824
gsm_inhibit_dialog_constructor (GType type,
825
guint n_construct_properties,
826
GObjectConstructParam *construct_properties)
828
GsmInhibitDialog *dialog;
830
GdkDisplay *gdkdisplay;
831
#endif /* HAVE_XRENDER */
833
dialog = GSM_INHIBIT_DIALOG (G_OBJECT_CLASS (gsm_inhibit_dialog_parent_class)->constructor (type,
834
n_construct_properties,
835
construct_properties));
838
gdkdisplay = gdk_display_get_default ();
840
gdk_x11_display_error_trap_push (gdkdisplay);
841
if (XRenderQueryExtension (GDK_DISPLAY_XDISPLAY (gdkdisplay), &dialog->priv->xrender_event_base, &dialog->priv->xrender_error_base)) {
842
g_debug ("GsmInhibitDialog: Initialized XRender extension");
843
dialog->priv->have_xrender = TRUE;
845
g_debug ("GsmInhibitDialog: Unable to initialize XRender extension");
846
dialog->priv->have_xrender = FALSE;
848
gdk_display_sync (gdkdisplay);
849
gdk_x11_display_error_trap_pop_ignored (gdkdisplay);
850
#endif /* HAVE_XRENDER */
852
/* FIXME: turn this on when it is ready */
853
dialog->priv->have_xrender = FALSE;
855
setup_dialog (dialog);
857
gtk_widget_show_all (GTK_WIDGET (dialog));
859
return G_OBJECT (dialog);
863
gsm_inhibit_dialog_dispose (GObject *object)
865
GsmInhibitDialog *dialog;
867
g_return_if_fail (object != NULL);
868
g_return_if_fail (GSM_IS_INHIBIT_DIALOG (object));
870
dialog = GSM_INHIBIT_DIALOG (object);
872
g_debug ("GsmInhibitDialog: dispose called");
874
g_clear_object (&dialog->priv->list_store);
876
if (dialog->priv->inhibitors != NULL) {
877
g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
878
on_store_inhibitor_added,
880
g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
881
on_store_inhibitor_removed,
884
g_clear_object (&dialog->priv->inhibitors);
887
g_clear_object (&dialog->priv->xml);
889
G_OBJECT_CLASS (gsm_inhibit_dialog_parent_class)->dispose (object);
893
gsm_inhibit_dialog_class_init (GsmInhibitDialogClass *klass)
895
GObjectClass *object_class = G_OBJECT_CLASS (klass);
897
object_class->get_property = gsm_inhibit_dialog_get_property;
898
object_class->set_property = gsm_inhibit_dialog_set_property;
899
object_class->constructor = gsm_inhibit_dialog_constructor;
900
object_class->dispose = gsm_inhibit_dialog_dispose;
902
g_object_class_install_property (object_class,
904
g_param_spec_int ("action",
910
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
911
g_object_class_install_property (object_class,
912
PROP_INHIBITOR_STORE,
913
g_param_spec_object ("inhibitor-store",
917
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
918
g_object_class_install_property (object_class,
920
g_param_spec_object ("client-store",
924
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
926
g_type_class_add_private (klass, sizeof (GsmInhibitDialogPrivate));
930
gsm_inhibit_dialog_init (GsmInhibitDialog *dialog)
932
GtkWidget *content_area;
936
dialog->priv = GSM_INHIBIT_DIALOG_GET_PRIVATE (dialog);
938
dialog->priv->xml = gtk_builder_new ();
939
gtk_builder_set_translation_domain (dialog->priv->xml, GETTEXT_PACKAGE);
942
if (!gtk_builder_add_from_file (dialog->priv->xml,
943
GTKBUILDER_DIR "/" GTKBUILDER_FILE,
946
g_warning ("Could not load inhibitor UI file: %s",
948
g_error_free (error);
950
g_warning ("Could not load inhibitor UI file.");
954
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
955
widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
957
gtk_container_add (GTK_CONTAINER (content_area), widget);
959
gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
960
gtk_window_set_icon_name (GTK_WINDOW (dialog), GSM_ICON_LOGOUT);
961
gtk_window_set_title (GTK_WINDOW (dialog), "");
962
g_object_set (dialog,
968
gsm_inhibit_dialog_new (GsmStore *inhibitors,
974
object = g_object_new (GSM_TYPE_INHIBIT_DIALOG,
976
"inhibitor-store", inhibitors,
977
"client-store", clients,
980
return GTK_WIDGET (object);