]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - src/x-server-xmir.c
c8759ed6c97604c744bcfca71d29a37124d21880
[sojka/lightdm.git] / src / x-server-xmir.c
1 /*
2  * Copyright (C) 2010-2016 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation, either version 3 of the License, or (at your option) any later
7  * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
8  * license.
9  */
10
11 #include <config.h>
12
13 #include "x-server-xmir.h"
14
15 struct XServerXmirPrivate
16 {
17     /* Compositor we are running under */
18     UnitySystemCompositor *compositor;
19
20     /* TRUE if we are waiting for the compositor to start */
21     gboolean waiting_for_compositor;
22
23     /* ID to report to Mir */
24     gchar *mir_id;
25
26     /* Filename of socket Mir is listening on */
27     gchar *mir_socket;
28 };
29
30 G_DEFINE_TYPE (XServerXmir, x_server_xmir, X_SERVER_LOCAL_TYPE);
31
32 static void
33 compositor_ready_cb (UnitySystemCompositor *compositor, XServerXmir *server)
34 {
35     gboolean result;
36
37     if (!server->priv->waiting_for_compositor)
38         return;
39     server->priv->waiting_for_compositor = FALSE;
40
41     result = X_SERVER_LOCAL_CLASS (x_server_xmir_parent_class)->start (DISPLAY_SERVER (server));
42     if (!result)
43         display_server_stop (DISPLAY_SERVER (server));
44 }
45
46 static void
47 compositor_stopped_cb (UnitySystemCompositor *compositor, XServerXmir *server)
48 {
49     display_server_stop (DISPLAY_SERVER (server));  
50 }
51
52 XServerXmir *
53 x_server_xmir_new (UnitySystemCompositor *compositor)
54 {
55     XServerXmir *server;
56     gchar *name;
57
58     server = g_object_new (X_SERVER_XMIR_TYPE, NULL);
59     x_server_local_set_command (X_SERVER_LOCAL (server), "Xmir");
60     server->priv->compositor = g_object_ref (compositor);
61     g_signal_connect (compositor, DISPLAY_SERVER_SIGNAL_READY, G_CALLBACK (compositor_ready_cb), server);
62     g_signal_connect (compositor, DISPLAY_SERVER_SIGNAL_STOPPED, G_CALLBACK (compositor_stopped_cb), server);
63   
64     name = g_strdup_printf ("x-%d", x_server_get_display_number (X_SERVER (server)));
65     display_server_set_name (DISPLAY_SERVER (server), name);
66     g_free (name);
67
68
69     return server;
70 }
71
72 void
73 x_server_xmir_set_mir_id (XServerXmir *server, const gchar *id)
74 {
75     g_return_if_fail (server != NULL);
76     g_free (server->priv->mir_id);
77     server->priv->mir_id = g_strdup (id);
78 }
79
80 const gchar *
81 x_server_xmir_get_mir_id (XServerXmir *server)
82 {
83     g_return_val_if_fail (server != NULL, NULL);
84     return server->priv->mir_id;
85 }
86
87 void
88 x_server_xmir_set_mir_socket (XServerXmir *server, const gchar *socket)
89 {
90     g_return_if_fail (server != NULL);
91     g_free (server->priv->mir_socket);
92     server->priv->mir_socket = g_strdup (socket);
93 }
94
95 static void
96 x_server_xmir_add_args (XServerLocal *x_server, GString *command)
97 {
98     XServerXmir *server = X_SERVER_XMIR (x_server);
99
100     if (server->priv->mir_id)
101         g_string_append_printf (command, " -mir %s", server->priv->mir_id);
102
103     if (server->priv->mir_socket)
104         g_string_append_printf (command, " -mirSocket %s", server->priv->mir_socket);
105 }
106
107 static DisplayServer *
108 x_server_xmir_get_parent (DisplayServer *server)
109 {
110     return DISPLAY_SERVER (X_SERVER_XMIR (server)->priv->compositor);
111 }
112
113 static gint
114 x_server_xmir_get_vt (DisplayServer *server)
115 {
116     return display_server_get_vt (DISPLAY_SERVER (X_SERVER_XMIR (server)->priv->compositor));
117 }
118
119 static gboolean
120 x_server_xmir_start (DisplayServer *display_server)
121 {
122     XServerXmir *server = X_SERVER_XMIR (display_server);
123
124     if (display_server_get_is_ready (DISPLAY_SERVER (server->priv->compositor)))
125         return X_SERVER_LOCAL_CLASS (x_server_xmir_parent_class)->start (display_server);
126     else
127     {
128         if (!server->priv->waiting_for_compositor)
129         {
130             server->priv->waiting_for_compositor = TRUE;
131             if (!display_server_start (DISPLAY_SERVER (server->priv->compositor)))
132                 return FALSE;
133         }
134         return TRUE;
135     }
136 }
137
138 static void
139 x_server_xmir_init (XServerXmir *server)
140 {
141     server->priv = G_TYPE_INSTANCE_GET_PRIVATE (server, X_SERVER_XMIR_TYPE, XServerXmirPrivate);
142 }
143
144 static void
145 x_server_xmir_finalize (GObject *object)
146 {
147     XServerXmir *self = X_SERVER_XMIR (object);
148
149     if (self->priv->compositor)
150     {
151         g_signal_handlers_disconnect_matched (self->priv->compositor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
152         g_object_unref (self->priv->compositor);
153     }
154     g_free (self->priv->mir_id);
155     g_free (self->priv->mir_socket);
156
157     G_OBJECT_CLASS (x_server_xmir_parent_class)->finalize (object);
158 }
159
160 static void
161 x_server_xmir_class_init (XServerXmirClass *klass)
162 {
163     GObjectClass *object_class = G_OBJECT_CLASS (klass);
164     DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
165     XServerLocalClass *x_server_local_class = X_SERVER_LOCAL_CLASS (klass);  
166
167     x_server_local_class->add_args = x_server_xmir_add_args;
168     display_server_class->get_parent = x_server_xmir_get_parent;
169     display_server_class->get_vt = x_server_xmir_get_vt;
170     display_server_class->start = x_server_xmir_start;
171     object_class->finalize = x_server_xmir_finalize;
172
173     g_type_class_add_private (klass, sizeof (XServerXmirPrivate));
174 }