static Status register_client_callback (SmsConn conn, SmPointer manager_data, char *previous_id) { GsmXSMPClient *client = manager_data; gboolean handled; char *id; g_debug ("GsmXSMPClient: Client '%s' received RegisterClient(%s)", client->priv->description, previous_id ? previous_id : "NULL"); /* There are three cases: * 1. id is NULL - we'll use a new one * 2. id is known - we'll use known one * 3. id is unknown - this is an error */ id = g_strdup (previous_id); handled = FALSE; g_signal_emit (client, signals[REGISTER_REQUEST], 0, &id, &handled); if (! handled) { g_debug ("GsmXSMPClient: RegisterClient not handled!"); g_free (id); free (previous_id); g_assert_not_reached (); return FALSE; } if (IS_STRING_EMPTY (id)) { g_debug ("GsmXSMPClient: rejected: invalid previous_id"); free (previous_id); return FALSE; } g_object_set (client, "startup-id", id, NULL); set_description (client); g_debug ("GsmXSMPClient: Sending RegisterClientReply to '%s'", client->priv->description); SmsRegisterClientReply (conn, id); if (IS_STRING_EMPTY (previous_id)) { /* Send the initial SaveYourself. */ g_debug ("GsmXSMPClient: Sending initial SaveYourself"); SmsSaveYourself (conn, SmSaveLocal, False, SmInteractStyleNone, False); client->priv->current_save_yourself = SmSaveLocal; } gsm_client_set_status (GSM_CLIENT (client), GSM_CLIENT_REGISTERED); g_free (id); free (previous_id); return TRUE; }
static void create_manager (void) { GsmStore *client_store; client_store = gsm_store_new (); manager = gsm_manager_new (client_store, failsafe); g_object_unref (client_store); g_unix_signal_add (SIGTERM, term_or_int_signal_cb, manager); g_unix_signal_add (SIGINT, term_or_int_signal_cb, manager); g_unix_signal_add (SIGUSR1, sigusr1_cb, manager); g_unix_signal_add (SIGUSR2, sigusr2_cb, manager); if (IS_STRING_EMPTY (session_name)) { session_name = _gsm_manager_get_default_session (manager); } if (!gsm_session_fill (manager, session_name)) { gsm_fail_whale_dialog_we_failed (FALSE, TRUE, NULL); } _gsm_manager_set_renderer (manager, gl_renderer); gsm_manager_start (manager); }
/* This doesn't contain the required components, so we need to always * call append_required_apps() after a call to append_default_apps(). */ static void append_default_apps(GsmManager* manager, const char* default_session_key, char** autostart_dirs) { gint i; gchar** default_apps; GSettings* settings; g_debug("main: *** Adding default apps"); g_assert(default_session_key != NULL); g_assert(autostart_dirs != NULL); settings = g_settings_new (GSM_SCHEMA); default_apps = g_settings_get_strv (settings, default_session_key); g_object_unref(settings); for (i = 0; default_apps[i]; i++) { char* app_path; if (IS_STRING_EMPTY((char*) default_apps[i])) { continue; } app_path = gsm_util_find_desktop_file_for_app_name(default_apps[i], autostart_dirs); if (app_path != NULL) { gsm_manager_add_autostart_app(manager, app_path, NULL); g_free(app_path); } } g_strfreev (default_apps); }
static void handle_end_session_response (GsmDBusClient *client, DBusMessage *message) { const char *sender; DBusMessage *reply; DBusError error; dbus_bool_t is_ok; const char *reason; dbus_error_init (&error); if (! dbus_message_get_args (message, &error, DBUS_TYPE_BOOLEAN, &is_ok, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID)) { if (dbus_error_is_set (&error)) { g_warning ("Invalid method call: %s", error.message); dbus_error_free (&error); } raise_error (client->priv->connection, message, DBUS_ERROR_FAILED, "There is a syntax error in the invocation of the method EndSessionResponse"); return; } g_debug ("GsmDBusClient: got EndSessionResponse is-ok:%d reason=%s", is_ok, reason); /* make sure it is from our client */ sender = dbus_message_get_sender (message); if (sender == NULL || IS_STRING_EMPTY (client->priv->bus_name) || strcmp (sender, client->priv->bus_name) != 0) { raise_error (client->priv->connection, message, DBUS_ERROR_FAILED, "Caller not recognized as the client"); return; } reply = dbus_message_new_method_return (message); if (reply == NULL) { g_error ("No memory"); } gsm_client_end_session_response (GSM_CLIENT (client), is_ok, FALSE, FALSE, reason); if (! dbus_connection_send (client->priv->connection, reply, NULL)) { g_error ("No memory"); } dbus_message_unref (reply); }
static gboolean inhibitor_has_bus_name (gpointer key, GsmInhibitor *inhibitor, RemoveClientData *data) { gboolean matches; const char *bus_name_b; bus_name_b = gsm_inhibitor_peek_bus_name (inhibitor); matches = FALSE; if (! IS_STRING_EMPTY (data->service_name) && ! IS_STRING_EMPTY (bus_name_b)) { matches = (strcmp (data->service_name, bus_name_b) == 0); if (matches) { g_debug ("GsmManager: removing inhibitor from %s for reason '%s' on connection %s", gsm_inhibitor_peek_app_id (inhibitor), gsm_inhibitor_peek_reason (inhibitor), gsm_inhibitor_peek_bus_name (inhibitor)); } } return matches; }
gboolean csm_inhibitor_get_client_id (CsmInhibitor *inhibitor, char **id, GError **error) { g_return_val_if_fail (CSM_IS_INHIBITOR (inhibitor), FALSE); /* object paths are not allowed to be NULL or blank */ if (IS_STRING_EMPTY (inhibitor->priv->client_id)) { g_set_error (error, CSM_INHIBITOR_ERROR, CSM_INHIBITOR_ERROR_NOT_SET, "Value is not set"); return FALSE; } *id = g_strdup (inhibitor->priv->client_id); g_debug ("CsmInhibitor: getting client-id = '%s'", *id); return TRUE; }
static GKeyFile * get_session_keyfile (const char *session, char **actual_session, gboolean *is_fallback) { GKeyFile *keyfile; gboolean session_runnable; char *value; GError *error = NULL; *actual_session = NULL; g_debug ("fill: *** Getting session '%s'", session); keyfile = find_valid_session_keyfile (session); if (!keyfile) return NULL; session_runnable = TRUE; value = g_key_file_get_string (keyfile, GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_RUNNABLE_KEY, NULL); if (!IS_STRING_EMPTY (value)) { g_debug ("fill: *** Launching helper '%s' to know if session is runnable", value); session_runnable = gsm_process_helper (value, GSM_RUNNABLE_HELPER_TIMEOUT, &error); if (!session_runnable) { g_warning ("Session '%s' runnable check failed: %s", session, error->message); g_clear_error (&error); } } g_free (value); if (session_runnable) { session_runnable = check_required (keyfile); } if (session_runnable) { *actual_session = g_strdup (session); if (is_fallback) *is_fallback = FALSE; return keyfile; } g_debug ("fill: *** Session is not runnable"); /* We can't run this session, so try to use the fallback */ value = g_key_file_get_string (keyfile, GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_FALLBACK_KEY, NULL); g_key_file_free (keyfile); keyfile = NULL; if (!IS_STRING_EMPTY (value)) { if (is_fallback) *is_fallback = TRUE; keyfile = get_session_keyfile (value, actual_session, NULL); } g_free (value); return keyfile; }
gboolean gsm_manager_inhibit (GsmManager *manager, const char *app_id, guint toplevel_xid, const char *reason, guint flags, DBusGMethodInvocation *context) { GsmInhibitor *inhibitor; guint cookie; g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE); g_debug ("GsmManager: Inhibit xid=%u app_id=%s reason=%s flags=%u", toplevel_xid, app_id, reason, flags); if (IS_STRING_EMPTY (app_id)) { GError *new_error; new_error = g_error_new (GSM_MANAGER_ERROR, GSM_MANAGER_ERROR_GENERAL, "Application ID not specified"); g_debug ("GsmManager: Unable to inhibit: %s", new_error->message); dbus_g_method_return_error (context, new_error); g_error_free (new_error); return FALSE; } if (IS_STRING_EMPTY (reason)) { GError *new_error; new_error = g_error_new (GSM_MANAGER_ERROR, GSM_MANAGER_ERROR_GENERAL, "Reason not specified"); g_debug ("GsmManager: Unable to inhibit: %s", new_error->message); dbus_g_method_return_error (context, new_error); g_error_free (new_error); return FALSE; } if (flags == 0) { GError *new_error; new_error = g_error_new (GSM_MANAGER_ERROR, GSM_MANAGER_ERROR_GENERAL, "Invalid inhibit flags"); g_debug ("GsmManager: Unable to inhibit: %s", new_error->message); dbus_g_method_return_error (context, new_error); g_error_free (new_error); return FALSE; } cookie = _generate_unique_cookie (manager); inhibitor = gsm_inhibitor_new (app_id, toplevel_xid, flags, reason, dbus_g_method_get_sender (context), cookie); gsm_store_add (manager->priv->inhibitors, gsm_inhibitor_peek_id (inhibitor), G_OBJECT (inhibitor)); g_object_unref (inhibitor); dbus_g_method_return (context, cookie); return TRUE; }
int main (int argc, char **argv) { struct sigaction sa; GError *error; char *display_str; CsmManager *manager; CsmStore *client_store; MdmSignalHandler *signal_handler; static char **override_autostart_dirs = NULL; static char *session_name = NULL; static GOptionEntry entries[] = { { "autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories"), N_("AUTOSTART_DIR") }, { "session", 0, 0, G_OPTION_ARG_STRING, &session_name, N_("Session to use"), N_("SESSION_NAME") }, { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL }, { "failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe, N_("Do not load user-specified applications"), NULL }, { "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL }, /* Translators: the 'fail whale' is the black dialog we show when something goes seriously wrong */ { "whale", 0, 0, G_OPTION_ARG_NONE, &please_fail, N_("Show the fail whale dialog for testing"), NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL } }; /* Make sure that we have a session bus */ if (!require_dbus_session (argc, argv, &error)) { csm_util_init_error (TRUE, "%s", error->message); } bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); GSettings *settings = g_settings_new ("org.cinnamon.SessionManager"); if (g_settings_get_boolean (settings, "debug")) { debug = TRUE; } g_object_unref(settings); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; sigemptyset (&sa.sa_mask); sigaction (SIGPIPE, &sa, 0); error = NULL; gtk_init_with_args (&argc, &argv, (char *) _(" - the Cinnamon session manager"), entries, GETTEXT_PACKAGE, &error); if (error != NULL) { g_warning ("%s", error->message); exit (1); } if (show_version) { g_print ("%s %s\n", argv [0], VERSION); exit (1); } if (please_fail) { csm_fail_whale_dialog_we_failed (TRUE, TRUE); gtk_main (); exit (1); } mdm_log_init (); mdm_log_set_debug (debug); /* Set DISPLAY explicitly for all our children, in case --display * was specified on the command line. */ display_str = gdk_get_display (); csm_util_setenv ("DISPLAY", display_str); g_free (display_str); const gchar *gtk_modules; gchar *new_gtk_modules = NULL; gtk_modules = g_getenv ("GTK_MODULES"); if (gtk_modules != NULL && g_strstr_len (gtk_modules, -1, "overlay-scrollbar")) { int i = 0; new_gtk_modules = g_strconcat ("", NULL); gchar **module_list = g_strsplit (gtk_modules, ":", -1); for (i = 0; i < g_strv_length (module_list); i++) { if (!g_strstr_len (module_list[i], -1, "overlay-scrollbar")) { gchar *tmp = new_gtk_modules; new_gtk_modules = g_strconcat (tmp, ":", module_list[i], NULL); g_free (tmp); } } g_strfreev (module_list); } if (new_gtk_modules) { csm_util_setenv ("GTK_MODULES", new_gtk_modules); } g_free (new_gtk_modules); /* Some third-party programs rely on GNOME_DESKTOP_SESSION_ID to * detect if GNOME is running. We keep this for compatibility reasons. */ csm_util_setenv ("GNOME_DESKTOP_SESSION_ID", "this-is-deprecated"); /* Make QT5 apps follow the GTK style */ csm_util_setenv ("QT_STYLE_OVERRIDE", "gtk"); client_store = csm_store_new (); /* Talk to logind before acquiring a name, since it does synchronous * calls at initialization time that invoke a main loop and if we * already owned a name, then we would service too early during * that main loop. */ g_object_unref (csm_get_system ()); if (!acquire_name ()) { csm_fail_whale_dialog_we_failed (TRUE, TRUE); gtk_main (); exit (1); } manager = csm_manager_new (client_store, failsafe); /* signal_handler = mdm_signal_handler_new (); mdm_signal_handler_add_fatal (signal_handler); mdm_signal_handler_add (signal_handler, SIGFPE, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGHUP, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGUSR1, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGTERM, signal_cb, manager); mdm_signal_handler_add (signal_handler, SIGINT, signal_cb, manager); mdm_signal_handler_set_fatal_func (signal_handler, shutdown_cb, manager); */ if (IS_STRING_EMPTY (session_name)) session_name = _csm_manager_get_default_session (manager); csm_util_set_autostart_dirs (override_autostart_dirs); if (!csm_session_fill (manager, session_name)) { csm_util_init_error (TRUE, "Failed to load session \"%s\"", session_name ? session_name : "(null)"); } csm_manager_start (manager); gtk_main (); if (manager != NULL) { g_debug ("Unreffing manager"); g_object_unref (manager); } if (client_store != NULL) { g_object_unref (client_store); } if (bus_proxy != NULL) { g_object_unref (bus_proxy); } mdm_log_shutdown (); return 0; }
static void append_required_apps(GsmManager* manager) { gchar** required_components; gint i; GSettings* settings; GSettings* settings_required_components; g_debug("main: *** Adding required apps"); settings = g_settings_new (GSM_SCHEMA); settings_required_components = g_settings_new (GSM_REQUIRED_COMPONENTS_SCHEMA); required_components = g_settings_get_strv(settings, GSM_REQUIRED_COMPONENTS_LIST_KEY); if (required_components == NULL) { g_warning("No required applications specified"); } for (i = 0; required_components[i]; i++) { char* default_provider; const char* component; if (IS_STRING_EMPTY((char*) required_components[i])) { continue; } component = required_components[i]; default_provider = g_settings_get_string (settings_required_components, component); g_debug ("main: %s looking for component: '%s'", component, default_provider); if (default_provider != NULL) { char* app_path; app_path = gsm_util_find_desktop_file_for_app_name(default_provider, NULL); if (app_path != NULL) { gsm_manager_add_autostart_app(manager, app_path, component); } else { g_warning("Unable to find provider '%s' of required component '%s'", default_provider, component); } g_free(app_path); } g_free(default_provider); } g_debug("main: *** Done adding required apps"); g_strfreev(required_components); g_object_unref(settings); g_object_unref(settings_required_components); }