2
* Copyright (C) 2011 Canonical Ltd.
4
* This library is free software; you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3 as published by
6
* the Free Software Foundation. See http://www.gnu.org/copyleft/lgpl.html the
7
* full text of the license.
14
#include <sys/types.h>
15
#include <sys/socket.h>
17
#include <gio/gunixsocketaddress.h>
19
#include "xig/xig-client.h"
20
#include "xig-common.h"
22
G_DEFINE_TYPE (XigClient, xig_client, G_TYPE_OBJECT);
24
struct XigClientPrivate
26
/* Socket to server */
30
/* Byte order being used */
33
/* TRUE if client has connected */
36
/* Server properties */
37
guint16 protocol_major_version;
38
guint16 protocol_minor_version;
39
guint32 release_number;
40
guint32 motion_buffer_size;
41
guint32 maximum_request_length;
42
guint8 image_byte_order;
43
guint8 bitmap_format_bit_order;
44
guint8 bitmap_format_scanline_unit;
45
guint8 bitmap_format_scanline_pad;
50
/* Allocated resource IDs */
51
guint32 resource_id_base;
52
guint32 resource_id_mask;
54
gboolean log_messages;
62
static guint signals[LAST_SIGNAL] = { 0 };
65
xig_client_new_from_environment (void)
69
client = g_object_new (xig_client_get_type (), NULL);
75
xig_client_set_log_messages (XigClient *client, gboolean log_messages)
77
client->priv->log_messages = log_messages;
81
xig_client_get_server_address (XigClient *client)
83
GSocketAddress *socket_address;
86
socket_address = g_socket_get_remote_address (client->priv->socket, &error);
88
g_warning ("Error getting remote socket address");
89
g_clear_error (&error);
93
if (G_IS_INET_SOCKET_ADDRESS (socket_address))
94
return g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
100
xig_client_disconnect (XigClient *client)
102
g_io_channel_shutdown (client->priv->channel, TRUE, NULL);
106
decode_connection_response (XigClient *client, const guint8 *buffer, gssize buffer_length)
108
guint8 response_code, n_screens, n_formats;
110
guint16 vendor_length;
113
response_code = read_card8 (buffer, buffer_length, &offset);
114
if (response_code != Success)
117
read_padding (1, &offset);
118
client->priv->protocol_major_version = read_card16 (buffer, buffer_length, client->priv->byte_order, &offset);
119
client->priv->protocol_minor_version = read_card16 (buffer, buffer_length, client->priv->byte_order, &offset);
120
/*n =*/ read_card16 (buffer, buffer_length, client->priv->byte_order, &offset);
121
client->priv->release_number = read_card32 (buffer, buffer_length, client->priv->byte_order, &offset);
122
client->priv->resource_id_base = read_card32 (buffer, buffer_length, client->priv->byte_order, &offset);
123
client->priv->resource_id_mask = read_card32 (buffer, buffer_length, client->priv->byte_order, &offset);
124
client->priv->motion_buffer_size = read_card32 (buffer, buffer_length, client->priv->byte_order, &offset);
125
vendor_length = read_card16 (buffer, buffer_length, client->priv->byte_order, &offset);
126
client->priv->maximum_request_length = read_card16 (buffer, buffer_length, client->priv->byte_order, &offset);
127
n_screens = read_card8 (buffer, buffer_length, &offset);
128
n_formats = read_card8 (buffer, buffer_length, &offset);
129
client->priv->image_byte_order = read_card8 (buffer, buffer_length, &offset);
130
client->priv->bitmap_format_bit_order = read_card8 (buffer, buffer_length, &offset);
131
client->priv->bitmap_format_scanline_unit = read_card8 (buffer, buffer_length, &offset);
132
client->priv->bitmap_format_scanline_pad = read_card8 (buffer, buffer_length, &offset);
133
client->priv->min_keycode = read_card8 (buffer, buffer_length, &offset);
134
client->priv->max_keycode = read_card8 (buffer, buffer_length, &offset);
135
read_padding (4, &offset);
136
client->priv->vendor = read_padded_string (buffer, buffer_length, vendor_length, &offset);
138
for (i = 0; i < n_formats; i++)
140
read_card8 (buffer, buffer_length, &offset);
141
read_card8 (buffer, buffer_length, &offset);
142
read_card8 (buffer, buffer_length, &offset);
143
read_padding (5, &offset);
146
for (i = 0; i < n_screens; i++)
153
decode_response (XigClient *client, const guint8 *buffer, gssize buffer_length)
158
while (offset < buffer_length)
160
opcode = read_card8 (buffer, buffer_length, &offset);
165
//send_error (client, Implementation, opcode, 0, client->priv->sequence_number, 0);
172
socket_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
174
XigClient *client = data;
175
guint8 buffer[MAXIMUM_REQUEST_LENGTH];
178
n_read = recv (g_io_channel_unix_get_fd (channel), buffer, MAXIMUM_REQUEST_LENGTH, 0);
180
g_warning ("Error reading from socket: %s", strerror (errno));
181
else if (n_read == 0)
183
g_signal_emit (client, signals[DISCONNECTED], 0);
188
if (client->priv->connected)
189
decode_response (client, buffer, n_read);
191
decode_connection_response (client, buffer, n_read);
198
xig_client_connect_sync (XigClient *client, GError **error)
200
client->priv->socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, error);
201
if (client->priv->socket == NULL)
204
client->priv->channel = g_io_channel_unix_new (g_socket_get_fd (client->priv->socket));
205
g_io_add_watch (client->priv->channel, G_IO_IN, socket_data_cb, client);
211
xig_client_init (XigClient *client)
213
client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client, xig_client_get_type (), XigClientPrivate);
217
xig_client_finalize (GObject *object)
219
XigClient *client = XIG_CLIENT (object);
221
g_free (client->priv->vendor);
225
xig_client_class_init (XigClientClass *klass)
227
GObjectClass *object_class = G_OBJECT_CLASS (klass);
229
object_class->finalize = xig_client_finalize;
231
g_type_class_add_private (klass, sizeof (XigClientPrivate));
233
signals[DISCONNECTED] =
234
g_signal_new ("disconnected",
235
G_TYPE_FROM_CLASS (klass),
237
G_STRUCT_OFFSET (XigClientClass, disconnected),
239
g_cclosure_marshal_VOID__VOID,