File: | cafe-session/main.c |
Warning: | line 629, column 16 Using a fixed address is not portable because that address will probably not be valid in all environments or platforms |
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) 2006 Novell, Inc. | |||
4 | * Copyright (C) 2008 Red Hat, Inc. | |||
5 | * | |||
6 | * This program is free software; you can redistribute it and/or | |||
7 | * modify it under the terms of the GNU General Public License as | |||
8 | * published by the Free Software Foundation; either version 2 of the | |||
9 | * License, or (at your option) any later version. | |||
10 | * | |||
11 | * This program is distributed in the hope that it will be useful, but | |||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
14 | * Lesser General Public License for more details. | |||
15 | * | |||
16 | * You should have received a copy of the GNU General Public License | |||
17 | * along with this program; if not, write to the Free Software | |||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |||
19 | * 02110-1301, USA. | |||
20 | */ | |||
21 | ||||
22 | #include <config.h> | |||
23 | ||||
24 | #include <libintl.h> | |||
25 | #include <signal.h> | |||
26 | #include <stdlib.h> | |||
27 | #include <string.h> | |||
28 | #include <unistd.h> | |||
29 | #include <errno(*__errno_location ()).h> | |||
30 | #include <time.h> | |||
31 | ||||
32 | #include <glib/gi18n.h> | |||
33 | #include <glib.h> | |||
34 | #include <ctk/ctk.h> | |||
35 | #include <gio/gio.h> | |||
36 | ||||
37 | #include <dbus/dbus.h> | |||
38 | #include <dbus/dbus-glib.h> | |||
39 | #include <dbus/dbus-glib-bindings.h> | |||
40 | #include <dbus/dbus-glib-lowlevel.h> | |||
41 | ||||
42 | #include "cdm-signal-handler.h" | |||
43 | #include "cdm-log.h" | |||
44 | ||||
45 | #include "csm-consolekit.h" | |||
46 | #ifdef HAVE_SYSTEMD1 | |||
47 | #include "csm-systemd.h" | |||
48 | #endif | |||
49 | #include "csm-util.h" | |||
50 | #include "csm-manager.h" | |||
51 | #include "csm-xsmp-server.h" | |||
52 | #include "csm-store.h" | |||
53 | ||||
54 | #include "msm-gnome.h" | |||
55 | ||||
56 | #define CSM_SCHEMA"org.cafe.session" "org.cafe.session" | |||
57 | #define CSM_DEFAULT_SESSION_KEY"default-session" "default-session" | |||
58 | #define CSM_REQUIRED_COMPONENTS_SCHEMA"org.cafe.session" ".required-components" CSM_SCHEMA"org.cafe.session" ".required-components" | |||
59 | #define CSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list" "required-components-list" | |||
60 | ||||
61 | #define ACCESSIBILITY_KEY"accessibility" "accessibility" | |||
62 | #define ACCESSIBILITY_SCHEMA"org.cafe.interface" "org.cafe.interface" | |||
63 | ||||
64 | #define DEBUG_SCHEMA"org.cafe.debug" "org.cafe.debug" | |||
65 | #define DEBUG_KEY"cafe-session" "cafe-session" | |||
66 | ||||
67 | #define VISUAL_SCHEMA"org.cafe.applications-at-visual" "org.cafe.applications-at-visual" | |||
68 | #define VISUAL_KEY"exec" "exec" | |||
69 | #define VISUAL_STARTUP_KEY"startup" "startup" | |||
70 | ||||
71 | #define MOBILITY_SCHEMA"org.cafe.applications-at-mobility" "org.cafe.applications-at-mobility" | |||
72 | #define MOBILITY_KEY"exec" "exec" | |||
73 | #define MOBILITY_STARTUP_KEY"startup" "startup" | |||
74 | ||||
75 | #define CAFE_INTERFACE_SCHEMA"org.cafe.interface" "org.cafe.interface" | |||
76 | #define CTK_OVERLAY_SCROLL"ctk-overlay-scrolling" "ctk-overlay-scrolling" | |||
77 | ||||
78 | #define CSM_DBUS_NAME"org.gnome.SessionManager" "org.gnome.SessionManager" | |||
79 | ||||
80 | #define KEY_AUTOSAVE"auto-save-session" "auto-save-session" | |||
81 | ||||
82 | static gboolean failsafe = FALSE(0); | |||
83 | static gboolean show_version = FALSE(0); | |||
84 | static gboolean debug = FALSE(0); | |||
85 | static gboolean disable_acceleration_check = FALSE(0); | |||
86 | static char *gl_renderer = NULL((void*)0); | |||
87 | ||||
88 | static gboolean | |||
89 | initialize_gsettings (void) | |||
90 | { | |||
91 | GSettings* settings; | |||
92 | time_t now = time (0); | |||
93 | gboolean ret; | |||
94 | ||||
95 | settings = g_settings_new (CSM_SCHEMA"org.cafe.session"); | |||
96 | ||||
97 | if (!settings) | |||
98 | return FALSE(0); | |||
99 | ||||
100 | ret = g_settings_set_int (settings, "session-start", now); | |||
101 | ||||
102 | g_settings_sync (); | |||
103 | ||||
104 | g_object_unref (settings); | |||
105 | ||||
106 | return ret; | |||
107 | } | |||
108 | ||||
109 | static void on_bus_name_lost(DBusGProxy* bus_proxy, const char* name, gpointer data) | |||
110 | { | |||
111 | g_warning("Lost name on bus: %s, exiting", name); | |||
112 | exit(1); | |||
113 | } | |||
114 | ||||
115 | static gboolean acquire_name_on_proxy(DBusGProxy* bus_proxy, const char* name) | |||
116 | { | |||
117 | GError* error; | |||
118 | guint result; | |||
119 | gboolean res; | |||
120 | gboolean ret; | |||
121 | ||||
122 | ret = FALSE(0); | |||
123 | ||||
124 | if (bus_proxy == NULL((void*)0)) | |||
125 | { | |||
126 | goto out; | |||
127 | } | |||
128 | ||||
129 | error = NULL((void*)0); | |||
130 | res = dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING((GType) ((16) << (2))), name, G_TYPE_UINT((GType) ((7) << (2))), 0, G_TYPE_INVALID((GType) ((0) << (2))), G_TYPE_UINT((GType) ((7) << (2))), &result, G_TYPE_INVALID((GType) ((0) << (2)))); | |||
131 | ||||
132 | if (! res) | |||
133 | { | |||
134 | if (error != NULL((void*)0)) | |||
135 | { | |||
136 | g_warning("Failed to acquire %s: %s", name, error->message); | |||
137 | g_error_free(error); | |||
138 | } | |||
139 | else | |||
140 | { | |||
141 | g_warning ("Failed to acquire %s", name); | |||
142 | } | |||
143 | ||||
144 | goto out; | |||
145 | } | |||
146 | ||||
147 | if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER1) | |||
148 | { | |||
149 | if (error != NULL((void*)0)) | |||
150 | { | |||
151 | g_warning("Failed to acquire %s: %s", name, error->message); | |||
152 | g_error_free(error); | |||
153 | } | |||
154 | else | |||
155 | { | |||
156 | g_warning("Failed to acquire %s", name); | |||
157 | } | |||
158 | ||||
159 | goto out; | |||
160 | } | |||
161 | ||||
162 | /* register for name lost */ | |||
163 | dbus_g_proxy_add_signal(bus_proxy, "NameLost", G_TYPE_STRING((GType) ((16) << (2))), G_TYPE_INVALID((GType) ((0) << (2)))); | |||
164 | dbus_g_proxy_connect_signal(bus_proxy, "NameLost", G_CALLBACK(on_bus_name_lost)((GCallback) (on_bus_name_lost)), NULL((void*)0), NULL((void*)0)); | |||
165 | ||||
166 | ret = TRUE(!(0)); | |||
167 | ||||
168 | out: | |||
169 | ||||
170 | return ret; | |||
171 | } | |||
172 | ||||
173 | static gboolean acquire_name(void) | |||
174 | { | |||
175 | DBusGProxy* bus_proxy; | |||
176 | GError* error; | |||
177 | DBusGConnection* connection; | |||
178 | ||||
179 | error = NULL((void*)0); | |||
180 | connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); | |||
181 | ||||
182 | if (connection == NULL((void*)0)) | |||
183 | { | |||
184 | csm_util_init_error(TRUE(!(0)), "Could not connect to session bus: %s", error->message); | |||
185 | /* not reached */ | |||
186 | } | |||
187 | ||||
188 | bus_proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS"org.freedesktop.DBus", DBUS_PATH_DBUS"/org/freedesktop/DBus", DBUS_INTERFACE_DBUS"org.freedesktop.DBus"); | |||
189 | ||||
190 | if (!acquire_name_on_proxy(bus_proxy, CSM_DBUS_NAME"org.gnome.SessionManager")) | |||
191 | { | |||
192 | csm_util_init_error(TRUE(!(0)), "%s", "Could not acquire name on session bus"); | |||
193 | /* not reached */ | |||
194 | } | |||
195 | ||||
196 | g_object_unref(bus_proxy); | |||
197 | ||||
198 | return TRUE(!(0)); | |||
199 | } | |||
200 | ||||
201 | /* This doesn't contain the required components, so we need to always | |||
202 | * call append_required_apps() after a call to append_default_apps(). */ | |||
203 | static void append_default_apps(CsmManager* manager, const char* default_session_key, char** autostart_dirs) | |||
204 | { | |||
205 | gint i; | |||
206 | gchar** default_apps; | |||
207 | GSettings* settings; | |||
208 | ||||
209 | g_debug("main: *** Adding default apps"); | |||
210 | ||||
211 | g_assert(default_session_key != NULL)do { if (default_session_key != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "main.c", 211, ((const char*) (__func__)), "default_session_key != NULL" ); } while (0); | |||
212 | g_assert(autostart_dirs != NULL)do { if (autostart_dirs != ((void*)0)) ; else g_assertion_message_expr (((gchar*) 0), "main.c", 212, ((const char*) (__func__)), "autostart_dirs != NULL" ); } while (0); | |||
213 | ||||
214 | settings = g_settings_new (CSM_SCHEMA"org.cafe.session"); | |||
215 | default_apps = g_settings_get_strv (settings, default_session_key); | |||
216 | g_object_unref(settings); | |||
217 | ||||
218 | for (i = 0; default_apps[i]; i++) | |||
219 | { | |||
220 | char* app_path; | |||
221 | ||||
222 | if (IS_STRING_EMPTY((char*) default_apps[i])(((char*) default_apps[i])==((void*)0)||((char*) default_apps [i])[0]=='\0')) | |||
223 | { | |||
224 | continue; | |||
225 | } | |||
226 | ||||
227 | app_path = csm_util_find_desktop_file_for_app_name(default_apps[i], autostart_dirs); | |||
228 | ||||
229 | if (app_path != NULL((void*)0)) | |||
230 | { | |||
231 | csm_manager_add_autostart_app(manager, app_path, NULL((void*)0)); | |||
232 | g_free(app_path); | |||
233 | } | |||
234 | } | |||
235 | ||||
236 | g_strfreev (default_apps); | |||
237 | } | |||
238 | ||||
239 | static void append_required_apps(CsmManager* manager) | |||
240 | { | |||
241 | gchar** required_components; | |||
242 | gint i; | |||
243 | GSettings* settings; | |||
244 | GSettings* settings_required_components; | |||
245 | ||||
246 | g_debug("main: *** Adding required apps"); | |||
247 | ||||
248 | settings = g_settings_new (CSM_SCHEMA"org.cafe.session"); | |||
249 | settings_required_components = g_settings_new (CSM_REQUIRED_COMPONENTS_SCHEMA"org.cafe.session" ".required-components"); | |||
250 | ||||
251 | required_components = g_settings_get_strv(settings, CSM_REQUIRED_COMPONENTS_LIST_KEY"required-components-list"); | |||
252 | ||||
253 | if (required_components == NULL((void*)0)) | |||
254 | { | |||
255 | g_warning("No required applications specified"); | |||
256 | } | |||
257 | else | |||
258 | { | |||
259 | for (i = 0; required_components[i]; i++) | |||
260 | { | |||
261 | char* default_provider; | |||
262 | const char* component; | |||
263 | ||||
264 | if (IS_STRING_EMPTY((char*) required_components[i])(((char*) required_components[i])==((void*)0)||((char*) required_components [i])[0]=='\0')) | |||
265 | { | |||
266 | continue; | |||
267 | } | |||
268 | ||||
269 | component = required_components[i]; | |||
270 | ||||
271 | default_provider = g_settings_get_string (settings_required_components, component); | |||
272 | ||||
273 | g_debug ("main: %s looking for component: '%s'", component, default_provider); | |||
274 | ||||
275 | if (default_provider != NULL((void*)0)) | |||
276 | { | |||
277 | char* app_path; | |||
278 | ||||
279 | app_path = csm_util_find_desktop_file_for_app_name(default_provider, NULL((void*)0)); | |||
280 | ||||
281 | if (app_path != NULL((void*)0)) | |||
282 | { | |||
283 | csm_manager_add_autostart_app(manager, app_path, component); | |||
284 | } | |||
285 | else | |||
286 | { | |||
287 | g_warning("Unable to find provider '%s' of required component '%s'", default_provider, component); | |||
288 | } | |||
289 | ||||
290 | g_free(app_path); | |||
291 | } | |||
292 | ||||
293 | g_free(default_provider); | |||
294 | } | |||
295 | } | |||
296 | ||||
297 | g_debug("main: *** Done adding required apps"); | |||
298 | ||||
299 | g_strfreev(required_components); | |||
300 | ||||
301 | g_object_unref(settings); | |||
302 | g_object_unref(settings_required_components); | |||
303 | } | |||
304 | ||||
305 | static void append_accessibility_apps(CsmManager* manager) | |||
306 | { | |||
307 | GSettings* mobility_settings; | |||
308 | GSettings* visual_settings; | |||
309 | ||||
310 | g_debug("main: *** Adding accesibility apps"); | |||
311 | ||||
312 | mobility_settings = g_settings_new (MOBILITY_SCHEMA"org.cafe.applications-at-mobility"); | |||
313 | visual_settings = g_settings_new (VISUAL_SCHEMA"org.cafe.applications-at-visual"); | |||
314 | ||||
315 | if (g_settings_get_boolean (mobility_settings, MOBILITY_STARTUP_KEY"startup")) | |||
316 | { | |||
317 | gchar *mobility_exec; | |||
318 | mobility_exec = g_settings_get_string (mobility_settings, MOBILITY_KEY"exec"); | |||
319 | if (mobility_exec != NULL((void*)0) && mobility_exec[0] != 0) | |||
320 | { | |||
321 | char* app_path; | |||
322 | app_path = csm_util_find_desktop_file_for_app_name(mobility_exec, NULL((void*)0)); | |||
323 | if (app_path != NULL((void*)0)) | |||
324 | { | |||
325 | csm_manager_add_autostart_app(manager, app_path, NULL((void*)0)); | |||
326 | g_free (app_path); | |||
327 | } | |||
328 | g_free (mobility_exec); | |||
329 | } | |||
330 | } | |||
331 | ||||
332 | if (g_settings_get_boolean (visual_settings, VISUAL_STARTUP_KEY"startup")) | |||
333 | { | |||
334 | gchar *visual_exec; | |||
335 | visual_exec = g_settings_get_string (visual_settings, VISUAL_KEY"exec"); | |||
336 | if (visual_exec != NULL((void*)0) && visual_exec[0] != 0) | |||
337 | { | |||
338 | char* app_path; | |||
339 | app_path = csm_util_find_desktop_file_for_app_name(visual_exec, NULL((void*)0)); | |||
340 | if (app_path != NULL((void*)0)) | |||
341 | { | |||
342 | csm_manager_add_autostart_app(manager, app_path, NULL((void*)0)); | |||
343 | g_free (app_path); | |||
344 | } | |||
345 | g_free (visual_exec); | |||
346 | } | |||
347 | } | |||
348 | ||||
349 | g_object_unref (mobility_settings); | |||
350 | g_object_unref (visual_settings); | |||
351 | } | |||
352 | ||||
353 | static void maybe_load_saved_session_apps(CsmManager* manager) | |||
354 | { | |||
355 | CsmConsolekit* consolekit = NULL((void*)0); | |||
356 | #ifdef HAVE_SYSTEMD1 | |||
357 | CsmSystemd* systemd = NULL((void*)0); | |||
358 | #endif | |||
359 | char* session_type; | |||
360 | gboolean is_login; | |||
361 | ||||
362 | #ifdef HAVE_SYSTEMD1 | |||
363 | if (LOGIND_RUNNING()(access("/run/systemd/seats/", 0) >= 0)) { | |||
364 | systemd = csm_get_systemd(); | |||
365 | session_type = csm_systemd_get_current_session_type(systemd); | |||
366 | is_login = g_strcmp0 (session_type, CSM_SYSTEMD_SESSION_TYPE_LOGIN_WINDOW"greeter") == 0; | |||
367 | } | |||
368 | else { | |||
369 | #endif | |||
370 | consolekit = csm_get_consolekit(); | |||
371 | session_type = csm_consolekit_get_current_session_type(consolekit); | |||
372 | is_login = g_strcmp0 (session_type, CSM_CONSOLEKIT_SESSION_TYPE_LOGIN_WINDOW"LoginWindow") == 0; | |||
373 | #ifdef HAVE_SYSTEMD1 | |||
374 | } | |||
375 | #endif | |||
376 | ||||
377 | if (!is_login) | |||
378 | { | |||
379 | GSettings* settings; | |||
380 | gboolean autostart; | |||
381 | ||||
382 | settings = g_settings_new (CSM_SCHEMA"org.cafe.session"); | |||
383 | autostart = g_settings_get_boolean (settings, KEY_AUTOSAVE"auto-save-session"); | |||
384 | g_object_unref (settings); | |||
385 | ||||
386 | if (autostart == TRUE(!(0))) | |||
387 | csm_manager_add_autostart_apps_from_dir(manager, csm_util_get_saved_session_dir()); | |||
388 | } | |||
389 | ||||
390 | if (consolekit != NULL((void*)0)) | |||
391 | g_object_unref(consolekit); | |||
392 | #ifdef HAVE_SYSTEMD1 | |||
393 | if (systemd != NULL((void*)0)) | |||
394 | g_object_unref(systemd); | |||
395 | #endif | |||
396 | g_free(session_type); | |||
397 | } | |||
398 | ||||
399 | static void load_standard_apps (CsmManager* manager, const char* default_session_key) | |||
400 | { | |||
401 | char** autostart_dirs; | |||
402 | int i; | |||
403 | ||||
404 | autostart_dirs = csm_util_get_autostart_dirs(); | |||
405 | ||||
406 | if (!failsafe) | |||
407 | { | |||
408 | maybe_load_saved_session_apps(manager); | |||
409 | ||||
410 | for (i = 0; autostart_dirs[i]; i++) | |||
411 | { | |||
412 | csm_manager_add_autostart_apps_from_dir(manager, autostart_dirs[i]); | |||
413 | } | |||
414 | } | |||
415 | ||||
416 | /* We do this at the end in case a saved session contains an | |||
417 | * application that already provides one of the components. */ | |||
418 | append_default_apps(manager, default_session_key, autostart_dirs); | |||
419 | append_required_apps(manager); | |||
420 | append_accessibility_apps(manager); | |||
421 | ||||
422 | g_strfreev(autostart_dirs); | |||
423 | } | |||
424 | ||||
425 | static void load_override_apps(CsmManager* manager, char** override_autostart_dirs) | |||
426 | { | |||
427 | int i; | |||
428 | ||||
429 | for (i = 0; override_autostart_dirs[i]; i++) | |||
430 | { | |||
431 | csm_manager_add_autostart_apps_from_dir(manager, override_autostart_dirs[i]); | |||
432 | } | |||
433 | } | |||
434 | ||||
435 | static gboolean signal_cb(int signo, gpointer data) | |||
436 | { | |||
437 | int ret; | |||
438 | CsmManager* manager; | |||
439 | ||||
440 | g_debug("Got callback for signal %d", signo); | |||
441 | ||||
442 | ret = TRUE(!(0)); | |||
443 | ||||
444 | switch (signo) | |||
445 | { | |||
446 | case SIGFPE8: | |||
447 | case SIGPIPE13: | |||
448 | /* let the fatal signals interrupt us */ | |||
449 | g_debug ("Caught signal %d, shutting down abnormally.", signo); | |||
450 | ret = FALSE(0); | |||
451 | break; | |||
452 | case SIGINT2: | |||
453 | case SIGTERM15: | |||
454 | manager = (CsmManager*) data; | |||
455 | csm_manager_logout(manager, CSM_MANAGER_LOGOUT_MODE_FORCE, NULL((void*)0)); | |||
456 | ||||
457 | /* let the fatal signals interrupt us */ | |||
458 | g_debug("Caught signal %d, shutting down normally.", signo); | |||
459 | ret = TRUE(!(0)); | |||
460 | break; | |||
461 | case SIGHUP1: | |||
462 | g_debug("Got HUP signal"); | |||
463 | ret = TRUE(!(0)); | |||
464 | break; | |||
465 | case SIGUSR110: | |||
466 | g_debug("Got USR1 signal"); | |||
467 | ret = TRUE(!(0)); | |||
468 | cdm_log_toggle_debug(); | |||
469 | break; | |||
470 | default: | |||
471 | g_debug("Caught unhandled signal %d", signo); | |||
472 | ret = TRUE(!(0)); | |||
473 | ||||
474 | break; | |||
475 | } | |||
476 | ||||
477 | return ret; | |||
478 | } | |||
479 | ||||
480 | static void shutdown_cb(gpointer data) | |||
481 | { | |||
482 | CsmManager* manager = (CsmManager*) data; | |||
483 | g_debug("Calling shutdown callback function"); | |||
484 | ||||
485 | /* | |||
486 | * When the signal handler gets a shutdown signal, it calls | |||
487 | * this function to inform CsmManager to not restart | |||
488 | * applications in the off chance a handler is already queued | |||
489 | * to dispatch following the below call to ctk_main_quit. | |||
490 | */ | |||
491 | csm_manager_set_phase(manager, CSM_MANAGER_PHASE_EXIT); | |||
492 | ||||
493 | ctk_main_quit(); | |||
494 | } | |||
495 | ||||
496 | static gboolean require_dbus_session(int argc, char** argv, GError** error) | |||
497 | { | |||
498 | char** new_argv; | |||
499 | int i; | |||
500 | ||||
501 | if (g_getenv("DBUS_SESSION_BUS_ADDRESS")) | |||
502 | { | |||
503 | return TRUE(!(0)); | |||
504 | } | |||
505 | ||||
506 | /* Just a sanity check to prevent infinite recursion if | |||
507 | * dbus-launch fails to set DBUS_SESSION_BUS_ADDRESS | |||
508 | */ | |||
509 | g_return_val_if_fail(!g_str_has_prefix(argv[0], "dbus-launch"), TRUE)do { if ((!(__builtin_constant_p ("dbus-launch")? __extension__ ({ const char * const __str = (argv[0]); const char * const __prefix = ("dbus-launch"); gboolean __result = (0); if (__str == ((void *)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix); else { const size_t __str_len = strlen (( (__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix ) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len ) == 0; } __result; }) : (g_str_has_prefix) (argv[0], "dbus-launch" ) ))) { } else { g_return_if_fail_warning (((gchar*) 0), ((const char*) (__func__)), "!g_str_has_prefix(argv[0], \"dbus-launch\")" ); return ((!(0))); } } while (0); | |||
510 | ||||
511 | /* +2 for our new arguments, +1 for NULL */ | |||
512 | new_argv = g_malloc(argc + 3 * sizeof (*argv)); | |||
513 | ||||
514 | new_argv[0] = "dbus-launch"; | |||
515 | new_argv[1] = "--exit-with-session"; | |||
516 | ||||
517 | for (i = 0; i < argc; i++) | |||
518 | { | |||
519 | new_argv[i + 2] = argv[i]; | |||
520 | } | |||
521 | ||||
522 | new_argv[i + 2] = NULL((void*)0); | |||
523 | ||||
524 | if (!execvp("dbus-launch", new_argv)) | |||
525 | { | |||
526 | g_set_error(error, G_SPAWN_ERRORg_spawn_error_quark (), G_SPAWN_ERROR_FAILED, "No session bus and could not exec dbus-launch: %s", g_strerror(errno(*__errno_location ()))); | |||
527 | g_free (new_argv); | |||
528 | return FALSE(0); | |||
529 | } | |||
530 | ||||
531 | g_free (new_argv); | |||
532 | ||||
533 | /* Should not be reached */ | |||
534 | return TRUE(!(0)); | |||
535 | } | |||
536 | ||||
537 | static void | |||
538 | debug_changed (GSettings *settings, gchar *key, gpointer user_data) | |||
539 | { | |||
540 | debug = g_settings_get_boolean (settings, DEBUG_KEY"cafe-session"); | |||
541 | cdm_log_set_debug (debug); | |||
542 | } | |||
543 | ||||
544 | static gboolean | |||
545 | schema_exists (const gchar* schema_name) | |||
546 | { | |||
547 | GSettingsSchemaSource *source; | |||
548 | GSettingsSchema *schema; | |||
549 | gboolean exists; | |||
550 | ||||
551 | source = g_settings_schema_source_get_default(); | |||
552 | schema = g_settings_schema_source_lookup (source, schema_name, FALSE(0)); | |||
553 | exists = (schema != NULL((void*)0)); | |||
554 | if (schema) | |||
555 | g_settings_schema_unref (schema); | |||
556 | ||||
557 | return exists; | |||
558 | } | |||
559 | ||||
560 | static void set_overlay_scroll (void) | |||
561 | { | |||
562 | GSettings *settings; | |||
563 | gboolean enabled; | |||
564 | ||||
565 | settings = g_settings_new (CAFE_INTERFACE_SCHEMA"org.cafe.interface"); | |||
566 | enabled = g_settings_get_boolean (settings, CTK_OVERLAY_SCROLL"ctk-overlay-scrolling"); | |||
567 | ||||
568 | if (enabled) { | |||
569 | csm_util_setenv ("CTK_OVERLAY_SCROLLING", "1"); | |||
570 | } else { | |||
571 | csm_util_setenv ("CTK_OVERLAY_SCROLLING", "0"); | |||
572 | } | |||
573 | ||||
574 | g_object_unref (settings); | |||
575 | } | |||
576 | ||||
577 | static gboolean | |||
578 | check_gl (GError **error) | |||
579 | { | |||
580 | int status; | |||
581 | char *argv[] = { LIBEXECDIR"/usr/libexec" "/cafe-session-check-accelerated", NULL((void*)0) }; | |||
582 | ||||
583 | if (getenv ("DISPLAY") == NULL((void*)0)) { | |||
584 | /* Not connected to X11, someone else will take care of checking GL */ | |||
585 | return TRUE(!(0)); | |||
586 | } | |||
587 | ||||
588 | if (!g_spawn_sync (NULL((void*)0), (char **) argv, NULL((void*)0), 0, NULL((void*)0), NULL((void*)0), &gl_renderer, NULL((void*)0), | |||
589 | &status, error)) { | |||
590 | return FALSE(0); | |||
591 | } | |||
592 | ||||
593 | return g_spawn_check_exit_status (status, error); | |||
594 | } | |||
595 | ||||
596 | int main(int argc, char** argv) | |||
597 | { | |||
598 | struct sigaction sa; | |||
599 | GError* error; | |||
600 | const char* display_str; | |||
601 | CsmManager* manager; | |||
602 | CsmStore* client_store; | |||
603 | CsmXsmpServer* xsmp_server; | |||
604 | GSettings* debug_settings = NULL((void*)0); | |||
605 | GSettings* accessibility_settings; | |||
606 | CdmSignalHandler* signal_handler; | |||
607 | static char** override_autostart_dirs = NULL((void*)0); | |||
608 | gboolean gl_failed = FALSE(0); | |||
609 | ||||
610 | static GOptionEntry entries[] = { | |||
611 | {"autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories")("Override standard autostart directories"), NULL((void*)0)}, | |||
612 | {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code")("Enable debugging code"), NULL((void*)0)}, | |||
613 | {"failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe, N_("Do not load user-specified applications")("Do not load user-specified applications"), NULL((void*)0)}, | |||
614 | {"version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application")("Version of this application"), NULL((void*)0)}, | |||
615 | { "disable-acceleration-check", 0, 0, G_OPTION_ARG_NONE, &disable_acceleration_check, N_("Disable hardware acceleration check")("Disable hardware acceleration check"), NULL((void*)0) }, | |||
616 | {NULL((void*)0), 0, 0, 0, NULL((void*)0), NULL((void*)0), NULL((void*)0) } | |||
617 | }; | |||
618 | ||||
619 | /* Make sure that we have a session bus */ | |||
620 | if (!require_dbus_session(argc, argv, &error)) | |||
| ||||
621 | { | |||
622 | csm_util_init_error(TRUE(!(0)), "%s", error->message); | |||
623 | } | |||
624 | ||||
625 | bindtextdomain(GETTEXT_PACKAGE"cafe-session-manager", LOCALE_DIR"/usr/share/locale"); | |||
626 | bind_textdomain_codeset(GETTEXT_PACKAGE"cafe-session-manager", "UTF-8"); | |||
627 | textdomain(GETTEXT_PACKAGE"cafe-session-manager"); | |||
628 | ||||
629 | sa.sa_handler__sigaction_handler.sa_handler = SIG_IGN((__sighandler_t) 1); | |||
| ||||
630 | sa.sa_flags = 0; | |||
631 | sigemptyset(&sa.sa_mask); | |||
632 | sigaction(SIGPIPE13, &sa, 0); | |||
633 | ||||
634 | error = NULL((void*)0); | |||
635 | ctk_init_with_args(&argc, &argv, (char*) _(" - the CAFE session manager")gettext (" - the CAFE session manager"), entries, GETTEXT_PACKAGE"cafe-session-manager", &error); | |||
636 | ||||
637 | if (error != NULL((void*)0)) | |||
638 | { | |||
639 | g_warning("%s", error->message); | |||
640 | exit(1); | |||
641 | } | |||
642 | ||||
643 | if (show_version) | |||
644 | { | |||
645 | g_print("%s %s\n", g_get_application_name(), VERSION"1.25.0"); | |||
646 | exit(1); | |||
647 | } | |||
648 | ||||
649 | csm_util_export_activation_environment (NULL((void*)0)); | |||
650 | ||||
651 | #ifdef HAVE_SYSTEMD1 | |||
652 | csm_util_export_user_environment (NULL((void*)0)); | |||
653 | #endif | |||
654 | ||||
655 | cdm_log_init(); | |||
656 | ||||
657 | /* Allows to enable/disable debug from GSettings only if it is not set from argument */ | |||
658 | if (!debug && schema_exists(DEBUG_SCHEMA"org.cafe.debug")) | |||
659 | { | |||
660 | debug_settings = g_settings_new (DEBUG_SCHEMA"org.cafe.debug"); | |||
661 | g_signal_connect (debug_settings, "changed::" DEBUG_KEY, G_CALLBACK (debug_changed), NULL)g_signal_connect_data ((debug_settings), ("changed::" "cafe-session" ), (((GCallback) (debug_changed))), (((void*)0)), ((void*)0), (GConnectFlags) 0); | |||
662 | debug = g_settings_get_boolean (debug_settings, DEBUG_KEY"cafe-session"); | |||
663 | } | |||
664 | ||||
665 | cdm_log_set_debug(debug); | |||
666 | ||||
667 | if (disable_acceleration_check) { | |||
668 | g_debug ("hardware acceleration check is disabled"); | |||
669 | } else { | |||
670 | /* Check GL, if it doesn't work out then force software fallback */ | |||
671 | if (!check_gl (&error)) { | |||
672 | gl_failed = TRUE(!(0)); | |||
673 | ||||
674 | g_debug ("hardware acceleration check failed: %s", | |||
675 | error? error->message : ""); | |||
676 | g_clear_error (&error); | |||
677 | if (g_getenv ("LIBGL_ALWAYS_SOFTWARE") == NULL((void*)0)) { | |||
678 | g_setenv ("LIBGL_ALWAYS_SOFTWARE", "1", TRUE(!(0))); | |||
679 | if (!check_gl (&error)) { | |||
680 | g_warning ("software acceleration check failed: %s", | |||
681 | error? error->message : ""); | |||
682 | g_clear_error (&error); | |||
683 | } else { | |||
684 | gl_failed = FALSE(0); | |||
685 | } | |||
686 | } | |||
687 | } | |||
688 | } | |||
689 | ||||
690 | if (gl_failed) { | |||
691 | g_warning ("gl_failed!"); | |||
692 | } | |||
693 | ||||
694 | if (g_getenv ("XDG_CURRENT_DESKTOP") == NULL((void*)0)) | |||
695 | csm_util_setenv ("XDG_CURRENT_DESKTOP", "CAFE"); | |||
696 | ||||
697 | /* Set DISPLAY explicitly for all our children, in case --display | |||
698 | * was specified on the command line. | |||
699 | */ | |||
700 | display_str = cdk_display_get_name (cdk_display_get_default()); | |||
701 | csm_util_setenv("DISPLAY", display_str); | |||
702 | ||||
703 | /* Some third-party programs rely on CAFE_DESKTOP_SESSION_ID to | |||
704 | * detect if CAFE is running. We keep this for compatibility reasons. | |||
705 | */ | |||
706 | csm_util_setenv("CAFE_DESKTOP_SESSION_ID", "this-is-deprecated"); | |||
707 | ||||
708 | /* | |||
709 | * Make sure gsettings is set up correctly. If not, then bail. | |||
710 | */ | |||
711 | ||||
712 | if (initialize_gsettings () != TRUE(!(0))) | |||
713 | exit (1); | |||
714 | ||||
715 | /* Look if accessibility is enabled */ | |||
716 | accessibility_settings = g_settings_new (ACCESSIBILITY_SCHEMA"org.cafe.interface"); | |||
717 | if (g_settings_get_boolean (accessibility_settings, ACCESSIBILITY_KEY"accessibility")) | |||
718 | { | |||
719 | csm_util_setenv("CTK_MODULES", "cail:atk-bridge"); | |||
720 | } | |||
721 | g_object_unref (accessibility_settings); | |||
722 | ||||
723 | client_store = csm_store_new(); | |||
724 | ||||
725 | xsmp_server = csm_xsmp_server_new(client_store); | |||
726 | ||||
727 | /* Now make sure they succeeded. (They'll call | |||
728 | * csm_util_init_error() if they failed.) | |||
729 | */ | |||
730 | acquire_name(); | |||
731 | ||||
732 | /* Starts gnome compat mode */ | |||
733 | msm_gnome_start(); | |||
734 | ||||
735 | /* Set to use Ctk3 overlay scroll */ | |||
736 | set_overlay_scroll (); | |||
737 | ||||
738 | manager = csm_manager_new(client_store, failsafe); | |||
739 | ||||
740 | signal_handler = cdm_signal_handler_new(); | |||
741 | cdm_signal_handler_add_fatal(signal_handler); | |||
742 | cdm_signal_handler_add(signal_handler, SIGFPE8, signal_cb, NULL((void*)0)); | |||
743 | cdm_signal_handler_add(signal_handler, SIGHUP1, signal_cb, NULL((void*)0)); | |||
744 | cdm_signal_handler_add(signal_handler, SIGUSR110, signal_cb, NULL((void*)0)); | |||
745 | cdm_signal_handler_add(signal_handler, SIGTERM15, signal_cb, manager); | |||
746 | cdm_signal_handler_add(signal_handler, SIGINT2, signal_cb, manager); | |||
747 | cdm_signal_handler_set_fatal_func(signal_handler, shutdown_cb, manager); | |||
748 | ||||
749 | if (override_autostart_dirs != NULL((void*)0)) | |||
750 | { | |||
751 | load_override_apps(manager, override_autostart_dirs); | |||
752 | } | |||
753 | else | |||
754 | { | |||
755 | load_standard_apps(manager, CSM_DEFAULT_SESSION_KEY"default-session"); | |||
756 | } | |||
757 | ||||
758 | csm_xsmp_server_start(xsmp_server); | |||
759 | _csm_manager_set_renderer (manager, gl_renderer); | |||
760 | csm_manager_start(manager); | |||
761 | ||||
762 | ctk_main(); | |||
763 | ||||
764 | if (xsmp_server != NULL((void*)0)) | |||
765 | { | |||
766 | g_object_unref(xsmp_server); | |||
767 | } | |||
768 | ||||
769 | if (manager != NULL((void*)0)) | |||
770 | { | |||
771 | g_debug("Unreffing manager"); | |||
772 | g_object_unref(manager); | |||
773 | } | |||
774 | ||||
775 | if (gl_renderer != NULL((void*)0)) | |||
776 | { | |||
777 | g_free (gl_renderer); | |||
778 | } | |||
779 | ||||
780 | if (client_store != NULL((void*)0)) | |||
781 | { | |||
782 | g_object_unref(client_store); | |||
783 | } | |||
784 | ||||
785 | if (debug_settings != NULL((void*)0)) | |||
786 | { | |||
787 | g_object_unref(debug_settings); | |||
788 | } | |||
789 | ||||
790 | msm_gnome_stop(); | |||
791 | cdm_log_shutdown(); | |||
792 | ||||
793 | return 0; | |||
794 | } | |||
795 |