Bug Summary

File:cafe-session/csm-manager.c
Warning:line 920, column 9
Value stored to 'reply' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name csm-manager.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/cafe-session -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I ../egg -D LOCALE_DIR="/usr/local/share/locale" -D DATA_DIR="/usr/local/share/cafe-session" -D LIBEXECDIR="/usr/local/libexec" -D CTKBUILDER_DIR="/usr/local/share/cafe-session-manager" -D I_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/cafe-session -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2023-12-13-192751-18718-1 -x c csm-manager.c
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2007 Novell, Inc.
4 * Copyright (C) 2008 Red Hat, Inc.
5 * Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <fcntl.h>
28#include <unistd.h>
29#include <string.h>
30#include <signal.h>
31#include <sys/stat.h>
32#include <sys/types.h>
33
34#include <glib.h>
35#include <glib/gi18n.h>
36#include <glib/gstdio.h>
37#include <glib-object.h>
38#include <dbus/dbus-glib.h>
39#include <dbus/dbus-glib-lowlevel.h>
40
41#include <ctk/ctk.h> /* for logout dialog */
42#include <gio/gio.h> /* for gsettings */
43#include <cdk/cdkx.h>
44
45#include "csm-manager.h"
46#include "csm-manager-glue.h"
47
48#include "csm-store.h"
49#include "csm-inhibitor.h"
50#include "csm-presence.h"
51
52#include "csm-xsmp-client.h"
53#include "csm-dbus-client.h"
54
55#include "csm-autostart-app.h"
56
57#include "csm-util.h"
58#include "cdm.h"
59#include "csm-logout-dialog.h"
60#include "csm-inhibit-dialog.h"
61#include "csm-consolekit.h"
62#ifdef HAVE_SYSTEMD1
63#include "csm-systemd.h"
64#endif
65#include "csm-session-save.h"
66
67#define CSM_MANAGER_GET_PRIVATE(o)(((CsmManagerPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((csm_manager_get_type ())))) GCC warning "Deprecated pre-processor symbol: replace with \"G_ADD_PRIVATE\""
)
(G_TYPE_INSTANCE_GET_PRIVATE ((o), CSM_TYPE_MANAGER, CsmManagerPrivate)((CsmManagerPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((csm_manager_get_type ())))) GCC warning "Deprecated pre-processor symbol: replace with \"G_ADD_PRIVATE\""
)
68
69#define CSM_MANAGER_DBUS_PATH"/org/gnome/SessionManager" "/org/gnome/SessionManager"
70#define CSM_MANAGER_DBUS_NAME"org.gnome.SessionManager" "org.gnome.SessionManager"
71
72#define CSM_MANAGER_PHASE_TIMEOUT30 30 /* seconds */
73
74/* In the exit phase, all apps were already given the chance to inhibit the session end
75 * At that stage we don't want to wait much for apps to respond, we want to exit, and fast.
76 */
77#define CSM_MANAGER_EXIT_PHASE_TIMEOUT1 1 /* seconds */
78
79#define CDM_FLEXISERVER_COMMAND"cdmflexiserver" "cdmflexiserver"
80#define CDM_FLEXISERVER_ARGS"--startnew Standard" "--startnew Standard"
81
82#define GDM_FLEXISERVER_COMMAND"gdmflexiserver" "gdmflexiserver"
83#define GDM_FLEXISERVER_ARGS"--startnew Standard" "--startnew Standard"
84
85
86#define LOCKDOWN_SCHEMA"org.cafe.lockdown" "org.cafe.lockdown"
87#define KEY_LOCK_DISABLE"disable-lock-screen" "disable-lock-screen"
88#define KEY_LOG_OUT_DISABLE"disable-log-out" "disable-log-out"
89#define KEY_USER_SWITCH_DISABLE"disable-user-switching" "disable-user-switching"
90
91#define SESSION_SCHEMA"org.cafe.session" "org.cafe.session"
92#define KEY_IDLE_DELAY"idle-delay" "idle-delay"
93#define KEY_AUTOSAVE"auto-save-session" "auto-save-session"
94
95#define SCREENSAVER_SCHEMA"org.cafe.screensaver" "org.cafe.screensaver"
96#define KEY_SLEEP_LOCK"lock-enabled" "lock-enabled"
97
98#ifdef __GNUC__4
99#define UNUSED_VARIABLE__attribute__ ((unused)) __attribute__ ((unused))
100#else
101#define UNUSED_VARIABLE__attribute__ ((unused))
102#endif
103
104typedef enum
105{
106 CSM_MANAGER_LOGOUT_NONE,
107 CSM_MANAGER_LOGOUT_LOGOUT,
108 CSM_MANAGER_LOGOUT_REBOOT,
109 CSM_MANAGER_LOGOUT_REBOOT_INTERACT,
110 CSM_MANAGER_LOGOUT_REBOOT_CDM,
111 CSM_MANAGER_LOGOUT_SHUTDOWN,
112 CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT,
113 CSM_MANAGER_LOGOUT_SHUTDOWN_CDM
114} CsmManagerLogoutType;
115
116typedef struct {
117 gboolean failsafe;
118 CsmStore *clients;
119 CsmStore *inhibitors;
120 CsmStore *apps;
121 CsmPresence *presence;
122
123 /* Current status */
124 CsmManagerPhase phase;
125 guint phase_timeout_id;
126 GSList *pending_apps;
127 CsmManagerLogoutMode logout_mode;
128 GSList *query_clients;
129 guint query_timeout_id;
130 /* This is used for CSM_MANAGER_PHASE_END_SESSION only at the moment,
131 * since it uses a sublist of all running client that replied in a
132 * specific way */
133 GSList *next_query_clients;
134 /* This is the action that will be done just before we exit */
135 CsmManagerLogoutType logout_type;
136
137 CtkWidget *inhibit_dialog;
138
139 /* List of clients which were disconnected due to disabled condition
140 * and shouldn't be automatically restarted */
141 GSList *condition_clients;
142
143 GSettings *settings_session;
144 GSettings *settings_lockdown;
145 GSettings *settings_screensaver;
146
147 const char *renderer;
148
149 DBusGProxy *bus_proxy;
150 DBusGConnection *connection;
151 gboolean dbus_disconnected : 1;
152} CsmManagerPrivate;
153
154enum {
155 PROP_0,
156 PROP_CLIENT_STORE,
157 PROP_RENDERER,
158 PROP_FAILSAFE
159};
160
161enum {
162 PHASE_CHANGED,
163 CLIENT_ADDED,
164 CLIENT_REMOVED,
165 INHIBITOR_ADDED,
166 INHIBITOR_REMOVED,
167 SESSION_RUNNING,
168 SESSION_OVER,
169 LAST_SIGNAL
170};
171
172static guint signals [LAST_SIGNAL] = { 0 };
173
174static void csm_manager_finalize (GObject *object);
175
176static gboolean _log_out_is_locked_down (CsmManager *manager);
177static gboolean _switch_user_is_locked_down (CsmManager *manager);
178
179static void _handle_client_end_session_response (CsmManager *manager,
180 CsmClient *client,
181 gboolean is_ok,
182 gboolean do_last,
183 gboolean cancel,
184 const char *reason);
185
186static gboolean auto_save_is_enabled (CsmManager *manager);
187static void maybe_save_session (CsmManager *manager);
188
189static gpointer manager_object = NULL((void*)0);
190
191G_DEFINE_TYPE_WITH_PRIVATE (CsmManager, csm_manager, G_TYPE_OBJECT)static void csm_manager_init (CsmManager *self); static void csm_manager_class_init
(CsmManagerClass *klass); static GType csm_manager_get_type_once
(void); static gpointer csm_manager_parent_class = ((void*)0
); static gint CsmManager_private_offset; static void csm_manager_class_intern_init
(gpointer klass) { csm_manager_parent_class = g_type_class_peek_parent
(klass); if (CsmManager_private_offset != 0) g_type_class_adjust_private_offset
(klass, &CsmManager_private_offset); csm_manager_class_init
((CsmManagerClass*) klass); } __attribute__ ((__unused__)) static
inline gpointer csm_manager_get_instance_private (CsmManager
*self) { return (((gpointer) ((guint8*) (self) + (glong) (CsmManager_private_offset
)))); } GType csm_manager_get_type (void) { static gsize static_g_define_type_id
= 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); (void
) (0 ? (gpointer) *(&static_g_define_type_id) : ((void*)0
)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter (&static_g_define_type_id
)); }))) { GType g_define_type_id = csm_manager_get_type_once
(); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); 0 ?
(void) (*(&static_g_define_type_id) = (g_define_type_id)
) : (void) 0; g_once_init_leave ((&static_g_define_type_id
), (gsize) (g_define_type_id)); })); } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType csm_manager_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
(((GType) ((20) << (2))), g_intern_static_string ("CsmManager"
), sizeof (CsmManagerClass), (GClassInitFunc)(void (*)(void))
csm_manager_class_intern_init, sizeof (CsmManager), (GInstanceInitFunc
)(void (*)(void)) csm_manager_init, (GTypeFlags) 0); { {{ CsmManager_private_offset
= g_type_add_instance_private (g_define_type_id, sizeof (CsmManagerPrivate
)); };} } return g_define_type_id; }
192
193GQuark
194csm_manager_error_quark (void)
195{
196 static GQuark ret = 0;
197 if (ret == 0) {
198 ret = g_quark_from_static_string ("csm_manager_error");
199 }
200
201 return ret;
202}
203
204#define ENUM_ENTRY(NAME, DESC){ NAME, "" "NAME" "", DESC } { NAME, "" #NAME "", DESC }
205
206GType
207csm_manager_error_get_type (void)
208{
209 static GType etype = 0;
210
211 if (etype == 0) {
212 static const GEnumValue values[] = {
213 ENUM_ENTRY (CSM_MANAGER_ERROR_GENERAL, "GeneralError"){ CSM_MANAGER_ERROR_GENERAL, "" "CSM_MANAGER_ERROR_GENERAL" ""
, "GeneralError" }
,
214 ENUM_ENTRY (CSM_MANAGER_ERROR_NOT_IN_INITIALIZATION, "NotInInitialization"){ CSM_MANAGER_ERROR_NOT_IN_INITIALIZATION, "" "CSM_MANAGER_ERROR_NOT_IN_INITIALIZATION"
"", "NotInInitialization" }
,
215 ENUM_ENTRY (CSM_MANAGER_ERROR_NOT_IN_RUNNING, "NotInRunning"){ CSM_MANAGER_ERROR_NOT_IN_RUNNING, "" "CSM_MANAGER_ERROR_NOT_IN_RUNNING"
"", "NotInRunning" }
,
216 ENUM_ENTRY (CSM_MANAGER_ERROR_ALREADY_REGISTERED, "AlreadyRegistered"){ CSM_MANAGER_ERROR_ALREADY_REGISTERED, "" "CSM_MANAGER_ERROR_ALREADY_REGISTERED"
"", "AlreadyRegistered" }
,
217 ENUM_ENTRY (CSM_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"){ CSM_MANAGER_ERROR_NOT_REGISTERED, "" "CSM_MANAGER_ERROR_NOT_REGISTERED"
"", "NotRegistered" }
,
218 ENUM_ENTRY (CSM_MANAGER_ERROR_INVALID_OPTION, "InvalidOption"){ CSM_MANAGER_ERROR_INVALID_OPTION, "" "CSM_MANAGER_ERROR_INVALID_OPTION"
"", "InvalidOption" }
,
219 ENUM_ENTRY (CSM_MANAGER_ERROR_LOCKED_DOWN, "LockedDown"){ CSM_MANAGER_ERROR_LOCKED_DOWN, "" "CSM_MANAGER_ERROR_LOCKED_DOWN"
"", "LockedDown" }
,
220 { 0, 0, 0 }
221 };
222
223 g_assert (CSM_MANAGER_NUM_ERRORS == G_N_ELEMENTS (values) - 1)do { if (CSM_MANAGER_NUM_ERRORS == (sizeof (values) / sizeof (
(values)[0])) - 1) ; else g_assertion_message_expr (((gchar*)
0), "csm-manager.c", 223, ((const char*) (__func__)), "CSM_MANAGER_NUM_ERRORS == G_N_ELEMENTS (values) - 1"
); } while (0)
;
224
225 etype = g_enum_register_static ("CsmManagerError", values);
226 }
227
228 return etype;
229}
230
231static gboolean
232_debug_client (const char *id,
233 CsmClient *client,
234 CsmManager *manager)
235{
236 g_debug ("CsmManager: Client %s", csm_client_peek_id (client));
237 return FALSE(0);
238}
239
240static void
241debug_clients (CsmManager *manager)
242{
243 CsmManagerPrivate *priv;
244 priv = csm_manager_get_instance_private (manager);
245 csm_store_foreach (priv->clients,
246 (CsmStoreFunc)_debug_client,
247 manager);
248}
249
250static gboolean
251_debug_inhibitor (const char *id,
252 CsmInhibitor *inhibitor,
253 CsmManager *manager)
254{
255 g_debug ("CsmManager: Inhibitor app:%s client:%s bus-name:%s reason:%s",
256 csm_inhibitor_peek_app_id (inhibitor),
257 csm_inhibitor_peek_client_id (inhibitor),
258 csm_inhibitor_peek_bus_name (inhibitor),
259 csm_inhibitor_peek_reason (inhibitor));
260 return FALSE(0);
261}
262
263static void
264debug_inhibitors (CsmManager *manager)
265{
266 CsmManagerPrivate *priv;
267
268 priv = csm_manager_get_instance_private (manager);
269 csm_store_foreach (priv->inhibitors,
270 (CsmStoreFunc)_debug_inhibitor,
271 manager);
272}
273
274static gboolean
275_find_by_cookie (const char *id,
276 CsmInhibitor *inhibitor,
277 guint *cookie_ap)
278{
279 guint cookie_b;
280
281 cookie_b = csm_inhibitor_peek_cookie (inhibitor);
282
283 return (*cookie_ap == cookie_b);
284}
285
286static gboolean
287_find_by_startup_id (const char *id,
288 CsmClient *client,
289 const char *startup_id_a)
290{
291 const char *startup_id_b;
292
293 startup_id_b = csm_client_peek_startup_id (client);
294 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
295 return FALSE(0);
296 }
297
298 return (strcmp (startup_id_a, startup_id_b) == 0);
299}
300
301static void
302app_condition_changed (CsmApp *app,
303 gboolean condition,
304 CsmManager *manager)
305{
306 CsmClient *client;
307 CsmManagerPrivate *priv;
308
309 priv = csm_manager_get_instance_private (manager);
310
311 g_debug ("CsmManager: app:%s condition changed condition:%d",
312 csm_app_peek_id (app),
313 condition);
314
315 client = (CsmClient *)csm_store_find (priv->clients,
316 (CsmStoreFunc)_find_by_startup_id,
317 (char *)csm_app_peek_startup_id (app));
318
319 if (condition) {
320 if (!csm_app_is_running (app) && client == NULL((void*)0)) {
321 GError *error = NULL((void*)0);
322 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
323
324 g_debug ("CsmManager: starting app '%s'", csm_app_peek_id (app));
325
326 res = csm_app_start (app, &error);
327 if (error != NULL((void*)0)) {
328 g_warning ("Not able to start app from its condition: %s",
329 error->message);
330 g_error_free (error);
331 }
332 } else {
333 g_debug ("CsmManager: not starting - app still running '%s'", csm_app_peek_id (app));
334 }
335 } else {
336 GError *error;
337 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
338
339 if (client != NULL((void*)0)) {
340 /* Kill client in case condition if false and make sure it won't
341 * be automatically restarted by adding the client to
342 * condition_clients */
343 priv->condition_clients =
344 g_slist_prepend (priv->condition_clients, client);
345
346 g_debug ("CsmManager: stopping client %s for app", csm_client_peek_id (client));
347
348 error = NULL((void*)0);
349 res = csm_client_stop (client, &error);
350 if (error != NULL((void*)0)) {
351 g_warning ("Not able to stop app client from its condition: %s",
352 error->message);
353 g_error_free (error);
354 }
355 } else {
356 g_debug ("CsmManager: stopping app %s", csm_app_peek_id (app));
357
358 /* If we don't have a client then we should try to kill the app,
359 * if it is running */
360 error = NULL((void*)0);
361 if (csm_app_is_running (app)) {
362 res = csm_app_stop (app, &error);
363 if (error != NULL((void*)0)) {
364 g_warning ("Not able to stop app from its condition: %s",
365 error->message);
366 g_error_free (error);
367 }
368 }
369 }
370 }
371}
372
373static const char *
374phase_num_to_name (guint phase)
375{
376 const char *name;
377
378 switch (phase) {
379 case CSM_MANAGER_PHASE_STARTUP:
380 name = "STARTUP";
381 break;
382 case CSM_MANAGER_PHASE_INITIALIZATION:
383 name = "INITIALIZATION";
384 break;
385 case CSM_MANAGER_PHASE_WINDOW_MANAGER:
386 name = "WINDOW_MANAGER";
387 break;
388 case CSM_MANAGER_PHASE_PANEL:
389 name = "PANEL";
390 break;
391 case CSM_MANAGER_PHASE_DESKTOP:
392 name = "DESKTOP";
393 break;
394 case CSM_MANAGER_PHASE_APPLICATION:
395 name = "APPLICATION";
396 break;
397 case CSM_MANAGER_PHASE_RUNNING:
398 name = "RUNNING";
399 break;
400 case CSM_MANAGER_PHASE_QUERY_END_SESSION:
401 name = "QUERY_END_SESSION";
402 break;
403 case CSM_MANAGER_PHASE_END_SESSION:
404 name = "END_SESSION";
405 break;
406 case CSM_MANAGER_PHASE_EXIT:
407 name = "EXIT";
408 break;
409 default:
410 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
410, ((const char*) (__func__)), ((void*)0)); } while (0)
;
411 break;
412 }
413
414 return name;
415}
416
417static void start_phase (CsmManager *manager);
418
419static void
420quit_request_completed_consolekit (CsmConsolekit *consolekit,
421 GError *error,
422 gpointer user_data)
423{
424 CdmLogoutAction fallback_action = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data));
425
426 if (error != NULL((void*)0)) {
427 cdm_set_logout_action (fallback_action);
428 }
429
430 g_object_unref (consolekit);
431
432 ctk_main_quit ();
433}
434
435#ifdef HAVE_SYSTEMD1
436static void
437quit_request_completed_systemd (CsmSystemd *systemd,
438 GError *error,
439 gpointer user_data)
440{
441 CdmLogoutAction fallback_action = GPOINTER_TO_INT (user_data)((gint) (glong) (user_data));
442
443 if (error != NULL((void*)0)) {
444 cdm_set_logout_action (fallback_action);
445 }
446
447 g_object_unref (systemd);
448
449 ctk_main_quit ();
450}
451#endif
452
453static void
454csm_manager_quit (CsmManager *manager)
455{
456 CsmConsolekit *consolekit;
457 CsmManagerPrivate *priv;
458#ifdef HAVE_SYSTEMD1
459 CsmSystemd *systemd;
460#endif
461
462 priv = csm_manager_get_instance_private (manager);
463 /* See the comment in request_reboot() for some more details about how
464 * this works. */
465
466 switch (priv->logout_type) {
467 case CSM_MANAGER_LOGOUT_LOGOUT:
468 ctk_main_quit ();
469 break;
470 case CSM_MANAGER_LOGOUT_REBOOT:
471 case CSM_MANAGER_LOGOUT_REBOOT_INTERACT:
472 cdm_set_logout_action (CDM_LOGOUT_ACTION_NONE);
473
474#ifdef HAVE_SYSTEMD1
475 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
476 systemd = csm_get_systemd ();
477 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
478 "request-completed",g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
479 G_CALLBACK (quit_request_completed_systemd),g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
480 GINT_TO_POINTER (CDM_LOGOUT_ACTION_REBOOT))g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_REBOOT
))), ((void*)0), (GConnectFlags) 0)
;
481 csm_systemd_attempt_restart (systemd);
482 }
483 else {
484#endif
485 consolekit = csm_get_consolekit ();
486 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
487 "request-completed",g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
488 G_CALLBACK (quit_request_completed_consolekit),g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
489 GINT_TO_POINTER (CDM_LOGOUT_ACTION_REBOOT))g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_REBOOT))), ((void*)0), (GConnectFlags
) 0)
;
490 csm_consolekit_attempt_restart (consolekit);
491#ifdef HAVE_SYSTEMD1
492 }
493#endif
494 break;
495 case CSM_MANAGER_LOGOUT_REBOOT_CDM:
496 cdm_set_logout_action (CDM_LOGOUT_ACTION_REBOOT);
497 ctk_main_quit ();
498 break;
499 case CSM_MANAGER_LOGOUT_SHUTDOWN:
500 case CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
501 cdm_set_logout_action (CDM_LOGOUT_ACTION_NONE);
502
503#ifdef HAVE_SYSTEMD1
504 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
505 systemd = csm_get_systemd ();
506 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
507 "request-completed",g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
508 G_CALLBACK (quit_request_completed_systemd),g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
509 GINT_TO_POINTER (CDM_LOGOUT_ACTION_SHUTDOWN))g_signal_connect_data ((systemd), ("request-completed"), (((GCallback
) (quit_request_completed_systemd))), (((gpointer) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN
))), ((void*)0), (GConnectFlags) 0)
;
510 csm_systemd_attempt_stop (systemd);
511 }
512 else {
513#endif
514 consolekit = csm_get_consolekit ();
515 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
516 "request-completed",g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
517 G_CALLBACK (quit_request_completed_consolekit),g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
518 GINT_TO_POINTER (CDM_LOGOUT_ACTION_SHUTDOWN))g_signal_connect_data ((consolekit), ("request-completed"), (
((GCallback) (quit_request_completed_consolekit))), (((gpointer
) (glong) (CDM_LOGOUT_ACTION_SHUTDOWN))), ((void*)0), (GConnectFlags
) 0)
;
519 csm_consolekit_attempt_stop (consolekit);
520#ifdef HAVE_SYSTEMD1
521 }
522#endif
523 break;
524 case CSM_MANAGER_LOGOUT_SHUTDOWN_CDM:
525 cdm_set_logout_action (CDM_LOGOUT_ACTION_SHUTDOWN);
526 ctk_main_quit ();
527 break;
528 default:
529 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
529, ((const char*) (__func__)), ((void*)0)); } while (0)
;
530 break;
531 }
532}
533
534static void
535end_phase (CsmManager *manager)
536{
537 CsmManagerPrivate *priv;
538 gboolean start_next_phase = TRUE(!(0));
539
540 priv = csm_manager_get_instance_private (manager);
541
542 g_debug ("CsmManager: ending phase %s\n",
543 phase_num_to_name (priv->phase));
544
545 g_slist_free (priv->pending_apps);
546 priv->pending_apps = NULL((void*)0);
547
548 g_slist_free (priv->query_clients);
549 priv->query_clients = NULL((void*)0);
550
551 g_slist_free (priv->next_query_clients);
552 priv->next_query_clients = NULL((void*)0);
553
554 if (priv->phase_timeout_id > 0) {
555 g_source_remove (priv->phase_timeout_id);
556 priv->phase_timeout_id = 0;
557 }
558
559 switch (priv->phase) {
560 case CSM_MANAGER_PHASE_STARTUP:
561 case CSM_MANAGER_PHASE_INITIALIZATION:
562 case CSM_MANAGER_PHASE_WINDOW_MANAGER:
563 case CSM_MANAGER_PHASE_PANEL:
564 case CSM_MANAGER_PHASE_DESKTOP:
565 case CSM_MANAGER_PHASE_APPLICATION:
566 break;
567 case CSM_MANAGER_PHASE_RUNNING:
568 if (_log_out_is_locked_down (manager)) {
569 g_warning ("Unable to logout: Logout has been locked down");
570 start_next_phase = FALSE(0);
571 }
572 break;
573 case CSM_MANAGER_PHASE_QUERY_END_SESSION:
574 break;
575 case CSM_MANAGER_PHASE_END_SESSION:
576 if (auto_save_is_enabled (manager))
577 maybe_save_session (manager);
578 break;
579 case CSM_MANAGER_PHASE_EXIT:
580 start_next_phase = FALSE(0);
581 csm_manager_quit (manager);
582 break;
583 default:
584 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
584, ((const char*) (__func__)), ((void*)0)); } while (0)
;
585 break;
586 }
587
588 if (start_next_phase) {
589 priv->phase++;
590 start_phase (manager);
591 }
592}
593
594static void
595app_registered (CsmApp *app,
596 CsmManager *manager)
597{
598 CsmManagerPrivate *priv;
599
600 priv = csm_manager_get_instance_private (manager);
601 priv->pending_apps = g_slist_remove (priv->pending_apps, app);
602 g_signal_handlers_disconnect_by_func (app, app_registered, manager)g_signal_handlers_disconnect_matched ((app), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (app_registered), (manager))
;
603
604 if (priv->pending_apps == NULL((void*)0)) {
605 if (priv->phase_timeout_id > 0) {
606 g_source_remove (priv->phase_timeout_id);
607 priv->phase_timeout_id = 0;
608 }
609
610 end_phase (manager);
611 }
612}
613
614static gboolean
615on_phase_timeout (CsmManager *manager)
616{
617 GSList *a;
618 CsmManagerPrivate *priv;
619
620 priv = csm_manager_get_instance_private (manager);
621 priv->phase_timeout_id = 0;
622
623 switch (priv->phase) {
624 case CSM_MANAGER_PHASE_STARTUP:
625 case CSM_MANAGER_PHASE_INITIALIZATION:
626 case CSM_MANAGER_PHASE_WINDOW_MANAGER:
627 case CSM_MANAGER_PHASE_PANEL:
628 case CSM_MANAGER_PHASE_DESKTOP:
629 case CSM_MANAGER_PHASE_APPLICATION:
630 for (a = priv->pending_apps; a; a = a->next) {
631 g_warning ("Application '%s' failed to register before timeout",
632 csm_app_peek_app_id (a->data));
633 g_signal_handlers_disconnect_by_func (a->data, app_registered, manager)g_signal_handlers_disconnect_matched ((a->data), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (app_registered), (manager))
;
634 /* FIXME: what if the app was filling in a required slot? */
635 }
636 break;
637 case CSM_MANAGER_PHASE_RUNNING:
638 break;
639 case CSM_MANAGER_PHASE_QUERY_END_SESSION:
640 case CSM_MANAGER_PHASE_END_SESSION:
641 break;
642 case CSM_MANAGER_PHASE_EXIT:
643 break;
644 default:
645 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
645, ((const char*) (__func__)), ((void*)0)); } while (0)
;
646 break;
647 }
648
649 end_phase (manager);
650
651 return FALSE(0);
652}
653
654static gboolean
655_autostart_delay_timeout (CsmApp *app)
656{
657 GError *error = NULL((void*)0);
658 gboolean res;
659
660 if (!csm_app_peek_is_disabled (app)
661 && !csm_app_peek_is_conditionally_disabled (app)) {
662 res = csm_app_start (app, &error);
663 if (!res) {
664 if (error != NULL((void*)0)) {
665 g_warning ("Could not launch application '%s': %s",
666 csm_app_peek_app_id (app),
667 error->message);
668 g_error_free (error);
669 }
670 }
671 }
672
673 g_object_unref (app);
674
675 return FALSE(0);
676}
677
678static gboolean
679_start_app (const char *id,
680 CsmApp *app,
681 CsmManager *manager)
682{
683 GError *error;
684 gboolean res;
685 int delay;
686 CsmManagerPrivate *priv;
687
688 priv = csm_manager_get_instance_private (manager);
689
690 if (csm_app_peek_phase (app) != priv->phase) {
691 goto out;
692 }
693
694 /* Keep track of app autostart condition in order to react
695 * accordingly in the future. */
696 g_signal_connect (app,g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
697 "condition-changed",g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
698 G_CALLBACK (app_condition_changed),g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
699 manager)g_signal_connect_data ((app), ("condition-changed"), (((GCallback
) (app_condition_changed))), (manager), ((void*)0), (GConnectFlags
) 0)
;
700
701 if (csm_app_peek_is_disabled (app)
702 || csm_app_peek_is_conditionally_disabled (app)) {
703 g_debug ("CsmManager: Skipping disabled app: %s", id);
704 goto out;
705 }
706
707 delay = csm_app_peek_autostart_delay (app);
708 if (delay > 0) {
709 g_timeout_add_seconds (delay,
710 (GSourceFunc)_autostart_delay_timeout,
711 g_object_ref (app)((__typeof__ (app)) (g_object_ref) (app)));
712 g_debug ("CsmManager: %s is scheduled to start in %d seconds", id, delay);
713 goto out;
714 }
715
716 error = NULL((void*)0);
717 res = csm_app_start (app, &error);
718 if (!res) {
719 if (error != NULL((void*)0)) {
720 g_warning ("Could not launch application '%s': %s",
721 csm_app_peek_app_id (app),
722 error->message);
723 g_error_free (error);
724 error = NULL((void*)0);
725 }
726 goto out;
727 }
728
729 if (priv->phase < CSM_MANAGER_PHASE_APPLICATION) {
730 g_signal_connect (app,g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
731 "exited",g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
732 G_CALLBACK (app_registered),g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
733 manager)g_signal_connect_data ((app), ("exited"), (((GCallback) (app_registered
))), (manager), ((void*)0), (GConnectFlags) 0)
;
734 g_signal_connect (app,g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
735 "registered",g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
736 G_CALLBACK (app_registered),g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
737 manager)g_signal_connect_data ((app), ("registered"), (((GCallback) (
app_registered))), (manager), ((void*)0), (GConnectFlags) 0)
;
738 priv->pending_apps = g_slist_prepend (priv->pending_apps, app);
739 }
740 out:
741 return FALSE(0);
742}
743
744static void
745do_phase_startup (CsmManager *manager)
746{
747 CsmManagerPrivate *priv;
748
749 priv = csm_manager_get_instance_private (manager);
750 csm_store_foreach (priv->apps,
751 (CsmStoreFunc)_start_app,
752 manager);
753
754 if (priv->pending_apps != NULL((void*)0)) {
755 if (priv->phase < CSM_MANAGER_PHASE_APPLICATION) {
756 priv->phase_timeout_id = g_timeout_add_seconds (CSM_MANAGER_PHASE_TIMEOUT30,
757 (GSourceFunc)on_phase_timeout,
758 manager);
759 }
760 } else {
761 end_phase (manager);
762 }
763}
764
765typedef struct {
766 CsmManager *manager;
767 guint flags;
768} ClientEndSessionData;
769
770
771static gboolean
772_client_end_session (CsmClient *client,
773 ClientEndSessionData *data)
774{
775 gboolean ret;
776 GError *error;
777 CsmManagerPrivate *priv;
778
779 priv = csm_manager_get_instance_private (data->manager);
780
781 error = NULL((void*)0);
782 ret = csm_client_end_session (client, data->flags, &error);
783 if (! ret) {
784 g_warning ("Unable to query client: %s", error->message);
785 g_error_free (error);
786 /* FIXME: what should we do if we can't communicate with client? */
787 } else {
788 g_debug ("CsmManager: adding client to end-session clients: %s", csm_client_peek_id (client));
789 priv->query_clients = g_slist_prepend (priv->query_clients,
790 client);
791 }
792
793 return FALSE(0);
794}
795
796static gboolean
797_client_end_session_helper (const char *id,
798 CsmClient *client,
799 ClientEndSessionData *data)
800{
801 return _client_end_session (client, data);
802}
803
804static void
805do_phase_end_session (CsmManager *manager)
806{
807 ClientEndSessionData data;
808 CsmManagerPrivate *priv;
809
810 data.manager = manager;
811 data.flags = 0;
812 priv = csm_manager_get_instance_private (manager);
813
814 if (priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_FORCE) {
815 data.flags |= CSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
816 }
817 if (auto_save_is_enabled (manager)) {
818 data.flags |= CSM_CLIENT_END_SESSION_FLAG_SAVE;
819 }
820
821 if (priv->phase_timeout_id > 0) {
822 g_source_remove (priv->phase_timeout_id);
823 priv->phase_timeout_id = 0;
824 }
825
826 if (csm_store_size (priv->clients) > 0) {
827 priv->phase_timeout_id = g_timeout_add_seconds (CSM_MANAGER_PHASE_TIMEOUT30,
828 (GSourceFunc)on_phase_timeout,
829 manager);
830
831 csm_store_foreach (priv->clients,
832 (CsmStoreFunc)_client_end_session_helper,
833 &data);
834 } else {
835 end_phase (manager);
836 }
837}
838
839static void
840do_phase_end_session_part_2 (CsmManager *manager)
841{
842 ClientEndSessionData data;
843 CsmManagerPrivate *priv;
844
845 data.manager = manager;
846 data.flags = 0;
847 priv = csm_manager_get_instance_private (manager);
848
849 if (priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_FORCE) {
850 data.flags |= CSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
851 }
852 if (auto_save_is_enabled (manager)) {
853 data.flags |= CSM_CLIENT_END_SESSION_FLAG_SAVE;
854 }
855 data.flags |= CSM_CLIENT_END_SESSION_FLAG_LAST;
856
857 /* keep the timeout that was started at the beginning of the
858 * CSM_MANAGER_PHASE_END_SESSION phase */
859
860 if (g_slist_length (priv->next_query_clients) > 0) {
861 g_slist_foreach (priv->next_query_clients,
862 (GFunc)_client_end_session,
863 &data);
864
865 g_slist_free (priv->next_query_clients);
866 priv->next_query_clients = NULL((void*)0);
867 } else {
868 end_phase (manager);
869 }
870}
871
872static gboolean
873_client_stop (const char *id,
874 CsmClient *client,
875 gpointer user_data)
876{
877 gboolean ret;
878 GError *error;
879
880 error = NULL((void*)0);
881 ret = csm_client_stop (client, &error);
882 if (! ret) {
883 g_warning ("Unable to stop client: %s", error->message);
884 g_error_free (error);
885 /* FIXME: what should we do if we can't communicate with client? */
886 } else {
887 g_debug ("CsmManager: stopped client: %s", csm_client_peek_id (client));
888 }
889
890 return FALSE(0);
891}
892
893#ifdef HAVE_SYSTEMD1
894static void
895maybe_restart_user_bus (CsmManager *manager)
896{
897 CsmSystemd *systemd;
898 CsmManagerPrivate *priv;
899 GDBusConnection *connection;
900
901 g_autoptr(GVariant)__attribute__((cleanup(glib_autoptr_cleanup_GVariant))) GVariant_autoptr reply = NULL((void*)0);
902 g_autoptr(GError)__attribute__((cleanup(glib_autoptr_cleanup_GError))) GError_autoptr error = NULL((void*)0);
903
904 priv = csm_manager_get_instance_private (manager);
905 if (priv->dbus_disconnected)
906 return;
907
908 systemd = csm_get_systemd ();
909
910 if (!csm_systemd_is_last_session_for_user (systemd))
911 return;
912
913 connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL((void*)0), &error);
914
915 if (error != NULL((void*)0)) {
916 g_debug ("CsmManager: failed to connect to session bus: %s", error->message);
917 return;
918 }
919
920 reply = g_dbus_connection_call_sync (connection,
Value stored to 'reply' is never read
921 "org.freedesktop.systemd1",
922 "/org/freedesktop/systemd1",
923 "org.freedesktop.systemd1.Manager",
924 "TryRestartUnit",
925 g_variant_new ("(ss)", "dbus.service", "replace"),
926 NULL((void*)0),
927 G_DBUS_CALL_FLAGS_NONE,
928 -1,
929 NULL((void*)0),
930 &error);
931
932 if (error != NULL((void*)0)) {
933 g_debug ("CsmManager: reloading user bus failed: %s", error->message);
934 }
935}
936#endif
937
938static void
939do_phase_exit (CsmManager *manager)
940{
941 CsmManagerPrivate *priv;
942
943 priv = csm_manager_get_instance_private (manager);
944 if (csm_store_size (priv->clients) > 0) {
945 csm_store_foreach (priv->clients,
946 (CsmStoreFunc)_client_stop,
947 NULL((void*)0));
948 }
949
950#ifdef HAVE_SYSTEMD1
951 maybe_restart_user_bus (manager);
952#endif
953
954 end_phase (manager);
955}
956
957static gboolean
958_client_query_end_session (const char *id,
959 CsmClient *client,
960 ClientEndSessionData *data)
961{
962 gboolean ret;
963 GError *error;
964 CsmManagerPrivate *priv;
965
966 priv = csm_manager_get_instance_private (data->manager);
967
968 error = NULL((void*)0);
969 ret = csm_client_query_end_session (client, data->flags, &error);
970 if (! ret) {
971 g_warning ("Unable to query client: %s", error->message);
972 g_error_free (error);
973 /* FIXME: what should we do if we can't communicate with client? */
974 } else {
975 g_debug ("CsmManager: adding client to query clients: %s", csm_client_peek_id (client));
976 priv->query_clients = g_slist_prepend (priv->query_clients, client);
977 }
978
979 return FALSE(0);
980}
981
982static gboolean
983inhibitor_has_flag (gpointer key,
984 CsmInhibitor *inhibitor,
985 gpointer data)
986{
987 guint flag;
988 guint flags;
989
990 flag = GPOINTER_TO_UINT (data)((guint) (gulong) (data));
991
992 flags = csm_inhibitor_peek_flags (inhibitor);
993
994 return (flags & flag);
995}
996
997static gboolean
998csm_manager_is_logout_inhibited (CsmManager *manager)
999{
1000 CsmInhibitor *inhibitor;
1001 CsmManagerPrivate *priv;
1002
1003 priv = csm_manager_get_instance_private (manager);
1004
1005 if (priv->inhibitors == NULL((void*)0)) {
1006 return FALSE(0);
1007 }
1008
1009 inhibitor = (CsmInhibitor *)csm_store_find (priv->inhibitors,
1010 (CsmStoreFunc)inhibitor_has_flag,
1011 GUINT_TO_POINTER (CSM_INHIBITOR_FLAG_LOGOUT)((gpointer) (gulong) (CSM_INHIBITOR_FLAG_LOGOUT)));
1012 if (inhibitor == NULL((void*)0)) {
1013 return FALSE(0);
1014 }
1015 return TRUE(!(0));
1016}
1017
1018static gboolean
1019csm_manager_is_idle_inhibited (CsmManager *manager)
1020{
1021 CsmInhibitor *inhibitor;
1022 CsmManagerPrivate *priv;
1023
1024 priv = csm_manager_get_instance_private (manager);
1025
1026 if (priv->inhibitors == NULL((void*)0)) {
1027 return FALSE(0);
1028 }
1029
1030 inhibitor = (CsmInhibitor *)csm_store_find (priv->inhibitors,
1031 (CsmStoreFunc)inhibitor_has_flag,
1032 GUINT_TO_POINTER (CSM_INHIBITOR_FLAG_IDLE)((gpointer) (gulong) (CSM_INHIBITOR_FLAG_IDLE)));
1033 if (inhibitor == NULL((void*)0)) {
1034 return FALSE(0);
1035 }
1036 return TRUE(!(0));
1037}
1038
1039static gboolean
1040_client_cancel_end_session (const char *id,
1041 CsmClient *client,
1042 CsmManager *manager)
1043{
1044 gboolean res;
1045 GError *error;
1046
1047 error = NULL((void*)0);
1048 res = csm_client_cancel_end_session (client, &error);
1049 if (! res) {
1050 g_warning ("Unable to cancel end session: %s", error->message);
1051 g_error_free (error);
1052 }
1053
1054 return FALSE(0);
1055}
1056
1057static gboolean
1058inhibitor_is_jit (gpointer key,
1059 CsmInhibitor *inhibitor,
1060 CsmManager *manager)
1061{
1062 gboolean matches;
1063 const char *id;
1064
1065 id = csm_inhibitor_peek_client_id (inhibitor);
1066
1067 matches = (id != NULL((void*)0) && id[0] != '\0');
1068
1069 return matches;
1070}
1071
1072static void
1073cancel_end_session (CsmManager *manager)
1074{
1075 CsmManagerPrivate *priv;
1076
1077 priv = csm_manager_get_instance_private (manager);
1078 /* just ignore if received outside of shutdown */
1079 if (priv->phase < CSM_MANAGER_PHASE_QUERY_END_SESSION) {
1080 return;
1081 }
1082
1083 /* switch back to running phase */
1084 g_debug ("CsmManager: Cancelling the end of session");
1085
1086 /* remove the dialog before we remove the inhibitors, else the dialog
1087 * will activate itself automatically when the last inhibitor will be
1088 * removed */
1089 if (priv->inhibit_dialog)
1090 ctk_widget_destroy (CTK_WIDGET (priv->inhibit_dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((ctk_widget_get_type ())))))
)
);
1091 priv->inhibit_dialog = NULL((void*)0);
1092
1093 /* clear all JIT inhibitors */
1094 csm_store_foreach_remove (priv->inhibitors,
1095 (CsmStoreFunc)inhibitor_is_jit,
1096 (gpointer)manager);
1097
1098 csm_store_foreach (priv->clients,
1099 (CsmStoreFunc)_client_cancel_end_session,
1100 NULL((void*)0));
1101
1102 csm_manager_set_phase (manager, CSM_MANAGER_PHASE_RUNNING);
1103 priv->logout_mode = CSM_MANAGER_LOGOUT_MODE_NORMAL;
1104
1105 priv->logout_type = CSM_MANAGER_LOGOUT_NONE;
1106 cdm_set_logout_action (CDM_LOGOUT_ACTION_NONE);
1107
1108 start_phase (manager);
1109}
1110
1111static gboolean
1112process_is_running (const char * name)
1113{
1114 int num_processes;
1115 char * command = g_strdup_printf ("pidof %s | wc -l", name);
1116 FILE *fp = popen(command, "r");
1117
1118 if (fscanf(fp, "%d", &num_processes) != 1)
1119 num_processes = 0;
1120
1121 pclose(fp);
1122 g_free (command);
1123
1124 if (num_processes > 0) {
1125 return TRUE(!(0));
1126 }
1127 else {
1128 return FALSE(0);
1129 }
1130}
1131
1132static void
1133manager_switch_user (CsmManager *manager)
1134{
1135 GError *error;
1136 gboolean res;
1137 char *command;
1138 const gchar *xdg_seat_path = g_getenv ("XDG_SEAT_PATH");
1139
1140 /* We have to do this here and in request_switch_user() because this
1141 * function can be called at a later time, not just directly after
1142 * request_switch_user(). */
1143 if (_switch_user_is_locked_down (manager)) {
1144 g_warning ("Unable to switch user: User switching has been locked down");
1145 return;
1146 }
1147
1148 if (process_is_running("cdm")) {
1149 /* CDM */
1150 command = g_strdup_printf ("%s %s",
1151 CDM_FLEXISERVER_COMMAND"cdmflexiserver",
1152 CDM_FLEXISERVER_ARGS"--startnew Standard");
1153
1154 error = NULL((void*)0);
1155 res = g_spawn_command_line_sync (command, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1156
1157 g_free (command);
1158
1159 if (! res) {
1160 g_debug ("CsmManager: Unable to start CDM greeter: %s", error->message);
1161 g_error_free (error);
1162 }
1163 }
1164 else if (process_is_running("gdm") || process_is_running("gdm3") || process_is_running("gdm-binary")) {
1165 /* GDM */
1166 command = g_strdup_printf ("%s %s",
1167 GDM_FLEXISERVER_COMMAND"gdmflexiserver",
1168 GDM_FLEXISERVER_ARGS"--startnew Standard");
1169
1170 error = NULL((void*)0);
1171 res = g_spawn_command_line_sync (command, NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1172
1173 g_free (command);
1174
1175 if (! res) {
1176 g_debug ("CsmManager: Unable to start GDM greeter: %s", error->message);
1177 g_error_free (error);
1178 }
1179 }
1180 else if (xdg_seat_path != NULL((void*)0)) {
1181 /* LightDM */
1182 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
1183 GDBusProxy *proxy = NULL((void*)0);
1184 error = NULL((void*)0);
1185
1186 proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
1187 flags,
1188 NULL((void*)0),
1189 "org.freedesktop.DisplayManager",
1190 xdg_seat_path,
1191 "org.freedesktop.DisplayManager.Seat",
1192 NULL((void*)0),
1193 &error);
1194 if (proxy != NULL((void*)0)) {
1195 g_dbus_proxy_call_sync (proxy,
1196 "SwitchToGreeter",
1197 g_variant_new ("()"),
1198 G_DBUS_CALL_FLAGS_NONE,
1199 -1,
1200 NULL((void*)0),
1201 NULL((void*)0));
1202 g_object_unref (proxy);
1203 }
1204 else {
1205 g_debug ("CsmManager: Unable to start LightDM greeter: %s", error->message);
1206 g_error_free (error);
1207 }
1208 }
1209}
1210
1211static gboolean
1212sleep_lock_is_enabled (CsmManager *manager)
1213{
1214 CsmManagerPrivate *priv;
1215
1216 priv = csm_manager_get_instance_private (manager);
1217 if (priv->settings_screensaver != NULL((void*)0))
1218 return g_settings_get_boolean (priv->settings_screensaver,
1219 KEY_SLEEP_LOCK"lock-enabled");
1220 else
1221 return FALSE(0);
1222}
1223
1224static void
1225manager_perhaps_lock (CsmManager *manager)
1226{
1227 GError *error;
1228 gboolean ret;
1229
1230 /* only lock if cafe-screensaver is set to lock */
1231 if (!sleep_lock_is_enabled (manager)) {
1232 return;
1233 }
1234
1235 /* do this sync to ensure it's on the screen when we start suspending */
1236 error = NULL((void*)0);
1237 ret = g_spawn_command_line_sync ("cafe-screensaver-command --lock", NULL((void*)0), NULL((void*)0), NULL((void*)0), &error);
1238 if (!ret) {
1239 g_warning ("Couldn't lock screen: %s", error->message);
1240 g_error_free (error);
1241 }
1242}
1243
1244static void
1245manager_attempt_hibernate (CsmManager *manager)
1246{
1247#ifdef HAVE_SYSTEMD1
1248 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
1249
1250 CsmSystemd *systemd;
1251
1252 systemd = csm_get_systemd ();
1253
1254 /* lock the screen before we suspend */
1255 manager_perhaps_lock (manager);
1256
1257 csm_systemd_attempt_hibernate (systemd);
1258 }
1259 else {
1260#endif
1261 CsmConsolekit *consolekit;
1262 consolekit = csm_get_consolekit ();
1263
1264 gboolean can_hibernate = csm_consolekit_can_hibernate (consolekit);
1265 if (can_hibernate) {
1266 /* lock the screen before we suspend */
1267 manager_perhaps_lock (manager);
1268
1269 csm_consolekit_attempt_hibernate (consolekit);
1270 }
1271#ifdef HAVE_SYSTEMD1
1272 }
1273#endif
1274}
1275
1276static void
1277manager_attempt_suspend (CsmManager *manager)
1278{
1279#ifdef HAVE_SYSTEMD1
1280 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
1281
1282 CsmSystemd *systemd;
1283
1284 systemd = csm_get_systemd ();
1285
1286 /* lock the screen before we suspend */
1287 manager_perhaps_lock (manager);
1288
1289 csm_systemd_attempt_suspend (systemd);
1290 }
1291 else {
1292#endif
1293 CsmConsolekit *consolekit;
1294 consolekit = csm_get_consolekit ();
1295
1296 gboolean can_suspend = csm_consolekit_can_suspend (consolekit);
1297 if (can_suspend) {
1298 /* lock the screen before we suspend */
1299 manager_perhaps_lock (manager);
1300
1301 csm_consolekit_attempt_suspend (consolekit);
1302 }
1303#ifdef HAVE_SYSTEMD1
1304 }
1305#endif
1306}
1307
1308static void
1309do_inhibit_dialog_action (CsmManager *manager,
1310 int action)
1311{
1312 CsmManagerPrivate *priv;
1313
1314 priv = csm_manager_get_instance_private (manager);
1315 switch (action) {
1316 case CSM_LOGOUT_ACTION_SWITCH_USER:
1317 manager_switch_user (manager);
1318 break;
1319 case CSM_LOGOUT_ACTION_HIBERNATE:
1320 manager_attempt_hibernate (manager);
1321 break;
1322 case CSM_LOGOUT_ACTION_SLEEP:
1323 manager_attempt_suspend (manager);
1324 break;
1325 case CSM_LOGOUT_ACTION_SHUTDOWN:
1326 case CSM_LOGOUT_ACTION_REBOOT:
1327 case CSM_LOGOUT_ACTION_LOGOUT:
1328 priv->logout_mode = CSM_MANAGER_LOGOUT_MODE_FORCE;
1329 end_phase (manager);
1330 break;
1331 default:
1332 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
1332, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1333 break;
1334 }
1335}
1336
1337static void
1338inhibit_dialog_response (CsmInhibitDialog *dialog,
1339 guint response_id,
1340 CsmManager *manager)
1341{
1342 int action;
1343 CsmManagerPrivate *priv;
1344
1345 g_debug ("CsmManager: Inhibit dialog response: %d", response_id);
1346
1347 priv = csm_manager_get_instance_private (manager);
1348 /* must destroy dialog before cancelling since we'll
1349 remove JIT inhibitors and we don't want to trigger
1350 action. */
1351 g_object_get (dialog, "action", &action, NULL((void*)0));
1352 ctk_widget_destroy (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
);
1353 priv->inhibit_dialog = NULL((void*)0);
1354
1355 /* In case of dialog cancel, switch user, hibernate and
1356 * suspend, we just perform the respective action and return,
1357 * without shutting down the session. */
1358 switch (response_id) {
1359 case CTK_RESPONSE_CANCEL:
1360 case CTK_RESPONSE_NONE:
1361 case CTK_RESPONSE_DELETE_EVENT:
1362 if (action == CSM_LOGOUT_ACTION_LOGOUT
1363 || action == CSM_LOGOUT_ACTION_SHUTDOWN
1364 || action == CSM_LOGOUT_ACTION_REBOOT) {
1365 cancel_end_session (manager);
1366 }
1367 break;
1368 case CTK_RESPONSE_ACCEPT:
1369 g_debug ("CsmManager: doing action %d", action);
1370 do_inhibit_dialog_action (manager, action);
1371 break;
1372 default:
1373 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
1373, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1374 break;
1375 }
1376}
1377
1378static void
1379query_end_session_complete (CsmManager *manager)
1380{
1381 CsmLogoutAction action;
1382 CsmManagerPrivate *priv;
1383
1384 priv = csm_manager_get_instance_private (manager);
1385
1386 g_debug ("CsmManager: query end session complete");
1387
1388 /* Remove the timeout since this can be called from outside the timer
1389 * and we don't want to have it called twice */
1390 if (priv->query_timeout_id > 0) {
1391 g_source_remove (priv->query_timeout_id);
1392 priv->query_timeout_id = 0;
1393 }
1394
1395 if (! csm_manager_is_logout_inhibited (manager)) {
1396 end_phase (manager);
1397 return;
1398 }
1399
1400 if (priv->inhibit_dialog != NULL((void*)0)) {
1401 g_debug ("CsmManager: inhibit dialog already up");
1402 ctk_window_present (CTK_WINDOW (priv->inhibit_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((ctk_window_get_type ())))))
)
);
1403 return;
1404 }
1405
1406 switch (priv->logout_type) {
1407 case CSM_MANAGER_LOGOUT_LOGOUT:
1408 action = CSM_LOGOUT_ACTION_LOGOUT;
1409 break;
1410 case CSM_MANAGER_LOGOUT_REBOOT:
1411 case CSM_MANAGER_LOGOUT_REBOOT_INTERACT:
1412 case CSM_MANAGER_LOGOUT_REBOOT_CDM:
1413 action = CSM_LOGOUT_ACTION_REBOOT;
1414 break;
1415 case CSM_MANAGER_LOGOUT_SHUTDOWN:
1416 case CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
1417 case CSM_MANAGER_LOGOUT_SHUTDOWN_CDM:
1418 action = CSM_LOGOUT_ACTION_SHUTDOWN;
1419 break;
1420 default:
1421 g_warning ("Unexpected logout type %d when creating inhibit dialog",
1422 priv->logout_type);
1423 action = CSM_LOGOUT_ACTION_LOGOUT;
1424 break;
1425 }
1426
1427 /* Note: CSM_LOGOUT_ACTION_SHUTDOWN and CSM_LOGOUT_ACTION_REBOOT are
1428 * actually handled the same way as CSM_LOGOUT_ACTION_LOGOUT in the
1429 * inhibit dialog; the action, if the button is clicked, will be to
1430 * simply go to the next phase. */
1431 priv->inhibit_dialog = csm_inhibit_dialog_new (priv->inhibitors,
1432 priv->clients,
1433 action);
1434
1435 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1436 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1437 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
1438 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
1439 ctk_widget_show (priv->inhibit_dialog);
1440
1441}
1442
1443static guint32
1444generate_cookie (void)
1445{
1446 guint32 cookie;
1447
1448 cookie = (guint32)g_random_int_range (1, G_MAXINT32((gint32) 0x7fffffff));
1449
1450 return cookie;
1451}
1452
1453static guint32
1454_generate_unique_cookie (CsmManager *manager)
1455{
1456 guint32 cookie;
1457 CsmManagerPrivate *priv;
1458
1459 priv = csm_manager_get_instance_private (manager);
1460
1461 do {
1462 cookie = generate_cookie ();
1463 } while (csm_store_find (priv->inhibitors, (CsmStoreFunc)_find_by_cookie, &cookie) != NULL((void*)0));
1464
1465 return cookie;
1466}
1467
1468static gboolean
1469_on_query_end_session_timeout (CsmManager *manager)
1470{
1471 GSList *l;
1472 CsmManagerPrivate *priv;
1473
1474 priv = csm_manager_get_instance_private (manager);
1475
1476 priv->query_timeout_id = 0;
1477
1478 g_debug ("CsmManager: query end session timed out");
1479
1480 for (l = priv->query_clients; l != NULL((void*)0); l = l->next) {
1481 guint cookie;
1482 CsmInhibitor *inhibitor;
1483 const char *bus_name;
1484 char *app_id;
1485
1486 g_warning ("Client '%s' failed to reply before timeout",
1487 csm_client_peek_id (l->data));
1488
1489 /* Don't add "not responding" inhibitors if logout is forced
1490 */
1491 if (priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_FORCE) {
1492 continue;
1493 }
1494
1495 /* Add JIT inhibit for unresponsive client */
1496 if (CSM_IS_DBUS_CLIENT (l->data)) {
1497 bus_name = csm_dbus_client_get_bus_name (l->data);
1498 } else {
1499 bus_name = NULL((void*)0);
1500 }
1501
1502 app_id = g_strdup (csm_client_peek_app_id (l->data))g_strdup_inline (csm_client_peek_app_id (l->data));
1503 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
1504 /* XSMP clients don't give us an app id unless we start them */
1505 g_free (app_id);
1506 app_id = csm_client_get_app_name (l->data);
1507 }
1508
1509 cookie = _generate_unique_cookie (manager);
1510 inhibitor = csm_inhibitor_new_for_client (csm_client_peek_id (l->data),
1511 app_id,
1512 CSM_INHIBITOR_FLAG_LOGOUT,
1513 _("Not responding")gettext ("Not responding"),
1514 bus_name,
1515 cookie);
1516 g_free (app_id);
1517 csm_store_add (priv->inhibitors, csm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
1518 g_object_unref (inhibitor);
1519 }
1520
1521 g_slist_free (priv->query_clients);
1522 priv->query_clients = NULL((void*)0);
1523
1524 query_end_session_complete (manager);
1525
1526 return FALSE(0);
1527}
1528
1529static void
1530do_phase_query_end_session (CsmManager *manager)
1531{
1532 ClientEndSessionData data;
1533 CsmManagerPrivate *priv;
1534
1535 data.manager = manager;
1536 data.flags = 0;
1537 priv = csm_manager_get_instance_private (manager);
1538
1539 if (priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_FORCE) {
1540 data.flags |= CSM_CLIENT_END_SESSION_FLAG_FORCEFUL;
1541 }
1542 /* We only query if an app is ready to log out, so we don't use
1543 * CSM_CLIENT_END_SESSION_FLAG_SAVE here.
1544 */
1545
1546 debug_clients (manager);
1547 g_debug ("CsmManager: sending query-end-session to clients (logout mode: %s)",
1548 priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_NORMAL? "normal" :
1549 priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_FORCE? "forceful":
1550 "no confirmation");
1551 csm_store_foreach (priv->clients,
1552 (CsmStoreFunc)_client_query_end_session,
1553 &data);
1554
1555 /* This phase doesn't time out unless logout is forced. Typically, this
1556 * separate timer is only used to show UI. */
1557 priv->query_timeout_id = g_timeout_add_seconds (1, (GSourceFunc)_on_query_end_session_timeout, manager);
1558}
1559
1560static void
1561update_idle (CsmManager *manager)
1562{
1563 CsmManagerPrivate *priv;
1564
1565 priv = csm_manager_get_instance_private (manager);
1566 if (csm_manager_is_idle_inhibited (manager)) {
1567 csm_presence_set_idle_enabled (priv->presence, FALSE(0));
1568 } else {
1569 csm_presence_set_idle_enabled (priv->presence, TRUE(!(0)));
1570 }
1571}
1572
1573static void
1574start_phase (CsmManager *manager)
1575{
1576 CsmManagerPrivate *priv;
1577
1578 priv = csm_manager_get_instance_private (manager);
1579
1580 g_debug ("CsmManager: starting phase %s\n",
1581 phase_num_to_name (priv->phase));
1582
1583 /* reset state */
1584 g_slist_free (priv->pending_apps);
1585 priv->pending_apps = NULL((void*)0);
1586 g_slist_free (priv->query_clients);
1587 priv->query_clients = NULL((void*)0);
1588 g_slist_free (priv->next_query_clients);
1589 priv->next_query_clients = NULL((void*)0);
1590
1591 if (priv->query_timeout_id > 0) {
1592 g_source_remove (priv->query_timeout_id);
1593 priv->query_timeout_id = 0;
1594 }
1595 if (priv->phase_timeout_id > 0) {
1596 g_source_remove (priv->phase_timeout_id);
1597 priv->phase_timeout_id = 0;
1598 }
1599
1600 switch (priv->phase) {
1601 case CSM_MANAGER_PHASE_STARTUP:
1602 case CSM_MANAGER_PHASE_INITIALIZATION:
1603 case CSM_MANAGER_PHASE_WINDOW_MANAGER:
1604 case CSM_MANAGER_PHASE_PANEL:
1605 case CSM_MANAGER_PHASE_DESKTOP:
1606 case CSM_MANAGER_PHASE_APPLICATION:
1607 do_phase_startup (manager);
1608 break;
1609 case CSM_MANAGER_PHASE_RUNNING:
1610 g_signal_emit (manager, signals[SESSION_RUNNING], 0);
1611 update_idle (manager);
1612 break;
1613 case CSM_MANAGER_PHASE_QUERY_END_SESSION:
1614 do_phase_query_end_session (manager);
1615 break;
1616 case CSM_MANAGER_PHASE_END_SESSION:
1617 do_phase_end_session (manager);
1618 break;
1619 case CSM_MANAGER_PHASE_EXIT:
1620 do_phase_exit (manager);
1621 break;
1622 default:
1623 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
1623, ((const char*) (__func__)), ((void*)0)); } while (0)
;
1624 break;
1625 }
1626}
1627
1628static gboolean
1629_debug_app_for_phase (const char *id,
1630 CsmApp *app,
1631 gpointer data)
1632{
1633 guint phase;
1634
1635 phase = GPOINTER_TO_UINT (data)((guint) (gulong) (data));
1636
1637 if (csm_app_peek_phase (app) != phase) {
1638 return FALSE(0);
1639 }
1640
1641 g_debug ("CsmManager:\tID: %s\tapp-id:%s\tis-disabled:%d\tis-conditionally-disabled:%d\tis-delayed:%d",
1642 csm_app_peek_id (app),
1643 csm_app_peek_app_id (app),
1644 csm_app_peek_is_disabled (app),
1645 csm_app_peek_is_conditionally_disabled (app),
1646 (csm_app_peek_autostart_delay (app) > 0));
1647
1648 return FALSE(0);
1649}
1650
1651static void
1652debug_app_summary (CsmManager *manager)
1653{
1654 guint phase;
1655 CsmManagerPrivate *priv;
1656
1657 priv = csm_manager_get_instance_private (manager);
1658
1659 g_debug ("CsmManager: App startup summary");
1660 for (phase = CSM_MANAGER_PHASE_INITIALIZATION; phase < CSM_MANAGER_PHASE_RUNNING; phase++) {
1661 g_debug ("CsmManager: Phase %s", phase_num_to_name (phase));
1662 csm_store_foreach (priv->apps,
1663 (CsmStoreFunc)_debug_app_for_phase,
1664 GUINT_TO_POINTER (phase)((gpointer) (gulong) (phase)));
1665 }
1666}
1667
1668void
1669csm_manager_start (CsmManager *manager)
1670{
1671 g_debug ("CsmManager: CSM starting to manage");
1672
1673 g_return_if_fail (CSM_IS_MANAGER (manager))do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return; } } while (0)
;
1674
1675 csm_manager_set_phase (manager, CSM_MANAGER_PHASE_INITIALIZATION);
1676 debug_app_summary (manager);
1677 start_phase (manager);
1678}
1679
1680void
1681_csm_manager_set_renderer (CsmManager *manager,
1682 const char *renderer)
1683{
1684 CsmManagerPrivate *priv;
1685 priv = csm_manager_get_instance_private (manager);
1686 priv->renderer = renderer;
1687}
1688
1689static gboolean
1690_app_has_app_id (const char *id,
1691 CsmApp *app,
1692 const char *app_id_a)
1693{
1694 const char *app_id_b;
1695
1696 app_id_b = csm_app_peek_app_id (app);
1697 return (app_id_b != NULL((void*)0) && strcmp (app_id_a, app_id_b) == 0);
1698}
1699
1700static CsmApp *
1701find_app_for_app_id (CsmManager *manager,
1702 const char *app_id)
1703{
1704 CsmApp *app;
1705 CsmManagerPrivate *priv;
1706
1707 priv = csm_manager_get_instance_private (manager);
1708 app = (CsmApp *)csm_store_find (priv->apps,
1709 (CsmStoreFunc)_app_has_app_id,
1710 (char *)app_id);
1711 return app;
1712}
1713
1714static gboolean
1715inhibitor_has_client_id (gpointer key,
1716 CsmInhibitor *inhibitor,
1717 const char *client_id_a)
1718{
1719 gboolean matches;
1720 const char *client_id_b;
1721
1722 client_id_b = csm_inhibitor_peek_client_id (inhibitor);
1723
1724 matches = FALSE(0);
1725 if (! IS_STRING_EMPTY (client_id_a)((client_id_a)==((void*)0)||(client_id_a)[0]=='\0') && ! IS_STRING_EMPTY (client_id_b)((client_id_b)==((void*)0)||(client_id_b)[0]=='\0')) {
1726 matches = (strcmp (client_id_a, client_id_b) == 0);
1727 if (matches) {
1728 g_debug ("CsmManager: removing JIT inhibitor for %s for reason '%s'",
1729 csm_inhibitor_peek_client_id (inhibitor),
1730 csm_inhibitor_peek_reason (inhibitor));
1731 }
1732 }
1733
1734 return matches;
1735}
1736
1737static gboolean
1738_app_has_startup_id (const char *id,
1739 CsmApp *app,
1740 const char *startup_id_a)
1741{
1742 const char *startup_id_b;
1743
1744 startup_id_b = csm_app_peek_startup_id (app);
1745
1746 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
1747 return FALSE(0);
1748 }
1749
1750 return (strcmp (startup_id_a, startup_id_b) == 0);
1751}
1752
1753static CsmApp *
1754find_app_for_startup_id (CsmManager *manager,
1755 const char *startup_id)
1756{
1757 CsmApp *found_app;
1758 GSList *a;
1759 CsmManagerPrivate *priv;
1760
1761 found_app = NULL((void*)0);
1762 priv = csm_manager_get_instance_private (manager);
1763
1764 /* If we're starting up the session, try to match the new client
1765 * with one pending apps for the current phase. If not, try to match
1766 * with any of the autostarted apps. */
1767 if (priv->phase < CSM_MANAGER_PHASE_APPLICATION) {
1768 for (a = priv->pending_apps; a != NULL((void*)0); a = a->next) {
1769 CsmApp *app = CSM_APP (a->data);
1770
1771 if (strcmp (startup_id, csm_app_peek_startup_id (app)) == 0) {
1772 found_app = app;
1773 goto out;
1774 }
1775 }
1776 } else {
1777 CsmApp *app;
1778
1779 app = (CsmApp *)csm_store_find (priv->apps,
1780 (CsmStoreFunc)_app_has_startup_id,
1781 (char *)startup_id);
1782 if (app != NULL((void*)0)) {
1783 found_app = app;
1784 goto out;
1785 }
1786 }
1787 out:
1788 return found_app;
1789}
1790
1791static void
1792_disconnect_client (CsmManager *manager,
1793 CsmClient *client)
1794{
1795 gboolean is_condition_client;
1796 CsmApp *app;
1797 GError *error;
1798 gboolean UNUSED_VARIABLE__attribute__ ((unused)) res;
1799 const char *app_id;
1800 const char *startup_id;
1801 gboolean app_restart;
1802 CsmClientRestartStyle client_restart_hint;
1803 CsmManagerPrivate *priv;
1804
1805 g_debug ("CsmManager: disconnect client: %s", csm_client_peek_id (client));
1806
1807 /* take a ref so it doesn't get finalized */
1808 g_object_ref (client)((__typeof__ (client)) (g_object_ref) (client));
1809
1810 csm_client_set_status (client, CSM_CLIENT_FINISHED);
1811
1812 is_condition_client = FALSE(0);
1813 priv = csm_manager_get_instance_private (manager);
1814 if (g_slist_find (priv->condition_clients, client)) {
1815 priv->condition_clients = g_slist_remove (priv->condition_clients, client);
1816
1817 is_condition_client = TRUE(!(0));
1818 }
1819
1820 /* remove any inhibitors for this client */
1821 csm_store_foreach_remove (priv->inhibitors,
1822 (CsmStoreFunc)inhibitor_has_client_id,
1823 (gpointer)csm_client_peek_id (client));
1824
1825 app = NULL((void*)0);
1826
1827 /* first try to match on startup ID */
1828 startup_id = csm_client_peek_startup_id (client);
1829 if (! IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
1830 app = find_app_for_startup_id (manager, startup_id);
1831
1832 }
1833
1834 /* then try to find matching app-id */
1835 if (app == NULL((void*)0)) {
1836 app_id = csm_client_peek_app_id (client);
1837 if (! IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
1838 g_debug ("CsmManager: disconnect for app '%s'", app_id);
1839 app = find_app_for_app_id (manager, app_id);
1840 }
1841 }
1842
1843 if (priv->phase == CSM_MANAGER_PHASE_QUERY_END_SESSION) {
1844 /* Instead of answering our end session query, the client just exited.
1845 * Treat that as an "okay, end the session" answer.
1846 *
1847 * This call implicitly removes any inhibitors for the client, along
1848 * with removing the client from the pending query list.
1849 */
1850 _handle_client_end_session_response (manager,
1851 client,
1852 TRUE(!(0)),
1853 FALSE(0),
1854 FALSE(0),
1855 "Client exited in "
1856 "query end session phase "
1857 "instead of end session "
1858 "phase");
1859 }
1860
1861 if (priv->dbus_disconnected && CSM_IS_DBUS_CLIENT (client)) {
1862 g_debug ("CsmManager: dbus disconnected, not restarting application");
1863 goto out;
1864 }
1865
1866
1867 if (app == NULL((void*)0)) {
1868 g_debug ("CsmManager: unable to find application for client - not restarting");
1869 goto out;
1870 }
1871
1872 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION) {
1873 g_debug ("CsmManager: in shutdown, not restarting application");
1874 goto out;
1875 }
1876
1877 app_restart = csm_app_peek_autorestart (app);
1878 client_restart_hint = csm_client_peek_restart_style_hint (client);
1879
1880 /* allow legacy clients to override the app info */
1881 if (! app_restart
1882 && client_restart_hint != CSM_CLIENT_RESTART_IMMEDIATELY) {
1883 g_debug ("CsmManager: autorestart not set, not restarting application");
1884 goto out;
1885 }
1886
1887 if (is_condition_client) {
1888 g_debug ("CsmManager: app conditionally disabled, not restarting application");
1889 goto out;
1890 }
1891
1892 g_debug ("CsmManager: restarting app");
1893
1894 error = NULL((void*)0);
1895 res = csm_app_restart (app, &error);
1896 if (error != NULL((void*)0)) {
1897 g_warning ("Error on restarting session managed app: %s", error->message);
1898 g_error_free (error);
1899 }
1900
1901 out:
1902 g_object_unref (client);
1903}
1904
1905typedef struct {
1906 const char *service_name;
1907 CsmManager *manager;
1908} RemoveClientData;
1909
1910static gboolean
1911_disconnect_dbus_client (const char *id,
1912 CsmClient *client,
1913 RemoveClientData *data)
1914{
1915 const char *name;
1916
1917 if (! CSM_IS_DBUS_CLIENT (client)) {
1918 return FALSE(0);
1919 }
1920
1921 /* If no service name, then we simply disconnect all clients */
1922 if (!data->service_name) {
1923 _disconnect_client (data->manager, client);
1924 return TRUE(!(0));
1925 }
1926
1927 name = csm_dbus_client_get_bus_name (CSM_DBUS_CLIENT (client));
1928 if (IS_STRING_EMPTY (name)((name)==((void*)0)||(name)[0]=='\0')) {
1929 return FALSE(0);
1930 }
1931
1932 if (strcmp (data->service_name, name) == 0) {
1933 _disconnect_client (data->manager, client);
1934 return TRUE(!(0));
1935 }
1936
1937 return FALSE(0);
1938}
1939
1940/**
1941 * remove_clients_for_connection:
1942 * @manager: a #CsmManager
1943 * @service_name: a service name
1944 *
1945 * Disconnects clients that own @service_name.
1946 *
1947 * If @service_name is NULL, then disconnects all clients for the connection.
1948 */
1949static void
1950remove_clients_for_connection (CsmManager *manager,
1951 const char *service_name)
1952{
1953 RemoveClientData data;
1954 CsmManagerPrivate *priv;
1955
1956 data.service_name = service_name;
1957 data.manager = manager;
1958 priv = csm_manager_get_instance_private (manager);
1959
1960 /* disconnect dbus clients for name */
1961 csm_store_foreach_remove (priv->clients,
1962 (CsmStoreFunc)_disconnect_dbus_client,
1963 &data);
1964
1965 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION
1966 && csm_store_size (priv->clients) == 0) {
1967 g_debug ("CsmManager: last client disconnected - exiting");
1968 end_phase (manager);
1969 }
1970}
1971
1972static gboolean
1973inhibitor_has_bus_name (gpointer key,
1974 CsmInhibitor *inhibitor,
1975 RemoveClientData *data)
1976{
1977 gboolean matches;
1978 const char *bus_name_b;
1979
1980 bus_name_b = csm_inhibitor_peek_bus_name (inhibitor);
1981
1982 matches = FALSE(0);
1983 if (! IS_STRING_EMPTY (data->service_name)((data->service_name)==((void*)0)||(data->service_name)
[0]=='\0')
&& ! IS_STRING_EMPTY (bus_name_b)((bus_name_b)==((void*)0)||(bus_name_b)[0]=='\0')) {
1984 matches = (strcmp (data->service_name, bus_name_b) == 0);
1985 if (matches) {
1986 g_debug ("CsmManager: removing inhibitor from %s for reason '%s' on connection %s",
1987 csm_inhibitor_peek_app_id (inhibitor),
1988 csm_inhibitor_peek_reason (inhibitor),
1989 csm_inhibitor_peek_bus_name (inhibitor));
1990 }
1991 }
1992
1993 return matches;
1994}
1995
1996static void
1997remove_inhibitors_for_connection (CsmManager *manager,
1998 const char *service_name)
1999{
2000 guint UNUSED_VARIABLE__attribute__ ((unused)) n_removed;
2001 RemoveClientData data;
2002 CsmManagerPrivate *priv;
2003
2004 data.service_name = service_name;
2005 data.manager = manager;
2006 priv = csm_manager_get_instance_private (manager);
2007
2008 debug_inhibitors (manager);
2009
2010 n_removed = csm_store_foreach_remove (priv->inhibitors,
2011 (CsmStoreFunc)inhibitor_has_bus_name,
2012 &data);
2013}
2014
2015static void
2016bus_name_owner_changed (DBusGProxy *bus_proxy,
2017 const char *service_name,
2018 const char *old_service_name,
2019 const char *new_service_name,
2020 CsmManager *manager)
2021{
2022 if (strlen (new_service_name) == 0
2023 && strlen (old_service_name) > 0) {
2024 /* service removed */
2025 remove_inhibitors_for_connection (manager, old_service_name);
2026 remove_clients_for_connection (manager, old_service_name);
2027 } else if (strlen (old_service_name) == 0
2028 && strlen (new_service_name) > 0) {
2029 /* service added */
2030
2031 /* use this if we support automatically registering
2032 * well known bus names */
2033 }
2034}
2035
2036static DBusHandlerResult
2037csm_manager_bus_filter (DBusConnection *connection,
2038 DBusMessage *message,
2039 void *user_data)
2040{
2041 CsmManager *manager;
2042 CsmManagerPrivate *priv;
2043
2044 manager = CSM_MANAGER (user_data);
2045 priv = csm_manager_get_instance_private (manager);
2046
2047 if (dbus_message_is_signal (message,
2048 DBUS_INTERFACE_LOCAL"org.freedesktop.DBus.Local", "Disconnected") &&
2049 strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL"/org/freedesktop/DBus/Local") == 0) {
2050 g_debug ("CsmManager: dbus disconnected; disconnecting dbus clients...");
2051 priv->dbus_disconnected = TRUE(!(0));
2052 remove_clients_for_connection (manager, NULL((void*)0));
2053 /* let other filters get this disconnected signal, so that they
2054 * can handle it too */
2055 }
2056
2057 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
2058}
2059
2060static gboolean
2061register_manager (CsmManager *manager)
2062{
2063 GError *error = NULL((void*)0);
2064 CsmManagerPrivate *priv;
2065 DBusConnection *connection;
2066
2067 error = NULL((void*)0);
2068 priv = csm_manager_get_instance_private (manager);
2069
2070 priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
2071 if (priv->connection == NULL((void*)0)) {
2072 if (error != NULL((void*)0)) {
2073 g_critical ("error getting session bus: %s", error->message);
2074 g_error_free (error);
2075 }
2076 exit (1);
2077 }
2078
2079 connection = dbus_g_connection_get_connection (priv->connection);
2080 dbus_connection_add_filter (connection,
2081 csm_manager_bus_filter,
2082 manager, NULL((void*)0));
2083 priv->dbus_disconnected = FALSE(0);
2084
2085 priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection,
2086 DBUS_SERVICE_DBUS"org.freedesktop.DBus",
2087 DBUS_PATH_DBUS"/org/freedesktop/DBus",
2088 DBUS_INTERFACE_DBUS"org.freedesktop.DBus");
2089 dbus_g_proxy_add_signal (priv->bus_proxy,
2090 "NameOwnerChanged",
2091 G_TYPE_STRING((GType) ((16) << (2))),
2092 G_TYPE_STRING((GType) ((16) << (2))),
2093 G_TYPE_STRING((GType) ((16) << (2))),
2094 G_TYPE_INVALID((GType) ((0) << (2))));
2095 dbus_g_proxy_connect_signal (priv->bus_proxy,
2096 "NameOwnerChanged",
2097 G_CALLBACK (bus_name_owner_changed)((GCallback) (bus_name_owner_changed)),
2098 manager,
2099 NULL((void*)0));
2100
2101 dbus_g_connection_register_g_object (priv->connection, CSM_MANAGER_DBUS_PATH"/org/gnome/SessionManager", G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
);
2102
2103 return TRUE(!(0));
2104}
2105
2106static void
2107csm_manager_set_failsafe (CsmManager *manager,
2108 gboolean enabled)
2109{
2110 CsmManagerPrivate *priv;
2111
2112 g_return_if_fail (CSM_IS_MANAGER (manager))do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return; } } while (0)
;
2113
2114 priv = csm_manager_get_instance_private (manager);
2115
2116 priv->failsafe = enabled;
2117}
2118
2119static gboolean
2120_client_has_startup_id (const char *id,
2121 CsmClient *client,
2122 const char *startup_id_a)
2123{
2124 const char *startup_id_b;
2125
2126 startup_id_b = csm_client_peek_startup_id (client);
2127
2128 if (IS_STRING_EMPTY (startup_id_b)((startup_id_b)==((void*)0)||(startup_id_b)[0]=='\0')) {
2129 return FALSE(0);
2130 }
2131
2132 return (strcmp (startup_id_a, startup_id_b) == 0);
2133}
2134
2135static void
2136on_client_disconnected (CsmClient *client,
2137 CsmManager *manager)
2138{
2139 CsmManagerPrivate *priv;
2140
2141 g_debug ("CsmManager: disconnect client");
2142
2143 priv = csm_manager_get_instance_private (manager);
2144
2145 _disconnect_client (manager, client);
2146 csm_store_remove (priv->clients, csm_client_peek_id (client));
2147 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION
2148 && csm_store_size (priv->clients) == 0) {
2149 g_debug ("CsmManager: last client disconnected - exiting");
2150 end_phase (manager);
2151 }
2152}
2153
2154static gboolean
2155on_xsmp_client_register_request (CsmXSMPClient *client,
2156 char **id,
2157 CsmManager *manager)
2158{
2159 gboolean handled;
2160 char *new_id;
2161 CsmApp *app;
2162 CsmManagerPrivate *priv;
2163
2164 handled = TRUE(!(0));
2165 new_id = NULL((void*)0);
2166 priv = csm_manager_get_instance_private (manager);
2167
2168 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION) {
2169 goto out;
2170 }
2171
2172 if (IS_STRING_EMPTY (*id)((*id)==((void*)0)||(*id)[0]=='\0')) {
2173 new_id = csm_util_generate_startup_id ();
2174 } else {
2175 CsmClient *client;
2176
2177 client = (CsmClient *)csm_store_find (priv->clients,
2178 (CsmStoreFunc)_client_has_startup_id,
2179 *id);
2180 /* We can't have two clients with the same id. */
2181 if (client != NULL((void*)0)) {
2182 goto out;
2183 }
2184
2185 new_id = g_strdup (*id)g_strdup_inline (*id);
2186 }
2187
2188 g_debug ("CsmManager: Adding new client %s to session", new_id);
2189
2190 g_signal_connect (client,g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2191 "disconnected",g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2192 G_CALLBACK (on_client_disconnected),g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
2193 manager)g_signal_connect_data ((client), ("disconnected"), (((GCallback
) (on_client_disconnected))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2194
2195 /* If it's a brand new client id, we just accept the client*/
2196 if (IS_STRING_EMPTY (*id)((*id)==((void*)0)||(*id)[0]=='\0')) {
2197 goto out;
2198 }
2199
2200 app = find_app_for_startup_id (manager, new_id);
2201 if (app != NULL((void*)0)) {
2202 csm_client_set_app_id (CSM_CLIENT (client), csm_app_peek_app_id (app));
2203 csm_app_registered (app);
2204 goto out;
2205 }
2206
2207 /* app not found */
2208 g_free (new_id);
2209 new_id = NULL((void*)0);
2210
2211 out:
2212 g_free (*id);
2213 *id = new_id;
2214
2215 return handled;
2216}
2217
2218static gboolean
2219auto_save_is_enabled (CsmManager *manager)
2220{
2221 CsmManagerPrivate *priv;
2222
2223 priv = csm_manager_get_instance_private (manager);
2224 return g_settings_get_boolean (priv->settings_session,
2225 KEY_AUTOSAVE"auto-save-session");
2226}
2227
2228static void
2229maybe_save_session (CsmManager *manager)
2230{
2231 CsmConsolekit *consolekit = NULL((void*)0);
2232#ifdef HAVE_SYSTEMD1
2233 CsmSystemd *systemd = NULL((void*)0);
2234#endif
2235 char *session_type;
2236 GError *error;
2237 CsmManagerPrivate *priv;
2238
2239#ifdef HAVE_SYSTEMD1
2240 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
2241 systemd = csm_get_systemd ();
2242 session_type = csm_systemd_get_current_session_type (systemd);
2243
2244 if (g_strcmp0 (session_type, CSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") == 0) {
2245 goto out;
2246 }
2247 }
2248 else {
2249#endif
2250 consolekit = csm_get_consolekit ();
2251 session_type = csm_consolekit_get_current_session_type (consolekit);
2252
2253 if (g_strcmp0 (session_type, CSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") == 0) {
2254 goto out;
2255 }
2256#ifdef HAVE_SYSTEMD1
2257 }
2258#endif
2259
2260 priv = csm_manager_get_instance_private (manager);
2261 /* We only allow session saving when session is running or when
2262 * logging out */
2263 if (priv->phase != CSM_MANAGER_PHASE_RUNNING &&
2264 priv->phase != CSM_MANAGER_PHASE_END_SESSION) {
2265 goto out;
2266 }
2267
2268 error = NULL((void*)0);
2269 csm_session_save (priv->clients, &error);
2270
2271 if (error) {
2272 g_warning ("Error saving session: %s", error->message);
2273 g_error_free (error);
2274 }
2275
2276out:
2277 if (consolekit != NULL((void*)0))
2278 g_object_unref (consolekit);
2279#ifdef HAVE_SYSTEMD1
2280 if (systemd != NULL((void*)0))
2281 g_object_unref (systemd);
2282#endif
2283 g_free (session_type);
2284}
2285
2286static void
2287_handle_client_end_session_response (CsmManager *manager,
2288 CsmClient *client,
2289 gboolean is_ok,
2290 gboolean do_last,
2291 gboolean cancel,
2292 const char *reason)
2293{
2294 CsmManagerPrivate *priv;
2295
2296 priv = csm_manager_get_instance_private (manager);
2297 /* just ignore if received outside of shutdown */
2298 if (priv->phase < CSM_MANAGER_PHASE_QUERY_END_SESSION) {
2299 return;
2300 }
2301
2302 g_debug ("CsmManager: Response from end session request: is-ok=%d do-last=%d cancel=%d reason=%s", is_ok, do_last, cancel, reason ? reason :"");
2303
2304 if (cancel) {
2305 cancel_end_session (manager);
2306 return;
2307 }
2308
2309 priv->query_clients = g_slist_remove (priv->query_clients, client);
2310
2311 if (! is_ok && priv->logout_mode != CSM_MANAGER_LOGOUT_MODE_FORCE) {
2312 guint cookie;
2313 CsmInhibitor *inhibitor;
2314 char *app_id;
2315 const char *bus_name;
2316
2317 /* FIXME: do we support updating the reason? */
2318
2319 /* Create JIT inhibit */
2320 if (CSM_IS_DBUS_CLIENT (client)) {
2321 bus_name = csm_dbus_client_get_bus_name (CSM_DBUS_CLIENT (client));
2322 } else {
2323 bus_name = NULL((void*)0);
2324 }
2325
2326 app_id = g_strdup (csm_client_peek_app_id (client))g_strdup_inline (csm_client_peek_app_id (client));
2327 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
2328 /* XSMP clients don't give us an app id unless we start them */
2329 g_free (app_id);
2330 app_id = csm_client_get_app_name (client);
2331 }
2332
2333 cookie = _generate_unique_cookie (manager);
2334 inhibitor = csm_inhibitor_new_for_client (csm_client_peek_id (client),
2335 app_id,
2336 CSM_INHIBITOR_FLAG_LOGOUT,
2337 reason != NULL((void*)0) ? reason : _("Not responding")gettext ("Not responding"),
2338 bus_name,
2339 cookie);
2340 g_free (app_id);
2341 csm_store_add (priv->inhibitors, csm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
2342 g_object_unref (inhibitor);
2343 } else {
2344 csm_store_foreach_remove (priv->inhibitors,
2345 (CsmStoreFunc)inhibitor_has_client_id,
2346 (gpointer)csm_client_peek_id (client));
2347 }
2348
2349 if (priv->phase == CSM_MANAGER_PHASE_QUERY_END_SESSION) {
2350 if (priv->query_clients == NULL((void*)0)) {
2351 query_end_session_complete (manager);
2352 }
2353 } else if (priv->phase == CSM_MANAGER_PHASE_END_SESSION) {
2354 if (do_last) {
2355 /* This only makes sense if we're in part 1 of
2356 * CSM_MANAGER_PHASE_END_SESSION. Doing this in part 2
2357 * can only happen because of a buggy client that loops
2358 * wanting to be last again and again. The phase
2359 * timeout will take care of this issue. */
2360 priv->next_query_clients = g_slist_prepend (priv->next_query_clients,
2361 client);
2362 }
2363
2364 /* we can continue to the next step if all clients have replied
2365 * and if there's no inhibitor */
2366 if (priv->query_clients != NULL((void*)0)
2367 || csm_manager_is_logout_inhibited (manager)) {
2368 return;
2369 }
2370
2371 if (priv->next_query_clients != NULL((void*)0)) {
2372 do_phase_end_session_part_2 (manager);
2373 } else {
2374 end_phase (manager);
2375 }
2376 }
2377}
2378
2379static void
2380on_client_end_session_response (CsmClient *client,
2381 gboolean is_ok,
2382 gboolean do_last,
2383 gboolean cancel,
2384 const char *reason,
2385 CsmManager *manager)
2386{
2387 _handle_client_end_session_response (manager,
2388 client,
2389 is_ok,
2390 do_last,
2391 cancel,
2392 reason);
2393}
2394
2395static void
2396on_xsmp_client_logout_request (CsmXSMPClient *client,
2397 gboolean show_dialog,
2398 CsmManager *manager)
2399{
2400 GError *error;
2401 int logout_mode;
2402
2403 if (show_dialog) {
2404 logout_mode = CSM_MANAGER_LOGOUT_MODE_NORMAL;
2405 } else {
2406 logout_mode = CSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION;
2407 }
2408
2409 error = NULL((void*)0);
2410 csm_manager_logout (manager, logout_mode, &error);
2411 if (error != NULL((void*)0)) {
2412 g_warning ("Unable to logout: %s", error->message);
2413 g_error_free (error);
2414 }
2415}
2416
2417static void
2418on_store_client_added (CsmStore *store,
2419 const char *id,
2420 CsmManager *manager)
2421{
2422 CsmClient *client;
2423
2424 g_debug ("CsmManager: Client added: %s", id);
2425
2426 client = (CsmClient *)csm_store_lookup (store, id);
2427
2428 /* a bit hacky */
2429 if (CSM_IS_XSMP_CLIENT (client)) {
2430 g_signal_connect (client,g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2431 "register-request",g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2432 G_CALLBACK (on_xsmp_client_register_request),g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
2433 manager)g_signal_connect_data ((client), ("register-request"), (((GCallback
) (on_xsmp_client_register_request))), (manager), ((void*)0),
(GConnectFlags) 0)
;
2434 g_signal_connect (client,g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2435 "logout-request",g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2436 G_CALLBACK (on_xsmp_client_logout_request),g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
2437 manager)g_signal_connect_data ((client), ("logout-request"), (((GCallback
) (on_xsmp_client_logout_request))), (manager), ((void*)0), (
GConnectFlags) 0)
;
2438 }
2439
2440 g_signal_connect (client,g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2441 "end-session-response",g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2442 G_CALLBACK (on_client_end_session_response),g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
2443 manager)g_signal_connect_data ((client), ("end-session-response"), ((
(GCallback) (on_client_end_session_response))), (manager), ((
void*)0), (GConnectFlags) 0)
;
2444
2445 g_signal_emit (manager, signals [CLIENT_ADDED], 0, id);
2446 /* FIXME: disconnect signal handler */
2447}
2448
2449static void
2450on_store_client_removed (CsmStore *store,
2451 const char *id,
2452 CsmManager *manager)
2453{
2454 g_debug ("CsmManager: Client removed: %s", id);
2455
2456 g_signal_emit (manager, signals [CLIENT_REMOVED], 0, id);
2457}
2458
2459static void
2460csm_manager_set_client_store (CsmManager *manager,
2461 CsmStore *store)
2462{
2463 CsmManagerPrivate *priv;
2464
2465 g_return_if_fail (CSM_IS_MANAGER (manager))do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return; } } while (0)
;
2466 priv = csm_manager_get_instance_private (manager);
2467
2468 if (store != NULL((void*)0)) {
2469 g_object_ref (store)((__typeof__ (store)) (g_object_ref) (store));
2470 }
2471
2472 if (priv->clients != NULL((void*)0)) {
2473 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2474 on_store_client_added,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2475 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
;
2476 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2477 on_store_client_removed,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2478 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
;
2479
2480 g_object_unref (priv->clients);
2481 }
2482
2483
2484 g_debug ("CsmManager: setting client store %p", store);
2485
2486 priv->clients = store;
2487
2488 if (priv->clients != NULL((void*)0)) {
2489 g_signal_connect (priv->clients,g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2490 "added",g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2491 G_CALLBACK (on_store_client_added),g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2492 manager)g_signal_connect_data ((priv->clients), ("added"), (((GCallback
) (on_store_client_added))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2493 g_signal_connect (priv->clients,g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2494 "removed",g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2495 G_CALLBACK (on_store_client_removed),g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
2496 manager)g_signal_connect_data ((priv->clients), ("removed"), (((GCallback
) (on_store_client_removed))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2497 }
2498}
2499
2500static void
2501csm_manager_set_property (GObject *object,
2502 guint prop_id,
2503 const GValue *value,
2504 GParamSpec *pspec)
2505{
2506 CsmManager *self;
2507
2508 self = CSM_MANAGER (object);
2509
2510 switch (prop_id) {
2511 case PROP_FAILSAFE:
2512 csm_manager_set_failsafe (self, g_value_get_boolean (value));
2513 break;
2514 case PROP_CLIENT_STORE:
2515 csm_manager_set_client_store (self, g_value_get_object (value));
2516 break;
2517 default:
2518 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "csm-manager.c", 2518, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2519 break;
2520 }
2521}
2522
2523static void
2524csm_manager_get_property (GObject *object,
2525 guint prop_id,
2526 GValue *value,
2527 GParamSpec *pspec)
2528{
2529 CsmManager *self;
2530 CsmManagerPrivate *priv;
2531
2532 self = CSM_MANAGER (object);
2533 priv = csm_manager_get_instance_private (self);
2534
2535 switch (prop_id) {
2536 case PROP_FAILSAFE:
2537 g_value_set_boolean (value, priv->failsafe);
2538 break;
2539 case PROP_CLIENT_STORE:
2540 g_value_set_object (value, priv->clients);
2541 break;
2542 case PROP_RENDERER:
2543 g_value_set_string (value, priv->renderer);
2544 break;
2545 default:
2546 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "csm-manager.c", 2546, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
2547 break;
2548 }
2549}
2550
2551static gboolean
2552_find_app_provides (const char *id,
2553 CsmApp *app,
2554 const char *service)
2555{
2556 return csm_app_provides (app, service);
2557}
2558
2559static GObject *
2560csm_manager_constructor (GType type,
2561 guint n_construct_properties,
2562 GObjectConstructParam *construct_properties)
2563{
2564 CsmManager *manager;
2565
2566 manager = CSM_MANAGER (G_OBJECT_CLASS (csm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((csm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->constructor (type,
2567 n_construct_properties,
2568 construct_properties));
2569 return G_OBJECT (manager)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((manager)), (((GType) ((20) << (2))))))))
;
2570}
2571
2572static void
2573on_store_inhibitor_added (CsmStore *store,
2574 const char *id,
2575 CsmManager *manager)
2576{
2577 g_debug ("CsmManager: Inhibitor added: %s", id);
2578 g_signal_emit (manager, signals [INHIBITOR_ADDED], 0, id);
2579 update_idle (manager);
2580}
2581
2582static void
2583on_store_inhibitor_removed (CsmStore *store,
2584 const char *id,
2585 CsmManager *manager)
2586{
2587 g_debug ("CsmManager: Inhibitor removed: %s", id);
2588 g_signal_emit (manager, signals [INHIBITOR_REMOVED], 0, id);
2589 update_idle (manager);
2590}
2591
2592static void
2593csm_manager_dispose (GObject *object)
2594{
2595 CsmManagerPrivate *priv;
2596 CsmManager *manager = CSM_MANAGER (object);
2597
2598 g_debug ("CsmManager: disposing manager");
2599
2600 priv = csm_manager_get_instance_private (manager);
2601
2602 if (priv->clients != NULL((void*)0)) {
2603 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2604 on_store_client_added,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
2605 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_added), (manager))
;
2606 g_signal_handlers_disconnect_by_func (priv->clients,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2607 on_store_client_removed,g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
2608 manager)g_signal_handlers_disconnect_matched ((priv->clients), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (on_store_client_removed), (manager))
;
2609 g_object_unref (priv->clients);
2610 priv->clients = NULL((void*)0);
2611 }
2612
2613 if (priv->apps != NULL((void*)0)) {
2614 g_object_unref (priv->apps);
2615 priv->apps = NULL((void*)0);
2616 }
2617
2618 if (priv->inhibitors != NULL((void*)0)) {
2619 g_signal_handlers_disconnect_by_func (priv->inhibitors,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
2620 on_store_inhibitor_added,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
2621 manager)g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_added), (manager))
;
2622 g_signal_handlers_disconnect_by_func (priv->inhibitors,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
2623 on_store_inhibitor_removed,g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
2624 manager)g_signal_handlers_disconnect_matched ((priv->inhibitors), (
GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA)
, 0, 0, ((void*)0), (on_store_inhibitor_removed), (manager))
;
2625
2626 g_object_unref (priv->inhibitors);
2627 priv->inhibitors = NULL((void*)0);
2628 }
2629
2630 if (priv->presence != NULL((void*)0)) {
2631 g_object_unref (priv->presence);
2632 priv->presence = NULL((void*)0);
2633 }
2634
2635 if (priv->settings_session) {
2636 g_object_unref (priv->settings_session);
2637 priv->settings_session = NULL((void*)0);
2638 }
2639
2640 if (priv->settings_lockdown) {
2641 g_object_unref (priv->settings_lockdown);
2642 priv->settings_lockdown = NULL((void*)0);
2643 }
2644
2645 if (priv->settings_screensaver) {
2646 g_object_unref (priv->settings_screensaver);
2647 priv->settings_screensaver = NULL((void*)0);
2648 }
2649 G_OBJECT_CLASS (csm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((csm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->dispose (object);
2650}
2651
2652static void
2653csm_manager_class_init (CsmManagerClass *klass)
2654{
2655 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
2656
2657 object_class->get_property = csm_manager_get_property;
2658 object_class->set_property = csm_manager_set_property;
2659 object_class->constructor = csm_manager_constructor;
2660 object_class->finalize = csm_manager_finalize;
2661 object_class->dispose = csm_manager_dispose;
2662
2663 signals [PHASE_CHANGED] =
2664 g_signal_new ("phase-changed",
2665 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2666 G_SIGNAL_RUN_LAST,
2667 G_STRUCT_OFFSET (CsmManagerClass, phase_changed)((glong) __builtin_offsetof(CsmManagerClass, phase_changed)),
2668 NULL((void*)0),
2669 NULL((void*)0),
2670 g_cclosure_marshal_VOID__STRING,
2671 G_TYPE_NONE((GType) ((1) << (2))),
2672 1, G_TYPE_STRING((GType) ((16) << (2))));
2673
2674 signals [SESSION_RUNNING] =
2675 g_signal_new ("session-running",
2676 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
2677 G_SIGNAL_RUN_LAST,
2678 G_STRUCT_OFFSET (CsmManagerClass, session_running)((glong) __builtin_offsetof(CsmManagerClass, session_running)
)
,
2679 NULL((void*)0),
2680 NULL((void*)0),
2681 g_cclosure_marshal_VOID__VOID,
2682 G_TYPE_NONE((GType) ((1) << (2))),
2683 0);
2684
2685 signals [SESSION_OVER] =
2686 g_signal_new ("session-over",
2687 G_OBJECT_CLASS_TYPE (object_class)((((GTypeClass*) (object_class))->g_type)),
2688 G_SIGNAL_RUN_LAST,
2689 G_STRUCT_OFFSET (CsmManagerClass, session_over)((glong) __builtin_offsetof(CsmManagerClass, session_over)),
2690 NULL((void*)0), NULL((void*)0),
2691 g_cclosure_marshal_VOID__VOID,
2692 G_TYPE_NONE((GType) ((1) << (2))),
2693 0);
2694 signals [CLIENT_ADDED] =
2695 g_signal_new ("client-added",
2696 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2697 G_SIGNAL_RUN_LAST,
2698 G_STRUCT_OFFSET (CsmManagerClass, client_added)((glong) __builtin_offsetof(CsmManagerClass, client_added)),
2699 NULL((void*)0),
2700 NULL((void*)0),
2701 g_cclosure_marshal_VOID__BOXED,
2702 G_TYPE_NONE((GType) ((1) << (2))),
2703 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2704 signals [CLIENT_REMOVED] =
2705 g_signal_new ("client-removed",
2706 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2707 G_SIGNAL_RUN_LAST,
2708 G_STRUCT_OFFSET (CsmManagerClass, client_removed)((glong) __builtin_offsetof(CsmManagerClass, client_removed)),
2709 NULL((void*)0),
2710 NULL((void*)0),
2711 g_cclosure_marshal_VOID__BOXED,
2712 G_TYPE_NONE((GType) ((1) << (2))),
2713 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2714 signals [INHIBITOR_ADDED] =
2715 g_signal_new ("inhibitor-added",
2716 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2717 G_SIGNAL_RUN_LAST,
2718 G_STRUCT_OFFSET (CsmManagerClass, inhibitor_added)((glong) __builtin_offsetof(CsmManagerClass, inhibitor_added)
)
,
2719 NULL((void*)0),
2720 NULL((void*)0),
2721 g_cclosure_marshal_VOID__BOXED,
2722 G_TYPE_NONE((GType) ((1) << (2))),
2723 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2724 signals [INHIBITOR_REMOVED] =
2725 g_signal_new ("inhibitor-removed",
2726 G_TYPE_FROM_CLASS (object_class)(((GTypeClass*) (object_class))->g_type),
2727 G_SIGNAL_RUN_LAST,
2728 G_STRUCT_OFFSET (CsmManagerClass, inhibitor_removed)((glong) __builtin_offsetof(CsmManagerClass, inhibitor_removed
))
,
2729 NULL((void*)0),
2730 NULL((void*)0),
2731 g_cclosure_marshal_VOID__BOXED,
2732 G_TYPE_NONE((GType) ((1) << (2))),
2733 1, DBUS_TYPE_G_OBJECT_PATH(dbus_g_object_path_get_g_type ()));
2734
2735 g_object_class_install_property (object_class,
2736 PROP_FAILSAFE,
2737 g_param_spec_boolean ("failsafe",
2738 NULL((void*)0),
2739 NULL((void*)0),
2740 FALSE(0),
2741 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2742 g_object_class_install_property (object_class,
2743 PROP_CLIENT_STORE,
2744 g_param_spec_object ("client-store",
2745 NULL((void*)0),
2746 NULL((void*)0),
2747 CSM_TYPE_STORE(csm_store_get_type ()),
2748 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
2749
2750 g_object_class_install_property (object_class,
2751 PROP_RENDERER,
2752 g_param_spec_string ("renderer",
2753 NULL((void*)0),
2754 NULL((void*)0),
2755 NULL((void*)0),
2756 G_PARAM_READABLE));
2757
2758 dbus_g_object_type_install_info (CSM_TYPE_MANAGER(csm_manager_get_type ()), &dbus_glib_csm_manager_object_info);
2759 dbus_g_error_domain_register (CSM_MANAGER_ERRORcsm_manager_error_quark (), NULL((void*)0), CSM_MANAGER_TYPE_ERROR(csm_manager_error_get_type ()));
2760}
2761
2762static void
2763load_idle_delay_from_gsettings (CsmManager *manager)
2764{
2765 glong value;
2766 CsmManagerPrivate *priv;
2767
2768 priv = csm_manager_get_instance_private (manager);
2769 value = g_settings_get_int (priv->settings_session,
2770 KEY_IDLE_DELAY"idle-delay");
2771 csm_presence_set_idle_timeout (priv->presence, value * 60000);
2772}
2773
2774static void
2775on_gsettings_key_changed (GSettings *settings,
2776 gchar *key,
2777 CsmManager *manager)
2778{
2779 CsmManagerPrivate *priv;
2780
2781 priv = csm_manager_get_instance_private (manager);
2782 if (g_strcmp0 (key, KEY_IDLE_DELAY"idle-delay") == 0) {
2783 int delay;
2784 delay = g_settings_get_int (settings, key);
2785 csm_presence_set_idle_timeout (priv->presence, delay * 60000);
2786 } else if (g_strcmp0 (key, KEY_LOCK_DISABLE"disable-lock-screen") == 0) {
2787 /* ??? */
2788 gboolean UNUSED_VARIABLE__attribute__ ((unused)) disabled;
2789 disabled = g_settings_get_boolean (settings, key);
2790 } else if (g_strcmp0 (key, KEY_USER_SWITCH_DISABLE"disable-user-switching") == 0) {
2791 /* ??? */
2792 gboolean UNUSED_VARIABLE__attribute__ ((unused)) disabled;
2793 disabled = g_settings_get_boolean (settings, key);
2794 } else {
2795 g_debug ("Config key not handled: %s", key);
2796 }
2797}
2798
2799static void
2800on_presence_status_changed (CsmPresence *presence,
2801 guint status,
2802 CsmManager *manager)
2803{
2804#ifdef HAVE_SYSTEMD1
2805 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
2806 CsmSystemd *systemd;
2807
2808 systemd = csm_get_systemd ();
2809 csm_systemd_set_session_idle (systemd,
2810 (status == CSM_PRESENCE_STATUS_IDLE));
2811 }
2812 else {
2813#endif
2814 CsmConsolekit *consolekit;
2815
2816 consolekit = csm_get_consolekit ();
2817 csm_consolekit_set_session_idle (consolekit,
2818 (status == CSM_PRESENCE_STATUS_IDLE));
2819#ifdef HAVE_SYSTEMD1
2820 }
2821#endif
2822}
2823
2824static void
2825csm_manager_init (CsmManager *manager)
2826{
2827 gchar **schemas = NULL((void*)0);
2828 gboolean schema_exists;
2829 guint i;
2830 CsmManagerPrivate *priv;
2831
2832 priv = csm_manager_get_instance_private (manager);
2833
2834 priv->settings_session = g_settings_new (SESSION_SCHEMA"org.cafe.session");
2835 priv->settings_lockdown = g_settings_new (LOCKDOWN_SCHEMA"org.cafe.lockdown");
2836
2837 /* check if cafe-screensaver is installed */
2838 g_settings_schema_source_list_schemas (g_settings_schema_source_get_default (), TRUE(!(0)), &schemas, NULL((void*)0));
2839 schema_exists = FALSE(0);
2840 for (i = 0; schemas[i] != NULL((void*)0); i++) {
2841 if (g_str_equal (schemas[i], SCREENSAVER_SCHEMA)(strcmp ((const char *) (schemas[i]), (const char *) ("org.cafe.screensaver"
)) == 0)
) {
2842 schema_exists = TRUE(!(0));
2843 break;
2844 }
2845 }
2846
2847 g_strfreev (schemas);
2848
2849 if (schema_exists == TRUE(!(0)))
2850 priv->settings_screensaver = g_settings_new (SCREENSAVER_SCHEMA"org.cafe.screensaver");
2851 else
2852 priv->settings_screensaver = NULL((void*)0);
2853
2854 priv->inhibitors = csm_store_new ();
2855 g_signal_connect (priv->inhibitors,g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2856 "added",g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2857 G_CALLBACK (on_store_inhibitor_added),g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
2858 manager)g_signal_connect_data ((priv->inhibitors), ("added"), (((GCallback
) (on_store_inhibitor_added))), (manager), ((void*)0), (GConnectFlags
) 0)
;
2859 g_signal_connect (priv->inhibitors,g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2860 "removed",g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2861 G_CALLBACK (on_store_inhibitor_removed),g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
2862 manager)g_signal_connect_data ((priv->inhibitors), ("removed"), ((
(GCallback) (on_store_inhibitor_removed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2863
2864 priv->apps = csm_store_new ();
2865
2866 priv->presence = csm_presence_new ();
2867 g_signal_connect (priv->presence,g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2868 "status-changed",g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2869 G_CALLBACK (on_presence_status_changed),g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
2870 manager)g_signal_connect_data ((priv->presence), ("status-changed"
), (((GCallback) (on_presence_status_changed))), (manager), (
(void*)0), (GConnectFlags) 0)
;
2871 g_signal_connect (priv->settings_session,g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2872 "changed",g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2873 G_CALLBACK (on_gsettings_key_changed),g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2874 manager)g_signal_connect_data ((priv->settings_session), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2875 g_signal_connect (priv->settings_lockdown,g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2876 "changed",g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2877 G_CALLBACK (on_gsettings_key_changed),g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
2878 manager)g_signal_connect_data ((priv->settings_lockdown), ("changed"
), (((GCallback) (on_gsettings_key_changed))), (manager), ((void
*)0), (GConnectFlags) 0)
;
2879
2880 load_idle_delay_from_gsettings (manager);
2881}
2882
2883static void
2884csm_manager_finalize (GObject *object)
2885{
2886 CsmManager *manager;
2887 CsmManagerPrivate *priv;
2888
2889 g_return_if_fail (object != NULL)do { if ((object != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "object != NULL")
; return; } } while (0)
;
2890 g_return_if_fail (CSM_IS_MANAGER (object))do { if ((CSM_IS_MANAGER (object))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (object)"
); return; } } while (0)
;
2891
2892 manager = CSM_MANAGER (object);
2893 priv = csm_manager_get_instance_private (manager);
2894
2895 g_return_if_fail (priv != NULL)do { if ((priv != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "priv != NULL"); return
; } } while (0)
;
2896
2897 G_OBJECT_CLASS (csm_manager_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((csm_manager_parent_class)), (((GType) ((20) << (2)
)))))))
->finalize (object);
2898}
2899
2900CsmManager *
2901csm_manager_new (CsmStore *client_store,
2902 gboolean failsafe)
2903{
2904 if (manager_object != NULL((void*)0)) {
2905 g_object_ref (manager_object)((__typeof__ (manager_object)) (g_object_ref) (manager_object
))
;
2906 } else {
2907 gboolean res;
2908
2909 manager_object = g_object_new (CSM_TYPE_MANAGER(csm_manager_get_type ()),
2910 "client-store", client_store,
2911 "failsafe", failsafe,
2912 NULL((void*)0));
2913
2914 g_object_add_weak_pointer (manager_object,
2915 (gpointer *) &manager_object);
2916 res = register_manager (manager_object);
2917 if (! res) {
2918 g_object_unref (manager_object);
2919 return NULL((void*)0);
2920 }
2921 }
2922
2923 return CSM_MANAGER (manager_object);
2924}
2925
2926gboolean
2927csm_manager_setenv (CsmManager *manager,
2928 const char *variable,
2929 const char *value,
2930 GError **error)
2931{
2932 CsmManagerPrivate *priv;
2933
2934 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
2935
2936 priv = csm_manager_get_instance_private (manager);
2937 if (priv->phase > CSM_MANAGER_PHASE_INITIALIZATION) {
2938 g_set_error (error,
2939 CSM_MANAGER_ERRORcsm_manager_error_quark (),
2940 CSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
2941 "Setenv interface is only available during the Initialization phase");
2942 return FALSE(0);
2943 }
2944
2945 csm_util_setenv (variable, value);
2946
2947 return TRUE(!(0));
2948}
2949
2950gboolean
2951csm_manager_initialization_error (CsmManager *manager,
2952 const char *message,
2953 gboolean fatal,
2954 GError **error)
2955{
2956 CsmManagerPrivate *priv;
2957 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
2958
2959 priv = csm_manager_get_instance_private (manager);
2960
2961 if (priv->phase > CSM_MANAGER_PHASE_INITIALIZATION) {
2962 g_set_error (error,
2963 CSM_MANAGER_ERRORcsm_manager_error_quark (),
2964 CSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
2965 "InitializationError interface is only available during the Initialization phase");
2966 return FALSE(0);
2967 }
2968
2969 csm_util_init_error (fatal, "%s", message);
2970
2971 return TRUE(!(0));
2972}
2973
2974static gboolean
2975csm_manager_is_switch_user_inhibited (CsmManager *manager)
2976{
2977 CsmInhibitor *inhibitor;
2978 CsmManagerPrivate *priv;
2979
2980 priv = csm_manager_get_instance_private (manager);
2981
2982 if (priv->inhibitors == NULL((void*)0)) {
2983 return FALSE(0);
2984 }
2985
2986 inhibitor = (CsmInhibitor *)csm_store_find (priv->inhibitors,
2987 (CsmStoreFunc)inhibitor_has_flag,
2988 GUINT_TO_POINTER (CSM_INHIBITOR_FLAG_SWITCH_USER)((gpointer) (gulong) (CSM_INHIBITOR_FLAG_SWITCH_USER)));
2989 if (inhibitor == NULL((void*)0)) {
2990 return FALSE(0);
2991 }
2992 return TRUE(!(0));
2993}
2994
2995static gboolean
2996csm_manager_is_suspend_inhibited (CsmManager *manager)
2997{
2998 CsmInhibitor *inhibitor;
2999 CsmManagerPrivate *priv;
3000
3001 priv = csm_manager_get_instance_private (manager);
3002
3003 if (priv->inhibitors == NULL((void*)0)) {
3004 return FALSE(0);
3005 }
3006
3007 inhibitor = (CsmInhibitor *)csm_store_find (priv->inhibitors,
3008 (CsmStoreFunc)inhibitor_has_flag,
3009 GUINT_TO_POINTER (CSM_INHIBITOR_FLAG_SUSPEND)((gpointer) (gulong) (CSM_INHIBITOR_FLAG_SUSPEND)));
3010 if (inhibitor == NULL((void*)0)) {
3011 return FALSE(0);
3012 }
3013 return TRUE(!(0));
3014}
3015
3016static void
3017request_reboot_privileges_completed_consolekit (CsmConsolekit *consolekit,
3018 gboolean success,
3019 gboolean ask_later,
3020 GError *error,
3021 CsmManager *manager)
3022{
3023 CsmManagerPrivate *priv;
3024
3025 priv = csm_manager_get_instance_private (manager);
3026 /* make sure we disconnect the signal handler so that it's not called
3027 * again next time the event is fired -- this can happen if the reboot
3028 * is cancelled. */
3029 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3030 request_reboot_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3031 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
;
3032
3033 g_object_unref (consolekit);
3034
3035 if (success) {
3036 if (ask_later) {
3037 priv->logout_type = CSM_MANAGER_LOGOUT_REBOOT_INTERACT;
3038 } else {
3039 priv->logout_type = CSM_MANAGER_LOGOUT_REBOOT;
3040 }
3041
3042 end_phase (manager);
3043 }
3044}
3045
3046#ifdef HAVE_SYSTEMD1
3047static void
3048request_reboot_privileges_completed_systemd (CsmSystemd *systemd,
3049 gboolean success,
3050 gboolean ask_later,
3051 GError *error,
3052 CsmManager *manager)
3053{
3054 CsmManagerPrivate *priv;
3055
3056 priv = csm_manager_get_instance_private (manager);
3057 /* make sure we disconnect the signal handler so that it's not called
3058 * again next time the event is fired -- this can happen if the reboot
3059 * is cancelled. */
3060 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3061 request_reboot_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3062 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
;
3063
3064 g_object_unref (systemd);
3065
3066 if (success) {
3067 if (ask_later) {
3068 priv->logout_type = CSM_MANAGER_LOGOUT_REBOOT_INTERACT;
3069 } else {
3070 priv->logout_type = CSM_MANAGER_LOGOUT_REBOOT;
3071 }
3072
3073 end_phase (manager);
3074 }
3075}
3076#endif
3077
3078static void
3079request_reboot (CsmManager *manager)
3080{
3081 CsmConsolekit *consolekit;
3082#ifdef HAVE_SYSTEMD1
3083 CsmSystemd *systemd;
3084#endif
3085 gboolean success;
3086 CsmManagerPrivate *priv;
3087
3088 g_debug ("CsmManager: requesting reboot");
3089
3090 priv = csm_manager_get_instance_private (manager);
3091
3092 /* We request the privileges before doing anything. There are a few
3093 * different cases here:
3094 *
3095 * - no systemd: we fallback on ConsoleKit
3096 * - no ConsoleKit: we fallback on CDM
3097 * - no password required: everything is fine
3098 * - password asked once: we ask for it now. If the user enters it
3099 * fine, then all is great. If the user doesn't enter it fine, we
3100 * don't do anything (so no logout).
3101 * - password asked each time: we don't ask it for now since we don't
3102 * want to ask for it twice. Instead we'll ask for it at the very
3103 * end. If the user will enter it fine, then all is great again. If
3104 * the user doesn't enter it fine, then we'll just fallback to CDM.
3105 *
3106 * The last case (password asked each time) is a bit broken, but
3107 * there's really nothing we can do about it. Generally speaking,
3108 * though, the password will only be asked once (unless the system is
3109 * configured in paranoid mode), and most probably only if there are
3110 * more than one user connected. So the general case is that it will
3111 * just work fine.
3112 */
3113
3114#ifdef HAVE_SYSTEMD1
3115 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3116 systemd = csm_get_systemd ();
3117 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3118 "privileges-completed",g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3119 G_CALLBACK (request_reboot_privileges_completed_systemd),g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
3120 manager)g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_reboot_privileges_completed_systemd))),
(manager), ((void*)0), (GConnectFlags) 0)
;
3121 success = csm_systemd_get_restart_privileges (systemd);
3122
3123 if (!success) {
3124 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3125 request_reboot_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
3126 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_systemd), (manager))
;
3127 g_object_unref (systemd);
3128
3129 priv->logout_type = CSM_MANAGER_LOGOUT_REBOOT_CDM;
3130 end_phase (manager);
3131 }
3132 }
3133 else {
3134#endif
3135 consolekit = csm_get_consolekit ();
3136 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3137 "privileges-completed",g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3138 G_CALLBACK (request_reboot_privileges_completed_consolekit),g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3139 manager)g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_reboot_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
;
3140 success = csm_consolekit_get_restart_privileges (consolekit);
3141
3142 if (!success) {
3143 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3144 request_reboot_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
3145 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_reboot_privileges_completed_consolekit), (manager
))
;
3146 g_object_unref (consolekit);
3147
3148 priv->logout_type = CSM_MANAGER_LOGOUT_REBOOT_CDM;
3149 end_phase (manager);
3150 }
3151#ifdef HAVE_SYSTEMD1
3152 }
3153#endif
3154}
3155
3156static void
3157request_shutdown_privileges_completed_consolekit (CsmConsolekit *consolekit,
3158 gboolean success,
3159 gboolean ask_later,
3160 GError *error,
3161 CsmManager *manager)
3162{
3163 CsmManagerPrivate *priv;
3164
3165 priv = csm_manager_get_instance_private (manager);
3166 /* make sure we disconnect the signal handler so that it's not called
3167 * again next time the event is fired -- this can happen if the reboot
3168 * is cancelled. */
3169 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3170 request_shutdown_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3171 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
;
3172
3173 g_object_unref (consolekit);
3174
3175 if (success) {
3176 if (ask_later) {
3177 priv->logout_type = CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT;
3178 } else {
3179 priv->logout_type = CSM_MANAGER_LOGOUT_SHUTDOWN;
3180 }
3181
3182 end_phase (manager);
3183 }
3184}
3185
3186#ifdef HAVE_SYSTEMD1
3187static void
3188request_shutdown_privileges_completed_systemd (CsmSystemd *systemd,
3189 gboolean success,
3190 gboolean ask_later,
3191 GError *error,
3192 CsmManager *manager)
3193{
3194 CsmManagerPrivate *priv;
3195
3196 priv = csm_manager_get_instance_private (manager);
3197 /* make sure we disconnect the signal handler so that it's not called
3198 * again next time the event is fired -- this can happen if the reboot
3199 * is cancelled. */
3200 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3201 request_shutdown_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3202 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
;
3203
3204 g_object_unref (systemd);
3205
3206 if (success) {
3207 if (ask_later) {
3208 priv->logout_type = CSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT;
3209 } else {
3210 priv->logout_type = CSM_MANAGER_LOGOUT_SHUTDOWN;
3211 }
3212
3213 end_phase (manager);
3214 }
3215}
3216#endif
3217
3218static void
3219request_shutdown (CsmManager *manager)
3220{
3221 CsmConsolekit *consolekit;
3222#ifdef HAVE_SYSTEMD1
3223 CsmSystemd *systemd;
3224#endif
3225 gboolean success;
3226 CsmManagerPrivate *priv;
3227
3228 g_debug ("CsmManager: requesting shutdown");
3229
3230 priv = csm_manager_get_instance_private (manager);
3231
3232 /* See the comment in request_reboot() for some more details about how
3233 * this works. */
3234
3235#ifdef HAVE_SYSTEMD1
3236 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3237 systemd = csm_get_systemd ();
3238 g_signal_connect (systemd,g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3239 "privileges-completed",g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3240 G_CALLBACK (request_shutdown_privileges_completed_systemd),g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
3241 manager)g_signal_connect_data ((systemd), ("privileges-completed"), (
((GCallback) (request_shutdown_privileges_completed_systemd))
), (manager), ((void*)0), (GConnectFlags) 0)
;
3242 success = csm_systemd_get_stop_privileges (systemd);
3243
3244 if (!success) {
3245 g_signal_handlers_disconnect_by_func (systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3246 request_shutdown_privileges_completed_systemd,g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
3247 manager)g_signal_handlers_disconnect_matched ((systemd), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_systemd), (manager
))
;
3248 g_object_unref (systemd);
3249
3250 priv->logout_type = CSM_MANAGER_LOGOUT_SHUTDOWN_CDM;
3251 end_phase (manager);
3252 }
3253 }
3254 else {
3255#endif
3256 consolekit = csm_get_consolekit ();
3257 g_signal_connect (consolekit,g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3258 "privileges-completed",g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3259 G_CALLBACK (request_shutdown_privileges_completed_consolekit),g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
3260 manager)g_signal_connect_data ((consolekit), ("privileges-completed")
, (((GCallback) (request_shutdown_privileges_completed_consolekit
))), (manager), ((void*)0), (GConnectFlags) 0)
;
3261 success = csm_consolekit_get_stop_privileges (consolekit);
3262
3263 if (!success) {
3264 g_signal_handlers_disconnect_by_func (consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3265 request_shutdown_privileges_completed_consolekit,g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
3266 manager)g_signal_handlers_disconnect_matched ((consolekit), (GSignalMatchType
) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*)
0), (request_shutdown_privileges_completed_consolekit), (manager
))
;
3267 g_object_unref (consolekit);
3268
3269 priv->logout_type = CSM_MANAGER_LOGOUT_SHUTDOWN_CDM;
3270 end_phase (manager);
3271 }
3272#ifdef HAVE_SYSTEMD1
3273 }
3274#endif
3275}
3276
3277static void
3278request_suspend (CsmManager *manager)
3279{
3280 CsmManagerPrivate *priv;
3281
3282 g_debug ("CsmManager: requesting suspend");
3283
3284 if (! csm_manager_is_suspend_inhibited (manager)) {
3285 manager_attempt_suspend (manager);
3286 return;
3287 }
3288
3289 priv = csm_manager_get_instance_private (manager);
3290 if (priv->inhibit_dialog != NULL((void*)0)) {
3291 g_debug ("CsmManager: inhibit dialog already up");
3292 ctk_window_present (CTK_WINDOW (priv->inhibit_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((ctk_window_get_type ())))))
)
);
3293 return;
3294 }
3295
3296 priv->inhibit_dialog = csm_inhibit_dialog_new (priv->inhibitors,
3297 priv->clients,
3298 CSM_LOGOUT_ACTION_SLEEP);
3299
3300 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3301 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3302 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3303 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3304 ctk_widget_show (priv->inhibit_dialog);
3305}
3306
3307static void
3308request_hibernate (CsmManager *manager)
3309{
3310 CsmManagerPrivate *priv;
3311
3312 g_debug ("CsmManager: requesting hibernate");
3313
3314 /* hibernate uses suspend inhibit */
3315 if (! csm_manager_is_suspend_inhibited (manager)) {
3316 manager_attempt_hibernate (manager);
3317 return;
3318 }
3319
3320 priv = csm_manager_get_instance_private (manager);
3321 if (priv->inhibit_dialog != NULL((void*)0)) {
3322 g_debug ("CsmManager: inhibit dialog already up");
3323 ctk_window_present (CTK_WINDOW (priv->inhibit_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((ctk_window_get_type ())))))
)
);
3324 return;
3325 }
3326
3327 priv->inhibit_dialog = csm_inhibit_dialog_new (priv->inhibitors,
3328 priv->clients,
3329 CSM_LOGOUT_ACTION_HIBERNATE);
3330
3331 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3332 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3333 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3334 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3335 ctk_widget_show (priv->inhibit_dialog);
3336}
3337
3338
3339static void
3340request_logout (CsmManager *manager,
3341 CsmManagerLogoutMode mode)
3342{
3343 CsmManagerPrivate *priv;
3344
3345 g_debug ("CsmManager: requesting logout");
3346
3347 priv = csm_manager_get_instance_private (manager);
3348
3349 priv->logout_mode = mode;
3350 priv->logout_type = CSM_MANAGER_LOGOUT_LOGOUT;
3351
3352 end_phase (manager);
3353}
3354
3355static void
3356request_switch_user (CsmManager *manager)
3357{
3358 CsmManagerPrivate *priv;
3359
3360 g_debug ("CsmManager: requesting user switch");
3361
3362 /* See comment in manager_switch_user() to understand why we do this in
3363 * both functions. */
3364 if (_switch_user_is_locked_down (manager)) {
3365 g_warning ("Unable to switch user: User switching has been locked down");
3366 return;
3367 }
3368
3369 if (! csm_manager_is_switch_user_inhibited (manager)) {
3370 manager_switch_user (manager);
3371 return;
3372 }
3373
3374 priv = csm_manager_get_instance_private (manager);
3375 if (priv->inhibit_dialog != NULL((void*)0)) {
3376 g_debug ("CsmManager: inhibit dialog already up");
3377 ctk_window_present (CTK_WINDOW (priv->inhibit_dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((priv->inhibit_dialog)), ((ctk_window_get_type ())))))
)
);
3378 return;
3379 }
3380
3381 priv->inhibit_dialog = csm_inhibit_dialog_new (priv->inhibitors,
3382 priv->clients,
3383 CSM_LOGOUT_ACTION_SWITCH_USER);
3384
3385 g_signal_connect (priv->inhibit_dialog,g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3386 "response",g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3387 G_CALLBACK (inhibit_dialog_response),g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
3388 manager)g_signal_connect_data ((priv->inhibit_dialog), ("response"
), (((GCallback) (inhibit_dialog_response))), (manager), ((void
*)0), (GConnectFlags) 0)
;
3389 ctk_widget_show (priv->inhibit_dialog);
3390}
3391
3392static void
3393logout_dialog_response (CsmLogoutDialog *logout_dialog,
3394 guint response_id,
3395 CsmManager *manager)
3396{
3397 CsmManagerPrivate *priv;
3398
3399 priv = csm_manager_get_instance_private (manager);
3400 /* We should only be here if mode has already have been set from
3401 * show_fallback_shutdown/logout_dialog
3402 */
3403 g_assert (priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_NORMAL)do { if (priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_NORMAL
) ; else g_assertion_message_expr (((gchar*) 0), "csm-manager.c"
, 3403, ((const char*) (__func__)), "priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_NORMAL"
); } while (0)
;
3404
3405 g_debug ("CsmManager: Logout dialog response: %d", response_id);
3406
3407 ctk_widget_destroy (CTK_WIDGET (logout_dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((logout_dialog)), ((ctk_widget_get_type ()))))))
);
3408
3409 /* In case of dialog cancel, switch user, hibernate and
3410 * suspend, we just perform the respective action and return,
3411 * without shutting down the session. */
3412 switch (response_id) {
3413 case CTK_RESPONSE_CANCEL:
3414 case CTK_RESPONSE_NONE:
3415 case CTK_RESPONSE_DELETE_EVENT:
3416 break;
3417 case CSM_LOGOUT_RESPONSE_SWITCH_USER:
3418 request_switch_user (manager);
3419 break;
3420 case CSM_LOGOUT_RESPONSE_HIBERNATE:
3421 request_hibernate (manager);
3422 break;
3423 case CSM_LOGOUT_RESPONSE_SLEEP:
3424 request_suspend (manager);
3425 break;
3426 case CSM_LOGOUT_RESPONSE_SHUTDOWN:
3427 request_shutdown (manager);
3428 break;
3429 case CSM_LOGOUT_RESPONSE_REBOOT:
3430 request_reboot (manager);
3431 break;
3432 case CSM_LOGOUT_RESPONSE_LOGOUT:
3433 /* We've already gotten confirmation from the user so
3434 * initiate the logout in NO_CONFIRMATION mode.
3435 *
3436 * (it shouldn't matter whether we use NO_CONFIRMATION or stay
3437 * with NORMAL, unless the shell happens to start after the
3438 * user confirmed)
3439 */
3440 request_logout (manager, CSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION);
3441 break;
3442 default:
3443 g_assert_not_reached ()do { g_assertion_message_expr (((gchar*) 0), "csm-manager.c",
3443, ((const char*) (__func__)), ((void*)0)); } while (0)
;
3444 break;
3445 }
3446}
3447
3448static void
3449show_shutdown_dialog (CsmManager *manager)
3450{
3451 CtkWidget *dialog;
3452 CsmManagerPrivate *priv;
3453
3454 priv = csm_manager_get_instance_private (manager);
3455 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION) {
3456 /* Already shutting down, nothing more to do */
3457 return;
3458 }
3459
3460 priv->logout_mode = CSM_MANAGER_LOGOUT_MODE_NORMAL;
3461
3462 dialog = csm_get_shutdown_dialog (cdk_screen_get_default (),
3463 ctk_get_current_event_time ());
3464
3465 g_signal_connect (dialog,g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3466 "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3467 G_CALLBACK (logout_dialog_response),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3468 manager)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
;
3469 ctk_widget_show (dialog);
3470 ctk_window_present_with_time (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
,
3471 cdk_x11_get_server_time (ctk_widget_get_window (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
)));
3472}
3473
3474static void
3475show_logout_dialog (CsmManager *manager)
3476{
3477 CtkWidget *dialog;
3478 CsmManagerPrivate *priv;
3479
3480 priv = csm_manager_get_instance_private (manager);
3481 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION) {
3482 /* Already shutting down, nothing more to do */
3483 return;
3484 }
3485
3486 priv->logout_mode = CSM_MANAGER_LOGOUT_MODE_NORMAL;
3487
3488 dialog = csm_get_logout_dialog (cdk_screen_get_default (),
3489 ctk_get_current_event_time ());
3490
3491 g_signal_connect (dialog,g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3492 "response",g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3493 G_CALLBACK (logout_dialog_response),g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
3494 manager)g_signal_connect_data ((dialog), ("response"), (((GCallback) (
logout_dialog_response))), (manager), ((void*)0), (GConnectFlags
) 0)
;
3495 ctk_widget_show (dialog);
3496 ctk_window_present_with_time (CTK_WINDOW (dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
,
3497 cdk_x11_get_server_time (ctk_widget_get_window (CTK_WIDGET (dialog)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_widget_get_type ()))))))
)));
3498}
3499
3500static void
3501user_logout (CsmManager *manager,
3502 CsmManagerLogoutMode mode)
3503{
3504 gboolean logout_prompt;
3505 CsmManagerPrivate *priv;
3506
3507 priv = csm_manager_get_instance_private (manager);
3508
3509 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION) {
3510 /* Already shutting down, nothing more to do */
3511 return;
3512 }
3513
3514 logout_prompt =
3515 g_settings_get_boolean (priv->settings_session,
3516 "logout-prompt");
3517
3518 /* If the shell isn't running, and this isn't a non-interative logout request,
3519 * and the user has their settings configured to show a confirmation dialog for
3520 * logout, then go ahead and show the confirmation dialog now.
3521 */
3522 if (mode == CSM_MANAGER_LOGOUT_MODE_NORMAL && logout_prompt) {
3523 show_logout_dialog (manager);
3524 } else {
3525 request_logout (manager, mode);
3526 }
3527}
3528
3529/*
3530 dbus-send --session --type=method_call --print-reply
3531 --dest=org.gnome.SessionManager
3532 /org/gnome/SessionManager
3533 org.freedesktop.DBus.Introspectable.Introspect
3534*/
3535
3536gboolean
3537csm_manager_set_phase (CsmManager *manager,
3538 CsmManagerPhase phase)
3539{
3540 CsmManagerPrivate *priv;
3541
3542 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3543
3544 priv = csm_manager_get_instance_private (manager);
3545 priv->phase = phase;
3546 return (TRUE(!(0)));
3547}
3548
3549gboolean
3550csm_manager_request_shutdown (CsmManager *manager,
3551 GError **error)
3552{
3553 CsmManagerPrivate *priv;
3554 g_debug ("CsmManager: RequestShutdown called");
3555
3556 g_return_val_if_fail(CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3557
3558 priv = csm_manager_get_instance_private (manager);
3559 if (priv->phase != CSM_MANAGER_PHASE_RUNNING) {
3560 g_set_error (error,
3561 CSM_MANAGER_ERRORcsm_manager_error_quark (),
3562 CSM_MANAGER_ERROR_NOT_IN_RUNNING,
3563 "RequestShutdown interface is only available during the Running phase");
3564 return FALSE(0);
3565 }
3566
3567 request_shutdown (manager);
3568
3569 return TRUE(!(0));
3570}
3571
3572gboolean
3573csm_manager_request_reboot (CsmManager *manager,
3574 GError **error)
3575{
3576 CsmManagerPrivate *priv;
3577
3578 g_debug ("CsmManager: RequestReboot called");
3579
3580 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3581
3582 priv = csm_manager_get_instance_private (manager);
3583 if (priv->phase != CSM_MANAGER_PHASE_RUNNING) {
3584 g_set_error (error,
3585 CSM_MANAGER_ERRORcsm_manager_error_quark (),
3586 CSM_MANAGER_ERROR_NOT_IN_RUNNING,
3587 "RequestReboot interface is only available during the running phase");
3588 return FALSE(0);
3589 }
3590
3591 request_reboot (manager);
3592
3593 return TRUE(!(0));
3594}
3595
3596static gboolean
3597_log_out_is_locked_down (CsmManager *manager)
3598{
3599 CsmManagerPrivate *priv;
3600
3601 priv = csm_manager_get_instance_private (manager);
3602
3603 return g_settings_get_boolean (priv->settings_lockdown,
3604 KEY_LOG_OUT_DISABLE"disable-log-out");
3605}
3606
3607static gboolean
3608_switch_user_is_locked_down (CsmManager *manager)
3609{
3610 CsmManagerPrivate *priv;
3611
3612 priv = csm_manager_get_instance_private (manager);
3613 return g_settings_get_boolean (priv->settings_lockdown,
3614 KEY_USER_SWITCH_DISABLE"disable-user-switching");
3615}
3616
3617gboolean
3618csm_manager_shutdown (CsmManager *manager,
3619 GError **error)
3620{
3621 CsmManagerPrivate *priv;
3622 g_debug ("CsmManager: Shutdown called");
3623
3624 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3625
3626 priv = csm_manager_get_instance_private (manager);
3627 if (priv->phase != CSM_MANAGER_PHASE_RUNNING) {
3628 g_set_error (error,
3629 CSM_MANAGER_ERRORcsm_manager_error_quark (),
3630 CSM_MANAGER_ERROR_NOT_IN_RUNNING,
3631 "Shutdown interface is only available during the Running phase");
3632 return FALSE(0);
3633 }
3634
3635 if (_log_out_is_locked_down (manager)) {
3636 g_set_error (error,
3637 CSM_MANAGER_ERRORcsm_manager_error_quark (),
3638 CSM_MANAGER_ERROR_LOCKED_DOWN,
3639 "Logout has been locked down");
3640 return FALSE(0);
3641 }
3642
3643 show_shutdown_dialog (manager);
3644
3645 return TRUE(!(0));
3646}
3647
3648gboolean
3649csm_manager_can_shutdown (CsmManager *manager,
3650 gboolean *shutdown_available,
3651 GError **error)
3652{
3653 CsmConsolekit *consolekit;
3654#ifdef HAVE_SYSTEMD1
3655 CsmSystemd *systemd;
3656#endif
3657 g_debug ("CsmManager: CanShutdown called");
3658
3659 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3660
3661#ifdef HAVE_SYSTEMD1
3662 if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) {
3663 systemd = csm_get_systemd ();
3664 *shutdown_available = csm_systemd_can_stop (systemd)
3665 || csm_systemd_can_restart (systemd)
3666 || csm_systemd_can_suspend (systemd)
3667 || csm_systemd_can_hibernate (systemd);
3668 g_object_unref (systemd);
3669 }
3670 else {
3671#endif
3672 consolekit = csm_get_consolekit ();
3673 *shutdown_available = !_log_out_is_locked_down (manager) &&
3674 (csm_consolekit_can_stop (consolekit)
3675 || csm_consolekit_can_restart (consolekit)
3676 || csm_consolekit_can_suspend (consolekit)
3677 || csm_consolekit_can_hibernate (consolekit));
3678 g_object_unref (consolekit);
3679#ifdef HAVE_SYSTEMD1
3680 }
3681#endif
3682
3683 return TRUE(!(0));
3684}
3685
3686gboolean
3687csm_manager_logout (CsmManager *manager,
3688 guint logout_mode,
3689 GError **error)
3690{
3691 CsmManagerPrivate *priv;
3692 g_debug ("CsmManager: Logout called");
3693
3694 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3695
3696 priv = csm_manager_get_instance_private (manager);
3697 if (priv->phase != CSM_MANAGER_PHASE_RUNNING) {
3698 g_set_error (error,
3699 CSM_MANAGER_ERRORcsm_manager_error_quark (),
3700 CSM_MANAGER_ERROR_NOT_IN_RUNNING,
3701 "Shutdown interface is only available during the Running phase");
3702 return FALSE(0);
3703 }
3704
3705 if (_log_out_is_locked_down (manager)) {
3706 g_set_error (error,
3707 CSM_MANAGER_ERRORcsm_manager_error_quark (),
3708 CSM_MANAGER_ERROR_LOCKED_DOWN,
3709 "Logout has been locked down");
3710 return FALSE(0);
3711 }
3712
3713 switch (logout_mode) {
3714 case CSM_MANAGER_LOGOUT_MODE_NORMAL:
3715 case CSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION:
3716 case CSM_MANAGER_LOGOUT_MODE_FORCE:
3717 user_logout (manager, logout_mode);
3718 break;
3719
3720 default:
3721 g_debug ("Unknown logout mode option");
3722
3723 g_set_error (error,
3724 CSM_MANAGER_ERRORcsm_manager_error_quark (),
3725 CSM_MANAGER_ERROR_INVALID_OPTION,
3726 "Unknown logout mode flag");
3727 return FALSE(0);
3728 }
3729
3730 return TRUE(!(0));
3731}
3732
3733gboolean
3734csm_manager_register_client (CsmManager *manager,
3735 const char *app_id,
3736 const char *startup_id,
3737 DBusGMethodInvocation *context)
3738{
3739 char *new_startup_id;
3740 char *sender;
3741 CsmClient *client;
3742 CsmApp *app;
3743 CsmManagerPrivate *priv;
3744
3745 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3746
3747 app = NULL((void*)0);
3748 client = NULL((void*)0);
3749
3750 g_debug ("CsmManager: RegisterClient %s", startup_id);
3751
3752 priv = csm_manager_get_instance_private (manager);
3753 if (priv->phase >= CSM_MANAGER_PHASE_QUERY_END_SESSION) {
3754 GError *new_error;
3755
3756 g_debug ("Unable to register client: shutting down");
3757
3758 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3759 CSM_MANAGER_ERROR_NOT_IN_RUNNING,
3760 "Unable to register client");
3761 dbus_g_method_return_error (context, new_error);
3762 g_error_free (new_error);
3763 return FALSE(0);
3764 }
3765
3766 if (IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
3767 new_startup_id = csm_util_generate_startup_id ();
3768 } else {
3769
3770 client = (CsmClient *)csm_store_find (priv->clients,
3771 (CsmStoreFunc)_client_has_startup_id,
3772 (char *)startup_id);
3773 /* We can't have two clients with the same startup id. */
3774 if (client != NULL((void*)0)) {
3775 GError *new_error;
3776
3777 g_debug ("Unable to register client: already registered");
3778
3779 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3780 CSM_MANAGER_ERROR_ALREADY_REGISTERED,
3781 "Unable to register client");
3782 dbus_g_method_return_error (context, new_error);
3783 g_error_free (new_error);
3784 return FALSE(0);
3785 }
3786
3787 new_startup_id = g_strdup (startup_id)g_strdup_inline (startup_id);
3788 }
3789
3790 g_debug ("CsmManager: Adding new client %s to session", new_startup_id);
3791
3792 if (app == NULL((void*)0) && !IS_STRING_EMPTY (startup_id)((startup_id)==((void*)0)||(startup_id)[0]=='\0')) {
3793 app = find_app_for_startup_id (manager, startup_id);
3794 }
3795 if (app == NULL((void*)0) && !IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
3796 /* try to associate this app id with a known app */
3797 app = find_app_for_app_id (manager, app_id);
3798 }
3799
3800 sender = dbus_g_method_get_sender (context);
3801 client = csm_dbus_client_new (new_startup_id, sender);
3802 g_free (sender);
3803 if (client == NULL((void*)0)) {
3804 GError *new_error;
3805
3806 g_debug ("Unable to create client");
3807
3808 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3809 CSM_MANAGER_ERROR_GENERAL,
3810 "Unable to register client");
3811 dbus_g_method_return_error (context, new_error);
3812 g_error_free (new_error);
3813 return FALSE(0);
3814 }
3815
3816 csm_store_add (priv->clients, csm_client_peek_id (client), G_OBJECT (client)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((client)), (((GType) ((20) << (2))))))))
);
3817 /* the store will own the ref */
3818 g_object_unref (client);
3819
3820 if (app != NULL((void*)0)) {
3821 csm_client_set_app_id (client, csm_app_peek_app_id (app));
3822 csm_app_registered (app);
3823 } else {
3824 /* if an app id is specified store it in the client
3825 so we can save it later */
3826 csm_client_set_app_id (client, app_id);
3827 }
3828
3829 csm_client_set_status (client, CSM_CLIENT_REGISTERED);
3830
3831 g_assert (new_startup_id != NULL)do { if (new_startup_id != ((void*)0)) ; else g_assertion_message_expr
(((gchar*) 0), "csm-manager.c", 3831, ((const char*) (__func__
)), "new_startup_id != NULL"); } while (0)
;
3832 g_free (new_startup_id);
3833
3834 dbus_g_method_return (context, csm_client_peek_id (client));
3835
3836 return TRUE(!(0));
3837}
3838
3839gboolean
3840csm_manager_unregister_client (CsmManager *manager,
3841 const char *client_id,
3842 DBusGMethodInvocation *context)
3843{
3844 CsmClient *client;
3845 CsmManagerPrivate *priv;
3846
3847 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3848
3849 g_debug ("CsmManager: UnregisterClient %s", client_id);
3850
3851 priv = csm_manager_get_instance_private (manager);
3852 client = (CsmClient *)csm_store_lookup (priv->clients, client_id);
3853 if (client == NULL((void*)0)) {
3854 GError *new_error;
3855
3856 g_debug ("Unable to unregister client: not registered");
3857
3858 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3859 CSM_MANAGER_ERROR_NOT_REGISTERED,
3860 "Unable to unregister client");
3861 dbus_g_method_return_error (context, new_error);
3862 g_error_free (new_error);
3863 return FALSE(0);
3864 }
3865
3866 /* don't disconnect client here, only change the status.
3867 Wait until it leaves the bus before disconnecting it */
3868 csm_client_set_status (client, CSM_CLIENT_UNREGISTERED);
3869
3870 dbus_g_method_return (context);
3871
3872 return TRUE(!(0));
3873}
3874
3875gboolean
3876csm_manager_inhibit (CsmManager *manager,
3877 const char *app_id,
3878 guint toplevel_xid,
3879 const char *reason,
3880 guint flags,
3881 DBusGMethodInvocation *context)
3882{
3883 CsmInhibitor *inhibitor;
3884 guint cookie;
3885 CsmManagerPrivate *priv;
3886
3887 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3888
3889 g_debug ("CsmManager: Inhibit xid=%u app_id=%s reason=%s flags=%u",
3890 toplevel_xid,
3891 app_id,
3892 reason,
3893 flags);
3894
3895 priv = csm_manager_get_instance_private (manager);
3896 if (priv->logout_mode == CSM_MANAGER_LOGOUT_MODE_FORCE) {
3897 GError *new_error;
3898
3899 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3900 CSM_MANAGER_ERROR_GENERAL,
3901 "Forced logout cannot be inhibited");
3902 g_debug ("CsmManager: Unable to inhibit: %s", new_error->message);
3903 dbus_g_method_return_error (context, new_error);
3904 g_error_free (new_error);
3905 return FALSE(0);
3906 }
3907
3908 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
3909 GError *new_error;
3910
3911 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3912 CSM_MANAGER_ERROR_GENERAL,
3913 "Application ID not specified");
3914 g_debug ("CsmManager: Unable to inhibit: %s", new_error->message);
3915 dbus_g_method_return_error (context, new_error);
3916 g_error_free (new_error);
3917 return FALSE(0);
3918 }
3919
3920 if (IS_STRING_EMPTY (reason)((reason)==((void*)0)||(reason)[0]=='\0')) {
3921 GError *new_error;
3922
3923 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3924 CSM_MANAGER_ERROR_GENERAL,
3925 "Reason not specified");
3926 g_debug ("CsmManager: Unable to inhibit: %s", new_error->message);
3927 dbus_g_method_return_error (context, new_error);
3928 g_error_free (new_error);
3929 return FALSE(0);
3930 }
3931
3932 if (flags == 0) {
3933 GError *new_error;
3934
3935 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3936 CSM_MANAGER_ERROR_GENERAL,
3937 "Invalid inhibit flags");
3938 g_debug ("CsmManager: Unable to inhibit: %s", new_error->message);
3939 dbus_g_method_return_error (context, new_error);
3940 g_error_free (new_error);
3941 return FALSE(0);
3942 }
3943
3944 cookie = _generate_unique_cookie (manager);
3945 inhibitor = csm_inhibitor_new (app_id,
3946 toplevel_xid,
3947 flags,
3948 reason,
3949 dbus_g_method_get_sender (context),
3950 cookie);
3951 csm_store_add (priv->inhibitors, csm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((inhibitor)), (((GType) ((20) << (2))))))))
);
3952 g_object_unref (inhibitor);
3953
3954 dbus_g_method_return (context, cookie);
3955
3956 return TRUE(!(0));
3957}
3958
3959gboolean
3960csm_manager_uninhibit (CsmManager *manager,
3961 guint cookie,
3962 DBusGMethodInvocation *context)
3963{
3964 CsmInhibitor *inhibitor;
3965 CsmManagerPrivate *priv;
3966
3967 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
3968
3969 g_debug ("CsmManager: Uninhibit %u", cookie);
3970
3971 priv = csm_manager_get_instance_private (manager);
3972 inhibitor = (CsmInhibitor *)csm_store_find (priv->inhibitors,
3973 (CsmStoreFunc)_find_by_cookie,
3974 &cookie);
3975 if (inhibitor == NULL((void*)0)) {
3976 GError *new_error;
3977
3978 new_error = g_error_new (CSM_MANAGER_ERRORcsm_manager_error_quark (),
3979 CSM_MANAGER_ERROR_GENERAL,
3980 "Unable to uninhibit: Invalid cookie");
3981 dbus_g_method_return_error (context, new_error);
3982 g_debug ("Unable to uninhibit: %s", new_error->message);
3983 g_error_free (new_error);
3984 return FALSE(0);
3985 }
3986
3987 g_debug ("CsmManager: removing inhibitor %s %u reason '%s' %u connection %s",
3988 csm_inhibitor_peek_app_id (inhibitor),
3989 csm_inhibitor_peek_toplevel_xid (inhibitor),
3990 csm_inhibitor_peek_reason (inhibitor),
3991 csm_inhibitor_peek_flags (inhibitor),
3992 csm_inhibitor_peek_bus_name (inhibitor));
3993
3994 csm_store_remove (priv->inhibitors, csm_inhibitor_peek_id (inhibitor));
3995
3996 dbus_g_method_return (context);
3997
3998 return TRUE(!(0));
3999}
4000
4001gboolean
4002csm_manager_is_inhibited (CsmManager *manager,
4003 guint flags,
4004 gboolean *is_inhibited,
4005 GError *error)
4006{
4007 CsmInhibitor *inhibitor;
4008 CsmManagerPrivate *priv;
4009
4010 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4011
4012 priv = csm_manager_get_instance_private (manager);
4013 if (priv->inhibitors == NULL((void*)0)
4014 || csm_store_size (priv->inhibitors) == 0) {
4015 *is_inhibited = FALSE(0);
4016 return TRUE(!(0));
4017 }
4018
4019 inhibitor = (CsmInhibitor *) csm_store_find (priv->inhibitors,
4020 (CsmStoreFunc)inhibitor_has_flag,
4021 GUINT_TO_POINTER (flags)((gpointer) (gulong) (flags)));
4022 if (inhibitor == NULL((void*)0)) {
4023 *is_inhibited = FALSE(0);
4024 } else {
4025 *is_inhibited = TRUE(!(0));
4026 }
4027
4028 return TRUE(!(0));
4029
4030}
4031
4032static gboolean
4033listify_store_ids (char *id,
4034 GObject *object,
4035 GPtrArray **array)
4036{
4037 g_ptr_array_add (*array, g_strdup (id)g_strdup_inline (id));
4038 return FALSE(0);
4039}
4040
4041gboolean
4042csm_manager_get_clients (CsmManager *manager,
4043 GPtrArray **clients,
4044 GError **error)
4045{
4046 CsmManagerPrivate *priv;
4047 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4048
4049 if (clients == NULL((void*)0)) {
4050 return FALSE(0);
4051 }
4052
4053 *clients = g_ptr_array_new ();
4054 priv = csm_manager_get_instance_private (manager);
4055 csm_store_foreach (priv->clients, (CsmStoreFunc)listify_store_ids, clients);
4056
4057 return TRUE(!(0));
4058}
4059
4060gboolean
4061csm_manager_get_inhibitors (CsmManager *manager,
4062 GPtrArray **inhibitors,
4063 GError **error)
4064{
4065 CsmManagerPrivate *priv;
4066
4067 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4068
4069 if (inhibitors == NULL((void*)0)) {
4070 return FALSE(0);
4071 }
4072
4073 *inhibitors = g_ptr_array_new ();
4074 priv = csm_manager_get_instance_private (manager);
4075 csm_store_foreach (priv->inhibitors,
4076 (CsmStoreFunc) listify_store_ids,
4077 inhibitors);
4078
4079 return TRUE(!(0));
4080}
4081
4082
4083static gboolean
4084_app_has_autostart_condition (const char *id,
4085 CsmApp *app,
4086 const char *condition)
4087{
4088 gboolean has;
4089 gboolean disabled;
4090
4091 has = csm_app_has_autostart_condition (app, condition);
4092 disabled = csm_app_peek_is_disabled (app);
4093
4094 return has && !disabled;
4095}
4096
4097gboolean
4098csm_manager_is_autostart_condition_handled (CsmManager *manager,
4099 const char *condition,
4100 gboolean *handled,
4101 GError **error)
4102{
4103 CsmApp *app;
4104 CsmManagerPrivate *priv;
4105
4106 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4107
4108 priv = csm_manager_get_instance_private (manager);
4109 app = (CsmApp *) csm_store_find (priv->apps,(
4110 CsmStoreFunc) _app_has_autostart_condition,
4111 (char *)condition);
4112
4113 if (app != NULL((void*)0)) {
4114 *handled = TRUE(!(0));
4115 } else {
4116 *handled = FALSE(0);
4117 }
4118
4119 return TRUE(!(0));
4120}
4121
4122static void
4123append_app (CsmManager *manager,
4124 CsmApp *app)
4125{
4126 const char *id;
4127 const char *app_id;
4128 CsmApp *dup;
4129 CsmManagerPrivate *priv;
4130
4131 id = csm_app_peek_id (app);
4132 if (IS_STRING_EMPTY (id)((id)==((void*)0)||(id)[0]=='\0')) {
4133 g_debug ("CsmManager: not adding app: no id");
4134 return;
4135 }
4136
4137 priv = csm_manager_get_instance_private (manager);
4138 dup = (CsmApp *)csm_store_lookup (priv->apps, id);
4139 if (dup != NULL((void*)0)) {
4140 g_debug ("CsmManager: not adding app: already added");
4141 return;
4142 }
4143
4144 app_id = csm_app_peek_app_id (app);
4145 if (IS_STRING_EMPTY (app_id)((app_id)==((void*)0)||(app_id)[0]=='\0')) {
4146 g_debug ("CsmManager: not adding app: no app-id");
4147 return;
4148 }
4149
4150 dup = find_app_for_app_id (manager, app_id);
4151 if (dup != NULL((void*)0)) {
4152 g_debug ("CsmManager: not adding app: app-id already exists");
4153 return;
4154 }
4155
4156 csm_store_add (priv->apps, id, G_OBJECT (app)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), (((GType) ((20) << (2))))))))
);
4157}
4158
4159gboolean
4160csm_manager_add_autostart_app (CsmManager *manager,
4161 const char *path,
4162 const char *provides)
4163{
4164 CsmApp *app;
4165 CsmManagerPrivate *priv;
4166
4167 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4168 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
((0)); } } while (0)
;
4169
4170 priv = csm_manager_get_instance_private (manager);
4171 /* first check to see if service is already provided */
4172 if (provides != NULL((void*)0)) {
4173 CsmApp *dup;
4174
4175 dup = (CsmApp *)csm_store_find (priv->apps,
4176 (CsmStoreFunc)_find_app_provides,
4177 (char *)provides);
4178 if (dup != NULL((void*)0)) {
4179 g_debug ("CsmManager: service '%s' is already provided", provides);
4180 return FALSE(0);
4181 }
4182 }
4183
4184 app = csm_autostart_app_new (path);
4185 if (app == NULL((void*)0)) {
4186 g_warning ("could not read %s", path);
4187 return FALSE(0);
4188 }
4189
4190 g_debug ("CsmManager: read %s", path);
4191 append_app (manager, app);
4192 g_object_unref (app);
4193
4194 return TRUE(!(0));
4195}
4196
4197gboolean
4198csm_manager_add_autostart_apps_from_dir (CsmManager *manager,
4199 const char *path)
4200{
4201 GDir *dir;
4202 const char *name;
4203
4204 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4205 g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "path != NULL"); return
((0)); } } while (0)
;
4206
4207 g_debug ("CsmManager: *** Adding autostart apps for %s", path);
4208
4209 dir = g_dir_open (path, 0, NULL((void*)0));
4210 if (dir == NULL((void*)0)) {
4211 return FALSE(0);
4212 }
4213
4214 while ((name = g_dir_read_name (dir))) {
4215 char *desktop_file;
4216
4217 if (!g_str_has_suffix (name, ".desktop")(__builtin_constant_p (".desktop")? __extension__ ({ const char
* const __str = (name); const char * const __suffix = (".desktop"
); gboolean __result = (0); if (__str == ((void*)0) || __suffix
== ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix
))); if (__str_len >= __suffix_len) __result = memcmp (__str
+ __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len
) == 0; } __result; }) : (g_str_has_suffix) (name, ".desktop"
) )
) {
4218 continue;
4219 }
4220
4221 desktop_file = g_build_filename (path, name, NULL((void*)0));
4222 csm_manager_add_autostart_app (manager, desktop_file, NULL((void*)0));
4223 g_free (desktop_file);
4224 }
4225
4226 g_dir_close (dir);
4227
4228 return TRUE(!(0));
4229}
4230
4231gboolean
4232csm_manager_is_session_running (CsmManager *manager,
4233 gboolean *running,
4234 GError **error)
4235{
4236 CsmManagerPrivate *priv;
4237
4238 g_return_val_if_fail (CSM_IS_MANAGER (manager), FALSE)do { if ((CSM_IS_MANAGER (manager))) { } else { g_return_if_fail_warning
(((gchar*) 0), ((const char*) (__func__)), "CSM_IS_MANAGER (manager)"
); return ((0)); } } while (0)
;
4239
4240 priv = csm_manager_get_instance_private (manager);
4241 *running = (priv->phase == CSM_MANAGER_PHASE_RUNNING);
4242 return TRUE(!(0));
4243}