diff options
Diffstat (limited to 'gtk/controller/spice-controller-listener.c')
-rw-r--r-- | gtk/controller/spice-controller-listener.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/gtk/controller/spice-controller-listener.c b/gtk/controller/spice-controller-listener.c new file mode 100644 index 0000000..076f74e --- /dev/null +++ b/gtk/controller/spice-controller-listener.c @@ -0,0 +1,149 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2012 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <glib.h> +#include <glib/gstdio.h> + +#include "spice-controller-listener.h" + +#ifdef G_OS_WIN32 +#include <windows.h> +#include "namedpipe.h" +#include "namedpipelistener.h" +#endif + +#ifdef G_OS_UNIX +#include <gio/gunixsocketaddress.h> +#endif + +/** + * SpiceControllerListenerError: + * @SPICE_CONTROLLER_LISTENER_ERROR_VALUE: invalid value. + * + * Possible errors of controller listener related functions. + **/ + +/** + * SPICE_CONTROLLER_LISTENER_ERROR: + * + * The error domain of the controller listener subsystem. + **/ +GQuark +spice_controller_listener_error_quark (void) +{ + return g_quark_from_static_string ("spice-controller-listener-error"); +} + +GObject* +spice_controller_listener_new (const gchar *address, GError **error) +{ + GObject *listener = NULL; + gchar *addr = NULL; + + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + addr = g_strdup (address); + +#ifdef G_OS_WIN32 + if (addr == NULL) + addr = g_strdup (g_getenv ("SPICE_XPI_NAMEDPIPE")); + if (addr == NULL) + addr = g_strdup_printf ("\\\\.\\pipe\\SpiceController-%lu", GetCurrentProcessId ()); +#else + if (addr == NULL) + addr = g_strdup (g_getenv ("SPICE_XPI_SOCKET")); +#endif + if (addr == NULL) { + g_set_error (error, + SPICE_CONTROLLER_LISTENER_ERROR, + SPICE_CONTROLLER_LISTENER_ERROR_VALUE, +#ifdef G_OS_WIN32 + "Missing namedpipe address" +#else + "Missing socket address" +#endif + ); + goto end; + } + + g_unlink (addr); + +#ifdef G_OS_WIN32 + { + SpiceNamedPipe *np; + + listener = G_OBJECT (spice_named_pipe_listener_new ()); + + np = spice_named_pipe_new (addr, error); + if (!np) { + g_object_unref (listener); + listener = NULL; + goto end; + } + + spice_named_pipe_listener_add_named_pipe (SPICE_NAMED_PIPE_LISTENER (listener), np); + } +#else + { + listener = G_OBJECT (g_socket_listener_new ()); + + if (!g_socket_listener_add_address (G_SOCKET_LISTENER (listener), + G_SOCKET_ADDRESS (g_unix_socket_address_new (addr)), + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + NULL, + NULL, + error)) + g_warning ("failed to add address"); + } +#endif + +end: + g_free (addr); + return listener; +} + +void +spice_controller_listener_accept_async (GObject *listener, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(G_IS_OBJECT(listener)); + +#ifdef G_OS_WIN32 + spice_named_pipe_listener_accept_async (SPICE_NAMED_PIPE_LISTENER (listener), cancellable, callback, user_data); +#else + g_socket_listener_accept_async (G_SOCKET_LISTENER (listener), cancellable, callback, user_data); +#endif +} + +GIOStream* +spice_controller_listener_accept_finish (GObject *listener, + GAsyncResult *result, + GObject **source_object, + GError **error) +{ + g_return_val_if_fail(G_IS_OBJECT(listener), NULL); + +#ifdef G_OS_WIN32 + spice_named_pipe_listener_accept_finish (SPICE_NAMED_PIPE_LISTENER (listener), result, source_object, error); +#else + g_socket_listener_accept_finish (G_SOCKET_LISTENER (listener), result, source_object, error); +#endif +} |