]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - src/x-server.c
Make the display number a vfunc from the X server class
[sojka/lightdm.git] / src / x-server.c
1 /*
2  * Copyright (C) 2010-2011 Robert Ancell.
3  * Author: Robert Ancell <robert.ancell@canonical.com>
4  *
5  * This program is free software: you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License as published by the Free Software
7  * Foundation, either version 3 of the License, or (at your option) any later
8  * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
9  * license.
10  */
11
12 #include <config.h>
13 #include <string.h>
14 #include <xcb/xcb.h>
15
16 #include "x-server.h"
17 #include "configuration.h"
18
19 struct XServerPrivate
20 {
21     /* Host running the server */
22     gchar *hostname;
23
24     /* Cached server address */
25     gchar *address;
26
27     /* Authority */
28     XAuthority *authority;
29
30     /* Connection to this X server */
31     xcb_connection_t *connection;
32 };
33
34 G_DEFINE_TYPE (XServer, x_server, DISPLAY_SERVER_TYPE);
35
36 void
37 x_server_set_hostname (XServer *server, const gchar *hostname)
38 {
39     g_return_if_fail (server != NULL);
40     g_free (server->priv->hostname);
41     server->priv->hostname = g_strdup (hostname);
42     g_free (server->priv->address);
43     server->priv->address = NULL;
44 }
45
46 gchar *
47 x_server_get_hostname (XServer *server)
48 {
49     g_return_val_if_fail (server != NULL, NULL);
50     return server->priv->hostname;
51 }
52
53 guint
54 x_server_get_display_number (XServer *server)
55 {
56     g_return_val_if_fail (server != NULL, 0);
57     return X_SERVER_GET_CLASS (server)->get_display_number (server);
58 }
59
60 const gchar *
61 x_server_get_address (XServer *server)
62 {
63     g_return_val_if_fail (server != NULL, NULL);
64
65     if (!server->priv->address)
66     {
67         if (server->priv->hostname)
68             server->priv->address = g_strdup_printf("%s:%d", server->priv->hostname, x_server_get_display_number (server));
69         else
70             server->priv->address = g_strdup_printf(":%d", x_server_get_display_number (server));
71     }
72
73     return server->priv->address;
74 }
75
76 void
77 x_server_set_authority (XServer *server, XAuthority *authority)
78 {
79     g_return_if_fail (server != NULL);
80
81     g_clear_object (&server->priv->authority);
82     if (authority)
83         server->priv->authority = g_object_ref (authority);
84 }
85
86 XAuthority *
87 x_server_get_authority (XServer *server)
88 {
89     g_return_val_if_fail (server != NULL, NULL);
90     return server->priv->authority;
91 }
92
93 static const gchar *
94 x_server_get_session_type (DisplayServer *server)
95 {
96     return "x";
97 }
98
99 static gboolean
100 x_server_get_can_share (DisplayServer *server)
101 {
102     return TRUE;
103 }
104
105 static gboolean
106 x_server_start (DisplayServer *display_server)
107 {
108     XServer *server = X_SERVER (display_server);
109     xcb_auth_info_t *auth = NULL, a;
110
111     if (server->priv->authority)
112     {
113         a.namelen = strlen (x_authority_get_authorization_name (server->priv->authority));
114         a.name = (char *) x_authority_get_authorization_name (server->priv->authority);
115         a.datalen = x_authority_get_authorization_data_length (server->priv->authority);
116         a.data = (char *) x_authority_get_authorization_data (server->priv->authority);
117         auth = &a;
118     }
119
120     /* Open connection */
121     l_debug (server, "Connecting to XServer %s", x_server_get_address (server));
122     server->priv->connection = xcb_connect_to_display_with_auth_info (x_server_get_address (server), auth, NULL);
123     if (xcb_connection_has_error (server->priv->connection))
124     {
125         l_debug (server, "Error connecting to XServer %s", x_server_get_address (server));
126         return FALSE;
127     }
128
129     return DISPLAY_SERVER_CLASS (x_server_parent_class)->start (display_server);
130 }
131
132 static void
133 x_server_connect_session (DisplayServer *display_server, Session *session)
134 {
135     gint vt;
136
137     session_set_env (session, "XDG_SESSION_TYPE", "x11");
138
139     display_server = session_get_display_server (session);
140
141     vt = display_server_get_vt (display_server);
142     if (vt > 0)
143     {
144         gchar *t;
145
146         t = g_strdup_printf ("/dev/tty%d", vt);
147         session_set_tty (session, t);
148         g_free (t);
149
150         t = g_strdup_printf ("%d", vt);
151         session_set_env (session, "XDG_VTNR", t);
152         g_free (t);
153     }
154     else
155         l_debug (session, "Not setting XDG_VTNR");
156
157     session_set_env (session, "DISPLAY", x_server_get_address (X_SERVER (display_server)));
158     session_set_xdisplay (session, x_server_get_address (X_SERVER (display_server)));
159     session_set_remote_host_name (session, x_server_get_hostname (X_SERVER (display_server)));
160     session_set_x_authority (session,
161                              x_server_get_authority (X_SERVER (display_server)),
162                              config_get_boolean (config_get_instance (), "LightDM", "user-authority-in-system-dir"));
163 }
164
165 static void
166 x_server_disconnect_session (DisplayServer *display_server, Session *session)
167 {
168     gint vt;
169
170     session_unset_env (session, "XDG_SESSION_TYPE");
171     vt = display_server_get_vt (display_server);
172     if (vt > 0)
173     {
174         session_set_tty (session, NULL);
175         session_unset_env (session, "XDG_VTNR");
176     }
177     session_unset_env (session, "DISPLAY");
178     session_set_xdisplay (session, NULL);
179     session_set_remote_host_name (session, NULL);
180     session_set_x_authority (session, NULL, FALSE);
181 }
182
183 void
184 x_server_init (XServer *server)
185 {
186     server->priv = G_TYPE_INSTANCE_GET_PRIVATE (server, X_SERVER_TYPE, XServerPrivate);
187 }
188
189 static void
190 x_server_finalize (GObject *object)
191 {
192     XServer *self = X_SERVER (object);
193
194     g_free (self->priv->hostname);
195     g_free (self->priv->address);
196     g_clear_object (&self->priv->authority);
197     if (self->priv->connection)
198         xcb_disconnect (self->priv->connection);
199
200     G_OBJECT_CLASS (x_server_parent_class)->finalize (object);
201 }
202
203 static void
204 x_server_class_init (XServerClass *klass)
205 {
206     GObjectClass *object_class = G_OBJECT_CLASS (klass);
207     DisplayServerClass *display_server_class = DISPLAY_SERVER_CLASS (klass);
208
209     display_server_class->get_session_type = x_server_get_session_type;
210     display_server_class->get_can_share = x_server_get_can_share;
211     display_server_class->start = x_server_start;
212     display_server_class->connect_session = x_server_connect_session;
213     display_server_class->disconnect_session = x_server_disconnect_session;
214     object_class->finalize = x_server_finalize;
215
216     g_type_class_add_private (klass, sizeof (XServerPrivate));
217 }