File: | cafe-session/csm-manager.c |
Warning: | line 920, column 9 Value stored to 'reply' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |
104 | typedef 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 | |
116 | typedef 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 | |
154 | enum { |
155 | PROP_0, |
156 | PROP_CLIENT_STORE, |
157 | PROP_RENDERER, |
158 | PROP_FAILSAFE |
159 | }; |
160 | |
161 | enum { |
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 | |
172 | static guint signals [LAST_SIGNAL] = { 0 }; |
173 | |
174 | static void csm_manager_finalize (GObject *object); |
175 | |
176 | static gboolean _log_out_is_locked_down (CsmManager *manager); |
177 | static gboolean _switch_user_is_locked_down (CsmManager *manager); |
178 | |
179 | static 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 | |
186 | static gboolean auto_save_is_enabled (CsmManager *manager); |
187 | static void maybe_save_session (CsmManager *manager); |
188 | |
189 | static gpointer manager_object = NULL((void*)0); |
190 | |
191 | G_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 | |
193 | GQuark |
194 | csm_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 | |
206 | GType |
207 | csm_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 | |
231 | static 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 | |
240 | static void |
241 | debug_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 | |
250 | static 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 | |
263 | static void |
264 | debug_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 | |
274 | static 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 | |
286 | static 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 | |
301 | static void |
302 | app_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 | |
373 | static const char * |
374 | phase_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 | |
417 | static void start_phase (CsmManager *manager); |
418 | |
419 | static void |
420 | quit_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 |
436 | static void |
437 | quit_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 | |
453 | static void |
454 | csm_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 | |
534 | static void |
535 | end_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 | |
594 | static void |
595 | app_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 | |
614 | static gboolean |
615 | on_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 | |
654 | static 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 | |
678 | static 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 | |
744 | static void |
745 | do_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 | |
765 | typedef struct { |
766 | CsmManager *manager; |
767 | guint flags; |
768 | } ClientEndSessionData; |
769 | |
770 | |
771 | static 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 | |
796 | static 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 | |
804 | static void |
805 | do_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 | |
839 | static void |
840 | do_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 | |
872 | static 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 |
894 | static void |
895 | maybe_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 | |
938 | static void |
939 | do_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 | |
957 | static 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 | |
982 | static gboolean |
983 | inhibitor_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 | |
997 | static gboolean |
998 | csm_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 | |
1018 | static gboolean |
1019 | csm_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 | |
1039 | static 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 | |
1057 | static gboolean |
1058 | inhibitor_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 | |
1072 | static void |
1073 | cancel_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 | |
1111 | static gboolean |
1112 | process_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 | |
1132 | static void |
1133 | manager_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 | |
1211 | static gboolean |
1212 | sleep_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 | |
1224 | static void |
1225 | manager_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 | |
1244 | static void |
1245 | manager_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 | |
1276 | static void |
1277 | manager_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 | |
1308 | static void |
1309 | do_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 | |
1337 | static void |
1338 | inhibit_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 | |
1378 | static void |
1379 | query_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 | |
1443 | static guint32 |
1444 | generate_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 | |
1453 | static 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 | |
1468 | static 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 | |
1529 | static void |
1530 | do_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 | |
1560 | static void |
1561 | update_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 | |
1573 | static void |
1574 | start_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 | |
1628 | static 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 | |
1651 | static void |
1652 | debug_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 | |
1668 | void |
1669 | csm_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 | |
1680 | void |
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 | |
1689 | static 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 | |
1700 | static CsmApp * |
1701 | find_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 | |
1714 | static gboolean |
1715 | inhibitor_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 | |
1737 | static 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 | |
1753 | static CsmApp * |
1754 | find_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 | |
1791 | static 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 | |
1905 | typedef struct { |
1906 | const char *service_name; |
1907 | CsmManager *manager; |
1908 | } RemoveClientData; |
1909 | |
1910 | static 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 | */ |
1949 | static void |
1950 | remove_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 | |
1972 | static gboolean |
1973 | inhibitor_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 | |
1996 | static void |
1997 | remove_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 | |
2015 | static void |
2016 | bus_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 | |
2036 | static DBusHandlerResult |
2037 | csm_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 | |
2060 | static gboolean |
2061 | register_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 | |
2106 | static void |
2107 | csm_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 | |
2119 | static 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 | |
2135 | static void |
2136 | on_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 | |
2154 | static gboolean |
2155 | on_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 | |
2218 | static gboolean |
2219 | auto_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 | |
2228 | static void |
2229 | maybe_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 | |
2276 | out: |
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 | |
2286 | static 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 | |
2379 | static void |
2380 | on_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 | |
2395 | static void |
2396 | on_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 | |
2417 | static void |
2418 | on_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 | |
2449 | static void |
2450 | on_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 | |
2459 | static void |
2460 | csm_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 | |
2500 | static void |
2501 | csm_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 | |
2523 | static void |
2524 | csm_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 | |
2551 | static 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 | |
2559 | static GObject * |
2560 | csm_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 | |
2572 | static void |
2573 | on_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 | |
2582 | static void |
2583 | on_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 | |
2592 | static void |
2593 | csm_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 | |
2652 | static void |
2653 | csm_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 | |
2762 | static void |
2763 | load_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 | |
2774 | static void |
2775 | on_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 | |
2799 | static void |
2800 | on_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 | |
2824 | static void |
2825 | csm_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 | |
2883 | static void |
2884 | csm_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 | |
2900 | CsmManager * |
2901 | csm_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 | |
2926 | gboolean |
2927 | csm_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 | |
2950 | gboolean |
2951 | csm_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 | |
2974 | static gboolean |
2975 | csm_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 | |
2995 | static gboolean |
2996 | csm_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 | |
3016 | static void |
3017 | request_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 |
3047 | static void |
3048 | request_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 | |
3078 | static void |
3079 | request_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 | |
3156 | static void |
3157 | request_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 |
3187 | static void |
3188 | request_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 | |
3218 | static void |
3219 | request_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 | |
3277 | static void |
3278 | request_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 | |
3307 | static void |
3308 | request_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 | |
3339 | static void |
3340 | request_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 | |
3355 | static void |
3356 | request_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 | |
3392 | static void |
3393 | logout_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 | |
3448 | static void |
3449 | show_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 | |
3474 | static void |
3475 | show_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 | |
3500 | static void |
3501 | user_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 | |
3536 | gboolean |
3537 | csm_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 | |
3549 | gboolean |
3550 | csm_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 | |
3572 | gboolean |
3573 | csm_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 | |
3596 | static 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 | |
3607 | static 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 | |
3617 | gboolean |
3618 | csm_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 | |
3648 | gboolean |
3649 | csm_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 | |
3686 | gboolean |
3687 | csm_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 | |
3733 | gboolean |
3734 | csm_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 | |
3839 | gboolean |
3840 | csm_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 | |
3875 | gboolean |
3876 | csm_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 | |
3959 | gboolean |
3960 | csm_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 | |
4001 | gboolean |
4002 | csm_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 | |
4032 | static gboolean |
4033 | listify_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 | |
4041 | gboolean |
4042 | csm_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 | |
4060 | gboolean |
4061 | csm_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 | |
4083 | static 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 | |
4097 | gboolean |
4098 | csm_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 | |
4122 | static void |
4123 | append_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 | |
4159 | gboolean |
4160 | csm_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 | |
4197 | gboolean |
4198 | csm_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 | |
4231 | gboolean |
4232 | csm_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 | } |