]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - src/unity-system-compositor.c
Releasing 1.20.0
[sojka/lightdm.git] / src / unity-system-compositor.c
index a9b83e6f38707bb8b268d377bd0f829a8f2252a3..83eacbac055ef746e6f4e45c17559a310a7c95ed 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2013 Canonical Ltd.
  * Author: Robert Ancell <robert.ancell@canonical.com>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free Software
  * Foundation, either version 3 of the License, or (at your option) any later
 #include "unity-system-compositor.h"
 #include "configuration.h"
 #include "process.h"
-#include "greeter.h"
+#include "greeter-session.h"
 #include "vt.h"
 
 struct UnitySystemCompositorPrivate
 {
     /* Compositor process */
     Process *process;
-  
-    /* File to log to */
-    gchar *log_file;    
 
     /* Command to run the compositor */
     gchar *command;
@@ -61,9 +58,16 @@ struct UnitySystemCompositorPrivate
 
     /* TRUE when received ready signal */
     gboolean is_ready;
+
+    /* Counters for Mir IDs to use */
+    int next_session_id;
+    int next_greeter_id;  
 };
 
-G_DEFINE_TYPE (UnitySystemCompositor, unity_system_compositor, DISPLAY_SERVER_TYPE);
+static void unity_system_compositor_logger_iface_init (LoggerInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UnitySystemCompositor, unity_system_compositor, DISPLAY_SERVER_TYPE,
+                         G_IMPLEMENT_INTERFACE (LOGGER_TYPE, unity_system_compositor_logger_iface_init));               
 
 typedef enum
 {
@@ -85,6 +89,8 @@ void
 unity_system_compositor_set_command (UnitySystemCompositor *compositor, const gchar *command)
 {
     g_return_if_fail (compositor != NULL);
+    g_return_if_fail (command != NULL);
+
     g_free (compositor->priv->command);
     compositor->priv->command = g_strdup (command);
 }
@@ -138,11 +144,14 @@ write_message (UnitySystemCompositor *compositor, guint16 id, const guint8 *payl
     data[1] = id & 0xFF;
     data[2] = payload_length >> 8;
     data[3] = payload_length & 0xFF;
-    memcpy (data + 4, payload, payload_length);
+    if (payload)
+        memcpy (data + 4, payload, payload_length);
 
     errno = 0;
     if (write (compositor->priv->to_compositor_pipe[1], data, data_length) != data_length)
         l_warning (compositor, "Failed to write to compositor: %s", strerror (errno));
+
+    g_free (data);
 }
 
 void
@@ -170,15 +179,28 @@ static void
 unity_system_compositor_connect_session (DisplayServer *display_server, Session *session)
 {
     UnitySystemCompositor *compositor = UNITY_SYSTEM_COMPOSITOR (display_server);
-    const gchar *name;
+
+    session_set_env (session, "XDG_SESSION_TYPE", "mir");
 
     if (compositor->priv->socket)
-        session_set_env (session, "MIR_SOCKET", compositor->priv->socket);
-    if (IS_GREETER (session))
-        name = "greeter-0";
-    else
-        name = "session-0";
-    session_set_env (session, "MIR_SERVER_NAME", name);
+        session_set_env (session, "MIR_SERVER_HOST_SOCKET", compositor->priv->socket);
+
+    if (!session_get_env (session, "MIR_SERVER_NAME"))
+    {
+        gchar *name;
+        if (IS_GREETER_SESSION (session))
+        {
+            name = g_strdup_printf ("greeter-%d", compositor->priv->next_greeter_id);
+            compositor->priv->next_greeter_id++;
+        }
+        else
+        {
+            name = g_strdup_printf ("session-%d", compositor->priv->next_session_id);
+            compositor->priv->next_session_id++;
+        }
+        session_set_env (session, "MIR_SERVER_NAME", name);
+        g_free (name);
+    }
 
     if (compositor->priv->vt >= 0)
     {
@@ -191,7 +213,8 @@ unity_system_compositor_connect_session (DisplayServer *display_server, Session
 static void
 unity_system_compositor_disconnect_session (DisplayServer *display_server, Session *session)
 {
-    session_unset_env (session, "MIR_SOCKET");
+    session_unset_env (session, "XDG_SESSION_TYPE");
+    session_unset_env (session, "MIR_SERVER_HOST_SOCKET");
     session_unset_env (session, "MIR_SERVER_NAME");
     session_unset_env (session, "XDG_VTNR");
 }
@@ -226,10 +249,11 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
     gsize n_to_read = 0;
     guint16 id, payload_length;
     /*guint8 *payload;*/
-  
+
     if (condition == G_IO_HUP)
     {
         l_debug (compositor, "Compositor closed communication channel");
+        compositor->priv->from_compositor_watch = 0;
         return FALSE;
     }
 
@@ -312,7 +336,7 @@ read_cb (GIOChannel *source, GIOCondition condition, gpointer data)
 }
 
 static void
-run_cb (Process *process, UnitySystemCompositor *compositor)
+run_cb (Process *process, gpointer user_data)
 {
     int fd;
 
@@ -320,29 +344,6 @@ run_cb (Process *process, UnitySystemCompositor *compositor)
     fd = open ("/dev/null", O_RDONLY);
     dup2 (fd, STDIN_FILENO);
     close (fd);
-
-    /* Redirect output to logfile */
-    if (compositor->priv->log_file)
-    {
-         int fd;
-         gchar *old_filename;
-
-         /* Move old file out of the way */
-         old_filename = g_strdup_printf ("%s.old", compositor->priv->log_file);
-         rename (compositor->priv->log_file, old_filename);
-         g_free (old_filename);
-
-         /* Create new file and log to it */
-         fd = g_open (compositor->priv->log_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-         if (fd < 0)
-             l_warning (compositor, "Failed to open log file %s: %s", compositor->priv->log_file, g_strerror (errno));
-         else
-         {
-             dup2 (fd, STDOUT_FILENO);
-             dup2 (fd, STDERR_FILENO);
-             close (fd);
-         }
-    }
 }
 
 static gboolean
@@ -381,8 +382,9 @@ static gboolean
 unity_system_compositor_start (DisplayServer *server)
 {
     UnitySystemCompositor *compositor = UNITY_SYSTEM_COMPOSITOR (server);
-    gboolean result;
-    gchar *dir, *command, *absolute_command, *value;
+    gboolean result, backup_logs;
+    GString *command;
+    gchar *dir, *log_file, *absolute_command, *value;
 
     g_return_val_if_fail (compositor->priv->process == NULL, FALSE);
 
@@ -407,12 +409,15 @@ unity_system_compositor_start (DisplayServer *server)
 
     /* Setup logging */
     dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
-    compositor->priv->log_file = g_build_filename (dir, "unity-system-compositor.log", NULL);
-    l_debug (compositor, "Logging to %s", compositor->priv->log_file);
+    log_file = g_build_filename (dir, "unity-system-compositor.log", NULL);
+    l_debug (compositor, "Logging to %s", log_file);
     g_free (dir);
 
     /* Setup environment */
-    compositor->priv->process = process_new ();
+    compositor->priv->process = process_new (run_cb, compositor);
+    backup_logs = config_get_boolean (config_get_instance (), "LightDM", "backup-logs");
+    process_set_log_file (compositor->priv->process, log_file, TRUE, backup_logs ? LOG_MODE_BACKUP_AND_TRUNCATE : LOG_MODE_APPEND);
+    g_free (log_file);
     process_set_clear_environment (compositor->priv->process, TRUE);
     process_set_env (compositor->priv->process, "XDG_SEAT", "seat0");
     value = g_strdup_printf ("%d", compositor->priv->vt);
@@ -426,22 +431,31 @@ unity_system_compositor_start (DisplayServer *server)
         process_set_env (compositor->priv->process, "LD_LIBRARY_PATH", g_getenv ("LD_LIBRARY_PATH"));
     }
 
-    command = g_strdup_printf ("%s --file '%s' --from-dm-fd %d --to-dm-fd %d --vt %d", compositor->priv->command, compositor->priv->socket, compositor->priv->to_compositor_pipe[0], compositor->priv->from_compositor_pipe[1], compositor->priv->vt);
-    absolute_command = get_absolute_command (command);
-    g_free (command);
+    /* Generate command line to run */
+    absolute_command = get_absolute_command (compositor->priv->command);
+    if (!absolute_command)
+    {
+        l_debug (compositor, "Can't launch compositor %s, not found in path", compositor->priv->command);
+        return FALSE;
+    }
+    command = g_string_new (absolute_command);
+    g_free (absolute_command);
+    g_string_append_printf (command, " --file '%s'", compositor->priv->socket);
+    g_string_append_printf (command, " --from-dm-fd %d --to-dm-fd %d", compositor->priv->to_compositor_pipe[0], compositor->priv->from_compositor_pipe[1]);
+    if (compositor->priv->vt > 0)
+        g_string_append_printf (command, " --vt %d", compositor->priv->vt);
+    process_set_command (compositor->priv->process, command->str);
+    g_string_free (command, TRUE);
 
     /* Start the compositor */
-    process_set_command (compositor->priv->process, absolute_command);
-    g_free (absolute_command);
-    g_signal_connect (compositor->priv->process, "stopped", G_CALLBACK (stopped_cb), compositor);
-    g_signal_connect (compositor->priv->process, "run", G_CALLBACK (run_cb), compositor);
+    g_signal_connect (compositor->priv->process, PROCESS_SIGNAL_STOPPED, G_CALLBACK (stopped_cb), compositor);
     result = process_start (compositor->priv->process, FALSE);
 
     /* Close compostor ends of the pipes */
     close (compositor->priv->to_compositor_pipe[0]);
-    compositor->priv->to_compositor_pipe[0] = 0;
+    compositor->priv->to_compositor_pipe[0] = -1;
     close (compositor->priv->from_compositor_pipe[1]);
-    compositor->priv->from_compositor_pipe[1] = 0;
+    compositor->priv->from_compositor_pipe[1] = -1;
 
     if (!result)
         return FALSE;
@@ -455,7 +469,7 @@ unity_system_compositor_start (DisplayServer *server)
 
     return TRUE;
 }
+
 static void
 unity_system_compositor_stop (DisplayServer *server)
 {
@@ -468,23 +482,24 @@ unity_system_compositor_init (UnitySystemCompositor *compositor)
     compositor->priv = G_TYPE_INSTANCE_GET_PRIVATE (compositor, UNITY_SYSTEM_COMPOSITOR_TYPE, UnitySystemCompositorPrivate);
     compositor->priv->vt = -1;
     compositor->priv->command = g_strdup ("unity-system-compositor");
-    compositor->priv->socket = g_strdup ("/tmp/mir_socket");
+    compositor->priv->socket = g_strdup ("/run/mir_socket");
     compositor->priv->timeout = -1;
+    compositor->priv->to_compositor_pipe[0] = -1;
+    compositor->priv->to_compositor_pipe[1] = -1;
+    compositor->priv->from_compositor_pipe[0] = -1;
+    compositor->priv->from_compositor_pipe[1] = -1;
 }
 
 static void
 unity_system_compositor_finalize (GObject *object)
 {
-    UnitySystemCompositor *self;
-
-    self = UNITY_SYSTEM_COMPOSITOR (object);  
+    UnitySystemCompositor *self = UNITY_SYSTEM_COMPOSITOR (object);
 
     if (self->priv->process)
     {
         g_signal_handlers_disconnect_matched (self->priv->process, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
         g_object_unref (self->priv->process);
     }
-    g_free (self->priv->log_file);
     g_free (self->priv->command);
     g_free (self->priv->socket);
     if (self->priv->have_vt_ref)
@@ -494,9 +509,10 @@ unity_system_compositor_finalize (GObject *object)
     close (self->priv->from_compositor_pipe[0]);
     close (self->priv->from_compositor_pipe[1]);
     g_io_channel_unref (self->priv->from_compositor_channel);
-    g_source_remove (self->priv->from_compositor_watch);
+    if (self->priv->from_compositor_watch)
+        g_source_remove (self->priv->from_compositor_watch);
     g_free (self->priv->read_buffer);
-    if (self->priv->timeout_source != 0)
+    if (self->priv->timeout_source)
         g_source_remove (self->priv->timeout_source);
 
     G_OBJECT_CLASS (unity_system_compositor_parent_class)->finalize (object);
@@ -517,3 +533,15 @@ unity_system_compositor_class_init (UnitySystemCompositorClass *klass)
 
     g_type_class_add_private (klass, sizeof (UnitySystemCompositorPrivate));
 }
+
+static gint
+unity_system_compositor_real_logprefix (Logger *self, gchar *buf, gulong buflen)
+{
+    return g_snprintf (buf, buflen, "Unity System Compositor: ");
+}
+
+static void
+unity_system_compositor_logger_iface_init (LoggerInterface *iface)
+{
+    iface->logprefix = &unity_system_compositor_real_logprefix;
+}