It contains all the generic code, then platform-specific controller implementations will inherit from it and overload the non-generic parts abstract methods. --- SpiceXPI/src/plugin/Makefile.am | 2 + SpiceXPI/src/plugin/controller-unix.cpp | 209 +++----------------------- SpiceXPI/src/plugin/controller-unix.h | 96 ++++++++++++ SpiceXPI/src/plugin/controller.cpp | 252 ++++++++++++++++++++++++++++++++ SpiceXPI/src/plugin/controller.h | 27 ++-- SpiceXPI/src/plugin/plugin.cpp | 22 +-- SpiceXPI/src/plugin/plugin.h | 2 +- 7 files changed, 398 insertions(+), 212 deletions(-) create mode 100644 SpiceXPI/src/plugin/controller-unix.h create mode 100644 SpiceXPI/src/plugin/controller.cpp diff --git a/SpiceXPI/src/plugin/Makefile.am b/SpiceXPI/src/plugin/Makefile.am index 2f12e70..2db218e 100644 --- a/SpiceXPI/src/plugin/Makefile.am +++ b/SpiceXPI/src/plugin/Makefile.am @@ -26,8 +26,10 @@ libnsISpicec_la_SOURCES = \ $(top_srcdir)/common/rederrorcodes.h \ glib-compat.c \ glib-compat.h \ + controller.cpp \ controller.h \ controller-unix.cpp \ + controller-unix.h \ npapi/npapi.h \ npapi/npfunctions.h \ npapi/npruntime.h \ diff --git a/SpiceXPI/src/plugin/controller-unix.cpp b/SpiceXPI/src/plugin/controller-unix.cpp index ddbd8c0..b3bd832 100644 --- a/SpiceXPI/src/plugin/controller-unix.cpp +++ b/SpiceXPI/src/plugin/controller-unix.cpp @@ -41,6 +41,7 @@ * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ +#include "config.h" #include <cstdio> #include <cstdlib> @@ -58,11 +59,11 @@ extern "C" { } #include "rederrorcodes.h" -#include "controller.h" +#include "controller-unix.h" #include "plugin.h" -SpiceController::SpiceController(nsPluginInstance *aPlugin): - m_plugin(aPlugin), +SpiceControllerUnix::SpiceControllerUnix(nsPluginInstance *aPlugin): + SpiceController(aPlugin), m_client_socket(-1) { // create temporary directory in /tmp @@ -70,7 +71,7 @@ SpiceController::SpiceController(nsPluginInstance *aPlugin): m_tmp_dir = mkdtemp(tmp_dir); } -SpiceController::~SpiceController() +SpiceControllerUnix::~SpiceControllerUnix() { g_debug(G_STRFUNC); Disconnect(); @@ -79,17 +80,7 @@ SpiceController::~SpiceController() rmdir(m_tmp_dir.c_str()); } -void SpiceController::SetFilename(const std::string &name) -{ - m_name = name; -} - -void SpiceController::SetProxy(const std::string &proxy) -{ - m_proxy = proxy; -} - -int SpiceController::Connect() +int SpiceControllerUnix::Connect() { // check, if we have a filename for socket to create if (m_name.empty()) @@ -123,23 +114,11 @@ int SpiceController::Connect() return rc; } -int SpiceController::Connect(const int nRetries) +bool SpiceControllerUnix::CheckPipe() { - int rc = -1; - int sleep_time = 0; - - // try to connect for specified count - for (int i = 0; rc != 0 && i < nRetries; ++i) - { - rc = Connect(); - g_usleep(sleep_time * G_USEC_PER_SEC); - ++sleep_time; - } - - return rc; } -void SpiceController::GetClientPaths(GStrv *client_argv, GStrv *fallback_argv) +void SpiceControllerUnixGetClientPaths(GStrv *client_argv, GStrv *fallback_argv) { if (client_argv != NULL) { *client_argv = g_new0(char *, 2); @@ -153,7 +132,7 @@ void SpiceController::GetClientPaths(GStrv *client_argv, GStrv *fallback_argv) } } -void SpiceController::SetupControllerPipe(GStrv &env) +void SpiceControllerUnix::SetupControllerPipe(GStrv &env) { std::string socket_file(this->m_tmp_dir); socket_file += "/spice-xpi"; @@ -163,18 +142,13 @@ void SpiceController::SetupControllerPipe(GStrv &env) env = g_environ_setenv(env, "SPICE_XPI_SOCKET", socket_file.c_str(), TRUE); } -void SpiceController::Disconnect() +void SpiceControllerUnix::StopClient() { - // close the socket - close(m_client_socket); - m_client_socket = -1; - - // delete the temporary file, which is used for the socket - unlink(m_name.c_str()); - m_name.clear(); + if (m_pid_controller > 0) + kill(-m_pid_controller, SIGTERM); } -uint32_t SpiceController::Write(const void *lpBuffer, uint32_t nBytesToWrite) +uint32_t SpiceControllerUnix::Write(const void *lpBuffer, uint32_t nBytesToWrite) { ssize_t len = send(m_client_socket, lpBuffer, nBytesToWrite, 0); @@ -187,156 +161,13 @@ uint32_t SpiceController::Write(const void *lpBuffer, uint32_t nBytesToWrite) return len; } -void SpiceController::ChildExited(GPid pid, gint status, gpointer user_data) +void SpiceControllerUnix::Disconnect() { - SpiceController *fake_this = (SpiceController *)user_data; - - g_message("Client with pid %p exited", pid); - - g_main_loop_quit(fake_this->m_child_watch_mainloop); - /* FIXME: we are not in the main thread!! */ - fake_this->m_plugin->OnSpiceClientExit(status); -} - -void SpiceController::WaitForPid(GPid pid) -{ - GMainContext *context; - GSource *source; - - context = g_main_context_new(); - - m_child_watch_mainloop = g_main_loop_new(context, FALSE); - source = g_child_watch_source_new(pid); - g_source_set_callback(source, (GSourceFunc)ChildExited, this, NULL); - g_source_attach(source, context); - - g_main_loop_run(m_child_watch_mainloop); - - g_main_loop_unref(m_child_watch_mainloop); - g_main_context_unref(context); - - g_spawn_close_pid(pid); - if (pid == m_pid_controller) - m_pid_controller = 0; -} - - -gpointer SpiceController::ClientThread(gpointer data) -{ - SpiceController *fake_this = (SpiceController *)data; - gchar **env = g_get_environ(); - GPid pid; - gboolean spawned = FALSE; - GError *error = NULL; - GStrv client_argv; - GStrv fallback_argv; - fake_this->GetClientPaths(&client_argv, &fallback_argv); - - { - char *argv_str = g_strjoinv(" ", client_argv); - g_warning("main client cmdline: %s", argv_str); - g_free(argv_str); - argv_str = g_strjoinv(" ", fallback_argv); - g_warning("fallback client cmdline: %s", argv_str); - g_free(argv_str); - } - - fake_this->SetupControllerPipe(env); - - if (!fake_this->m_proxy.empty()) - env = g_environ_setenv(env, "SPICE_PROXY", fake_this->m_proxy.c_str(), TRUE); - - if (client_argv != NULL) { - spawned = g_spawn_async(NULL, - client_argv, env, - G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, /* child_func, child_arg */ - &pid, &error); - if (error != NULL) { - g_warning("failed to start %s: %s", client_argv[0], error->message); - g_warn_if_fail(spawned == FALSE); - g_clear_error(&error); - } - } - if (!spawned && (fallback_argv != NULL)) { - // TODO: temporary fallback for backward compatibility - g_message("failed to run preferred client, running fallback client instead"); - spawned = g_spawn_async(NULL, fallback_argv, env, - G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, /* child_func, child_arg */ - &pid, &error); - if (error != NULL) { - g_warning("failed to start %s: %s", fallback_argv[0], error->message); - g_warn_if_fail(spawned == FALSE); - g_clear_error(&error); - } - } - g_strfreev(env); - g_strfreev(client_argv); - g_strfreev(fallback_argv); - - if (!spawned) { - g_critical("ERROR failed to run spicec fallback"); - return NULL; - } - -#ifdef XP_UNIX - fake_this->m_pid_controller = pid; -#endif - fake_this->WaitForPid(pid); - - return NULL; -} - -bool SpiceController::StartClient() -{ - GThread *thread; - - thread = g_thread_create(ClientThread, this, FALSE, NULL); - - return (thread != NULL); -} - -void SpiceController::StopClient() -{ - if (m_pid_controller > 0) - kill(-m_pid_controller, SIGTERM); -} - -int SpiceController::TranslateRC(int nRC) -{ - switch (nRC) - { - case SPICEC_ERROR_CODE_SUCCESS: - return 0; - - case SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED: - return RDP_ERROR_CODE_HOST_NOT_FOUND; - - case SPICEC_ERROR_CODE_CONNECT_FAILED: - return RDP_ERROR_CODE_WINSOCK_CONNECT_FAILED; - - case SPICEC_ERROR_CODE_ERROR: - case SPICEC_ERROR_CODE_SOCKET_FAILED: - return RDP_ERROR_CODE_INTERNAL_ERROR; - - case SPICEC_ERROR_CODE_RECV_FAILED: - return RDP_ERROR_RECV_WINSOCK_FAILED; - - case SPICEC_ERROR_CODE_SEND_FAILED: - return RDP_ERROR_SEND_WINSOCK_FAILED; - - case SPICEC_ERROR_CODE_NOT_ENOUGH_MEMORY: - return RDP_ERROR_CODE_OUT_OF_MEMORY; - - case SPICEC_ERROR_CODE_AGENT_TIMEOUT: - return RDP_ERROR_CODE_TIMEOUT; - - case SPICEC_ERROR_CODE_AGENT_ERROR: - return RDP_ERROR_CODE_INTERNAL_ERROR; + // close the socket + close(m_client_socket); + m_client_socket = -1; - default: - return RDP_ERROR_CODE_INTERNAL_ERROR; - } + // delete the temporary file, which is used for the socket + unlink(m_name.c_str()); + m_name.clear(); } - diff --git a/SpiceXPI/src/plugin/controller-unix.h b/SpiceXPI/src/plugin/controller-unix.h new file mode 100644 index 0000000..e72663b --- /dev/null +++ b/SpiceXPI/src/plugin/controller-unix.h @@ -0,0 +1,96 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Copyright 2009-2011, Red Hat Inc. + * Copyright 2013, Red Hat Inc. + * Based on mozilla.org's scriptable plugin example + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Uri Lublin + * Martin Stransky + * Peter Hatina + * Christophe Fergeau + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef SPICE_CONTROLLER_UNIX_H +#define SPICE_CONTROLLER_UNIX_H + +/* + Basic assumption: + ------------------ + Cross platform compatible. + Easy to transform into remote process communication + Secured + + chosen: + Unix - Unix Domain Sockets (easy to change into regular sockets for remote communication) + Windows - Named pipe (which allows remote access and is duplex + (rather than anonymous pipe which is local only and one way) +*/ + +#include <glib.h> +#include <glib-object.h> /* for GStrv */ +#include <gio/gio.h> +#include <string> +extern "C" { +# include <stdint.h> +# include <limits.h> +} + +#include <spice/controller_prot.h> +#include "controller.h" + +class nsPluginInstance; + +class SpiceControllerUnix: public SpiceController +{ +public: + SpiceControllerUnix(nsPluginInstance *aPlugin); + virtual ~SpiceControllerUnix(); + + virtual void StopClient(); + virtual uint32_t Write(const void *lpBuffer, uint32_t nBytesToWrite); + int Connect(int nRetries) { return SpiceController::Connect(nRetries); }; + +private: + virtual int Connect(); + virtual void Disconnect(); + virtual void SetupControllerPipe(GStrv &env); + virtual bool CheckPipe(); + virtual void GetClientPaths(GStrv *client_argv, GStrv *fallback_argv); + + int m_client_socket; + std::string m_tmp_dir; +}; + +#endif // SPICE_CONTROLLER_UNIX_H diff --git a/SpiceXPI/src/plugin/controller.cpp b/SpiceXPI/src/plugin/controller.cpp new file mode 100644 index 0000000..6011f5d --- /dev/null +++ b/SpiceXPI/src/plugin/controller.cpp @@ -0,0 +1,252 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * Copyright 2009-2011, Red Hat Inc. + * Copyright 2013, Red Hat Inc. + * Based on mozilla.org's scriptable plugin example + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Uri Lublin + * Martin Stransky + * Peter Hatina + * Christophe Fergeau + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "config.h" + +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <cerrno> +#include <glib.h> + +#include "rederrorcodes.h" +#include "controller.h" +#include "plugin.h" + +SpiceController::SpiceController(nsPluginInstance *aPlugin): + m_pid_controller(0), + m_pipe(NULL), + m_plugin(aPlugin), + m_child_watch_mainloop(NULL) +{ +} + +SpiceController::~SpiceController() +{ + g_debug(G_STRFUNC); + Disconnect(); +} + +void SpiceController::SetFilename(const std::string &name) +{ + m_name = name; +} + +void SpiceController::SetProxy(const std::string &proxy) +{ + m_proxy = proxy; +} + +#define FACILITY_SPICEX 50 +#define FACILITY_CREATE_RED_PROCESS 51 +#define FACILITY_STRING_OPERATION 52 +#define FACILITY_CREATE_RED_EVENT 53 +#define FACILITY_CREATE_RED_PIPE 54 +#define FACILITY_PIPE_OPERATION 55 + +int SpiceController::Connect(const int nRetries) +{ + int rc = -1; + int sleep_time = 0; + + // try to connect for specified count + for (int i = 0; rc != 0 && i < nRetries; ++i) + { + rc = Connect(); + g_usleep(sleep_time * G_USEC_PER_SEC); + ++sleep_time; + } + + return rc; +} + +void SpiceController::Disconnect() +{ +} + +void SpiceController::ChildExited(GPid pid, gint status, gpointer user_data) +{ + SpiceController *fake_this = (SpiceController *)user_data; + + g_message("Client with pid %p exited", pid); + + g_main_loop_quit(fake_this->m_child_watch_mainloop); + /* FIXME: we are not in the main thread!! */ + fake_this->m_plugin->OnSpiceClientExit(status); +} + +void SpiceController::WaitForPid(GPid pid) +{ + GMainContext *context; + GSource *source; + + context = g_main_context_new(); + + m_child_watch_mainloop = g_main_loop_new(context, FALSE); + source = g_child_watch_source_new(pid); + g_source_set_callback(source, (GSourceFunc)ChildExited, this, NULL); + g_source_attach(source, context); + + g_main_loop_run(m_child_watch_mainloop); + + g_main_loop_unref(m_child_watch_mainloop); + g_main_context_unref(context); + + g_spawn_close_pid(pid); + if (pid == m_pid_controller) + m_pid_controller = 0; +} + +gpointer SpiceController::ClientThread(gpointer data) +{ + SpiceController *fake_this = (SpiceController *)data; + gchar **env = g_get_environ(); + GPid pid; + gboolean spawned = FALSE; + GError *error = NULL; + GStrv client_argv; + GStrv fallback_argv; + fake_this->GetClientPaths(&client_argv, &fallback_argv); + + { + char *argv_str = g_strjoinv(" ", client_argv); + g_warning("main client cmdline: %s", argv_str); + g_free(argv_str); + argv_str = g_strjoinv(" ", fallback_argv); + g_warning("fallback client cmdline: %s", argv_str); + g_free(argv_str); + } + + fake_this->SetupControllerPipe(env); + + if (!fake_this->m_proxy.empty()) + env = g_environ_setenv(env, "SPICE_PROXY", fake_this->m_proxy.c_str(), TRUE); + + if (client_argv != NULL) { + spawned = g_spawn_async(NULL, + client_argv, env, + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, /* child_func, child_arg */ + &pid, &error); + if (error != NULL) { + g_warning("failed to start %s: %s", client_argv[0], error->message); + g_warn_if_fail(spawned == FALSE); + g_clear_error(&error); + } + } + if (!spawned && (fallback_argv != NULL)) { + // TODO: temporary fallback for backward compatibility + g_message("failed to run preferred client, running fallback client instead"); + spawned = g_spawn_async(NULL, fallback_argv, env, + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, /* child_func, child_arg */ + &pid, &error); + if (error != NULL) { + g_warning("failed to start %s: %s", fallback_argv[0], error->message); + g_warn_if_fail(spawned == FALSE); + g_clear_error(&error); + } + } + g_strfreev(env); + g_strfreev(client_argv); + g_strfreev(fallback_argv); + + if (!spawned) { + g_critical("ERROR failed to run spicec fallback"); + return NULL; + } + +#ifdef XP_UNIX + fake_this->m_pid_controller = pid; +#endif + fake_this->WaitForPid(pid); + + return NULL; +} + +bool SpiceController::StartClient() +{ + GThread *thread; + + thread = g_thread_create(ClientThread, this, FALSE, NULL); + + return (thread != NULL); +} + +int SpiceController::TranslateRC(int nRC) +{ + switch (nRC) + { + case SPICEC_ERROR_CODE_SUCCESS: + return 0; + + case SPICEC_ERROR_CODE_GETHOSTBYNAME_FAILED: + return RDP_ERROR_CODE_HOST_NOT_FOUND; + + case SPICEC_ERROR_CODE_CONNECT_FAILED: + return RDP_ERROR_CODE_WINSOCK_CONNECT_FAILED; + + case SPICEC_ERROR_CODE_ERROR: + case SPICEC_ERROR_CODE_SOCKET_FAILED: + return RDP_ERROR_CODE_INTERNAL_ERROR; + + case SPICEC_ERROR_CODE_RECV_FAILED: + return RDP_ERROR_RECV_WINSOCK_FAILED; + + case SPICEC_ERROR_CODE_SEND_FAILED: + return RDP_ERROR_SEND_WINSOCK_FAILED; + + case SPICEC_ERROR_CODE_NOT_ENOUGH_MEMORY: + return RDP_ERROR_CODE_OUT_OF_MEMORY; + + case SPICEC_ERROR_CODE_AGENT_TIMEOUT: + return RDP_ERROR_CODE_TIMEOUT; + + case SPICEC_ERROR_CODE_AGENT_ERROR: + return RDP_ERROR_CODE_INTERNAL_ERROR; + + default: + return RDP_ERROR_CODE_INTERNAL_ERROR; + } +} diff --git a/SpiceXPI/src/plugin/controller.h b/SpiceXPI/src/plugin/controller.h index de4516c..4473dd4 100644 --- a/SpiceXPI/src/plugin/controller.h +++ b/SpiceXPI/src/plugin/controller.h @@ -60,6 +60,7 @@ #include <glib.h> #include <glib-object.h> /* for GStrv */ +#include <gio/gio.h> #include <string> extern "C" { # include <stdint.h> @@ -74,32 +75,34 @@ class SpiceController { public: SpiceController(nsPluginInstance *aPlugin); - ~SpiceController(); + virtual ~SpiceController(); bool StartClient(); - void StopClient(); + virtual void StopClient() = 0; void SetFilename(const std::string &name); void SetProxy(const std::string &proxy); int Connect(int nRetries); - void Disconnect(); - uint32_t Write(const void *lpBuffer, uint32_t nBytesToWrite); + virtual void Disconnect(); + virtual uint32_t Write(const void *lpBuffer, uint32_t nBytesToWrite) = 0; static int TranslateRC(int nRC); +protected: + std::string m_name; + std::string m_proxy; + GPid m_pid_controller; + GOutputStream *m_pipe; + private: - int Connect(); + virtual int Connect() = 0; void WaitForPid(GPid pid); - void SetupControllerPipe(GStrv &env); - void GetClientPaths(GStrv *client_argv, GStrv *fallback_argv); + virtual void SetupControllerPipe(GStrv &env) = 0; + virtual bool CheckPipe() = 0; + virtual void GetClientPaths(GStrv *client_argv, GStrv *fallback_argv) = 0; static void ChildExited(GPid pid, gint status, gpointer user_data); static gpointer ClientThread(gpointer data); nsPluginInstance *m_plugin; - int m_client_socket; - std::string m_name; - std::string m_tmp_dir; - pid_t m_pid_controller; - std::string m_proxy; GMainLoop *m_child_watch_mainloop; }; diff --git a/SpiceXPI/src/plugin/plugin.cpp b/SpiceXPI/src/plugin/plugin.cpp index e8c916e..5ecc793 100644 --- a/SpiceXPI/src/plugin/plugin.cpp +++ b/SpiceXPI/src/plugin/plugin.cpp @@ -67,7 +67,7 @@ extern "C" { #include <fstream> #include <set> -#include "controller.h" +#include "controller-unix.h" #include "plugin.h" #include "nsScriptablePeer.h" @@ -173,7 +173,6 @@ void NS_DestroyPluginInstance(nsPluginInstanceBase *aPlugin) nsPluginInstance::nsPluginInstance(NPP aInstance): nsPluginInstanceBase(), m_connected_status(-2), - m_external_controller(this), m_instance(aInstance), m_initialized(true), m_window(NULL), @@ -186,6 +185,8 @@ nsPluginInstance::nsPluginInstance(NPP aInstance): m_scriptable_peer(NULL) { g_type_init(); + + m_external_controller = new SpiceControllerUnix(this); } nsPluginInstance::~nsPluginInstance() @@ -196,6 +197,7 @@ nsPluginInstance::~nsPluginInstance() // and zero its m_plugin member if (m_scriptable_peer) NPN_ReleaseObject(m_scriptable_peer); + delete(m_external_controller); } NPBool nsPluginInstance::init(NPWindow *aWindow) @@ -221,7 +223,7 @@ NPBool nsPluginInstance::init(NPWindow *aWindow) m_color_depth.clear(); m_disable_effects.clear(); m_proxy.clear(); - m_external_controller.SetProxy(std::string()); + m_external_controller->SetProxy(std::string()); m_fullscreen = false; m_smartcard = false; @@ -526,12 +528,12 @@ char *nsPluginInstance::GetProxy() const void nsPluginInstance::SetProxy(const char *aProxy) { m_proxy = aProxy; - m_external_controller.SetProxy(m_proxy); + m_external_controller->SetProxy(m_proxy); } void nsPluginInstance::WriteToPipe(const void *data, uint32_t size) { - m_external_controller.Write(data, size); + m_external_controller->Write(data, size); } void nsPluginInstance::SendInit() @@ -628,12 +630,12 @@ void nsPluginInstance::Connect() return; } - if (!m_external_controller.StartClient()) { + if (!m_external_controller->StartClient()) { g_critical("failed to start SPICE client"); return; } - if (m_external_controller.Connect(10) != 0) + if (m_external_controller->Connect(10) != 0) { g_critical("could not connect to spice client controller"); return; @@ -681,7 +683,7 @@ void nsPluginInstance::Show() void nsPluginInstance::Disconnect() { - m_external_controller.StopClient(); + m_external_controller->StopClient(); } void nsPluginInstance::ConnectedStatus(int32_t *retval) @@ -755,11 +757,11 @@ void nsPluginInstance::CallOnDisconnected(int code) void nsPluginInstance::OnSpiceClientExit(int exit_code) { - m_connected_status = m_external_controller.TranslateRC(exit_code); + m_connected_status = m_external_controller->TranslateRC(exit_code); if (!getenv("SPICE_XPI_DEBUG")) { CallOnDisconnected(exit_code); - m_external_controller.Disconnect(); + m_external_controller->Disconnect(); } RemoveTrustStoreFile(); diff --git a/SpiceXPI/src/plugin/plugin.h b/SpiceXPI/src/plugin/plugin.h index 5e7f079..7884dc7 100644 --- a/SpiceXPI/src/plugin/plugin.h +++ b/SpiceXPI/src/plugin/plugin.h @@ -190,7 +190,7 @@ private: bool RemoveTrustStoreFile(); int32_t m_connected_status; - SpiceController m_external_controller; + SpiceController *m_external_controller; NPP m_instance; NPBool m_initialized; -- 1.8.1.4 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel