diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2012-01-23 12:46:13 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2012-01-23 14:34:52 +0100 |
commit | a43aea896653d6c092b05dcb5a805548ec61ebb5 (patch) | |
tree | a945b3e85bc273068865b5d0cfe91df8d017d40e | |
parent | c5cf7fb3bc4b48ee10c8128d4f2670f870fedad8 (diff) |
controller: use a controller listener abstraction
Add a wrapper file for named pipe and socket listener, so we can release
tarball with code compatible with windows and unix.
-rw-r--r-- | gtk/controller/Makefile.am | 8 | ||||
-rw-r--r-- | gtk/controller/controller.vala | 25 | ||||
-rw-r--r-- | gtk/controller/custom.vapi | 24 | ||||
-rw-r--r-- | gtk/controller/spice-controller-listener.c | 149 | ||||
-rw-r--r-- | gtk/controller/spice-controller-listener.h | 50 |
5 files changed, 209 insertions, 47 deletions
diff --git a/gtk/controller/Makefile.am b/gtk/controller/Makefile.am index 2d5c5af..522e014 100644 --- a/gtk/controller/Makefile.am +++ b/gtk/controller/Makefile.am @@ -14,12 +14,6 @@ AM_VALAFLAGS = \ -C -g \ $(NULL) -if OS_WIN32 -AM_VALAFLAGS += --pkg gio-windows-2.0 -D WIN32 -else -AM_VALAFLAGS += --pkg gio-unix-2.0 -endif - lib_LTLIBRARIES = libspice-controller.la noinst_PROGRAMS = test-controller @@ -31,6 +25,8 @@ libspice_controller_la_VALASOURCES = \ $(NULL) libspice_controller_la_SOURCES = \ custom.h \ + spice-controller-listener.c \ + spice-controller-listener.h \ $(libspice_controller_la_VALASOURCES:.vala=.c) \ $(NULL) diff --git a/gtk/controller/controller.vala b/gtk/controller/controller.vala index e33278f..237e817 100644 --- a/gtk/controller/controller.vala +++ b/gtk/controller/controller.vala @@ -221,29 +221,8 @@ public class Controller: Object { public async void listen (string? addr = null) throws GLib.Error, SpiceCtrl.Error { - if (addr == null) -#if WIN32 - if (Environment.get_variable ("SPICE_XPI_NAMEDPIPE") != null) - addr = (string*)"%s".printf (Environment.get_variable ("SPICE_XPI_NAMEDPIPE")); // FIXME vala... - else - addr = (string*)"\\\\.\\pipe\\SpiceController-%lu".printf (GetCurrentProcessId ()); -#else - if (Environment.get_variable ("SPICE_XPI_SOCKET") != null) - addr = (string*)"%s".printf (Environment.get_variable ("SPICE_XPI_SOCKET")); // FIXME vala... -#endif - if (addr == null) - throw new SpiceCtrl.Error.VALUE ("Missing socket or namedpipe address"); - FileUtils.unlink (addr); - -#if WIN32 - var listener = new NamedPipeListener (); - var np = new NamedPipe (addr); - listener.add_named_pipe (np); -#else - var listener = new SocketListener (); - listener.add_address (new UnixSocketAddress (addr), - SocketType.STREAM, SocketProtocol.DEFAULT, null, null); -#endif + var listener = ControllerListener.new_listener (addr); + for (;;) { var c = yield listener.accept_async (); nclients += 1; diff --git a/gtk/controller/custom.vapi b/gtk/controller/custom.vapi index b3eeb4e..7a94b82 100644 --- a/gtk/controller/custom.vapi +++ b/gtk/controller/custom.vapi @@ -7,25 +7,13 @@ namespace Custom { } namespace Spice { - [CCode (cheader_filename = "namedpipe.h")] - public class NamedPipe: Object { - public NamedPipe (string name) throws GLib.Error; - } - [CCode (cheader_filename = "namedpipeconnection.h")] - public class NamedPipeConnection: GLib.IOStream { - } + [CCode (cname = "GObject", ref_function = "g_object_ref", unref_function = "g_object_unref", free_function = "")] + class ControllerListener { + [CCode (cname = "spice_controller_listener_new", cheader_filename = "spice-controller-listener.h")] + public static ControllerListener new_listener (string addr) throws GLib.Error; - [CCode (cheader_filename = "namedpipelistener.h")] - public class NamedPipeListener: Object { - [CCode (has_construct_function = false)] - public NamedPipeListener (); - public async unowned Spice.NamedPipeConnection accept_async (GLib.Cancellable? cancellable = null, out GLib.Object? source_object = null) throws GLib.Error; - public void add_named_pipe (NamedPipe namedpipe); + [CCode (cname = "spice_controller_listener_accept_async", cheader_filename = "spice-controller-listener.h")] + public async unowned GLib.IOStream accept_async (GLib.Cancellable? cancellable = null, out GLib.Object? source_object = null) throws GLib.Error; } } - -namespace Win32 { - [CCode (cheader_filename = "windows.h", cname = "GetCurrentProcessId")] - public uint32 GetCurrentProcessId (); -} 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 +} diff --git a/gtk/controller/spice-controller-listener.h b/gtk/controller/spice-controller-listener.h new file mode 100644 index 0000000..fc6ba3d --- /dev/null +++ b/gtk/controller/spice-controller-listener.h @@ -0,0 +1,50 @@ +/* -*- 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/>. +*/ +#ifndef __SPICE_CONTROLLER_LISTENER_H__ +#define __SPICE_CONTROLLER_LISTENER_H__ + +#include <gio/gio.h> + +G_BEGIN_DECLS + +#define SPICE_CONTROLLER_LISTENER_ERROR spice_controller_listener_error_quark () +GQuark spice_controller_listener_error_quark (void); + +typedef enum +{ + SPICE_CONTROLLER_LISTENER_ERROR_VALUE /* incorrect value */ +} SpiceControllerListenerError; + + +GObject* spice_controller_listener_new (const gchar *address, GError **error); + +void spice_controller_listener_accept_async (GObject *listener, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GIOStream* spice_controller_listener_accept_finish (GObject *listener, + GAsyncResult *result, + GObject **source_object, + GError **error); +G_END_DECLS + +#endif /* __SPICE_CONTROLLER_LISTENER_H__ */ + + + |