after this patch: "LoadPlugin: failed to initialize"..., 212LoadPlugin: failed to initialize shared library /home/elmarco/.mozilla/plugins/libnsISpicec.so [/home/elmarco/.mozilla/plugins/libnsISpicec.so: undefined symbol: _ZN19SpiceControllerUnix14GetClientPathsEPPPcS2_ On Tue, Mar 12, 2013 at 12:23 PM, Christophe Fergeau <cfergeau@xxxxxxxxxx> wrote: > 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 -- Marc-André Lureau _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel