~lightdm-team/lightdm/1.4

« back to all changes in this revision

Viewing changes to tests/src/x-server.c

  • Committer: Robert Ancell
  • Date: 2013-06-17 21:47:26 UTC
  • Revision ID: robert.ancell@canonical.com-20130617214726-pwfjk0cz18bnklwr
Backport all test improvements from trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include <gio/gio.h>
11
11
#include <gio/gunixsocketaddress.h>
12
12
 
13
 
#include "x-common.h"
14
13
#include "x-server.h"
15
14
 
16
15
G_DEFINE_TYPE (XServer, x_server, G_TYPE_OBJECT);
17
 
G_DEFINE_TYPE (XScreen, x_screen, G_TYPE_OBJECT);
18
 
G_DEFINE_TYPE (XVisual, x_visual, G_TYPE_OBJECT);
19
16
G_DEFINE_TYPE (XClient, x_client, G_TYPE_OBJECT);
20
17
 
21
18
#define MAXIMUM_REQUEST_LENGTH 65535
22
19
 
23
 
enum
24
 
{
25
 
    Failed = 0,
26
 
    Success = 1,
27
 
    Authenticate = 2
28
 
};
29
 
 
30
 
enum
31
 
{
32
 
    Error = 0,
33
 
    Reply = 1,
34
 
};
35
 
 
36
 
enum
37
 
{
38
 
    InternAtom = 16,
39
 
    GetProperty = 20,
40
 
    QueryExtension = 98,
41
 
    kbUseExtension = 200
42
 
};
43
 
 
44
 
enum
45
 
{
46
 
    BadAtom = 5,
47
 
    BadImplementation = 17
48
 
};
49
 
 
50
20
enum {
51
21
    X_SERVER_CLIENT_CONNECTED,
52
22
    X_SERVER_CLIENT_DISCONNECTED,
54
24
};
55
25
static guint x_server_signals[X_SERVER_LAST_SIGNAL] = { 0 };
56
26
 
57
 
typedef struct
58
 
{
59
 
    guint8 depth;
60
 
    guint8 bits_per_pixel;
61
 
    guint8 scanline_pad;
62
 
} PixmapFormat;
63
 
 
64
27
struct XServerPrivate
65
28
{
66
 
    gchar *vendor;
67
 
 
68
29
    gint display_number;
69
 
  
70
 
    guint32 motion_buffer_size;
71
 
    guint8 image_byte_order;
72
 
    guint8 bitmap_format_bit_order;
73
 
  
74
 
    guint8 min_keycode;
75
 
    guint8 max_keycode;
76
 
 
77
 
    GList *pixmap_formats;  
78
 
    GList *screens;
79
 
 
80
 
    gboolean listen_unix;
81
 
    gboolean listen_tcp;
82
 
    gint tcp_port;
 
30
 
83
31
    gchar *socket_path;
84
 
    GSocket *unix_socket;
85
 
    GIOChannel *unix_channel;
86
 
    GSocket *tcp_socket;
87
 
    GIOChannel *tcp_channel;
 
32
    GSocket *socket;
 
33
    GIOChannel *channel;
88
34
    GHashTable *clients;
89
 
    GHashTable *atoms;
90
 
    gint next_atom_index;
91
35
};
92
36
 
93
37
struct XClientPrivate
95
39
    XServer *server;
96
40
    GSocket *socket;  
97
41
    GIOChannel *channel;
98
 
    guint8 byte_order;
99
 
    gboolean connected;
100
 
    guint16 sequence_number;
101
 
};
102
 
 
103
 
struct XScreenPrivate
104
 
{
105
 
    guint32 white_pixel;
106
 
    guint32 black_pixel;
107
 
    guint32 current_input_masks;
108
 
    guint16 width_in_pixels;
109
 
    guint16 height_in_pixels;
110
 
    guint16 width_in_millimeters;
111
 
    guint16 height_in_millimeters;
112
 
    GList *visuals;
113
 
};
114
 
 
115
 
struct XVisualPrivate
116
 
{
117
 
    guint32 id;
118
 
    guint8 depth;
119
 
    guint8 class;
120
 
    guint8 bits_per_rgb_value;
121
 
    guint16 colormap_entries;
122
 
    guint32 red_mask;
123
 
    guint32 green_mask;
124
 
    guint32 blue_mask;
125
42
};
126
43
 
127
44
enum
128
45
{
129
 
    X_CLIENT_CONNECT,
130
46
    X_CLIENT_DISCONNECTED,
131
47
    X_CLIENT_LAST_SIGNAL
132
48
};
133
49
static guint x_client_signals[X_CLIENT_LAST_SIGNAL] = { 0 };
134
50
 
135
 
GInetAddress *
136
 
x_client_get_address (XClient *client)
137
 
{
138
 
    GSocketAddress *socket_address;
139
 
    GError *error = NULL;
140
 
 
141
 
    socket_address = g_socket_get_remote_address (client->priv->socket, &error);
142
 
    if (error)
143
 
        g_warning ("Error getting remote socket address");
144
 
    g_clear_error (&error);
145
 
    if (!socket_address)
146
 
        return NULL;
147
 
 
148
 
    if (G_IS_INET_SOCKET_ADDRESS (socket_address))
149
 
        return g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
150
 
    else
151
 
        return NULL;
152
 
}
153
 
 
154
51
void
155
52
x_client_send_failed (XClient *client, const gchar *reason)
156
53
{
157
 
    guint8 buffer[MAXIMUM_REQUEST_LENGTH];
158
 
    gsize n_written = 0, length_offset;
159
 
 
160
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, Failed, &n_written);
161
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, strlen (reason), &n_written);
162
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, X_PROTOCOL_MAJOR_VERSION, &n_written);
163
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, X_PROTOCOL_MINOR_VERSION, &n_written);
164
 
    length_offset = n_written;
165
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written);
166
 
    write_padded_string (buffer, MAXIMUM_REQUEST_LENGTH, reason, &n_written);
167
 
 
168
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, (n_written - length_offset) / 4, &length_offset);
169
 
 
170
 
    send (g_io_channel_unix_get_fd (client->priv->channel), buffer, n_written, 0);
 
54
    gchar *message;
 
55
  
 
56
    message = g_strdup_printf ("FAILED:%s", reason);
 
57
    send (g_io_channel_unix_get_fd (client->priv->channel), message, strlen (message), 0);
 
58
    g_free (message);
171
59
}
172
60
 
173
61
void 
174
62
x_client_send_success (XClient *client)
175
63
{
176
 
    XServer *server = client->priv->server;
177
 
    guint8 buffer[MAXIMUM_REQUEST_LENGTH];
178
 
    gsize n_written = 0, length_offset;
179
 
    GList *link;
180
 
 
181
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, Success, &n_written);
182
 
    write_padding (buffer, MAXIMUM_REQUEST_LENGTH, 1, &n_written);
183
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, X_PROTOCOL_MAJOR_VERSION, &n_written);
184
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, X_PROTOCOL_MINOR_VERSION, &n_written);
185
 
    length_offset = n_written;
186
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written);
187
 
    write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, X_RELEASE_NUMBER, &n_written);
188
 
    write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0x00a00000, &n_written); // resource-id-base
189
 
    write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0x001fffff, &n_written); // resource-id-mask
190
 
    write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, server->priv->motion_buffer_size, &n_written);
191
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, strlen (client->priv->server->priv->vendor), &n_written);
192
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, MAXIMUM_REQUEST_LENGTH, &n_written);
193
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, g_list_length (server->priv->screens), &n_written);
194
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, g_list_length (server->priv->pixmap_formats), &n_written);
195
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, server->priv->image_byte_order, &n_written);
196
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, server->priv->bitmap_format_bit_order, &n_written);
197
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 32, &n_written); // bitmap-format-scanline-unit
198
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 32, &n_written); // bitmap-format-scanline-pad
199
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, server->priv->min_keycode, &n_written);
200
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, server->priv->max_keycode, &n_written);
201
 
    write_padding (buffer, MAXIMUM_REQUEST_LENGTH, 4, &n_written);
202
 
    write_padded_string (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->server->priv->vendor, &n_written);
203
 
 
204
 
    for (link = server->priv->pixmap_formats; link; link = link->next)
205
 
    {
206
 
        PixmapFormat *format = link->data;
207
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, format->depth, &n_written);
208
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, format->bits_per_pixel, &n_written);
209
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, format->scanline_pad, &n_written);
210
 
        write_padding (buffer, MAXIMUM_REQUEST_LENGTH, 5, &n_written);
211
 
    }
212
 
 
213
 
    for (link = server->priv->screens; link; link = link->next)
214
 
    {
215
 
        XScreen *screen = link->data;
216
 
        guint8 depth, n_depths = 0;
217
 
        gsize n_depths_offset;
218
 
 
219
 
        write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 87, &n_written); // root
220
 
        write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 32, &n_written); // default-colormap
221
 
        write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, screen->priv->white_pixel, &n_written);
222
 
        write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, screen->priv->black_pixel, &n_written);
223
 
        write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, screen->priv->current_input_masks, &n_written);
224
 
        write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, screen->priv->width_in_pixels, &n_written);
225
 
        write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, screen->priv->height_in_pixels, &n_written);
226
 
        write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, screen->priv->width_in_millimeters, &n_written);
227
 
        write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, screen->priv->height_in_millimeters, &n_written);
228
 
        write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 1, &n_written); // min-installed-maps
229
 
        write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 1, &n_written); // max-installed-maps
230
 
        write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 34, &n_written); // root-visual
231
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 0, &n_written); // backing-stores
232
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 0, &n_written); // save-unders
233
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 24, &n_written); // root-depth
234
 
        n_depths_offset = n_written;
235
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 0, &n_written);
236
 
 
237
 
        depth = 0;
238
 
        while (TRUE)
239
 
        {
240
 
            GList *visual_link;
241
 
            guint16 n_visuals = 0;
242
 
 
243
 
            /* Find the next depth to this one */
244
 
            guint8 next_depth = 255;
245
 
            for (visual_link = screen->priv->visuals; visual_link; visual_link = visual_link->next)
246
 
            {
247
 
                XVisual *visual = visual_link->data;
248
 
                if (visual->priv->depth > depth && visual->priv->depth < next_depth)
249
 
                    next_depth = visual->priv->depth;
250
 
            }
251
 
            if (next_depth == 255)
252
 
                break;
253
 
            depth = next_depth;
254
 
            n_depths++;
255
 
 
256
 
            for (visual_link = screen->priv->visuals; visual_link; visual_link = visual_link->next)
257
 
            {
258
 
                XVisual *visual = visual_link->data;
259
 
                if (visual->priv->depth == depth)
260
 
                    n_visuals++;
261
 
            }
262
 
 
263
 
            write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, depth, &n_written);
264
 
            write_padding (buffer, MAXIMUM_REQUEST_LENGTH, 1, &n_written);
265
 
            write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, n_visuals, &n_written);
266
 
            write_padding (buffer, MAXIMUM_REQUEST_LENGTH, 4, &n_written);
267
 
 
268
 
            for (visual_link = screen->priv->visuals; visual_link; visual_link = visual_link->next)
269
 
            {
270
 
                XVisual *visual = visual_link->data;
271
 
 
272
 
                if (visual->priv->depth != depth)
273
 
                    continue;
274
 
 
275
 
                write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, visual->priv->id, &n_written);
276
 
                write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, visual->priv->class, &n_written);
277
 
                write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, visual->priv->bits_per_rgb_value, &n_written);
278
 
                write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, visual->priv->colormap_entries, &n_written);
279
 
                write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, visual->priv->red_mask, &n_written);
280
 
                write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, visual->priv->green_mask, &n_written);
281
 
                write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, visual->priv->blue_mask, &n_written);
282
 
                write_padding (buffer, MAXIMUM_REQUEST_LENGTH, 4, &n_written);
283
 
            }
284
 
        }
285
 
 
286
 
        write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, n_depths, &n_depths_offset);
287
 
    }
288
 
 
289
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, (n_written - length_offset) / 4, &length_offset);
290
 
 
291
 
    send (g_io_channel_unix_get_fd (client->priv->channel), buffer, n_written, 0);
292
 
}
293
 
 
294
 
void
295
 
x_client_send_error (XClient *client, int type, int major, int minor)
296
 
{
297
 
    guint8 buffer[MAXIMUM_REQUEST_LENGTH];
298
 
    gsize n_written = 0;
299
 
 
300
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, Error, &n_written);
301
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, type, &n_written);
302
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, client->priv->sequence_number, &n_written);
303
 
    write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written); /* resourceID */
304
 
    write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, minor, &n_written);
305
 
    write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, major, &n_written);
306
 
    write_padding (buffer, MAXIMUM_REQUEST_LENGTH, 21, &n_written);
307
 
 
308
 
    send (g_io_channel_unix_get_fd (client->priv->channel), buffer, n_written, 0);
 
64
    gchar *message;
 
65
 
 
66
    message = g_strdup ("SUCCESS");
 
67
    send (g_io_channel_unix_get_fd (client->priv->channel), message, strlen (message), 0);
 
68
    g_free (message);
309
69
}
310
70
 
311
71
void
318
78
x_client_init (XClient *client)
319
79
{
320
80
    client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client, x_client_get_type (), XClientPrivate);
321
 
    client->priv->sequence_number = 1;
322
81
}
323
82
 
324
83
static void
326
85
{
327
86
    g_type_class_add_private (klass, sizeof (XClientPrivate));
328
87
 
329
 
    x_client_signals[X_CLIENT_CONNECT] =
330
 
        g_signal_new ("connect",
331
 
                      G_TYPE_FROM_CLASS (klass),
332
 
                      G_SIGNAL_RUN_LAST,
333
 
                      G_STRUCT_OFFSET (XClientClass, connect),
334
 
                      NULL, NULL,
335
 
                      g_cclosure_marshal_VOID__POINTER,
336
 
                      G_TYPE_NONE, 1, G_TYPE_POINTER);
337
88
    x_client_signals[X_CLIENT_DISCONNECTED] =
338
89
        g_signal_new ("disconnected",
339
90
                      G_TYPE_FROM_CLASS (klass),
349
100
{
350
101
    XServer *server = g_object_new (x_server_get_type (), NULL);
351
102
    server->priv->display_number = display_number;
352
 
    server->priv->tcp_port = 6000 + display_number;
353
103
    return server;
354
104
}
355
105
 
356
 
XScreen *
357
 
x_server_add_screen (XServer *server, guint32 white_pixel, guint32 black_pixel, guint32 current_input_masks, guint16 width_in_pixels, guint16 height_in_pixels, guint16 width_in_millimeters, guint16 height_in_millimeters)
358
 
{
359
 
    XScreen *screen;
360
 
 
361
 
    screen = g_object_new (x_screen_get_type (), NULL);
362
 
 
363
 
    screen->priv->white_pixel = white_pixel;
364
 
    screen->priv->black_pixel = black_pixel;
365
 
    screen->priv->current_input_masks = current_input_masks;
366
 
    screen->priv->width_in_pixels = width_in_pixels;
367
 
    screen->priv->height_in_pixels = height_in_pixels;
368
 
    screen->priv->width_in_millimeters = width_in_millimeters;
369
 
    screen->priv->height_in_millimeters = height_in_millimeters;
370
 
  
371
 
    server->priv->screens = g_list_append (server->priv->screens, screen);
372
 
 
373
 
    return screen;
374
 
}
375
 
 
376
 
void
377
 
x_server_add_pixmap_format (XServer *server, guint8 depth, guint8 bits_per_pixel, guint8 scanline_pad)
378
 
{
379
 
    PixmapFormat *format;
380
 
  
381
 
    format = g_malloc0 (sizeof (PixmapFormat));
382
 
    format->depth = depth;
383
 
    format->bits_per_pixel = bits_per_pixel;
384
 
    format->scanline_pad = scanline_pad;
385
 
    server->priv->pixmap_formats = g_list_append (server->priv->pixmap_formats, format);
386
 
}
387
 
 
388
 
void
389
 
x_server_set_listen_unix (XServer *server, gboolean listen_unix)
390
 
{
391
 
    server->priv->listen_unix = listen_unix;
392
 
}
393
 
 
394
 
void
395
 
x_server_set_listen_tcp (XServer *server, gboolean listen_tcp)
396
 
{
397
 
    server->priv->listen_tcp = listen_tcp;
398
 
}
399
 
 
400
 
XVisual *
401
 
x_screen_add_visual (XScreen *screen, guint8 depth, guint8 class, guint8 bits_per_rgb_value, guint16 colormap_entries, guint32 red_mask, guint32 green_mask, guint32 blue_mask)
402
 
{
403
 
    XVisual *visual;
404
 
 
405
 
    visual = g_object_new (x_visual_get_type (), NULL);
406
 
    visual->priv->id = 0; // FIXME
407
 
    visual->priv->depth = depth;
408
 
    visual->priv->class = class;
409
 
    visual->priv->bits_per_rgb_value = bits_per_rgb_value;
410
 
    visual->priv->colormap_entries = colormap_entries;
411
 
    visual->priv->red_mask = red_mask;
412
 
    visual->priv->green_mask = green_mask;
413
 
    visual->priv->blue_mask = blue_mask;
414
 
    
415
 
    return visual;
416
 
}
417
 
 
418
 
static void
419
 
decode_connection_request (XClient *client, const guint8 *buffer, gssize buffer_length)
420
 
{
421
 
    guint8 byte_order;
422
 
    gsize offset = 0;
423
 
    guint16 n;
424
 
    XConnect *message;
425
 
 
426
 
    byte_order = read_card8 (buffer, buffer_length, &offset);
427
 
    if (!(byte_order == 'B' || byte_order == 'l'))
428
 
    {
429
 
        g_warning ("Invalid byte order");
430
 
        return;
431
 
    }
432
 
  
433
 
    message = g_malloc0 (sizeof (XConnect));
434
 
 
435
 
    message->byte_order = byte_order == 'B' ? X_BYTE_ORDER_MSB : X_BYTE_ORDER_LSB;
436
 
    read_padding (1, &offset);
437
 
    message->protocol_major_version = read_card16 (buffer, buffer_length, message->byte_order, &offset);
438
 
    message->protocol_minor_version = read_card16 (buffer, buffer_length, message->byte_order, &offset);
439
 
    n = read_card16 (buffer, buffer_length, message->byte_order, &offset);
440
 
    message->authorization_protocol_data_length = read_card16 (buffer, buffer_length, message->byte_order, &offset);
441
 
    read_padding (2, &offset);
442
 
    message->authorization_protocol_name = read_padded_string (buffer, buffer_length, n, &offset);
443
 
    message->authorization_protocol_data = read_string8 (buffer, buffer_length, message->authorization_protocol_data_length, &offset);
444
 
    read_padding (pad (message->authorization_protocol_data_length), &offset);
445
 
 
446
 
    /* Store information about the client */
447
 
    client->priv->byte_order = message->byte_order;
448
 
    client->priv->connected = TRUE;
449
 
 
450
 
    g_signal_emit (client, x_client_signals[X_CLIENT_CONNECT], 0, message);
451
 
 
452
 
    g_free (message->authorization_protocol_name);
453
 
    g_free (message->authorization_protocol_data);
454
 
    g_free (message);
455
 
}
456
 
 
457
 
static void
458
 
process_intern_atom (XClient *client, const guint8 *buffer, gssize buffer_length)
459
 
{
460
 
    /* Decode */
461
 
 
462
 
    gsize offset = 0;
463
 
    guint8 onlyIfExists;
464
 
    guint16 n;
465
 
    gchar *name;
466
 
    int atom;
467
 
 
468
 
    read_padding (1, &offset); /* reqType */
469
 
    onlyIfExists = read_card8 (buffer, buffer_length, &offset);
470
 
    read_padding (2, &offset); /* length */
471
 
    n = read_card16 (buffer, buffer_length, client->priv->byte_order, &offset);
472
 
    read_padding (2, &offset);
473
 
    name = read_padded_string (buffer, buffer_length, n, &offset);
474
 
 
475
 
    /* Process */
476
 
 
477
 
    atom = client->priv->server->priv->next_atom_index++;
478
 
 
479
 
    if (onlyIfExists)
480
 
    {
481
 
        g_free (name);
482
 
        if (!g_hash_table_lookup (client->priv->server->priv->atoms, GINT_TO_POINTER (atom)))
483
 
        {
484
 
            x_client_send_error (client, BadAtom, InternAtom, 0);
485
 
            return;
486
 
        }
487
 
    }
488
 
    else
489
 
        g_hash_table_insert (client->priv->server->priv->atoms, GINT_TO_POINTER (atom), name);
490
 
 
491
 
    /* Reply */
492
 
 
493
 
    guint8 outBuffer[MAXIMUM_REQUEST_LENGTH];
494
 
    gsize n_written = 0;
495
 
 
496
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, Reply, &n_written);
497
 
    write_padding (outBuffer, MAXIMUM_REQUEST_LENGTH, 1, &n_written);
498
 
    write_card16 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, client->priv->sequence_number, &n_written);
499
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written); /* length */
500
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, atom, &n_written);
501
 
    write_padding (outBuffer, MAXIMUM_REQUEST_LENGTH, 20, &n_written);
502
 
 
503
 
    send (g_io_channel_unix_get_fd (client->priv->channel), outBuffer, n_written, 0);
504
 
}
505
 
 
506
 
static void
507
 
process_get_property (XClient *client, const guint8 *buffer, gssize buffer_length)
508
 
{
509
 
    /* Decode */
510
 
 
511
 
    gsize offset = 0;
512
 
    guint8 delete;
513
 
    guint32 property;
514
 
    guint32 type;
515
 
 
516
 
    read_padding (1, &offset); /* reqType */
517
 
    delete = read_card8 (buffer, buffer_length, &offset);
518
 
    read_padding (2, &offset); /* length */
519
 
    read_padding (4, &offset); /* window */
520
 
    property = read_card32 (buffer, buffer_length, client->priv->byte_order, &offset);
521
 
    type = read_card32 (buffer, buffer_length, client->priv->byte_order, &offset);
522
 
    read_padding (4, &offset); /* longOffset */
523
 
    read_padding (4, &offset); /* longLength */
524
 
 
525
 
    /* Process */
526
 
 
527
 
    gchar *name = g_hash_table_lookup (client->priv->server->priv->atoms, GINT_TO_POINTER (property));
528
 
    GString *reply = NULL;
529
 
    guint8 format = 8;
530
 
 
531
 
    if (g_strcmp0 (name, "_XKB_RULES_NAMES") == 0)
532
 
    {
533
 
        GKeyFile *config;
534
 
 
535
 
        config = g_key_file_new ();
536
 
        g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL);
537
 
 
538
 
        reply = g_string_new ("");
539
 
 
540
 
        g_string_append (reply, "evdev"); /* rules file */
541
 
        g_string_append_c (reply, 0); /* embedded null byte */
542
 
 
543
 
        g_string_append (reply, "pc105"); /* model name */
544
 
        g_string_append_c (reply, 0); /* embedded null byte */
545
 
 
546
 
        if (g_key_file_has_key (config, "test-xserver-config", "keyboard-layout", NULL))
547
 
            g_string_append (reply, g_key_file_get_string (config, "test-xserver-config", "keyboard-layout", NULL));
548
 
        else
549
 
            g_string_append (reply, "us");
550
 
        g_string_append_c (reply, 0); /* embedded null byte */
551
 
 
552
 
        if (g_key_file_has_key (config, "test-xserver-config", "keyboard-variant", NULL))
553
 
            g_string_append (reply, g_key_file_get_string (config, "test-xserver-config", "keyboard-variant", NULL));
554
 
        g_string_append_c (reply, 0); /* embedded null byte */
555
 
 
556
 
        /* no xkb options */
557
 
        g_string_append_c (reply, 0); /* embedded null byte */
558
 
 
559
 
        g_key_file_free (config);
560
 
    }
561
 
 
562
 
    if (name && delete)
563
 
        g_hash_table_remove (client->priv->server->priv->atoms, GINT_TO_POINTER (property));
564
 
 
565
 
    /* Reply */
566
 
 
567
 
    if (!reply)
568
 
    {
569
 
        x_client_send_error (client, BadImplementation, GetProperty, 0);
570
 
        return;
571
 
    }
572
 
 
573
 
    guint8 outBuffer[MAXIMUM_REQUEST_LENGTH];
574
 
    gsize n_written = 0, length_offset, packet_start;
575
 
 
576
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, Reply, &n_written);
577
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, format, &n_written);
578
 
    write_card16 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, client->priv->sequence_number, &n_written);
579
 
    length_offset = n_written;
580
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written); /* length */
581
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, type, &n_written);
582
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written); /* bytesAfter */
583
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, reply->len, &n_written);
584
 
    write_padding (outBuffer, MAXIMUM_REQUEST_LENGTH, 12, &n_written);
585
 
    packet_start = n_written;
586
 
 
587
 
    write_string8 (outBuffer, MAXIMUM_REQUEST_LENGTH, (guint8 *) reply->str, reply->len, &n_written);
588
 
    write_padding (outBuffer, MAXIMUM_REQUEST_LENGTH, pad (reply->len), &n_written);
589
 
 
590
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, (n_written - packet_start) / 4, &length_offset);
591
 
 
592
 
    send (g_io_channel_unix_get_fd (client->priv->channel), outBuffer, n_written, 0);
593
 
 
594
 
    /* Cleanup */
595
 
 
596
 
    g_string_free (reply, TRUE);
597
 
}
598
 
 
599
 
static void
600
 
process_query_extension (XClient *client, const guint8 *buffer, gssize buffer_length)
601
 
{
602
 
    /* Decode */
603
 
 
604
 
    gsize offset = 0;
605
 
    guint8 n;
606
 
    gchar *name;
607
 
 
608
 
    read_padding (1, &offset); /* reqType */
609
 
    read_padding (1, &offset); /* pad */
610
 
    read_padding (2, &offset); /* length */
611
 
    n = read_card16 (buffer, buffer_length, client->priv->byte_order, &offset);
612
 
    read_padding (2, &offset); /* pad */
613
 
    name = read_padded_string (buffer, buffer_length, n, &offset);
614
 
 
615
 
    /* Process */
616
 
 
617
 
    guint8 present = 0;
618
 
    if (g_strcmp0 (name, "XKEYBOARD") == 0)
619
 
        present = 1;
620
 
 
621
 
    /* Reply */
622
 
 
623
 
    guint8 outBuffer[MAXIMUM_REQUEST_LENGTH];
624
 
    gsize n_written = 0;
625
 
 
626
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, Reply, &n_written);
627
 
    write_padding (outBuffer, MAXIMUM_REQUEST_LENGTH, 1, &n_written);
628
 
    write_card16 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, client->priv->sequence_number, &n_written);
629
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written); /* length */
630
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, present, &n_written);
631
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, kbUseExtension, &n_written); /* major_opcode */
632
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, 0, &n_written); /* first_event */
633
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, 0, &n_written); /* first_error */
634
 
    write_padding (outBuffer, MAXIMUM_REQUEST_LENGTH, 20, &n_written);
635
 
 
636
 
    send (g_io_channel_unix_get_fd (client->priv->channel), outBuffer, n_written, 0);
637
 
 
638
 
    /* Cleanup */
639
 
 
640
 
    g_free (name);
641
 
}
642
 
 
643
 
static void
644
 
process_kb_use_extension (XClient *client, const guint8 *buffer, gssize buffer_length)
645
 
{
646
 
    /* Nothing to decode, we don't care about parameters */
647
 
 
648
 
    /* Reply */
649
 
 
650
 
    guint8 outBuffer[MAXIMUM_REQUEST_LENGTH];
651
 
    gsize n_written = 0;
652
 
 
653
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, Reply, &n_written);
654
 
    write_card8 (outBuffer, MAXIMUM_REQUEST_LENGTH, 1, &n_written); /* supported */
655
 
    write_card16 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, client->priv->sequence_number, &n_written);
656
 
    write_card32 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written); /* length */
657
 
    write_card16 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 1, &n_written); /* serverMajor */
658
 
    write_card16 (outBuffer, MAXIMUM_REQUEST_LENGTH, client->priv->byte_order, 0, &n_written); /* serverMinor */
659
 
    write_padding (outBuffer, MAXIMUM_REQUEST_LENGTH, 20, &n_written);
660
 
 
661
 
    send (g_io_channel_unix_get_fd (client->priv->channel), outBuffer, n_written, 0);
662
 
}
663
 
 
664
 
static void
665
 
decode_request (XClient *client, const guint8 *buffer, gssize buffer_length)
666
 
{
667
 
    int opcode;
668
 
    gsize offset = 0;
669
 
 
670
 
    while (offset < buffer_length)
671
 
    {
672
 
        gsize start_offset;
673
 
        guint16 length;
674
 
 
675
 
        start_offset = offset;
676
 
        opcode = read_card8 (buffer, buffer_length, &offset);
677
 
        read_card8 (buffer, buffer_length, &offset);
678
 
        length = read_card16 (buffer, buffer_length, client->priv->byte_order, &offset) * 4;
679
 
 
680
 
        g_debug ("Got opcode=%d length=%d", opcode, length);
681
 
        offset = start_offset + length;
682
 
 
683
 
        switch (opcode)
684
 
        {
685
 
        case InternAtom:
686
 
            process_intern_atom (client, buffer + start_offset, length);
687
 
            break;
688
 
        case GetProperty:
689
 
            process_get_property (client, buffer + start_offset, length);
690
 
            break;
691
 
        case QueryExtension:
692
 
            process_query_extension (client, buffer + start_offset, length);
693
 
            break;
694
 
        case kbUseExtension:
695
 
            process_kb_use_extension (client, buffer + start_offset, length);
696
 
            break;
697
 
        default:
698
 
            /* Send an error because we don't understand the opcode yet */
699
 
            x_client_send_error (client, BadImplementation, opcode, 0);
700
 
            break;
701
 
        }
702
 
 
703
 
        client->priv->sequence_number++;
704
 
    }
705
 
}
706
 
 
707
 
static gboolean
708
 
socket_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
709
 
{
710
 
    XClient *client = data;
711
 
    guint8 buffer[MAXIMUM_REQUEST_LENGTH];
712
 
    gssize n_read;
713
 
 
714
 
    n_read = recv (g_io_channel_unix_get_fd (channel), buffer, MAXIMUM_REQUEST_LENGTH, 0);
715
 
    if (n_read < 0)
716
 
        g_warning ("Error reading from socket: %s", strerror (errno));
717
 
    else if (n_read == 0)
718
 
    {
719
 
        g_signal_emit (client, x_client_signals[X_CLIENT_DISCONNECTED], 0);
720
 
        return FALSE;
721
 
    }
722
 
    else
723
 
    {
724
 
        if (client->priv->connected)
725
 
            decode_request (client, buffer, n_read);
726
 
        else
727
 
            decode_connection_request (client, buffer, n_read);
728
 
    }
729
 
 
730
 
    return TRUE;
731
 
}
732
 
 
733
106
static void
734
107
x_client_disconnected_cb (XClient *client, XServer *server)
735
108
{
746
119
    XClient *client;
747
120
    GError *error = NULL;
748
121
 
749
 
    if (channel == server->priv->unix_channel)
750
 
        data_socket = g_socket_accept (server->priv->unix_socket, NULL, &error);
751
 
    else
752
 
        data_socket = g_socket_accept (server->priv->tcp_socket, NULL, &error);
 
122
    data_socket = g_socket_accept (server->priv->socket, NULL, &error);
753
123
    if (error)
754
124
        g_warning ("Error accepting connection: %s", strerror (errno));
755
125
    g_clear_error (&error);
762
132
    client->priv->socket = data_socket;
763
133
    client->priv->channel = g_io_channel_unix_new (g_socket_get_fd (data_socket));
764
134
    g_hash_table_insert (server->priv->clients, client->priv->channel, client);
765
 
    g_io_add_watch (client->priv->channel, G_IO_IN, socket_data_cb, client);
766
135
 
767
136
    g_signal_emit (server, x_server_signals[X_SERVER_CLIENT_CONNECTED], 0, client);
768
137
 
772
141
gboolean
773
142
x_server_start (XServer *server)
774
143
{
775
 
    if (server->priv->listen_unix)
776
 
    {
777
 
        GError *error = NULL;
778
 
      
779
 
        server->priv->socket_path = g_strdup_printf ("/tmp/.X11-unix/X%d", server->priv->display_number);
780
 
 
781
 
        server->priv->unix_socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
782
 
        if (!server->priv->unix_socket ||
783
 
            !g_socket_bind (server->priv->unix_socket, g_unix_socket_address_new (server->priv->socket_path), TRUE, &error) ||
784
 
            !g_socket_listen (server->priv->unix_socket, &error))
785
 
        {
786
 
            g_warning ("Error creating Unix X socket: %s", error->message);
787
 
            return FALSE;
788
 
        }
789
 
        server->priv->unix_channel = g_io_channel_unix_new (g_socket_get_fd (server->priv->unix_socket));
790
 
        g_io_add_watch (server->priv->unix_channel, G_IO_IN, socket_connect_cb, server);
791
 
    }
792
 
 
793
 
    if (server->priv->listen_tcp)
794
 
    {
795
 
        GError *error = NULL;
796
 
 
797
 
        server->priv->tcp_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &error);
798
 
        if (!server->priv->tcp_socket ||
799
 
            !g_socket_bind (server->priv->tcp_socket, g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), server->priv->tcp_port), TRUE, &error) ||
800
 
            !g_socket_listen (server->priv->tcp_socket, &error))
801
 
        {
802
 
            g_warning ("Error creating TCP/IP X socket: %s", error->message);
803
 
            return FALSE;
804
 
        }
805
 
        server->priv->tcp_channel = g_io_channel_unix_new (g_socket_get_fd (server->priv->tcp_socket));
806
 
        g_io_add_watch (server->priv->tcp_channel, G_IO_IN, socket_connect_cb, server);
807
 
    }
 
144
    gchar *name;
 
145
    GError *error = NULL;
 
146
 
 
147
    name = g_strdup_printf (".x:%d", server->priv->display_number);
 
148
    server->priv->socket_path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), name, NULL);
 
149
    g_free (name);
 
150
 
 
151
    server->priv->socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
 
152
    if (!server->priv->socket ||
 
153
        !g_socket_bind (server->priv->socket, g_unix_socket_address_new (server->priv->socket_path), TRUE, &error) ||
 
154
        !g_socket_listen (server->priv->socket, &error))
 
155
    {
 
156
        g_warning ("Error creating Unix X socket: %s", error->message);
 
157
        return FALSE;
 
158
    }
 
159
    server->priv->channel = g_io_channel_unix_new (g_socket_get_fd (server->priv->socket));
 
160
    g_io_add_watch (server->priv->channel, G_IO_IN, socket_connect_cb, server);
808
161
 
809
162
    return TRUE;
810
163
}
819
172
x_server_init (XServer *server)
820
173
{
821
174
    server->priv = G_TYPE_INSTANCE_GET_PRIVATE (server, x_server_get_type (), XServerPrivate);
822
 
    server->priv->vendor = g_strdup ("");
823
 
    server->priv->min_keycode = 8;
824
 
    server->priv->min_keycode = 255;
825
 
    server->priv->screens = NULL;
826
 
    server->priv->listen_unix = TRUE;
827
 
    server->priv->listen_tcp = TRUE;
828
175
    server->priv->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) g_io_channel_unref, g_object_unref);
829
 
    server->priv->atoms = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
830
 
    server->priv->next_atom_index = 1;
831
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("PRIMARY"));
832
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("SECONDARY"));
833
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("ARC"));
834
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("ATOM"));
835
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("BITMAP"));
836
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CARDINAL"));
837
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("COLORMAP"));
838
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CURSOR"));
839
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER0"));
840
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER1"));
841
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER2"));
842
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER3"));
843
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER4"));
844
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER5"));
845
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER6"));
846
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CUT_BUFFER7"));
847
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("DRAWABLE"));
848
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("FONT"));
849
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("INTEGER"));
850
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("PIXMAP"));
851
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("POINT"));
852
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RECTANGLE"));
853
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RESOURCE_MANAGER"));
854
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RGB_COLOR_MAP"));
855
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RGB_BEST_MAP"));
856
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RGB_BLUE_MAP"));
857
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RGB_DEFAULT_MAP"));
858
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RGB_GRAY_MAP"));
859
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RGB_GREEN_MAP"));
860
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RGB_RED_MAP"));
861
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("STRING"));
862
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("VISUALID"));
863
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WINDOW"));
864
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_COMMAND"));
865
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_HINTS"));
866
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_CLIENT_MACHINE"));
867
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_ICON_NAME"));
868
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_ICON_SIZE"));
869
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_NAME"));
870
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_NORMAL_HINTS"));
871
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_SIZE_HINTS"));
872
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_ZOOM_HINTS"));
873
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("MIN_SPACE"));
874
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("NORM_SPACE"));
875
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("MAX_SPACE"));
876
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("END_SPACE"));
877
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("SUPERSCRIPT_X"));
878
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("SUPERSCRIPT_Y"));
879
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("SUBSCRIPT_X"));
880
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("SUBSCRIPT_Y"));
881
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("UNDERLINE_POSITION"));
882
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("UNDERLINE_THICKNESS"));
883
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("STRIKEOUT_ASCENT"));
884
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("STRIKEOUT_DESCENT"));
885
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("ITALIC_ANGLE"));
886
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("X_HEIGHT"));
887
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("QUAD_WIDTH"));
888
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WEIGHT"));
889
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("POINT_SIZE"));
890
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("RESOLUTION"));
891
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("COPYRIGHT"));
892
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("NOTICE"));
893
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("FONT_NAME"));
894
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("FAMILY_NAME"));
895
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("FULL_NAME"));
896
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("CAP_HEIGHT"));
897
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_CLASS"));
898
 
    g_hash_table_insert (server->priv->atoms, GINT_TO_POINTER (server->priv->next_atom_index++), g_strdup ("WM_TRANSIENT_FOR"));
899
176
}
900
177
 
901
178
static void
902
179
x_server_finalize (GObject *object)
903
180
{
904
181
    XServer *server = (XServer *) object;
905
 
    g_free (server->priv->vendor);
906
182
    if (server->priv->socket_path)
907
183
        unlink (server->priv->socket_path);
908
 
    g_hash_table_unref (server->priv->atoms);
909
184
    G_OBJECT_CLASS (x_server_parent_class)->finalize (object);
910
185
}
911
186
 
932
207
                      g_cclosure_marshal_VOID__OBJECT,
933
208
                      G_TYPE_NONE, 1, x_client_get_type ());
934
209
}
935
 
 
936
 
static void
937
 
x_screen_init (XScreen *screen)
938
 
{
939
 
    screen->priv = G_TYPE_INSTANCE_GET_PRIVATE (screen, x_screen_get_type (), XScreenPrivate);
940
 
}
941
 
 
942
 
static void
943
 
x_screen_class_init (XScreenClass *klass)
944
 
{
945
 
    g_type_class_add_private (klass, sizeof (XScreenPrivate));
946
 
}
947
 
 
948
 
static void
949
 
x_visual_init (XVisual *visual)
950
 
{
951
 
    visual->priv = G_TYPE_INSTANCE_GET_PRIVATE (visual, x_visual_get_type (), XVisualPrivate);
952
 
}
953
 
 
954
 
static void
955
 
x_visual_class_init (XVisualClass *klass)
956
 
{
957
 
    g_type_class_add_private (klass, sizeof (XVisualPrivate));
958
 
}