2 * Copyright (C) 2010-2011 Robert Ancell.
3 * Author: Robert Ancell <robert.ancell@canonical.com>
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
14 #include "vnc-server.h"
20 static guint signals[LAST_SIGNAL] = { 0 };
22 struct VNCServerPrivate
24 /* Port to listen on */
27 /* Listening sockets */
28 GSocket *socket, *socket6;
31 G_DEFINE_TYPE (VNCServer, vnc_server, G_TYPE_OBJECT);
36 return g_object_new (VNC_SERVER_TYPE, NULL);
40 vnc_server_set_port (VNCServer *server, guint port)
42 g_return_if_fail (server != NULL);
43 server->priv->port = port;
47 vnc_server_get_port (VNCServer *server)
49 g_return_val_if_fail (server != NULL, 0);
50 return server->priv->port;
54 read_cb (GSocket *socket, GIOCondition condition, VNCServer *server)
57 GSocket *client_socket;
59 client_socket = g_socket_accept (socket, NULL, &error);
61 g_warning ("Failed to get connection from from VNC socket: %s", error->message);
62 g_clear_error (&error);
66 GInetSocketAddress *address;
69 address = G_INET_SOCKET_ADDRESS (g_socket_get_remote_address (client_socket, NULL));
70 hostname = g_inet_address_to_string (g_inet_socket_address_get_address (address));
71 g_debug ("Got VNC connection from %s:%d", hostname, g_inet_socket_address_get_port (address));
74 g_signal_emit (server, signals[NEW_CONNECTION], 0, client_socket);
81 open_tcp_socket (GSocketFamily family, guint port, GError **error)
84 GSocketAddress *address;
86 socket = g_socket_new (family, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, error);
90 address = g_inet_socket_address_new (g_inet_address_new_any (family), port);
91 if (!g_socket_bind (socket, address, TRUE, error) ||
92 !g_socket_listen (socket, error))
94 g_object_unref (socket);
102 vnc_server_start (VNCServer *server)
105 GError *error = NULL;
107 g_return_val_if_fail (server != NULL, FALSE);
109 server->priv->socket = open_tcp_socket (G_SOCKET_FAMILY_IPV4, server->priv->port, &error);
111 g_warning ("Failed to create IPv4 VNC socket: %s", error->message);
112 g_clear_error (&error);
114 if (server->priv->socket)
116 source = g_socket_create_source (server->priv->socket, G_IO_IN, NULL);
117 g_source_set_callback (source, (GSourceFunc) read_cb, server, NULL);
118 g_source_attach (source, NULL);
121 server->priv->socket6 = open_tcp_socket (G_SOCKET_FAMILY_IPV6, server->priv->port, &error);
123 g_warning ("Failed to create IPv6 VNC socket: %s", error->message);
124 g_clear_error (&error);
126 if (server->priv->socket6)
128 source = g_socket_create_source (server->priv->socket6, G_IO_IN, NULL);
129 g_source_set_callback (source, (GSourceFunc) read_cb, server, NULL);
130 g_source_attach (source, NULL);
133 if (!server->priv->socket && !server->priv->socket6)
140 vnc_server_init (VNCServer *server)
142 server->priv = G_TYPE_INSTANCE_GET_PRIVATE (server, VNC_SERVER_TYPE, VNCServerPrivate);
143 server->priv->port = 5900;
147 vnc_server_finalize (GObject *object)
151 self = VNC_SERVER (object);
153 if (self->priv->socket)
154 g_object_unref (self->priv->socket);
155 if (self->priv->socket6)
156 g_object_unref (self->priv->socket6);
158 G_OBJECT_CLASS (vnc_server_parent_class)->finalize (object);
162 vnc_server_class_init (VNCServerClass *klass)
164 GObjectClass *object_class = G_OBJECT_CLASS (klass);
166 object_class->finalize = vnc_server_finalize;
168 g_type_class_add_private (klass, sizeof (VNCServerPrivate));
170 signals[NEW_CONNECTION] =
171 g_signal_new (VNC_SERVER_SIGNAL_NEW_CONNECTION,
172 G_TYPE_FROM_CLASS (klass),
174 G_STRUCT_OFFSET (VNCServerClass, new_connection),
177 G_TYPE_NONE, 1, G_TYPE_SOCKET);