]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - tests/src/unity-system-compositor.c
Don't handle --standalone in test u-s-c
[sojka/lightdm.git] / tests / src / unity-system-compositor.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <glib-unix.h>
7
8 #include "status.h"
9
10 static GMainLoop *loop;
11 static int exit_status = EXIT_SUCCESS;
12 static int from_dm_fd = -1, to_dm_fd = -1;
13
14 static GKeyFile *config;
15
16 static void
17 quit (int status)
18 {
19     exit_status = status;
20     g_main_loop_quit (loop);
21 }
22
23 static gboolean
24 sigint_cb (gpointer user_data)
25 {
26     status_notify ("UNITY-SYSTEM-COMPOSITOR TERMINATE SIGNAL=%d", SIGINT);
27     quit (EXIT_SUCCESS);
28     return TRUE;
29 }
30
31 static gboolean
32 sigterm_cb (gpointer user_data)
33 {
34     status_notify ("UNITY-SYSTEM-COMPOSITOR TERMINATE SIGNAL=%d", SIGTERM);
35     quit (EXIT_SUCCESS);
36     return TRUE;
37 }
38
39 typedef enum
40 {
41    USC_MESSAGE_PING = 0,
42    USC_MESSAGE_PONG = 1,
43    USC_MESSAGE_READY = 2,
44    USC_MESSAGE_SESSION_CONNECTED = 3,
45    USC_MESSAGE_SET_ACTIVE_SESSION = 4,
46    USC_MESSAGE_SET_NEXT_SESSION = 5,
47 } USCMessageID;
48
49 static void
50 write_message (guint16 id, const guint8 *payload, guint16 payload_length)
51 {
52     guint8 *data;
53     gsize data_length = 4 + payload_length;
54
55     data = g_malloc (data_length);
56     data[0] = id >> 8;
57     data[1] = id & 0xFF;
58     data[2] = payload_length >> 8;
59     data[3] = payload_length & 0xFF;
60     memcpy (data + 4, payload, payload_length);
61
62     if (write (to_dm_fd, data, data_length) < 0)
63         fprintf (stderr, "Failed to write to daemon: %s\n", strerror (errno));
64 }
65
66 static gboolean
67 read_message_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
68 {
69     gchar header[4], *payload;
70     gsize n_read;
71     guint16 id;
72     guint16 payload_length;
73     GError *error = NULL;
74
75     if (g_io_channel_read_chars (channel, header, 4, &n_read, &error) != G_IO_STATUS_NORMAL)
76     {
77         g_printerr ("Failed to read header: %s\n", error->message);
78         return FALSE;
79     }
80     if (n_read != 4)
81     {
82         g_printerr ("Short read for header, %zi instead of expected 4\n", n_read);
83         return FALSE;
84     }
85     id = header[0] << 8 | header[1];
86     payload_length = header[2] << 8 | header[3];
87     payload = g_malloc0 (payload_length + 1);
88     if (g_io_channel_read_chars (channel, payload, payload_length, &n_read, &error) != G_IO_STATUS_NORMAL)
89     {
90         g_printerr ("Failed to read payload: %s\n", error->message);
91         return FALSE;
92     }
93     if (n_read != payload_length)
94     {
95         g_printerr ("Short read for payload, %zi instead of expected %d\n", n_read, payload_length);
96         return FALSE;      
97     }
98
99     switch (id)
100     {
101     case USC_MESSAGE_PING:
102         status_notify ("UNITY-SYSTEM-COMPOSITOR PING");
103         break;
104     case USC_MESSAGE_SET_ACTIVE_SESSION:
105         status_notify ("UNITY-SYSTEM-COMPOSITOR SET-ACTIVE-SESSION ID=%s", (gchar *)payload);
106         break;
107     case USC_MESSAGE_SET_NEXT_SESSION:
108         status_notify ("UNITY-SYSTEM-COMPOSITOR SET-NEXT-SESSION ID=%s", (gchar *)payload);
109         break;
110     default:
111         g_printerr ("Ignoring message %d with %d octets\n", id, payload_length);
112         break;
113     }
114
115     free (payload);
116
117     return TRUE;
118 }
119
120 static void
121 request_cb (const gchar *request)
122 {
123     if (!request)
124     {
125         g_main_loop_quit (loop);
126         return;
127     }
128
129     if (strcmp (request, "UNITY-SYSTEM-COMPOSITOR PING") == 0)
130         write_message (USC_MESSAGE_PING, NULL, 0);
131     else if (strcmp (request, "UNITY-SYSTEM-COMPOSITOR PONG") == 0)
132         write_message (USC_MESSAGE_PONG, NULL, 0);
133     else if (strcmp (request, "UNITY-SYSTEM-COMPOSITOR READY") == 0)
134         write_message (USC_MESSAGE_READY, NULL, 0);
135 }
136
137 int
138 main (int argc, char **argv)
139 {
140     int i;
141     GString *status_text;
142     gboolean test = FALSE;
143     int vt_number = -1;
144
145 #if !defined(GLIB_VERSION_2_36)
146     g_type_init ();
147 #endif
148
149     loop = g_main_loop_new (NULL, FALSE);
150
151     g_unix_signal_add (SIGINT, sigint_cb, NULL);
152     g_unix_signal_add (SIGTERM, sigterm_cb, NULL);
153
154     status_connect (request_cb);
155
156     for (i = 1; i < argc; i++)
157     {
158         char *arg = argv[i];
159
160         if (strcmp (arg, "--from-dm-fd") == 0)
161         {
162             from_dm_fd = atoi (argv[i+1]);
163             i++;
164         }
165         else if (strcmp (arg, "--to-dm-fd") == 0)
166         {
167             to_dm_fd = atoi (argv[i+1]);
168             i++;
169         }
170         else if (strcmp (arg, "--vt") == 0)
171         {
172             vt_number = atoi (argv[i+1]);
173             i++;
174         }
175         else if (strcmp (arg, "--file") == 0)
176         {
177             /*file = argv[i+1];*/
178             i++;
179         }
180         else if (strcmp (arg, "--test") == 0)
181             test = TRUE;
182         else
183             return EXIT_FAILURE;
184     }
185
186     g_io_add_watch (g_io_channel_unix_new (from_dm_fd), G_IO_IN, read_message_cb, NULL);
187
188     status_text = g_string_new ("UNITY-SYSTEM-COMPOSITOR START");
189     if (vt_number >= 0)
190         g_string_append_printf (status_text, " VT=%d", vt_number);
191     if (g_getenv ("XDG_VTNR"))
192         g_string_append_printf (status_text, " XDG_VTNR=%s", g_getenv ("XDG_VTNR"));
193     if (test)
194         g_string_append (status_text, " TEST=TRUE");
195     status_notify (status_text->str);
196     g_string_free (status_text, TRUE);
197
198     config = g_key_file_new ();
199     g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL);
200
201     if (g_key_file_has_key (config, "unity-system-compositor-config", "return-value", NULL))
202     {
203         int return_value = g_key_file_get_integer (config, "unity-system-compositor-config", "return-value", NULL);
204         status_notify ("UNITY-SYSTEM-COMPOSITOR EXIT CODE=%d", return_value);
205         return return_value;
206     }
207
208     g_main_loop_run (loop);
209
210     return exit_status;
211 }